test-validator: clone upgradeable programs (#30279)
* test-validator: clone upgradeable programs * typo & drop bincode dep & clone bound
This commit is contained in:
parent
0c36e4c82d
commit
6717c07af1
|
@ -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],
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue