diff --git a/magicblock-api/src/magic_validator.rs b/magicblock-api/src/magic_validator.rs index 079b32e12..23a207e98 100644 --- a/magicblock-api/src/magic_validator.rs +++ b/magicblock-api/src/magic_validator.rs @@ -200,11 +200,14 @@ impl MagicValidator { config.validator_config.ledger.path.as_ref(), config.validator_config.ledger.reset, )?; - Self::sync_validator_keypair_with_ledger( - ledger.ledger_path(), - &identity_keypair, - config.validator_config.ledger.reset, - )?; + + if config.validator_config.ledger.enforce_keypair_match { + Self::sync_validator_keypair_with_ledger( + ledger.ledger_path(), + &identity_keypair, + config.validator_config.ledger.reset, + )?; + } // SAFETY: // this code will never panic as the ledger_path always appends the diff --git a/magicblock-config/src/ledger.rs b/magicblock-config/src/ledger.rs index ece842137..87f52c6a4 100644 --- a/magicblock-config/src/ledger.rs +++ b/magicblock-config/src/ledger.rs @@ -18,6 +18,13 @@ pub struct LedgerConfig { #[arg(help = "Whether to reset the ledger before starting the validator.")] #[serde(default = "bool_true")] pub reset: bool, + /// Checks that the validator keypair matches the one in the ledger. + #[derive_env_var] + #[arg( + help = "Whether to check that the validator keypair matches the one in the ledger." + )] + #[serde(default = "bool_true")] + pub enforce_keypair_match: bool, /// The file system path onto which the ledger should be written at /// If left empty it will be auto-generated to a temporary folder #[derive_env_var] @@ -39,6 +46,11 @@ impl LedgerConfig { if self.reset == bool_true() && other.reset != bool_true() { self.reset = other.reset; } + if self.enforce_keypair_match == bool_true() + && other.enforce_keypair_match != bool_true() + { + self.enforce_keypair_match = other.enforce_keypair_match; + } if self.path == Default::default() && other.path != Default::default() { self.path = other.path; } @@ -54,6 +66,7 @@ impl Default for LedgerConfig { fn default() -> Self { Self { reset: bool_true(), + enforce_keypair_match: bool_true(), path: Default::default(), size: DEFAULT_LEDGER_SIZE_BYTES, } @@ -72,6 +85,7 @@ mod tests { fn test_merge_with_default() { let mut config = LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }; @@ -88,6 +102,7 @@ mod tests { let mut config = LedgerConfig::default(); let other = LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }; @@ -101,12 +116,14 @@ mod tests { fn test_merge_non_default() { let mut config = LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }; let original_config = config.clone(); let other = LedgerConfig { reset: true, + enforce_keypair_match: true, path: Some("ledger2.example.com".to_string()), size: 10000, }; diff --git a/magicblock-config/src/lib.rs b/magicblock-config/src/lib.rs index 416dc0b78..1bce13283 100644 --- a/magicblock-config/src/lib.rs +++ b/magicblock-config/src/lib.rs @@ -248,6 +248,7 @@ mod tests { }, ledger: LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }, @@ -327,6 +328,7 @@ mod tests { }, ledger: LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }, @@ -403,6 +405,7 @@ mod tests { }, ledger: LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger2.example.com".to_string()), size: 100000, }, @@ -472,6 +475,7 @@ mod tests { }, ledger: LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("ledger.example.com".to_string()), size: 1000000000, }, diff --git a/magicblock-config/tests/read_config.rs b/magicblock-config/tests/read_config.rs index 027a2cc73..a62c790ce 100644 --- a/magicblock-config/tests/read_config.rs +++ b/magicblock-config/tests/read_config.rs @@ -117,6 +117,7 @@ fn test_load_local_dev_with_programs_toml_envs_override() { env::set_var("VALIDATOR_COUNTRY_CODE", "CY"); env::set_var("VALIDATOR_FQDN", "magicblock.er.com"); env::set_var("LEDGER_RESET", "false"); + env::set_var("LEDGER_ENFORCE_KEYPAIR_MATCH", "false"); env::set_var("LEDGER_PATH", "/hello/world"); env::set_var("METRICS_ENABLED", "false"); env::set_var("METRICS_PORT", "1234"); @@ -165,6 +166,7 @@ fn test_load_local_dev_with_programs_toml_envs_override() { }, ledger: LedgerConfig { reset: false, + enforce_keypair_match: false, path: Some("/hello/world".to_string()), size: 123123 }, diff --git a/test-integration/configs/restore-ledger-conf.devnet.toml b/test-integration/configs/restore-ledger-conf.devnet.toml index acf726463..c37399453 100644 --- a/test-integration/configs/restore-ledger-conf.devnet.toml +++ b/test-integration/configs/restore-ledger-conf.devnet.toml @@ -36,6 +36,10 @@ path = "../target/deploy/program_flexi_counter.so" id = "DmnRGfyyftzacFb1XadYhWF6vWqXwtQk5tbr6XgR3BA1" path = "../schedulecommit/elfs/mdp.so" +[[program]] +id = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr" +path = "../programs/memo/memo.so" + [rpc] port = 7799 diff --git a/test-integration/programs/memo/memo.so b/test-integration/programs/memo/memo.so new file mode 100644 index 000000000..88385a01d Binary files /dev/null and b/test-integration/programs/memo/memo.so differ diff --git a/test-integration/test-ledger-restore/src/lib.rs b/test-integration/test-ledger-restore/src/lib.rs index c68c60288..a226a6783 100644 --- a/test-integration/test-ledger-restore/src/lib.rs +++ b/test-integration/test-ledger-restore/src/lib.rs @@ -59,6 +59,7 @@ pub fn setup_offline_validator( reset, path: Some(ledger_path.display().to_string()), size: DEFAULT_LEDGER_SIZE_BYTES, + ..Default::default() }, accounts: accounts_config.clone(), programs, @@ -86,6 +87,8 @@ pub fn setup_validator_with_local_remote( ledger_path: &Path, programs: Option>, reset: bool, + enforce_keypair_match: bool, + loaded_accounts: &LoadedAccounts, ) -> (TempDir, Child, IntegrationTestContext) { let mut accounts_config = AccountsConfig { lifecycle: LifecycleMode::Ephemeral, @@ -103,8 +106,10 @@ pub fn setup_validator_with_local_remote( let config = EphemeralConfig { ledger: LedgerConfig { reset, + enforce_keypair_match, path: Some(ledger_path.display().to_string()), size: DEFAULT_LEDGER_SIZE_BYTES, + ..Default::default() }, accounts: accounts_config.clone(), programs, @@ -112,10 +117,7 @@ pub fn setup_validator_with_local_remote( }; let (default_tmpdir_config, Some(mut validator)) = - start_magicblock_validator_with_config_struct( - config, - &LoadedAccounts::with_delegation_program_test_authority(), - ) + start_magicblock_validator_with_config_struct(config, &loaded_accounts) else { panic!("validator should set up correctly"); }; diff --git a/test-integration/test-ledger-restore/tests/00_empty_validator.rs b/test-integration/test-ledger-restore/tests/00_empty_validator.rs index 93969fd70..2374bd4b6 100644 --- a/test-integration/test-ledger-restore/tests/00_empty_validator.rs +++ b/test-integration/test-ledger-restore/tests/00_empty_validator.rs @@ -1,6 +1,8 @@ use std::{path::Path, process::Child}; -use integration_test_tools::tmpdir::resolve_tmp_dir; +use integration_test_tools::{ + loaded_accounts::LoadedAccounts, tmpdir::resolve_tmp_dir, +}; use test_ledger_restore::{ setup_validator_with_local_remote, wait_for_ledger_persist, TMP_DIR_LEDGER, }; @@ -22,8 +24,13 @@ fn restore_ledger_empty_validator() { fn write(ledger_path: &Path) -> (Child, u64) { // Launch a validator and airdrop to an account - let (_, mut validator, _) = - setup_validator_with_local_remote(ledger_path, None, true); + let (_, mut validator, _) = setup_validator_with_local_remote( + ledger_path, + None, + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); let slot = wait_for_ledger_persist(&mut validator); @@ -33,8 +40,13 @@ fn write(ledger_path: &Path) -> (Child, u64) { fn read(ledger_path: &Path) -> Child { // Launch another validator reusing ledger - let (_, validator, _) = - setup_validator_with_local_remote(ledger_path, None, false); + let (_, validator, _) = setup_validator_with_local_remote( + ledger_path, + None, + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); validator } diff --git a/test-integration/test-ledger-restore/tests/06_delegated_account.rs b/test-integration/test-ledger-restore/tests/06_delegated_account.rs index 292973001..3736cfdfc 100644 --- a/test-integration/test-ledger-restore/tests/06_delegated_account.rs +++ b/test-integration/test-ledger-restore/tests/06_delegated_account.rs @@ -1,4 +1,5 @@ use cleanass::assert_eq; +use integration_test_tools::loaded_accounts::LoadedAccounts; use integration_test_tools::validator::cleanup; use std::{path::Path, process::Child}; @@ -50,8 +51,13 @@ fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { // NOTE: in this test we preload the counter program in the ephemeral instead // of relying on it being cloned from the remote - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payer on chain expect!( @@ -105,8 +111,13 @@ fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { fn read(ledger_path: &Path, payer: &Pubkey) -> Child { let programs = get_programs(); - let (_, mut validator, _) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, _) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); wait_for_cloned_accounts_hydration(); diff --git a/test-integration/test-ledger-restore/tests/07_commit_delegated_account.rs b/test-integration/test-ledger-restore/tests/07_commit_delegated_account.rs index cbcb0edd7..a41a3605d 100644 --- a/test-integration/test-ledger-restore/tests/07_commit_delegated_account.rs +++ b/test-integration/test-ledger-restore/tests/07_commit_delegated_account.rs @@ -1,4 +1,5 @@ use cleanass::assert_eq; +use integration_test_tools::loaded_accounts::LoadedAccounts; use integration_test_tools::validator::cleanup; use std::{path::Path, process::Child}; @@ -47,8 +48,13 @@ fn restore_ledger_containing_delegated_and_committed_account() { fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payer on chain expect!( @@ -168,8 +174,13 @@ fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { fn read(ledger_path: &Path, payer: &Pubkey) -> Child { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); wait_for_cloned_accounts_hydration(); diff --git a/test-integration/test-ledger-restore/tests/08_commit_update.rs b/test-integration/test-ledger-restore/tests/08_commit_update.rs index 9f90c9fad..f8e3c56dd 100644 --- a/test-integration/test-ledger-restore/tests/08_commit_update.rs +++ b/test-integration/test-ledger-restore/tests/08_commit_update.rs @@ -1,4 +1,5 @@ use cleanass::assert_eq; +use integration_test_tools::loaded_accounts::LoadedAccounts; use integration_test_tools::validator::cleanup; use std::{path::Path, process::Child}; @@ -50,8 +51,13 @@ fn restore_ledger_committed_and_updated_account() { fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payer on chain expect!( @@ -159,8 +165,13 @@ fn read(ledger_path: &Path, payer_kp: &Keypair) -> Child { let payer = &payer_kp.pubkey(); let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); wait_for_cloned_accounts_hydration(); diff --git a/test-integration/test-ledger-restore/tests/09_restore_different_accounts_multiple_times.rs b/test-integration/test-ledger-restore/tests/09_restore_different_accounts_multiple_times.rs index f77f25e3f..63593aac5 100644 --- a/test-integration/test-ledger-restore/tests/09_restore_different_accounts_multiple_times.rs +++ b/test-integration/test-ledger-restore/tests/09_restore_different_accounts_multiple_times.rs @@ -1,4 +1,5 @@ use cleanass::assert_eq; +use integration_test_tools::loaded_accounts::LoadedAccounts; use integration_test_tools::validator::cleanup; use std::{path::Path, process::Child}; @@ -64,8 +65,13 @@ fn write( ) -> (Child, u64, u64) { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payers on chain expect!( @@ -170,8 +176,13 @@ fn read( let payer_readonly = &payer_readonly_kp.pubkey(); let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); wait_for_cloned_accounts_hydration(); diff --git a/test-integration/test-ledger-restore/tests/10_readonly_update_after.rs b/test-integration/test-ledger-restore/tests/10_readonly_update_after.rs index 7575d9e63..b54993d83 100644 --- a/test-integration/test-ledger-restore/tests/10_readonly_update_after.rs +++ b/test-integration/test-ledger-restore/tests/10_readonly_update_after.rs @@ -1,4 +1,5 @@ use cleanass::assert_eq; +use integration_test_tools::loaded_accounts::LoadedAccounts; use std::{path::Path, process::Child}; use integration_test_tools::{ @@ -144,8 +145,13 @@ fn write( ) -> (Child, u64) { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payers on chain expect!( @@ -263,8 +269,13 @@ fn read( let payer_readonly = &payer_readonly_kp.pubkey(); let programs = get_programs_with_flexi_counter(); - let (_, mut validator, _) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, _) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); wait_for_cloned_accounts_hydration(); diff --git a/test-integration/test-ledger-restore/tests/11_undelegate_before_restart.rs b/test-integration/test-ledger-restore/tests/11_undelegate_before_restart.rs index 877175e8a..a0f6a786c 100644 --- a/test-integration/test-ledger-restore/tests/11_undelegate_before_restart.rs +++ b/test-integration/test-ledger-restore/tests/11_undelegate_before_restart.rs @@ -1,5 +1,6 @@ use cleanass::assert; use integration_test_tools::conversions::get_rpc_transwise_error_msg; +use integration_test_tools::loaded_accounts::LoadedAccounts; use integration_test_tools::validator::cleanup; use integration_test_tools::{expect, tmpdir::resolve_tmp_dir}; use integration_test_tools::{expect_err, unwrap, IntegrationTestContext}; @@ -59,8 +60,13 @@ fn restore_ledger_with_account_undelegated_before_restart() { fn write(ledger_path: &Path, payer: &Keypair) -> (Child, u64) { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(ledger_path, Some(programs), true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); // Airdrop to payer on chain expect!( @@ -113,8 +119,13 @@ fn update_counter_between_restarts(payer: &Keypair) -> Child { // before restarting the validator let (_, ledger_path) = resolve_tmp_dir("FORCE_UNIQUE_TMP_DIR_AND_IGNORE_THIS_ENV_VAR"); - let (_, mut validator, ctx) = - setup_validator_with_local_remote(&ledger_path, None, true); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + &ledger_path, + None, + true, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); let ix = create_add_and_schedule_commit_ix(payer.pubkey(), 3, true); let sig = confirm_tx_with_payer_ephem(ix, payer, &mut validator); @@ -149,8 +160,13 @@ fn update_counter_between_restarts(payer: &Keypair) -> Child { fn read(ledger_path: &Path, payer: &Keypair) -> Child { let programs = get_programs_with_flexi_counter(); - let (_, mut validator, _) = - setup_validator_with_local_remote(ledger_path, Some(programs), false); + let (_, mut validator, _) = setup_validator_with_local_remote( + ledger_path, + Some(programs), + false, + true, + &LoadedAccounts::with_delegation_program_test_authority(), + ); let ix = create_add_ix(payer.pubkey(), 1); let ctx = expect!(IntegrationTestContext::try_new_ephem_only(), validator); diff --git a/test-integration/test-ledger-restore/tests/14_restore_with_new_keypair.rs b/test-integration/test-ledger-restore/tests/14_restore_with_new_keypair.rs new file mode 100644 index 000000000..2f270886f --- /dev/null +++ b/test-integration/test-ledger-restore/tests/14_restore_with_new_keypair.rs @@ -0,0 +1,131 @@ +use cleanass::assert_eq; +use solana_rpc_client::rpc_client::RpcClient; +use std::{path::Path, process::Child}; + +use integration_test_tools::{ + expect, loaded_accounts::LoadedAccounts, tmpdir::resolve_tmp_dir, + validator::cleanup, +}; +use solana_sdk::{ + account::Account, bpf_loader_upgradeable, instruction::Instruction, + native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, signature::Keypair, + signer::Signer, transaction::Transaction, +}; +use test_ledger_restore::{ + setup_validator_with_local_remote, wait_for_ledger_persist, TMP_DIR_LEDGER, +}; + +const MEMO_PROGRAM_PK: Pubkey = Pubkey::new_from_array([ + 5, 74, 83, 90, 153, 41, 33, 6, 77, 36, 232, 113, 96, 218, 56, 124, 124, 53, + 181, 221, 188, 146, 187, 129, 228, 31, 168, 64, 65, 5, 68, 141, +]); + +// In this test we ensure that restoring from a ledger with a new validator +// authority works. +// This assumes a solana-test-validator is running on port 7799. + +#[test] +fn restore_ledger_with_new_validator_authority() { + let (_, ledger_path) = resolve_tmp_dir(TMP_DIR_LEDGER); + + // Write a transaction that clones the memo program + let (mut validator, _) = write(&ledger_path); + validator.kill().unwrap(); + + // Read the ledger and verify that the memo program is cloned + let mut validator = read(&ledger_path); + validator.kill().unwrap(); +} + +fn write(ledger_path: &Path) -> (Child, u64) { + let loaded_chain_accounts = + LoadedAccounts::new_with_new_validator_authority(); + // Airdrop to the new validator authority + RpcClient::new("http://localhost:7799") + .request_airdrop( + &loaded_chain_accounts.validator_authority(), + 10 * LAMPORTS_PER_SOL, + ) + .unwrap(); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + None, + true, + true, + &loaded_chain_accounts, + ); + + let payer = Keypair::new(); + expect!( + ctx.airdrop_chain(&payer.pubkey(), LAMPORTS_PER_SOL), + validator + ); + + // This transaction will clone the memo program + let memo_ix = Instruction::new_with_bytes( + MEMO_PROGRAM_PK, + &[ + 0x39, 0x34, 0x32, 0x32, 0x38, 0x30, 0x37, 0x2e, 0x35, 0x34, 0x30, + 0x30, 0x30, 0x32, + ], + vec![], + ); + let mut tx = Transaction::new_with_payer(&[memo_ix], Some(&payer.pubkey())); + expect!( + ctx.send_and_confirm_transaction_ephem(&mut tx, &[&payer]), + validator + ); + + let account = expect!( + ctx.try_ephem_client() + .map_err(|e| anyhow::anyhow!("{}", e)) + .and_then(|client| client + .get_account(&MEMO_PROGRAM_PK) + .map_err(|e| anyhow::anyhow!("{}", e))), + validator + ); + let Account { + owner, executable, .. + } = account; + assert_eq!(owner, bpf_loader_upgradeable::ID, cleanup(&mut validator)); + assert_eq!(executable, true, cleanup(&mut validator)); + + let slot = wait_for_ledger_persist(&mut validator); + + (validator, slot) +} + +fn read(ledger_path: &Path) -> Child { + let loaded_chain_accounts = + LoadedAccounts::new_with_new_validator_authority(); + // Airdrop to the new validator authority + RpcClient::new("http://localhost:7799") + .request_airdrop( + &loaded_chain_accounts.validator_authority(), + 10 * LAMPORTS_PER_SOL, + ) + .unwrap(); + let (_, mut validator, ctx) = setup_validator_with_local_remote( + ledger_path, + None, + false, + false, + &loaded_chain_accounts, + ); + + let account = expect!( + ctx.try_ephem_client() + .map_err(|e| anyhow::anyhow!("{}", e)) + .and_then(|client| client + .get_account(&MEMO_PROGRAM_PK) + .map_err(|e| anyhow::anyhow!("{}", e))), + validator + ); + let Account { + owner, executable, .. + } = account; + assert_eq!(owner, bpf_loader_upgradeable::ID, cleanup(&mut validator)); + assert_eq!(executable, true, cleanup(&mut validator)); + + validator +} diff --git a/test-integration/test-tools/src/loaded_accounts.rs b/test-integration/test-tools/src/loaded_accounts.rs index 5c9203b03..b1f6e757c 100644 --- a/test-integration/test-tools/src/loaded_accounts.rs +++ b/test-integration/test-tools/src/loaded_accounts.rs @@ -35,6 +35,15 @@ impl Default for LoadedAccounts { } impl LoadedAccounts { + pub fn new_with_new_validator_authority() -> Self { + Self { + validator_authority_kp: Keypair::new(), + luzid_authority: pubkey!( + "LUzidNSiPNjYNkxZcUm5hYHwnWPwsUfh2US1cpWwaBm" + ), + } + } + /// This use the test authority used in the delegation program as the validator /// authority. /// https://github.com/magicblock-labs/delegation-program/blob/7fc0ae9a59e48bea5b046b173ea0e34fd433c3c7/tests/fixtures/accounts.rs#L46