Add option to load accounts from file

This introduces the `--clone-from-file` option for
solana-test-validator. It allows specifying any number of files
(without extension) containing account info and data, which will be
loaded at genesis. This is similar to `--bpf-program` for programs
loading.

The files will be searched for in the CWD or in `tests/fixtures`.

Example: `solana-test-validator --clone-from-file SRM_token USD_token`
This commit is contained in:
losman0s
2021-12-11 22:17:57 +01:00
committed by Michael Vines
parent 0e9e67b65d
commit 9b06d64eb8
7 changed files with 93 additions and 8 deletions

View File

@ -13,6 +13,9 @@ edition = "2021"
[dependencies]
base64 = "0.12.3"
log = "0.4.14"
serde_derive = "1.0.103"
serde_json = "1.0.72"
solana-cli-output = { path = "../cli-output", version = "=1.10.0" }
solana-client = { path = "../client", version = "=1.10.0" }
solana-core = { path = "../core", version = "=1.10.0" }
solana-gossip = { path = "../gossip", version = "=1.10.0" }

View File

@ -1,6 +1,7 @@
#![allow(clippy::integer_arithmetic)]
use {
log::*,
solana_cli_output::CliAccount,
solana_client::rpc_client::RpcClient,
solana_core::{
tower_storage::TowerStorage,
@ -36,15 +37,23 @@ use {
solana_streamer::socket::SocketAddrSpace,
std::{
collections::HashMap,
fs::remove_dir_all,
fs::{remove_dir_all, File},
io::Read,
net::{IpAddr, Ipv4Addr, SocketAddr},
path::{Path, PathBuf},
str::FromStr,
sync::{Arc, RwLock},
thread::sleep,
time::Duration,
},
};
#[derive(Clone)]
pub struct AccountInfo<'a> {
pub address: Pubkey,
pub filename: &'a str,
}
#[derive(Clone)]
pub struct ProgramInfo {
pub program_id: Pubkey,
@ -204,6 +213,41 @@ impl TestValidatorGenesis {
self
}
pub fn add_accounts_from_json_files(&mut self, accounts: &[AccountInfo]) -> &mut Self {
for account in accounts {
let account_path =
solana_program_test::find_file(account.filename).unwrap_or_else(|| {
error!("Unable to locate {}", account.filename);
solana_core::validator::abort();
});
let mut file = File::open(&account_path).unwrap();
let mut account_info_raw = String::new();
file.read_to_string(&mut account_info_raw).unwrap();
let result: serde_json::Result<CliAccount> = serde_json::from_str(&account_info_raw);
let account_info = match result {
Err(err) => {
error!(
"Unable to deserialize {}: {}",
account_path.to_str().unwrap(),
err
);
solana_core::validator::abort();
}
Ok(deserialized) => deserialized,
};
let address = Pubkey::from_str(account_info.keyed_account.pubkey.as_str()).unwrap();
let account = account_info
.keyed_account
.account
.decode::<AccountSharedData>()
.unwrap();
self.add_account(address, account);
}
self
}
/// Add an account to the test environment with the account data in the provided `filename`
pub fn add_account_with_file_data(
&mut self,