test-validator: clone upgradeable programs (#30279)

* test-validator: clone upgradeable programs

* typo & drop bincode dep & clone bound
This commit is contained in:
skrrb 2023-02-16 16:28:01 +01:00 committed by GitHub
parent 0c36e4c82d
commit 6717c07af1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 0 deletions

View File

@ -29,6 +29,7 @@ use {
},
solana_sdk::{
account::{Account, AccountSharedData},
bpf_loader_upgradeable::UpgradeableLoaderState,
clock::{Slot, DEFAULT_MS_PER_SLOT},
commitment_config::CommitmentConfig,
epoch_schedule::EpochSchedule,
@ -312,6 +313,38 @@ impl TestValidatorGenesis {
Ok(self)
}
pub fn clone_upgradeable_programs<T>(
&mut self,
addresses: T,
rpc_client: &RpcClient,
) -> Result<&mut Self, String>
where
T: IntoIterator<Item = Pubkey>,
{
let addresses: Vec<Pubkey> = addresses.into_iter().collect();
self.clone_accounts(addresses.clone(), rpc_client, false)?;
let mut programdata_addresses: HashSet<Pubkey> = HashSet::new();
for address in addresses {
let account = self.accounts.get(&address).unwrap();
if let Ok(UpgradeableLoaderState::Program {
programdata_address,
}) = account.deserialize_data()
{
programdata_addresses.insert(programdata_address);
} else {
return Err(format!(
"Failed to read upgradeable program account {address}",
));
}
}
self.clone_accounts(programdata_addresses, rpc_client, false)?;
Ok(self)
}
pub fn add_accounts_from_json_files(
&mut self,
accounts: &[AccountInfo],

View File

@ -248,6 +248,11 @@ fn main() {
.map(|v| v.into_iter().collect())
.unwrap_or_default();
let upgradeable_programs_to_clone: HashSet<_> =
pubkeys_of(&matches, "clone_upgradeable_program")
.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),
@ -451,6 +456,18 @@ fn main() {
}
}
if !upgradeable_programs_to_clone.is_empty() {
if let Err(e) = genesis.clone_upgradeable_programs(
upgradeable_programs_to_clone,
cluster_rpc_client
.as_ref()
.expect("bug: --url argument missing?"),
) {
println!("Error: clone_upgradeable_programs failed: {e}");
exit(1);
}
}
if let Some(warp_slot) = warp_slot {
genesis.warp_slot(warp_slot);
}

View File

@ -2162,6 +2162,20 @@ pub fn test_app<'a>(version: &'a str, default_args: &'a DefaultTestArgs) -> App<
If the ledger already exists then this parameter is silently ignored",
),
)
.arg(
Arg::with_name("clone_upgradeable_program")
.long("clone-upgradeable-program")
.value_name("ADDRESS")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.multiple(true)
.requires("json_rpc_url")
.help(
"Copy an upgradeable program and its executable data 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)