diff --git a/ValidatorGuide.md b/ValidatorGuide.md deleted file mode 100644 index 7c295e9..0000000 --- a/ValidatorGuide.md +++ /dev/null @@ -1,55 +0,0 @@ -# How to run an EXZO Validator -## Build EXZO -### **1. Install rustc, cargo and rustfmt.** - -```bash -$ curl https://sh.rustup.rs -sSf | sh -$ source $HOME/.cargo/env -$ rustup component add rustfmt -``` - -Please sure you are always using the latest stable rust version by running: - -```bash -$ rustup update -``` - -On Linux systems you may need to install libssl-dev, pkg-config, zlib1g-dev, etc. On Ubuntu: - -```bash -$ sudo apt-get update -$ sudo apt-get install libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang make cmake protobuf-compiler -y -``` - -On Mac M1s, make sure you set up your terminal & homebrew [to use](https://5balloons.info/correct-way-to-install-and-use-homebrew-on-m1-macs/) Rosetta. You can install it with: - -```bash -$ softwareupdate --install-rosetta -``` - -### **2. Download the source code.** - -```bash -$ git clone https://github.com/ExzoNetwork/Exzo-Network-Blockchain.git -$ cd Exzo-Network-Blockchain -``` - -### **3. Build.** - -```bash -$ cargo build --release -``` - -## Validator Setup -### Configure EXZO CLI -**Mainnet** -``` -exzo config set --url https://rpc-main-1.exzo.network/rpc -``` - -**Testnet** -``` -exzo config set --url https://rpc-test-1.exzo.network/rpc -``` - -### Generate Validator Identity diff --git a/evm-utils/evm-block-recovery/src/exit_code.rs b/evm-utils/evm-block-recovery/src/exit_code.rs deleted file mode 100644 index bc59a9a..0000000 --- a/evm-utils/evm-block-recovery/src/exit_code.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub const UNABLE_TO_CREATE_LEDGER: i32 = 100; -pub const UNABLE_TO_QUERY_BIGTABLE: i32 = 101; -pub const INVALID_ARGUMENTS: i32 = 102; diff --git a/evm-utils/evm-block-recovery/src/timestamp.rs b/evm-utils/evm-block-recovery/src/timestamp.rs deleted file mode 100644 index a2084ea..0000000 --- a/evm-utils/evm-block-recovery/src/timestamp.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::{collections::HashMap, path::Path}; - -use anyhow::*; -use chrono::{DateTime, Utc}; -use evm_state::BlockNum; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize)] -struct BlockDto { - number: u64, - timestamp: Option>, - unixtime: Option, -} - -/// FIXME: Source timestamp file exported with Time Zone error -const FIVE_HRS: u64 = 18000; - -pub fn load_timestamps(path: impl AsRef) -> Result> { - let timestamps = std::fs::read_to_string(path).unwrap(); - - let result: HashMap = serde_json::from_str::>(×tamps) - .unwrap() - .into_iter() - .map(|block| { - let block_number = block.number; - - // Extract time from "unixtime" prop., or try to parse ISO 8601 "timestamp" prop. - let time = block - .unixtime - .or_else(|| block.timestamp.map(|t| t.timestamp() as u64 - FIVE_HRS)) - .unwrap(); - - (block_number, time) - }) - .collect(); - - Ok(result) -} diff --git a/exzo-fork 2/.gitignore b/exzo-fork 2/.gitignore deleted file mode 100644 index 5787da4..0000000 --- a/exzo-fork 2/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -exzo-changes-remote-*-*.txt -exzo-changes-*-*.txt -# Just exzo-changes with prefix :^ - mean that this pathspec should be ignored -pathspec-*-*.txt \ No newline at end of file diff --git a/exzo-fork 2/exzo-rewrite b/exzo-fork 2/exzo-rewrite deleted file mode 100644 index f7ffc47..0000000 --- a/exzo-fork 2/exzo-rewrite +++ /dev/null @@ -1 +0,0 @@ -install \ No newline at end of file diff --git a/exzo-fork 2/git-merge-cleanup.sh b/exzo-fork 2/git-merge-cleanup.sh deleted file mode 100755 index 11fef8a..0000000 --- a/exzo-fork 2/git-merge-cleanup.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env zsh - -# Use this script after `git merge` before resolving conflicts. - -current_folder="$(dirname "$0")" -# echo "Reading version from $current_folder/solana-base" -BASE=$(cat $current_folder/solana-base) -echo "Solana base version is $BASE" - -LOCAL=$(cat $current_folder/../.git/ORIG_HEAD) - -echo "Exzo commit is $LOCAL" -REMOTE=$(cat $current_folder/../.git/MERGE_HEAD) - -echo "Solana merging commit is $REMOTE" - -# LOCAL=$(git rev-parse HEAD) - -exzo_changes="$current_folder/exzo-changes-$BASE-$LOCAL.txt" - -remote_changes="$current_folder/exzo-changes-remote-$REMOTE-$LOCAL.txt" -# echo "Forming list of files that differ in current branch from base version $exzo_changes" -# 1. ignore docs/explorer/web3.js changes, use grep instead of pathspec exclude pattern because git is not handle it correctly -# - grep -Ev '^(docs|explorer|web3\.js)' -# 2. Use numstat with cut to save only file names - git diff --numstat | cut -f3- -# 3. If some file was renamed use only renamed part - sed -r 's/\{(.*) => (.*)\}/\2/' - - -git diff $LOCAL..$BASE --numstat | cut -f3- | sed -r 's/\{(.*) => (.*)\}/\2/' | grep -Ev '^(docs|explorer|web3\.js)' | sort > $exzo_changes - -git diff $REMOTE..$BASE --numstat | cut -f3- | sed -r 's/\{(.*) => (.*)\}/\2/' | grep -Ev '^(docs|explorer|web3\.js)' | sort > $remote_changes - -pathspec_file="$current_folder/automerge-$BASE-$LOCAL.txt" - -keep_ours_file="$current_folder/exzo-rewrite" - -# Exzo use multiple repositories instead of big mono-repo: -# 1. exzo-chain is repository only for blockchain related stuff. -# 2. web3-js mooved into https://github.com/exzo/web3.js -# 3. Explorer mooved into https://github.com/exzo/native-explorer -# 4. Docs are mooved into https://github.com/ExzoNetwork/Exzo-Network-Blockchain-docs -# 5. account-benches - -# Removes js related stuf -git rm -rf explorer web3.js docs - -# git checkout --ours --pathspec-from-file c - -# Now save all files that was modified in remote but wasnt in our local -# Filter out changes from file that wasn't touched by exzo changes - -for file in $(comm -23 $remote_changes $exzo_changes) -do -echo "Adding file $file from remote" -# its okay that this commands can not find some files, because its can be marked as already fixed -git checkout --theirs -- $file -git add $file -done - -# Old version with git pathspecs -# sed -e 's/^/\:\^/' $exzo_changes > $pathspec_file - -# if git checkout --theirs --pathspec-from-file $pathspec_file; then -# # If command succeed then no removed files found in remote branch -# else -# # if fails -# # 1. Collect list of failed files - -# git checkout --theirs --pathspec-from-file $pathspec_file |& awk '{ print $3 }' | sed "s/[«|»]/'/g" > "$current_folder/remote-removed.txt" - -# # 2. Explicitly remove files that was already removed. -# cat "$current_folder/remote-removed.txt" | xargs git rm -# # 3. Repeat checkout of remaining files -# git checkout --theirs --pathspec-from-file $pathspec_file cat -# fi - -# git add --pathspec-from-file $pathspec_file \ No newline at end of file diff --git a/exzo-fork 2/readme.md b/exzo-fork 2/readme.md deleted file mode 100644 index e34dcf6..0000000 --- a/exzo-fork 2/readme.md +++ /dev/null @@ -1,73 +0,0 @@ -# Exzo fork maintenance guide and tools - -Exzo is a fork of Solana blockchain. -This document will describe how we treat code, and manage branches. - -## Exzo releases -Solana has edge/beta/stable branches: -- edge is only used on testnet; -- beta is some kind of migration, early adoption of edge codebase to the mainnet; -- stable is widespread on mainnet - -Fixes are ported on all three branches edge/beta/stable. -New features are only mooved to the edge. - -**In Exzo Some of Solana changes (especially security fixes) are ported dirrectly to Exzo repository.** - -In Exzo we use `develop` branch as a single source of code. -- Our develop branch are tested on testnet and devnet. -- Realeases are tagged dirrectly on develop, and only those releases are used by validator. -- We don't have multi branches for testnet/mainnet purposes, because most of our network related features are already tested on solana edge branch. - - -## Merging solana features -At some point of time we do a "full-update" which merge all solana changes to the exzo develop. - -Merging are done using `git merge` and most of conflicts should be resolved manually, to make it easier for person who are resolving this conflicts. -In this document we describe some common parts that can be treat differently, and trying to document what changes are done in solana codebase by exzo. - -Short algorithm describing how to handle full update: -1. Pointing out what files was changed in exzo since last full-update. -For doing this we save special file called `solana-base` which contain single line - solana release tag that was used during last update. -** Note: ':!docs' ':!explorer' ':!web3.js' - are ignored folders -`git diff $TAG --numstat -- ':!docs' ':!explorer' ':!web3.js'` -2. Ignore removed files in merge. -We remove js related stuff from our monorepo -`git rm -rf docs web3.js explorer` -3. Ignore crates that was rewritted by us -`git checkout --theirs install` -4. Ignore files that wasnt modified by exzo (checkout number 1 of this algorithm) -`git checkout --theirs __` -5. Solve remaining conflicts by groups: -To solve conflicts we recommend to use some kind of 3way merging tools, like beyond compare -a) Solve Cargo.toml conflicts - need to automatize this - usually it contains version bumping, and some adding of evm-utils that can conflict with other dependencies addings. -b) Solve core, sdk and runtime, this 3 crates contain a lot of integration points and should be carefully merged most of changed files are listed in `many-changes.txt` -c) Solve remaining parts. -6. feature_set.rs - Porting new features from solana has different rules that just regular merge: -a) Make sure that no legacy features was removed before activation on mainnet/testnet - it can lead to instability. -b) Make sure that all public keys was changed - we have different secret keys. - -1-4 of this algorithm was implemented in shell script called `git-merge-cleanup.sh` - - -### Review of merge - -It's hard to review all changes, because github will visualize all the changes from merged branch. -To easier review, compare two diffs of `solana-base` (checkout solana-base file) and `develop` before and after merging, -they should be more or less the same. - -### Finalizing merge - -During solana merge, develop can have new features. Because we have single branch this can make some problems. -As algorithm that solve problems, use follow: -1. After merge is done create a new version branch '0.3', '0.5', etc. from latest `develop`. -2. Create a new tag and release latest version. -3. Rename merge branch to be `develop` all patches that was merged in latest release should be also cherry-picked to merged branch. -4. New pre-release with bumped version should be released for future tests. - - - -## Exzo versioning -Currently we dont use major version, and instead using minor and patch. -- Patch version are used when some small changes or feature is implemented. -- Major version are increased when "full-update" is done, or when some backward incompatible change is done - like snapshot version bumping. diff --git a/exzo-fork 2/solana-base b/exzo-fork 2/solana-base deleted file mode 100644 index 3f11645..0000000 --- a/exzo-fork 2/solana-base +++ /dev/null @@ -1 +0,0 @@ -v1.9.29 \ No newline at end of file diff --git a/exzo-fork/git-merge-cleanup.sh b/exzo-fork/git-merge-cleanup.sh old mode 100755 new mode 100644 index 620c559..11fef8a --- a/exzo-fork/git-merge-cleanup.sh +++ b/exzo-fork/git-merge-cleanup.sh @@ -36,8 +36,8 @@ keep_ours_file="$current_folder/exzo-rewrite" # Exzo use multiple repositories instead of big mono-repo: # 1. exzo-chain is repository only for blockchain related stuff. -# 2. web3-js mooved into https://github.com/ExzoNetwork/web3.js -# 3. Explorer mooved into https://github.com/ExzoNetwork/native-explorer +# 2. web3-js mooved into https://github.com/exzo/web3.js +# 3. Explorer mooved into https://github.com/exzo/native-explorer # 4. Docs are mooved into https://github.com/ExzoNetwork/Exzo-Network-Blockchain-docs # 5. account-benches diff --git a/install/src/bin/exzo-install-init 2.rs b/install/src/bin/exzo-install-init 2.rs deleted file mode 100644 index 1d173e3..0000000 --- a/install/src/bin/exzo-install-init 2.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::process::exit; - -fn press_enter() { - // On windows, where installation happens in a console that may have opened just for this - // purpose, give the user an opportunity to see the error before the window closes. - if cfg!(windows) && atty::is(atty::Stream::Stdin) { - println!(); - println!("Press the Enter key to continue."); - - use std::io::BufRead; - let stdin = std::io::stdin(); - let stdin = stdin.lock(); - let mut lines = stdin.lines(); - lines.next(); - } -} - -fn main() { - exzo_install::main_init().unwrap_or_else(|err| { - println!("Error: {}", err); - press_enter(); - exit(1); - }); - press_enter(); -} diff --git a/programs/exzo-account-program 2/.rustfmt.toml b/programs/exzo-account-program 2/.rustfmt.toml deleted file mode 100644 index 425e5fd..0000000 --- a/programs/exzo-account-program 2/.rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -merge_derives = false \ No newline at end of file diff --git a/programs/exzo-account-program 2/Cargo.toml b/programs/exzo-account-program 2/Cargo.toml deleted file mode 100644 index 2e8d5ba..0000000 --- a/programs/exzo-account-program 2/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "exzo-account-program" -version = "0.0.1" -edition = "2018" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - - -[dependencies] -borsh = "0.9.1" -borsh-derive = "0.9.1" -serde = { version = "1.0.125", features = ["derive"] } - -solana-sdk = { path = "../../sdk", version = "1.9.13" } - -[dev-dependencies] -base64 = "0.13.0" \ No newline at end of file diff --git a/programs/exzo-account-program 2/src/lib.rs b/programs/exzo-account-program 2/src/lib.rs deleted file mode 100644 index e818afa..0000000 --- a/programs/exzo-account-program 2/src/lib.rs +++ /dev/null @@ -1,202 +0,0 @@ -use std::convert::TryFrom; - -use borsh::{BorshDeserialize, BorshSchema, BorshSerialize}; -use serde::{Deserialize, Serialize}; - -use solana_sdk::pubkey::Pubkey; - -solana_sdk::declare_id!("VAcccHVjpknkW5N5R9sfRppQxYJrJYVV7QJGKchkQj5"); - -/// A wrapper enum for consistency across programs -#[derive(Debug, PartialEq)] -#[derive(BorshSerialize, BorshDeserialize, BorshSchema)] -#[derive(Serialize, Deserialize)] -#[serde(rename_all = "camelCase", tag = "type", content = "info")] -pub enum ExzoAccountType { - Account(VAccountInfo), - Storage(VAccountStorage), -} - -/// Program states. -#[repr(C)] -#[derive(PartialEq, Debug, Clone)] -#[derive(BorshSerialize, BorshDeserialize, BorshSchema)] -#[derive(Serialize, Deserialize)] -pub struct VAccountInfo { - /// Vaccount version - pub version: u8, - /// - pub owners: [Pubkey; 3], - /// Genesis owner key that generates Vaccount address - pub genesis_seed_key: Pubkey, - /// Storage version - pub operational_storage_nonce: u16, - /// Token storage nonce - pub token_storage_nonce: u16, - /// Programs storage nonce - pub programs_storage_nonce: u16, -} - -impl VAccountInfo { - const SUFFIX_OPERATIONAL_STORAGE: &'static [u8] = b"operationals"; - - pub fn find_storage_key(&self, vaccount: &Pubkey) -> Pubkey { - Pubkey::find_program_address( - &[ - &vaccount.to_bytes(), - Self::SUFFIX_OPERATIONAL_STORAGE, - &self.operational_storage_nonce.to_le_bytes(), - ], - &crate::id(), - ) - .0 - } -} - -/// Storage of the basic Vaccount information. -#[repr(C)] -#[derive(PartialEq, Debug, Clone)] -#[derive(BorshSerialize, BorshDeserialize, BorshSchema)] -#[derive(Serialize, Deserialize)] -pub struct VAccountStorage { - /// Operational in not extended VAccount - pub operationals: Vec, -} - -impl VAccountStorage { - pub const LEN: usize = std::mem::size_of::(); - - pub fn deserialize_stream_array(data: &[u8]) -> Result { - data.chunks(Self::LEN) - .map(Operational::try_from_slice) - .collect::>() - .map(|operationals| Self { operationals }) - } -} - -/// Operational key state. -#[repr(C)] -#[derive(Clone, Debug, Default, PartialEq)] -#[derive(BorshDeserialize, BorshSerialize, BorshSchema)] -#[derive(Serialize, Deserialize)] -pub struct Operational { - /// Operational key - pub pubkey: Pubkey, - /// Operational key state - pub state: OperationalState, - /// Type of the agent session associated with an operational key - pub agent_type: [u8; 32], - /// Allowed instruction for operational key - pub scopes: [u8; 4], - /// Allowed tokens - pub tokens_indices: [u8; 32], - /// Allowed program addresses - pub external_programs_indices: [u8; 32], - /// Master key is allowed to call any instruction in Vaccount - pub is_master_key: bool, -} - -/// Operational key state. -#[repr(u8)] -#[derive(Clone, Copy, Debug, PartialEq)] -#[derive(BorshDeserialize, BorshSerialize, BorshSchema)] -#[derive(Serialize, Deserialize)] -pub enum OperationalState { - /// Operational key is initialized - Initialized, - /// Operational has been frozen by the owner/operational freeze authority. - Frozen, -} - -impl Default for OperationalState { - fn default() -> Self { - OperationalState::Initialized - } -} - -// TODO: try to avoid direct size hardcodes -pub const ACCOUNT_LEN: usize = 135; - -#[derive(Debug)] -pub enum ParseError { - AccountNotParsable, -} - -impl TryFrom<&[u8]> for ExzoAccountType { - type Error = ParseError; - - fn try_from(data: &[u8]) -> Result { - if data.len() == ACCOUNT_LEN { - VAccountInfo::try_from_slice(data).map(ExzoAccountType::Account) - } else { - VAccountStorage::deserialize_stream_array(data).map(ExzoAccountType::Storage) - } - .map_err(|_| ParseError::AccountNotParsable) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use std::str::FromStr; - - #[test] - #[ignore] // TODO - fn it_checks_account_len() { - assert_eq!(std::mem::size_of::(), ACCOUNT_LEN); - assert_eq!( - solana_sdk::borsh::get_packed_len::(), - ACCOUNT_LEN - ) - } - - #[test] - fn test_deserialize_vaccountinfo() { - let vacc_data_base64 = include_str!("../tests_data/account_info.txt"); - let vacc_data = base64::decode(vacc_data_base64).unwrap(); - let vacc: VAccountInfo = borsh::BorshDeserialize::try_from_slice(&vacc_data[..]).unwrap(); - - assert_eq!( - vacc, - VAccountInfo { - version: 1, - owners: [ - Pubkey::from_str("9atTpuaX8WoxWr7xDanvMmE41bPWkCLnSM4V4CMTu4Lq").unwrap(), - Pubkey::default(), - Pubkey::default() - ], - genesis_seed_key: Pubkey::from_str("9atTpuaX8WoxWr7xDanvMmE41bPWkCLnSM4V4CMTu4Lq") - .unwrap(), - operational_storage_nonce: 25, - token_storage_nonce: 1, - programs_storage_nonce: 1 - } - ); - } - - #[test] - fn test_deserialize_vaccountstorage() { - let storage_data_base64 = include_str!("../tests_data/account_storage.txt"); - let storage_data = base64::decode(storage_data_base64).unwrap(); - - let vstorage = VAccountStorage::deserialize_stream_array(&storage_data).unwrap(); - - assert_eq!(vstorage.operationals.len(), 24); - assert_eq!( - vstorage.operationals[0], - Operational { - pubkey: Pubkey::from_str("6kNwJXdAuDuXzFKKhYzMpQY5yGSFyus4eXPxxWJkDe2C").unwrap(), - state: OperationalState::Initialized, - agent_type: [ - 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 - ], - scopes: [127, 250, 0, 0], - tokens_indices: [0; 32], - external_programs_indices: [0; 32], - is_master_key: false, - } - ); - } -} diff --git a/programs/exzo-account-program 2/tests_data/account_info.txt b/programs/exzo-account-program 2/tests_data/account_info.txt deleted file mode 100644 index 5a60ab0..0000000 --- a/programs/exzo-account-program 2/tests_data/account_info.txt +++ /dev/null @@ -1 +0,0 @@ -AX+L2di/S0km7vwWVWzabHtKq/S5CjWr58iCk6H+KxZqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH+L2di/S0km7vwWVWzabHtKq/S5CjWr58iCk6H+KxZqGQABAAEA \ No newline at end of file diff --git a/programs/exzo-account-program 2/tests_data/account_storage.txt b/programs/exzo-account-program 2/tests_data/account_storage.txt deleted file mode 100644 index ecbb9ad..0000000 --- a/programs/exzo-account-program 2/tests_data/account_storage.txt +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/programs/exzo-relying-party-program 2/.rustfmt.toml b/programs/exzo-relying-party-program 2/.rustfmt.toml deleted file mode 100644 index 425e5fd..0000000 --- a/programs/exzo-relying-party-program 2/.rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -merge_derives = false \ No newline at end of file diff --git a/programs/exzo-relying-party-program 2/Cargo.toml b/programs/exzo-relying-party-program 2/Cargo.toml deleted file mode 100644 index edfb431..0000000 --- a/programs/exzo-relying-party-program 2/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "exzo-relying-party-program" -version = "0.0.1" -edition = "2018" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -borsh = "0.9.1" -borsh-derive = "0.9.1" -serde = { version = "1.0.125", features = ["derive"] } -serde_with = "1.9" - -solana-program = { path = "../../sdk/program", version = "1.9.13" } diff --git a/programs/exzo-relying-party-program 2/src/lib.rs b/programs/exzo-relying-party-program 2/src/lib.rs deleted file mode 100644 index b254f41..0000000 --- a/programs/exzo-relying-party-program 2/src/lib.rs +++ /dev/null @@ -1,76 +0,0 @@ -use std::convert::TryFrom; - -use serde::{Deserialize, Serialize}; -use serde_with::serde_as; -use serde_with::DisplayFromStr; - -use { - borsh::{BorshDeserialize, BorshSchema, BorshSerialize}, - solana_program::{program_pack::IsInitialized, pubkey::Pubkey}, -}; -solana_program::declare_id!("VRPLtk4k31bDL99mn1A5mE96CUUzQ9PnftEwf2LvMiG"); - -/// Struct provided metadata of the related program -#[serde_as] -#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)] -#[derive(Serialize, Deserialize)] -pub struct RelyingPartyData { - /// Struct version, allows for upgrades to the program - pub version: u8, - /// The account allowed to update the data - #[serde_as(as = "DisplayFromStr")] - pub authority: Pubkey, - /// The metadata of the related program - pub related_program_data: RelatedProgramInfo, -} - -/// Metadata of the some program to show for Vaccount -#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, BorshSchema, PartialEq)] -#[derive(Serialize, Deserialize)] -pub struct RelatedProgramInfo { - /// Name of the program to show in Vaccount - pub name: String, - /// Icon content identifier - pub icon_cid: Vec, - /// Domain name of the related program - pub domain_name: String, - /// Allowed redirect URI for Vaccount in program - pub redirect_uri: Vec, -} - -impl RelatedProgramInfo { - /// https://en.wikipedia.org/wiki/Domain_name#Domain_name_syntax - pub const MAX_DOMAIN_LEN: u8 = 253; - /// Is valid domain name - pub fn is_valid_domain_name(domain_name: &str) -> bool { - if domain_name.len() > Self::MAX_DOMAIN_LEN as usize { - return false; - } - true - } -} - -impl RelyingPartyData { - /// Version to fill in on new created accounts - pub const CURRENT_VERSION: u8 = 1; -} - -impl IsInitialized for RelyingPartyData { - /// Is initialized - fn is_initialized(&self) -> bool { - self.version == Self::CURRENT_VERSION - } -} - -#[derive(Debug)] -pub enum ParseError { - AccountNotParsable, -} - -impl TryFrom<&[u8]> for RelyingPartyData { - type Error = ParseError; - - fn try_from(data: &[u8]) -> Result { - RelyingPartyData::try_from_slice(data).map_err(|_| ParseError::AccountNotParsable) - } -} diff --git a/validator/src/bin/exzo-test-validator 2.rs b/validator/src/bin/exzo-test-validator 2.rs deleted file mode 100644 index e3e919d..0000000 --- a/validator/src/bin/exzo-test-validator 2.rs +++ /dev/null @@ -1,728 +0,0 @@ -use { - clap::{crate_name, value_t, value_t_or_exit, values_t_or_exit, App, Arg}, - log::*, - solana_clap_utils::{ - input_parsers::{pubkey_of, pubkeys_of, value_of}, - input_validators::{ - is_parsable, is_pubkey, is_pubkey_or_keypair, is_slot, is_url_or_moniker, - normalize_to_url_if_moniker, - }, - }, - solana_client::rpc_client::RpcClient, - solana_core::tower_storage::FileTowerStorage, - solana_faucet::faucet::{run_local_faucet_with_port, FAUCET_PORT}, - solana_rpc::{rpc::JsonRpcConfig, rpc_pubsub_service::PubSubConfig}, - solana_sdk::{ - account::AccountSharedData, - clock::Slot, - epoch_schedule::{EpochSchedule, MINIMUM_SLOTS_PER_EPOCH}, - native_token::sol_to_lamports, - pubkey::Pubkey, - rent::Rent, - rpc_port, - signature::{read_keypair_file, write_keypair_file, Keypair, Signer}, - system_program, - }, - solana_streamer::socket::SocketAddrSpace, - solana_test_validator::*, - exzo_validator::{ - admin_rpc_service, dashboard::Dashboard, ledger_lockfile, lock_ledger, println_name_value, - redirect_stderr_to_file, - }, - std::{ - collections::HashSet, - fs, io, - net::{IpAddr, Ipv4Addr, SocketAddr}, - path::{Path, PathBuf}, - process::exit, - sync::{mpsc::channel, Arc, RwLock}, - time::{Duration, SystemTime, UNIX_EPOCH}, - }, -}; - -/* 10,000 was derived empirically by watching the size - * of the rocksdb/ directory self-limit itself to the - * 40MB-150MB range when running `solana-test-validator` - */ -const DEFAULT_MAX_LEDGER_SHREDS: u64 = 10_000; - -const DEFAULT_FAUCET_SOL: f64 = 1_000_000.; - -#[derive(PartialEq)] -enum Output { - None, - Log, - Dashboard, -} - -fn main() { - let default_rpc_port = rpc_port::DEFAULT_RPC_PORT.to_string(); - let default_faucet_port = FAUCET_PORT.to_string(); - let default_limit_ledger_size = DEFAULT_MAX_LEDGER_SHREDS.to_string(); - let default_faucet_sol = DEFAULT_FAUCET_SOL.to_string(); - - let matches = App::new("solana-test-validator") - .about("Test Validator") - .version(solana_version::version!()) - .arg({ - let arg = Arg::with_name("config_file") - .short("C") - .long("config") - .value_name("PATH") - .takes_value(true) - .help("Configuration file to use"); - if let Some(ref config_file) = *solana_cli_config::CONFIG_FILE { - arg.default_value(config_file) - } else { - arg - } - }) - .arg( - Arg::with_name("json_rpc_url") - .short("u") - .long("url") - .value_name("URL_OR_MONIKER") - .takes_value(true) - .validator(is_url_or_moniker) - .help( - "URL for Solana's JSON RPC or moniker (or their first letter): \ - [mainnet-beta, testnet, devnet, localhost]", - ), - ) - .arg( - Arg::with_name("mint_address") - .long("mint") - .value_name("PUBKEY") - .validator(is_pubkey) - .takes_value(true) - .help( - "Address of the mint account that will receive tokens \ - created at genesis. If the ledger already exists then \ - this parameter is silently ignored [default: client keypair]", - ), - ) - .arg( - Arg::with_name("ledger_path") - .short("l") - .long("ledger") - .value_name("DIR") - .takes_value(true) - .required(true) - .default_value("test-ledger") - .help("Use DIR as ledger location"), - ) - .arg( - Arg::with_name("reset") - .short("r") - .long("reset") - .takes_value(false) - .help( - "Reset the ledger to genesis if it exists. \ - By default the validator will resume an existing ledger (if present)", - ), - ) - .arg( - Arg::with_name("quiet") - .short("q") - .long("quiet") - .takes_value(false) - .conflicts_with("log") - .help("Quiet mode: suppress normal output"), - ) - .arg( - Arg::with_name("log") - .long("log") - .takes_value(false) - .conflicts_with("quiet") - .help("Log mode: stream the validator log"), - ) - .arg( - Arg::with_name("faucet_port") - .long("faucet-port") - .value_name("PORT") - .takes_value(true) - .default_value(&default_faucet_port) - .validator(exzo_validator::port_validator) - .help("Enable the faucet on this port"), - ) - .arg( - Arg::with_name("rpc_port") - .long("rpc-port") - .value_name("PORT") - .takes_value(true) - .default_value(&default_rpc_port) - .validator(exzo_validator::port_validator) - .help("Enable JSON RPC on this port, and the next port for the RPC websocket"), - ) - .arg( - Arg::with_name("rpc_pubsub_enable_vote_subscription") - .long("rpc-pubsub-enable-vote-subscription") - .takes_value(false) - .help("Enable the unstable RPC PubSub `voteSubscribe` subscription"), - ) - .arg( - Arg::with_name("bpf_program") - .long("bpf-program") - .value_name("ADDRESS_OR_PATH BPF_PROGRAM.SO") - .takes_value(true) - .number_of_values(2) - .multiple(true) - .help( - "Add a BPF program to the genesis configuration. \ - If the ledger already exists then this parameter is silently ignored. \ - First argument can be a public key or path to file that can be parsed as a keypair", - ), - ) - .arg( - Arg::with_name("account") - .long("account") - .value_name("ADDRESS FILENAME.JSON") - .takes_value(true) - .number_of_values(2) - .multiple(true) - .help( - "Load an account from the provided JSON file (see `solana account --help` on how to dump \ - an account to file). Files are searched for relatively to CWD and tests/fixtures. \ - If the ledger already exists then this parameter is silently ignored", - ), - ) - .arg( - Arg::with_name("no_bpf_jit") - .long("no-bpf-jit") - .takes_value(false) - .help("Disable the just-in-time compiler and instead use the interpreter for BPF. Windows always disables JIT."), - ) - .arg( - Arg::with_name("ticks_per_slot") - .long("ticks-per-slot") - .value_name("TICKS") - .validator(is_parsable::) - .takes_value(true) - .help("The number of ticks in a slot"), - ) - .arg( - Arg::with_name("slots_per_epoch") - .long("slots-per-epoch") - .value_name("SLOTS") - .validator(|value| { - value - .parse::() - .map_err(|err| format!("error parsing '{}': {}", value, err)) - .and_then(|slot| { - if slot < MINIMUM_SLOTS_PER_EPOCH { - Err(format!("value must be >= {}", MINIMUM_SLOTS_PER_EPOCH)) - } else { - Ok(()) - } - }) - }) - .takes_value(true) - .help( - "Override the number of slots in an epoch. \ - If the ledger already exists then this parameter is silently ignored", - ), - ) - .arg( - Arg::with_name("gossip_port") - .long("gossip-port") - .value_name("PORT") - .takes_value(true) - .help("Gossip port number for the validator"), - ) - .arg( - Arg::with_name("gossip_host") - .long("gossip-host") - .value_name("HOST") - .takes_value(true) - .validator(solana_net_utils::is_host) - .help( - "Gossip DNS name or IP address for the validator to advertise in gossip \ - [default: 127.0.0.1]", - ), - ) - .arg( - Arg::with_name("dynamic_port_range") - .long("dynamic-port-range") - .value_name("MIN_PORT-MAX_PORT") - .takes_value(true) - .validator(exzo_validator::port_range_validator) - .help( - "Range to use for dynamically assigned ports \ - [default: 1024-65535]", - ), - ) - .arg( - Arg::with_name("bind_address") - .long("bind-address") - .value_name("HOST") - .takes_value(true) - .validator(solana_net_utils::is_host) - .default_value("0.0.0.0") - .help("IP address to bind the validator ports [default: 0.0.0.0]"), - ) - .arg( - Arg::with_name("clone_account") - .long("clone") - .short("c") - .value_name("ADDRESS") - .takes_value(true) - .validator(is_pubkey_or_keypair) - .multiple(true) - .requires("json_rpc_url") - .help( - "Copy an account from the cluster referenced by the --url argument the \ - genesis configuration. \ - If the ledger already exists then this parameter is silently ignored", - ), - ) - .arg( - Arg::with_name("warp_slot") - .required(false) - .long("warp-slot") - .short("w") - .takes_value(true) - .value_name("WARP_SLOT") - .validator(is_slot) - .min_values(0) - .max_values(1) - .help( - "Warp the ledger to WARP_SLOT after starting the validator. \ - If no slot is provided then the current slot of the cluster \ - referenced by the --url argument will be used", - ), - ) - .arg( - Arg::with_name("limit_ledger_size") - .long("limit-ledger-size") - .value_name("SHRED_COUNT") - .takes_value(true) - .default_value(default_limit_ledger_size.as_str()) - .help("Keep this amount of shreds in root slots."), - ) - .arg( - Arg::with_name("faucet_sol") - .long("faucet-sol") - .takes_value(true) - .value_name("SOL") - .default_value(default_faucet_sol.as_str()) - .help( - "Give the faucet address this much SOL in genesis. \ - If the ledger already exists then this parameter is silently ignored", - ), - ) - .arg( - Arg::with_name("geyser_plugin_config") - .long("geyser-plugin-config") - .alias("accountsdb-plugin-config") - .value_name("FILE") - .takes_value(true) - .multiple(true) - .hidden(true) - .help("Specify the configuration file for the Geyser plugin."), - ) - .arg( - Arg::with_name("no_accounts_db_caching") - .long("no-accounts-db-caching") - .help("Disables accounts caching"), - ) - .arg( - Arg::with_name("deactivate_feature") - .long("deactivate-feature") - .takes_value(true) - .value_name("FEATURE_PUBKEY") - .validator(is_pubkey) - .multiple(true) - .help("deactivate this feature in genesis.") - ) - .get_matches(); - - let output = if matches.is_present("quiet") { - Output::None - } else if matches.is_present("log") { - Output::Log - } else { - Output::Dashboard - }; - - let ledger_path = value_t_or_exit!(matches, "ledger_path", PathBuf); - let reset_ledger = matches.is_present("reset"); - - if !ledger_path.exists() { - fs::create_dir(&ledger_path).unwrap_or_else(|err| { - println!( - "Error: Unable to create directory {}: {}", - ledger_path.display(), - err - ); - exit(1); - }); - } - - let mut ledger_lock = ledger_lockfile(&ledger_path); - let _ledger_write_guard = lock_ledger(&ledger_path, &mut ledger_lock); - if reset_ledger { - remove_directory_contents(&ledger_path).unwrap_or_else(|err| { - println!("Error: Unable to remove {}: {}", ledger_path.display(), err); - exit(1); - }) - } - solana_runtime::snapshot_utils::remove_tmp_snapshot_archives(&ledger_path); - - let validator_log_symlink = ledger_path.join("validator.log"); - - let logfile = if output != Output::Log { - let validator_log_with_timestamp = format!( - "validator-{}.log", - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() - ); - - let _ = fs::remove_file(&validator_log_symlink); - symlink::symlink_file(&validator_log_with_timestamp, &validator_log_symlink).unwrap(); - - Some( - ledger_path - .join(validator_log_with_timestamp) - .into_os_string() - .into_string() - .unwrap(), - ) - } else { - None - }; - let _logger_thread = redirect_stderr_to_file(logfile); - - info!("{} {}", crate_name!(), solana_version::version!()); - info!("Starting validator with: {:#?}", std::env::args_os()); - solana_core::validator::report_target_features(); - - // TODO: Ideally test-validator should *only* allow private addresses. - let socket_addr_space = SocketAddrSpace::new(/*allow_private_addr=*/ true); - let cli_config = if let Some(config_file) = matches.value_of("config_file") { - solana_cli_config::Config::load(config_file).unwrap_or_default() - } else { - solana_cli_config::Config::default() - }; - - let cluster_rpc_client = value_t!(matches, "json_rpc_url", String) - .map(normalize_to_url_if_moniker) - .map(RpcClient::new); - - let (mint_address, random_mint) = pubkey_of(&matches, "mint_address") - .map(|pk| (pk, false)) - .unwrap_or_else(|| { - read_keypair_file(&cli_config.keypair_path) - .map(|kp| (kp.pubkey(), false)) - .unwrap_or_else(|_| (Keypair::new().pubkey(), true)) - }); - - let rpc_port = value_t_or_exit!(matches, "rpc_port", u16); - let enable_vote_subscription = matches.is_present("rpc_pubsub_enable_vote_subscription"); - let faucet_port = value_t_or_exit!(matches, "faucet_port", u16); - let ticks_per_slot = value_t!(matches, "ticks_per_slot", u64).ok(); - let slots_per_epoch = value_t!(matches, "slots_per_epoch", Slot).ok(); - let gossip_host = matches.value_of("gossip_host").map(|gossip_host| { - solana_net_utils::parse_host(gossip_host).unwrap_or_else(|err| { - eprintln!("Failed to parse --gossip-host: {}", err); - exit(1); - }) - }); - let gossip_port = value_t!(matches, "gossip_port", u16).ok(); - let dynamic_port_range = matches.value_of("dynamic_port_range").map(|port_range| { - solana_net_utils::parse_port_range(port_range).unwrap_or_else(|| { - eprintln!("Failed to parse --dynamic-port-range"); - exit(1); - }) - }); - let bind_address = matches.value_of("bind_address").map(|bind_address| { - solana_net_utils::parse_host(bind_address).unwrap_or_else(|err| { - eprintln!("Failed to parse --bind-address: {}", err); - exit(1); - }) - }); - - let faucet_addr = Some(SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), - faucet_port, - )); - - let mut programs_to_load = vec![]; - if let Some(values) = matches.values_of("bpf_program") { - let values: Vec<&str> = values.collect::>(); - for address_program in values.chunks(2) { - match address_program { - [address, program] => { - let address = address - .parse::() - .or_else(|_| read_keypair_file(address).map(|keypair| keypair.pubkey())) - .unwrap_or_else(|err| { - println!("Error: invalid address {}: {}", address, err); - exit(1); - }); - - let program_path = PathBuf::from(program); - if !program_path.exists() { - println!( - "Error: program file does not exist: {}", - program_path.display() - ); - exit(1); - } - - programs_to_load.push(ProgramInfo { - program_id: address, - loader: solana_sdk::bpf_loader::id(), - program_path, - }); - } - _ => unreachable!(), - } - } - } - - let mut accounts_to_load = vec![]; - if let Some(values) = matches.values_of("account") { - let values: Vec<&str> = values.collect::>(); - for address_filename in values.chunks(2) { - match address_filename { - [address, filename] => { - let address = address.parse::().unwrap_or_else(|err| { - println!("Error: invalid address {}: {}", address, err); - exit(1); - }); - - accounts_to_load.push(AccountInfo { address, filename }); - } - _ => unreachable!(), - } - } - } - - let accounts_to_clone: HashSet<_> = pubkeys_of(&matches, "clone_account") - .map(|v| v.into_iter().collect()) - .unwrap_or_default(); - - let warp_slot = if matches.is_present("warp_slot") { - Some(match matches.value_of("warp_slot") { - Some(_) => value_t_or_exit!(matches, "warp_slot", Slot), - None => { - cluster_rpc_client.as_ref().unwrap_or_else(|_| { - println!("The --url argument must be provided if --warp-slot/-w is used without an explicit slot"); - exit(1); - - }).get_slot() - .unwrap_or_else(|err| { - println!("Unable to get current cluster slot: {}", err); - exit(1); - }) - } - }) - } else { - None - }; - - let faucet_lamports = sol_to_lamports(value_of(&matches, "faucet_sol").unwrap()); - let faucet_keypair_file = ledger_path.join("faucet-keypair.json"); - if !faucet_keypair_file.exists() { - write_keypair_file(&Keypair::new(), faucet_keypair_file.to_str().unwrap()).unwrap_or_else( - |err| { - println!( - "Error: Failed to write {}: {}", - faucet_keypair_file.display(), - err - ); - exit(1); - }, - ); - } - - let faucet_keypair = - read_keypair_file(faucet_keypair_file.to_str().unwrap()).unwrap_or_else(|err| { - println!( - "Error: Failed to read {}: {}", - faucet_keypair_file.display(), - err - ); - exit(1); - }); - let faucet_pubkey = faucet_keypair.pubkey(); - - if let Some(faucet_addr) = &faucet_addr { - let (sender, receiver) = channel(); - run_local_faucet_with_port(faucet_keypair, sender, None, faucet_addr.port()); - let _ = receiver.recv().expect("run faucet").unwrap_or_else(|err| { - println!("Error: failed to start faucet: {}", err); - exit(1); - }); - } - - let features_to_deactivate = pubkeys_of(&matches, "deactivate_feature").unwrap_or_default(); - - if TestValidatorGenesis::ledger_exists(&ledger_path) { - for (name, long) in &[ - ("bpf_program", "--bpf-program"), - ("clone_account", "--clone"), - ("account", "--account"), - ("mint_address", "--mint"), - ("ticks_per_slot", "--ticks-per-slot"), - ("slots_per_epoch", "--slots-per-epoch"), - ("faucet_sol", "--faucet-sol"), - ("deactivate_feature", "--deactivate-feature"), - ] { - if matches.is_present(name) { - println!("{} argument ignored, ledger already exists", long); - } - } - } else if random_mint { - println_name_value( - "\nNotice!", - "No wallet available. `solana airdrop` localnet SOL after creating one\n", - ); - } - - let mut genesis = TestValidatorGenesis::default(); - genesis.max_ledger_shreds = value_of(&matches, "limit_ledger_size"); - genesis.max_genesis_archive_unpacked_size = Some(u64::MAX); - genesis.accounts_db_caching_enabled = !matches.is_present("no_accounts_db_caching"); - - let tower_storage = Arc::new(FileTowerStorage::new(ledger_path.clone())); - - let admin_service_post_init = Arc::new(RwLock::new(None)); - admin_rpc_service::run( - &ledger_path, - admin_rpc_service::AdminRpcRequestMetadata { - rpc_addr: Some(SocketAddr::new( - IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), - rpc_port, - )), - start_progress: genesis.start_progress.clone(), - start_time: std::time::SystemTime::now(), - validator_exit: genesis.validator_exit.clone(), - authorized_voter_keypairs: genesis.authorized_voter_keypairs.clone(), - post_init: admin_service_post_init.clone(), - tower_storage: tower_storage.clone(), - archive_evm_state: None, - }, - ); - let dashboard = if output == Output::Dashboard { - Some( - Dashboard::new( - &ledger_path, - Some(&validator_log_symlink), - Some(&mut genesis.validator_exit.write().unwrap()), - ) - .unwrap(), - ) - } else { - None - }; - - genesis - .ledger_path(&ledger_path) - .tower_storage(tower_storage) - .add_account( - faucet_pubkey, - AccountSharedData::new(faucet_lamports, 0, &system_program::id()), - ) - .rpc_config(JsonRpcConfig { - enable_rpc_transaction_history: true, - enable_cpi_and_log_storage: true, - faucet_addr, - ..JsonRpcConfig::default_for_test() - }) - .pubsub_config(PubSubConfig { - enable_vote_subscription, - ..PubSubConfig::default() - }) - .bpf_jit(!matches.is_present("no_bpf_jit")) - .rpc_port(rpc_port) - .add_programs_with_path(&programs_to_load) - .add_accounts_from_json_files(&accounts_to_load) - .deactivate_features(&features_to_deactivate); - - if !accounts_to_clone.is_empty() { - genesis.clone_accounts( - accounts_to_clone, - cluster_rpc_client - .as_ref() - .expect("bug: --url argument missing?"), - ); - } - - if let Some(warp_slot) = warp_slot { - genesis.warp_slot(warp_slot); - } - - if let Some(ticks_per_slot) = ticks_per_slot { - genesis.ticks_per_slot(ticks_per_slot); - } - - if let Some(slots_per_epoch) = slots_per_epoch { - genesis.epoch_schedule(EpochSchedule::custom( - slots_per_epoch, - slots_per_epoch, - /* enable_warmup_epochs = */ false, - )); - - genesis.rent = Rent::with_slots_per_epoch(slots_per_epoch); - } - - if let Some(gossip_host) = gossip_host { - genesis.gossip_host(gossip_host); - } - - if let Some(gossip_port) = gossip_port { - genesis.gossip_port(gossip_port); - } - - if let Some(dynamic_port_range) = dynamic_port_range { - genesis.port_range(dynamic_port_range); - } - - if let Some(bind_address) = bind_address { - genesis.bind_ip_addr(bind_address); - } - - if matches.is_present("geyser_plugin_config") { - genesis.geyser_plugin_config_files = Some( - values_t_or_exit!(matches, "geyser_plugin_config", String) - .into_iter() - .map(PathBuf::from) - .collect(), - ); - } - - match genesis.start_with_mint_address(mint_address, socket_addr_space) { - Ok(test_validator) => { - *admin_service_post_init.write().unwrap() = - Some(admin_rpc_service::AdminRpcRequestMetadataPostInit { - bank_forks: test_validator.bank_forks(), - cluster_info: test_validator.cluster_info(), - vote_account: test_validator.vote_account_address(), - }); - if let Some(dashboard) = dashboard { - dashboard.run(Duration::from_millis(250)); - } - test_validator.join(); - } - Err(err) => { - drop(dashboard); - println!("Error: failed to start validator: {}", err); - exit(1); - } - } -} - -fn remove_directory_contents(ledger_path: &Path) -> Result<(), io::Error> { - for entry in fs::read_dir(ledger_path)? { - let entry = entry?; - if entry.metadata()?.is_dir() { - fs::remove_dir_all(entry.path())? - } else { - fs::remove_file(entry.path())? - } - } - Ok(()) -} diff --git a/validator/src/bin/exzo-test-validator.rs b/validator/src/bin/exzo-test-validator.rs index ffcfad4..e3e919d 100644 --- a/validator/src/bin/exzo-test-validator.rs +++ b/validator/src/bin/exzo-test-validator.rs @@ -716,12 +716,12 @@ fn main() { } fn remove_directory_contents(ledger_path: &Path) -> Result<(), io::Error> { - for entry in fs::read_dir(&ledger_path)? { + for entry in fs::read_dir(ledger_path)? { let entry = entry?; if entry.metadata()?.is_dir() { - fs::remove_dir_all(&entry.path())? + fs::remove_dir_all(entry.path())? } else { - fs::remove_file(&entry.path())? + fs::remove_file(entry.path())? } } Ok(())