From 8a331ee8916b8b51c08517abdf824c803e785835 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 10:42:01 +0100 Subject: [PATCH 01/10] refactor: copy create_account_instruction --- .../program-test/src/accounts/address_tree.rs | 2 +- .../src/accounts/address_tree_v2.rs | 2 +- .../program-test/src/accounts/state_tree.rs | 2 +- .../program-test/src/accounts/state_tree_v2.rs | 2 +- .../program-test/src/utils/create_account.rs | 17 +++++++++++++++++ sdk-libs/program-test/src/utils/mod.rs | 1 + 6 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 sdk-libs/program-test/src/utils/create_account.rs diff --git a/sdk-libs/program-test/src/accounts/address_tree.rs b/sdk-libs/program-test/src/accounts/address_tree.rs index 93252f114e..797af3286e 100644 --- a/sdk-libs/program-test/src/accounts/address_tree.rs +++ b/sdk-libs/program-test/src/accounts/address_tree.rs @@ -2,7 +2,7 @@ use account_compression::{ instruction::InitializeAddressMerkleTreeAndQueue, AddressMerkleTreeConfig, AddressQueueConfig, }; use anchor_lang::InstructionData; -use forester_utils::instructions::create_account::create_account_instruction; +use crate::utils::create_account::create_account_instruction; use light_client::rpc::{errors::RpcError, Rpc}; use solana_sdk::{ compute_budget::ComputeBudgetInstruction, diff --git a/sdk-libs/program-test/src/accounts/address_tree_v2.rs b/sdk-libs/program-test/src/accounts/address_tree_v2.rs index db5e677149..3d96c565d8 100644 --- a/sdk-libs/program-test/src/accounts/address_tree_v2.rs +++ b/sdk-libs/program-test/src/accounts/address_tree_v2.rs @@ -1,4 +1,4 @@ -use forester_utils::instructions::create_account_instruction; +use crate::utils::create_account::create_account_instruction; use light_batched_merkle_tree::{ initialize_address_tree::InitAddressTreeAccountsInstructionData, merkle_tree::get_merkle_tree_account_size, diff --git a/sdk-libs/program-test/src/accounts/state_tree.rs b/sdk-libs/program-test/src/accounts/state_tree.rs index 8f5d226934..df1be45042 100644 --- a/sdk-libs/program-test/src/accounts/state_tree.rs +++ b/sdk-libs/program-test/src/accounts/state_tree.rs @@ -3,7 +3,7 @@ use account_compression::{ StateMerkleTreeConfig, }; use anchor_lang::{InstructionData, ToAccountMetas}; -use forester_utils::instructions::create_account::create_account_instruction; +use crate::utils::create_account::create_account_instruction; use light_client::rpc::{errors::RpcError, Rpc}; use light_compressed_account::instruction_data::insert_into_queues::InsertIntoQueuesInstructionDataMut; use light_registry::protocol_config::state::ProtocolConfig; diff --git a/sdk-libs/program-test/src/accounts/state_tree_v2.rs b/sdk-libs/program-test/src/accounts/state_tree_v2.rs index a6458015ac..8d74b70d76 100644 --- a/sdk-libs/program-test/src/accounts/state_tree_v2.rs +++ b/sdk-libs/program-test/src/accounts/state_tree_v2.rs @@ -1,5 +1,5 @@ use anchor_lang::{AnchorSerialize, InstructionData, ToAccountMetas}; -use forester_utils::instructions::create_account_instruction; +use crate::utils::create_account::create_account_instruction; use light_batched_merkle_tree::{ initialize_state_tree::InitStateTreeAccountsInstructionData, merkle_tree::get_merkle_tree_account_size, queue::get_output_queue_account_size, diff --git a/sdk-libs/program-test/src/utils/create_account.rs b/sdk-libs/program-test/src/utils/create_account.rs new file mode 100644 index 0000000000..2ad469c0af --- /dev/null +++ b/sdk-libs/program-test/src/utils/create_account.rs @@ -0,0 +1,17 @@ +use account_compression::processor::initialize_address_merkle_tree::Pubkey; +use anchor_lang::solana_program::{instruction::Instruction, system_instruction}; +use solana_sdk::signature::{Keypair, Signer}; + +pub fn create_account_instruction( + payer: &Pubkey, + size: usize, + rent: u64, + id: &Pubkey, + keypair: Option<&Keypair>, +) -> Instruction { + let keypair = match keypair { + Some(keypair) => keypair.insecure_clone(), + None => Keypair::new(), + }; + system_instruction::create_account(payer, &keypair.pubkey(), rent, size as u64, id) +} \ No newline at end of file diff --git a/sdk-libs/program-test/src/utils/mod.rs b/sdk-libs/program-test/src/utils/mod.rs index 5419aa40a4..fd528aca93 100644 --- a/sdk-libs/program-test/src/utils/mod.rs +++ b/sdk-libs/program-test/src/utils/mod.rs @@ -1,3 +1,4 @@ pub mod assert; +pub mod create_account; pub mod find_light_bin; pub mod setup_light_programs; From 34a11736d785dfedb7f62ab61fdd73db55151fcc Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 11:22:47 +0100 Subject: [PATCH 02/10] refactor: copy TreeAccounts --- .../program-test/src/accounts/initialize.rs | 7 ++-- sdk-libs/program-test/src/utils/mod.rs | 1 + .../program-test/src/utils/tree_accounts.rs | 35 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 sdk-libs/program-test/src/utils/tree_accounts.rs diff --git a/sdk-libs/program-test/src/accounts/initialize.rs b/sdk-libs/program-test/src/accounts/initialize.rs index c70e3f8ba7..3115c7c5ba 100644 --- a/sdk-libs/program-test/src/accounts/initialize.rs +++ b/sdk-libs/program-test/src/accounts/initialize.rs @@ -1,8 +1,9 @@ use account_compression::{utils::constants::GROUP_AUTHORITY_SEED, GroupAuthority}; use forester_utils::{ - forester_epoch::{Epoch, TreeAccounts}, + forester_epoch::Epoch, registry::register_test_forester, }; +use crate::utils::tree_accounts::TreeAccounts; use light_client::{ indexer::{AddressMerkleTreeAccounts, StateMerkleTreeAccounts}, rpc::{Rpc, RpcError}, @@ -233,8 +234,10 @@ pub async fn initialize_accounts( }, ]; + let forester_tree_accounts: Vec = + tree_accounts.iter().map(|ta| ta.to_forester_utils()).collect(); registered_epoch - .fetch_account_and_add_trees_with_schedule(context, &tree_accounts) + .fetch_account_and_add_trees_with_schedule(context, &forester_tree_accounts) .await?; let ix = create_finalize_registration_instruction( &keypairs.forester.pubkey(), diff --git a/sdk-libs/program-test/src/utils/mod.rs b/sdk-libs/program-test/src/utils/mod.rs index fd528aca93..1d5c1ce969 100644 --- a/sdk-libs/program-test/src/utils/mod.rs +++ b/sdk-libs/program-test/src/utils/mod.rs @@ -2,3 +2,4 @@ pub mod assert; pub mod create_account; pub mod find_light_bin; pub mod setup_light_programs; +pub mod tree_accounts; diff --git a/sdk-libs/program-test/src/utils/tree_accounts.rs b/sdk-libs/program-test/src/utils/tree_accounts.rs new file mode 100644 index 0000000000..2eed41c019 --- /dev/null +++ b/sdk-libs/program-test/src/utils/tree_accounts.rs @@ -0,0 +1,35 @@ +use light_compressed_account::TreeType; +use solana_sdk::pubkey::Pubkey; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct TreeAccounts { + pub merkle_tree: Pubkey, + pub queue: Pubkey, + pub is_rolledover: bool, + pub tree_type: TreeType, +} + +impl TreeAccounts { + pub fn new( + merkle_tree: Pubkey, + queue: Pubkey, + tree_type: TreeType, + is_rolledover: bool, + ) -> Self { + Self { + merkle_tree, + queue, + tree_type, + is_rolledover, + } + } + + pub fn to_forester_utils(&self) -> forester_utils::forester_epoch::TreeAccounts { + forester_utils::forester_epoch::TreeAccounts::new( + self.merkle_tree, + self.queue, + self.tree_type, + self.is_rolledover, + ) + } +} \ No newline at end of file From 06aec11a1bcb220e6d8feadd3cf73ae9fd05dc5f Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 13:14:39 +0200 Subject: [PATCH 03/10] moved register test forester to light-program-test --- forester-utils/src/registry.rs | 33 +---------- forester/tests/legacy/batched_address_test.rs | 2 +- program-tests/utils/src/e2e_test_env.rs | 2 +- program-tests/utils/src/lib.rs | 3 +- .../program-test/src/accounts/initialize.rs | 6 +- sdk-libs/program-test/src/utils/mod.rs | 1 + .../src/utils/register_test_forester.rs | 58 +++++++++++++++++++ 7 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 sdk-libs/program-test/src/utils/register_test_forester.rs diff --git a/forester-utils/src/registry.rs b/forester-utils/src/registry.rs index b52547d398..cf2768396b 100644 --- a/forester-utils/src/registry.rs +++ b/forester-utils/src/registry.rs @@ -11,7 +11,7 @@ use light_registry::{ create_rollover_state_merkle_tree_instruction, CreateRolloverMerkleTreeInstructionInputs, }, protocol_config::state::ProtocolConfig, - sdk::{create_register_forester_instruction, create_update_forester_pda_instruction}, + sdk::create_update_forester_pda_instruction, utils::get_forester_pda, ForesterConfig, ForesterPda, }; @@ -27,37 +27,6 @@ use crate::{ instructions::create_account::create_account_instruction, }; -/// Creates and asserts forester account creation. -pub async fn register_test_forester( - rpc: &mut R, - governance_authority: &Keypair, - forester_authority: &Pubkey, - config: ForesterConfig, -) -> Result<(), RpcError> { - let ix = create_register_forester_instruction( - &governance_authority.pubkey(), - &governance_authority.pubkey(), - forester_authority, - config, - ); - rpc.create_and_send_transaction( - &[ix], - &governance_authority.pubkey(), - &[governance_authority], - ) - .await?; - assert_registered_forester( - rpc, - forester_authority, - ForesterPda { - authority: *forester_authority, - config, - active_weight: 1, - ..Default::default() - }, - ) - .await -} pub async fn update_test_forester( rpc: &mut R, diff --git a/forester/tests/legacy/batched_address_test.rs b/forester/tests/legacy/batched_address_test.rs index 3f239f1d7e..a9ba71b6ab 100644 --- a/forester/tests/legacy/batched_address_test.rs +++ b/forester/tests/legacy/batched_address_test.rs @@ -2,7 +2,7 @@ use std::{sync::Arc, time::Duration}; use forester::run_pipeline; use forester_utils::{ - registry::{register_test_forester, update_test_forester}, + registry::update_test_forester, rpc_pool::SolanaRpcPoolBuilder, }; use light_batched_merkle_tree::{ diff --git a/program-tests/utils/src/e2e_test_env.rs b/program-tests/utils/src/e2e_test_env.rs index 0225ca225f..0c21f32267 100644 --- a/program-tests/utils/src/e2e_test_env.rs +++ b/program-tests/utils/src/e2e_test_env.rs @@ -76,9 +76,9 @@ use forester_utils::{ account_zero_copy::AccountZeroCopy, address_merkle_tree_config::{address_tree_ready_for_rollover, state_tree_ready_for_rollover}, forester_epoch::{Epoch, Forester, TreeAccounts}, - registry::register_test_forester, utils::airdrop_lamports, }; +use light_program_test::utils::register_test_forester::register_test_forester; use light_batched_merkle_tree::{ batch::BatchState, constants::{DEFAULT_BATCH_ADDRESS_TREE_HEIGHT, TEST_DEFAULT_BATCH_SIZE}, diff --git a/program-tests/utils/src/lib.rs b/program-tests/utils/src/lib.rs index 889b6556a7..848ffe4cc3 100644 --- a/program-tests/utils/src/lib.rs +++ b/program-tests/utils/src/lib.rs @@ -46,10 +46,11 @@ pub use forester_utils::{ forester_epoch::{Epoch, TreeAccounts}, registry::{ create_rollover_address_merkle_tree_instructions, - create_rollover_state_merkle_tree_instructions, register_test_forester, + create_rollover_state_merkle_tree_instructions, update_test_forester, }, }; +pub use light_program_test::utils::register_test_forester::register_test_forester; pub use light_client::{ fee::{FeeConfig, TransactionParams}, rpc::{client::RpcUrl, LightClient, Rpc, RpcError}, diff --git a/sdk-libs/program-test/src/accounts/initialize.rs b/sdk-libs/program-test/src/accounts/initialize.rs index 3115c7c5ba..1b1efc5d6a 100644 --- a/sdk-libs/program-test/src/accounts/initialize.rs +++ b/sdk-libs/program-test/src/accounts/initialize.rs @@ -1,8 +1,6 @@ use account_compression::{utils::constants::GROUP_AUTHORITY_SEED, GroupAuthority}; -use forester_utils::{ - forester_epoch::Epoch, - registry::register_test_forester, -}; +use forester_utils::forester_epoch::Epoch; +use crate::utils::register_test_forester::register_test_forester; use crate::utils::tree_accounts::TreeAccounts; use light_client::{ indexer::{AddressMerkleTreeAccounts, StateMerkleTreeAccounts}, diff --git a/sdk-libs/program-test/src/utils/mod.rs b/sdk-libs/program-test/src/utils/mod.rs index 1d5c1ce969..e1b9d7be63 100644 --- a/sdk-libs/program-test/src/utils/mod.rs +++ b/sdk-libs/program-test/src/utils/mod.rs @@ -1,5 +1,6 @@ pub mod assert; pub mod create_account; pub mod find_light_bin; +pub mod register_test_forester; pub mod setup_light_programs; pub mod tree_accounts; diff --git a/sdk-libs/program-test/src/utils/register_test_forester.rs b/sdk-libs/program-test/src/utils/register_test_forester.rs new file mode 100644 index 0000000000..8953f317b8 --- /dev/null +++ b/sdk-libs/program-test/src/utils/register_test_forester.rs @@ -0,0 +1,58 @@ +use light_client::rpc::{Rpc, RpcError}; +use light_registry::{ + sdk::create_register_forester_instruction, + utils::get_forester_pda, + ForesterConfig, ForesterPda, +}; +use solana_sdk::{ + pubkey::Pubkey, + signature::{Keypair, Signer}, +}; + +/// Creates and asserts forester account creation. +pub async fn register_test_forester( + rpc: &mut R, + governance_authority: &Keypair, + forester_authority: &Pubkey, + config: ForesterConfig, +) -> Result<(), RpcError> { + let ix = create_register_forester_instruction( + &governance_authority.pubkey(), + &governance_authority.pubkey(), + forester_authority, + config, + ); + rpc.create_and_send_transaction( + &[ix], + &governance_authority.pubkey(), + &[governance_authority], + ) + .await?; + assert_registered_forester( + rpc, + forester_authority, + ForesterPda { + authority: *forester_authority, + config, + active_weight: 1, + ..Default::default() + }, + ) + .await +} + +async fn assert_registered_forester( + rpc: &mut R, + forester: &Pubkey, + expected_account: ForesterPda, +) -> Result<(), RpcError> { + let pda = get_forester_pda(forester).0; + let account_data = rpc.get_anchor_account::(&pda).await?.unwrap(); + if account_data != expected_account { + return Err(RpcError::AssertRpcError(format!( + "Expected account data: {:?}, got: {:?}", + expected_account, account_data + ))); + } + Ok(()) +} \ No newline at end of file From fd37d14a1b70d27aa9fc9d4aea2b3d941719647f Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 13:49:55 +0200 Subject: [PATCH 04/10] removed forester-utils dep --- Cargo.lock | 1 - program-tests/registry-test/tests/tests.rs | 1 - program-tests/utils/src/e2e_test_env.rs | 20 +--- program-tests/utils/src/lib.rs | 2 + program-tests/utils/src/setup_forester.rs | 95 +++++++++++++++++++ sdk-libs/program-test/Cargo.toml | 4 +- .../program-test/src/accounts/initialize.rs | 57 ----------- .../src/accounts/test_accounts.rs | 5 - .../program-test/src/program_test/config.rs | 2 - .../program-test/src/utils/tree_accounts.rs | 8 -- xtask/src/new_deployment.rs | 1 - 11 files changed, 101 insertions(+), 95 deletions(-) create mode 100644 program-tests/utils/src/setup_forester.rs diff --git a/Cargo.lock b/Cargo.lock index 541c1c22cf..d70d146368 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3561,7 +3561,6 @@ dependencies = [ "async-trait", "borsh 0.10.4", "bytemuck", - "forester-utils", "light-batched-merkle-tree", "light-client", "light-compressed-account", diff --git a/program-tests/registry-test/tests/tests.rs b/program-tests/registry-test/tests/tests.rs index 2b41e6c9e6..2f5bb2f91e 100644 --- a/program-tests/registry-test/tests/tests.rs +++ b/program-tests/registry-test/tests/tests.rs @@ -749,7 +749,6 @@ async fn test_register_and_update_forester_pda() { let config = ProgramTestConfig { protocol_config: ProtocolConfig::default(), with_prover: false, - register_forester_and_advance_to_active_phase: false, ..Default::default() }; diff --git a/program-tests/utils/src/e2e_test_env.rs b/program-tests/utils/src/e2e_test_env.rs index 0c21f32267..d4be1945fc 100644 --- a/program-tests/utils/src/e2e_test_env.rs +++ b/program-tests/utils/src/e2e_test_env.rs @@ -394,23 +394,9 @@ where .config; // TODO: add clear test env enum // register foresters is only compatible with ProgramTest environment - let (foresters, epoch_config) = - if let Some(registered_epoch) = test_accounts.protocol.forester_epoch.as_ref() { - let _forester = Forester { - registration: registered_epoch.clone(), - active: registered_epoch.clone(), - ..Default::default() - }; - // Forester epoch account is assumed to exist (is inited with test program deployment) - let forester = TestForester { - keypair: test_accounts.protocol.forester.insecure_clone(), - forester: _forester.clone(), - is_registered: Some(0), - }; - (vec![forester], _forester) - } else { - (Vec::::new(), Forester::default()) - }; + // Default forester setup - tests that need forester functionality should call + // setup_forester_and_advance_to_epoch explicitly and manage their own forester state + let (foresters, epoch_config) = (Vec::::new(), Forester::default()); Self { payer, indexer, diff --git a/program-tests/utils/src/lib.rs b/program-tests/utils/src/lib.rs index 848ffe4cc3..e9b415bd0f 100644 --- a/program-tests/utils/src/lib.rs +++ b/program-tests/utils/src/lib.rs @@ -32,6 +32,7 @@ pub mod mock_batched_forester; pub mod pack; pub mod registered_program_accounts_v1; pub mod setup_accounts; +pub mod setup_forester; #[allow(unused)] pub mod spl; pub mod state_tree_rollover; @@ -51,6 +52,7 @@ pub use forester_utils::{ }, }; pub use light_program_test::utils::register_test_forester::register_test_forester; +pub use setup_forester::setup_forester_and_advance_to_epoch; pub use light_client::{ fee::{FeeConfig, TransactionParams}, rpc::{client::RpcUrl, LightClient, Rpc, RpcError}, diff --git a/program-tests/utils/src/setup_forester.rs b/program-tests/utils/src/setup_forester.rs new file mode 100644 index 0000000000..f92fb7ebfe --- /dev/null +++ b/program-tests/utils/src/setup_forester.rs @@ -0,0 +1,95 @@ +use forester_utils::forester_epoch::{Epoch, TreeAccounts}; +use light_client::rpc::{Rpc, RpcError}; +use light_program_test::program_test::TestRpc; +use light_compressed_account::TreeType; +use light_registry::{ + protocol_config::state::ProtocolConfig, + sdk::create_finalize_registration_instruction, +}; +use light_program_test::utils::register_test_forester::register_test_forester; +use solana_sdk::{ + pubkey::Pubkey, + signature::{Keypair, Signer}, +}; +use light_registry::ForesterConfig; + +/// Sets up a forester, registers it, and advances to the active epoch phase. +/// This function encapsulates all forester-related setup that was previously +/// done conditionally in light-program-test. +/// +/// # Arguments +/// * `context` - The test RPC context +/// * `protocol_config` - Protocol configuration +/// * `forester_keypair` - Keypair for the forester +/// * `state_merkle_tree` - State merkle tree pubkey +/// * `nullifier_queue` - Nullifier queue pubkey +/// * `address_merkle_tree` - Address merkle tree pubkey +/// * `address_queue` - Address queue pubkey +/// +/// # Returns +/// * `Result` - The registered and activated epoch +pub async fn setup_forester_and_advance_to_epoch( + context: &mut R, + protocol_config: &ProtocolConfig, + governance_authority: &Keypair, + forester_keypair: &Keypair, + state_merkle_tree: Pubkey, + nullifier_queue: Pubkey, + address_merkle_tree: Pubkey, + address_queue: Pubkey, +) -> Result { + // Register the test forester + register_test_forester( + context, + governance_authority, + &forester_keypair.pubkey(), + ForesterConfig::default(), + ) + .await?; + + // Register the epoch + let mut registered_epoch = Epoch::register( + context, + protocol_config, + forester_keypair, + &forester_keypair.pubkey(), + ) + .await? + .unwrap(); + + // Advance to active phase + context.warp_to_slot(registered_epoch.phases.active.start)?; + + // Create tree accounts for the epoch + let tree_accounts = vec![ + TreeAccounts::new( + state_merkle_tree, + nullifier_queue, + TreeType::StateV1, + false, + ), + TreeAccounts::new( + address_merkle_tree, + address_queue, + TreeType::AddressV1, + false, + ), + ]; + + // Add trees to the epoch with schedule + registered_epoch + .fetch_account_and_add_trees_with_schedule(context, &tree_accounts) + .await?; + + // Finalize registration + let ix = create_finalize_registration_instruction( + &forester_keypair.pubkey(), + &forester_keypair.pubkey(), + 0, + ); + context + .create_and_send_transaction(&[ix], &forester_keypair.pubkey(), &[forester_keypair]) + .await?; + + Ok(registered_epoch) +} \ No newline at end of file diff --git a/sdk-libs/program-test/Cargo.toml b/sdk-libs/program-test/Cargo.toml index a202154304..c673cacb60 100644 --- a/sdk-libs/program-test/Cargo.toml +++ b/sdk-libs/program-test/Cargo.toml @@ -10,10 +10,9 @@ default = [] devenv = [ "v2", "light-client/devenv", - "forester-utils/devenv", "light-prover-client/devenv", ] -v2 = ["light-client/v2", "forester-utils/v2"] +v2 = ["light-client/v2"] [dependencies] light-sdk = { workspace = true, features = ["anchor"] } @@ -28,7 +27,6 @@ light-batched-merkle-tree = { workspace = true, features = ["test-only"] } # unreleased light-client = { workspace = true, features = ["program-test"] } -forester-utils = { workspace = true } light-prover-client = { workspace = true } litesvm = { workspace = true } diff --git a/sdk-libs/program-test/src/accounts/initialize.rs b/sdk-libs/program-test/src/accounts/initialize.rs index 1b1efc5d6a..af12ac68c1 100644 --- a/sdk-libs/program-test/src/accounts/initialize.rs +++ b/sdk-libs/program-test/src/accounts/initialize.rs @@ -1,21 +1,15 @@ use account_compression::{utils::constants::GROUP_AUTHORITY_SEED, GroupAuthority}; -use forester_utils::forester_epoch::Epoch; -use crate::utils::register_test_forester::register_test_forester; -use crate::utils::tree_accounts::TreeAccounts; use light_client::{ indexer::{AddressMerkleTreeAccounts, StateMerkleTreeAccounts}, rpc::{Rpc, RpcError}, }; -use light_compressed_account::TreeType; use light_registry::{ account_compression_cpi::sdk::get_registered_program_pda, sdk::{ - create_finalize_registration_instruction, create_initialize_governance_authority_instruction, create_initialize_group_authority_instruction, create_update_protocol_config_instruction, }, utils::{get_cpi_authority_pda, get_forester_pda, get_protocol_config_pda_address}, - ForesterConfig, }; use solana_sdk::{ pubkey::Pubkey, @@ -48,7 +42,6 @@ pub async fn initialize_accounts( ) -> Result { let ProgramTestConfig { protocol_config, - register_forester_and_advance_to_active_phase, v2_state_tree_config, v2_address_tree_config, skip_register_programs, @@ -106,13 +99,6 @@ pub async fn initialize_accounts( )); } - register_test_forester( - context, - &keypairs.governance_authority, - &keypairs.forester.pubkey(), - ForesterConfig::default(), - ) - .await?; #[cfg(feature = "devenv")] if !_skip_register_programs { @@ -207,48 +193,6 @@ pub async fn initialize_accounts( let registered_system_program_pda = get_registered_program_pda(&Pubkey::from(light_sdk::constants::LIGHT_SYSTEM_PROGRAM_ID)); let registered_registry_program_pda = get_registered_program_pda(&light_registry::ID); - let forester_epoch = if *register_forester_and_advance_to_active_phase { - let mut registered_epoch = Epoch::register( - context, - protocol_config, - &keypairs.forester, - &keypairs.forester.pubkey(), - ) - .await? - .unwrap(); - context.warp_to_slot(registered_epoch.phases.active.start)?; - let tree_accounts = vec![ - TreeAccounts { - tree_type: TreeType::StateV1, - merkle_tree: merkle_tree_pubkey, - queue: nullifier_queue_pubkey, - is_rolledover: false, - }, - TreeAccounts { - tree_type: TreeType::AddressV1, - merkle_tree: keypairs.address_merkle_tree.pubkey(), - queue: keypairs.address_merkle_tree_queue.pubkey(), - is_rolledover: false, - }, - ]; - - let forester_tree_accounts: Vec = - tree_accounts.iter().map(|ta| ta.to_forester_utils()).collect(); - registered_epoch - .fetch_account_and_add_trees_with_schedule(context, &forester_tree_accounts) - .await?; - let ix = create_finalize_registration_instruction( - &keypairs.forester.pubkey(), - &keypairs.forester.pubkey(), - 0, - ); - context - .create_and_send_transaction(&[ix], &keypairs.forester.pubkey(), &[&keypairs.forester]) - .await?; - Some(registered_epoch) - } else { - None - }; Ok(TestAccounts { protocol: ProtocolAccounts { governance_authority: keypairs.governance_authority.insecure_clone(), @@ -258,7 +202,6 @@ pub async fn initialize_accounts( registered_program_pda: registered_system_program_pda, registered_registry_program_pda, registered_forester_pda: get_forester_pda(&keypairs.forester.pubkey()).0, - forester_epoch, }, v1_state_trees: vec![StateMerkleTreeAccounts { merkle_tree: merkle_tree_pubkey, diff --git a/sdk-libs/program-test/src/accounts/test_accounts.rs b/sdk-libs/program-test/src/accounts/test_accounts.rs index 115577c71c..ea4284c30d 100644 --- a/sdk-libs/program-test/src/accounts/test_accounts.rs +++ b/sdk-libs/program-test/src/accounts/test_accounts.rs @@ -1,4 +1,3 @@ -use forester_utils::forester_epoch::Epoch; use light_client::indexer::{AddressMerkleTreeAccounts, StateMerkleTreeAccounts, TreeInfo}; use light_compressed_account::TreeType; use light_registry::{ @@ -25,7 +24,6 @@ pub struct ProtocolAccounts { pub registered_program_pda: Pubkey, pub registered_registry_program_pda: Pubkey, pub registered_forester_pda: Pubkey, - pub forester_epoch: Option, } #[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)] @@ -69,7 +67,6 @@ impl TestAccounts { )), registered_registry_program_pda: get_registered_program_pda(&light_registry::ID), registered_forester_pda: Pubkey::default(), - forester_epoch: None, // Set to None or to an appropriate Epoch value if needed }, v1_state_trees: vec![StateMerkleTreeAccounts { merkle_tree: pubkey!("smt1NamzXdq4AMqS2fS2F1i5KTYPZRhoHgWx38d8WsT"), @@ -120,7 +117,6 @@ impl TestAccounts { registered_program_pda, registered_registry_program_pda, registered_forester_pda: get_forester_pda(&forester_pubkey).0, - forester_epoch: None, }, v1_state_trees: vec![StateMerkleTreeAccounts { merkle_tree: merkle_tree_keypair.pubkey(), @@ -165,7 +161,6 @@ impl Clone for TestAccounts { registered_program_pda: self.protocol.registered_program_pda, registered_registry_program_pda: self.protocol.registered_registry_program_pda, registered_forester_pda: self.protocol.registered_forester_pda, - forester_epoch: self.protocol.forester_epoch.clone(), }, v1_state_trees: self.v1_state_trees.clone(), v1_address_trees: self.v1_address_trees.clone(), diff --git a/sdk-libs/program-test/src/program_test/config.rs b/sdk-libs/program-test/src/program_test/config.rs index ade109c29e..33d8262b50 100644 --- a/sdk-libs/program-test/src/program_test/config.rs +++ b/sdk-libs/program-test/src/program_test/config.rs @@ -13,7 +13,6 @@ use solana_sdk::pubkey::Pubkey; pub struct ProgramTestConfig { pub additional_programs: Option>, pub protocol_config: ProtocolConfig, - pub register_forester_and_advance_to_active_phase: bool, pub with_prover: bool, pub prover_config: Option, pub skip_register_programs: bool, @@ -105,7 +104,6 @@ impl Default for ProgramTestConfig { registration_phase_length: 2, ..Default::default() }, - register_forester_and_advance_to_active_phase: true, with_prover: true, prover_config: None, skip_second_v1_tree: false, diff --git a/sdk-libs/program-test/src/utils/tree_accounts.rs b/sdk-libs/program-test/src/utils/tree_accounts.rs index 2eed41c019..59c33d4f2d 100644 --- a/sdk-libs/program-test/src/utils/tree_accounts.rs +++ b/sdk-libs/program-test/src/utils/tree_accounts.rs @@ -24,12 +24,4 @@ impl TreeAccounts { } } - pub fn to_forester_utils(&self) -> forester_utils::forester_epoch::TreeAccounts { - forester_utils::forester_epoch::TreeAccounts::new( - self.merkle_tree, - self.queue, - self.tree_type, - self.is_rolledover, - ) - } } \ No newline at end of file diff --git a/xtask/src/new_deployment.rs b/xtask/src/new_deployment.rs index ff9a61b7a4..14d13788e3 100644 --- a/xtask/src/new_deployment.rs +++ b/xtask/src/new_deployment.rs @@ -168,7 +168,6 @@ pub async fn init_new_deployment(options: Options) -> anyhow::Result<()> { v1_state_tree_config: StateMerkleTreeConfig::default(), v2_state_tree_config: Some(InitStateTreeAccountsInstructionData::default()), v2_address_tree_config: Some(InitAddressTreeAccountsInstructionData::default()), - register_forester_and_advance_to_active_phase: false, ..Default::default() }; initialize_accounts(&mut rpc, &config, &test_keypairs) From 0a094fd222e2511d3e45fcb8aa3291a649392d85 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 14:19:13 +0200 Subject: [PATCH 05/10] refactor: test forester to light-test-utils --- program-tests/registry-test/tests/tests.rs | 31 ++++++++++++ program-tests/system-test/tests/test.rs | 19 +++++--- program-tests/utils/src/setup_forester.rs | 56 +++++++++------------- 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/program-tests/registry-test/tests/tests.rs b/program-tests/registry-test/tests/tests.rs index 2f5bb2f91e..537c784acc 100644 --- a/program-tests/registry-test/tests/tests.rs +++ b/program-tests/registry-test/tests/tests.rs @@ -74,6 +74,7 @@ use light_test_utils::{ e2e_test_env::init_program_test_env, register_test_forester, setup_accounts::setup_accounts, + setup_forester_and_advance_to_epoch, test_batch_forester::{ assert_perform_state_mt_roll_over, create_append_batch_ix_data, create_batch_update_address_tree_instruction_data_with_proof, perform_batch_append, @@ -193,6 +194,7 @@ async fn test_initialize_protocol_config() { payer, config: ProgramTestConfig::default(), }; + let payer = rpc.get_payer().insecure_clone(); let program_account_keypair = Keypair::from_bytes(&OLD_REGISTRY_ID_TEST_KEYPAIR).unwrap(); let protocol_config = ProtocolConfig::default(); @@ -550,6 +552,10 @@ async fn test_custom_forester() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let env = rpc.test_accounts.clone(); @@ -629,6 +635,10 @@ async fn test_custom_forester_batched() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_test_forester(true)) .await .unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let env = rpc.test_accounts.clone(); let tree_params = ProgramTestConfig::default_with_batched_trees(true) @@ -1017,6 +1027,10 @@ async fn failing_test_forester() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let env = rpc.test_accounts.clone(); let payer = rpc.get_payer().insecure_clone(); @@ -1408,6 +1422,10 @@ async fn test_migrate_state() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let test_accounts = rpc.test_accounts.clone(); let payer = rpc.get_payer().insecure_clone(); @@ -1677,6 +1695,10 @@ async fn test_rollover_batch_state_tree() { config.v2_state_tree_config = Some(params); let mut rpc = LightProgramTest::new(config).await.unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let test_accounts = rpc.test_accounts.clone(); let payer = rpc.get_payer().insecure_clone(); @@ -1868,6 +1890,11 @@ async fn test_batch_address_tree() { CREATE_ADDRESS_TEST_PROGRAM_ID, )]); let mut rpc = LightProgramTest::new(config).await.unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); + rpc.indexer = None; let env = rpc.test_accounts.clone(); @@ -2043,6 +2070,10 @@ async fn test_rollover_batch_address_tree() { )]); config.v2_address_tree_config = Some(tree_params); let mut rpc = LightProgramTest::new(config).await.unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); rpc.indexer = None; let env = rpc.test_accounts.clone(); diff --git a/program-tests/system-test/tests/test.rs b/program-tests/system-test/tests/test.rs index e6270e776d..b983f34edd 100644 --- a/program-tests/system-test/tests/test.rs +++ b/program-tests/system-test/tests/test.rs @@ -34,7 +34,7 @@ use light_system_program::{ use light_test_utils::{ airdrop_lamports, assert_compressed_tx::assert_created_compressed_accounts, - assert_custom_error_or_program_error, + assert_custom_error_or_program_error, setup_forester_and_advance_to_epoch, system_program::{ compress_sol_test, create_addresses_test, create_invoke_instruction, create_invoke_instruction_data_and_remaining_accounts, decompress_sol_test, @@ -1674,6 +1674,11 @@ async fn regenerate_accounts() { .unwrap(); let keypairs = for_regenerate_accounts(); + // Setup forester and get epoch information + let forester_epoch = setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); + // List of public keys to fetch and export let pubkeys = vec![ ("merkle_tree_pubkey", env.v1_state_trees[0].merkle_tree), @@ -1709,15 +1714,11 @@ async fn regenerate_accounts() { ), ( "forester_epoch_pda", - env.protocol - .forester_epoch - .as_ref() - .unwrap() - .forester_epoch_pda, + forester_epoch.forester_epoch_pda, ), ( "epoch_pda", - env.protocol.forester_epoch.as_ref().unwrap().epoch_pda, + forester_epoch.epoch_pda, ), ("batch_state_merkle_tree", env.v2_state_trees[0].merkle_tree), ("batched_output_queue", env.v2_state_trees[0].output_queue), @@ -1845,6 +1846,10 @@ async fn batch_invoke_test() { let config = ProgramTestConfig::default_test_forester(false); let mut rpc = LightProgramTest::new(config).await.unwrap(); + let protocol_config = rpc.config.protocol_config.clone(); + let forester_epoch = setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); let env = rpc.test_accounts.clone(); let payer = rpc.get_payer().insecure_clone(); diff --git a/program-tests/utils/src/setup_forester.rs b/program-tests/utils/src/setup_forester.rs index f92fb7ebfe..b8fad631ea 100644 --- a/program-tests/utils/src/setup_forester.rs +++ b/program-tests/utils/src/setup_forester.rs @@ -1,17 +1,13 @@ use forester_utils::forester_epoch::{Epoch, TreeAccounts}; use light_client::rpc::{Rpc, RpcError}; -use light_program_test::program_test::TestRpc; use light_compressed_account::TreeType; -use light_registry::{ - protocol_config::state::ProtocolConfig, - sdk::create_finalize_registration_instruction, -}; use light_program_test::utils::register_test_forester::register_test_forester; -use solana_sdk::{ - pubkey::Pubkey, - signature::{Keypair, Signer}, -}; +use light_program_test::{accounts::test_keypairs::TestKeypairs, program_test::TestRpc}; use light_registry::ForesterConfig; +use light_registry::{ + protocol_config::state::ProtocolConfig, sdk::create_finalize_registration_instruction, +}; +use solana_sdk::signature::Signer; /// Sets up a forester, registers it, and advances to the active epoch phase. /// This function encapsulates all forester-related setup that was previously @@ -20,29 +16,19 @@ use light_registry::ForesterConfig; /// # Arguments /// * `context` - The test RPC context /// * `protocol_config` - Protocol configuration -/// * `forester_keypair` - Keypair for the forester -/// * `state_merkle_tree` - State merkle tree pubkey -/// * `nullifier_queue` - Nullifier queue pubkey -/// * `address_merkle_tree` - Address merkle tree pubkey -/// * `address_queue` - Address queue pubkey /// /// # Returns /// * `Result` - The registered and activated epoch pub async fn setup_forester_and_advance_to_epoch( context: &mut R, protocol_config: &ProtocolConfig, - governance_authority: &Keypair, - forester_keypair: &Keypair, - state_merkle_tree: Pubkey, - nullifier_queue: Pubkey, - address_merkle_tree: Pubkey, - address_queue: Pubkey, ) -> Result { + let test_keypairs = TestKeypairs::program_test_default(); // Register the test forester register_test_forester( context, - governance_authority, - &forester_keypair.pubkey(), + &test_keypairs.governance_authority, + &test_keypairs.forester.pubkey(), ForesterConfig::default(), ) .await?; @@ -51,8 +37,8 @@ pub async fn setup_forester_and_advance_to_epoch( let mut registered_epoch = Epoch::register( context, protocol_config, - forester_keypair, - &forester_keypair.pubkey(), + &test_keypairs.forester, + &test_keypairs.forester.pubkey(), ) .await? .unwrap(); @@ -60,17 +46,17 @@ pub async fn setup_forester_and_advance_to_epoch( // Advance to active phase context.warp_to_slot(registered_epoch.phases.active.start)?; - // Create tree accounts for the epoch + // Create tree accounts for the epoch using test keypairs let tree_accounts = vec![ TreeAccounts::new( - state_merkle_tree, - nullifier_queue, + test_keypairs.state_merkle_tree.pubkey(), + test_keypairs.nullifier_queue.pubkey(), TreeType::StateV1, false, ), TreeAccounts::new( - address_merkle_tree, - address_queue, + test_keypairs.address_merkle_tree.pubkey(), + test_keypairs.address_merkle_tree_queue.pubkey(), TreeType::AddressV1, false, ), @@ -83,13 +69,17 @@ pub async fn setup_forester_and_advance_to_epoch( // Finalize registration let ix = create_finalize_registration_instruction( - &forester_keypair.pubkey(), - &forester_keypair.pubkey(), + &test_keypairs.forester.pubkey(), + &test_keypairs.forester.pubkey(), 0, ); context - .create_and_send_transaction(&[ix], &forester_keypair.pubkey(), &[forester_keypair]) + .create_and_send_transaction( + &[ix], + &test_keypairs.forester.pubkey(), + &[&test_keypairs.forester], + ) .await?; Ok(registered_epoch) -} \ No newline at end of file +} From baeab5697587afe51ec10bc056fca3a33d4a3813 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 14:23:22 +0200 Subject: [PATCH 06/10] fix lint --- forester-utils/src/registry.rs | 1 - program-tests/registry-test/tests/tests.rs | 14 +++++++------- program-tests/system-test/tests/test.rs | 14 ++++---------- program-tests/utils/src/e2e_test_env.rs | 2 +- program-tests/utils/src/lib.rs | 7 +++---- program-tests/utils/src/setup_forester.rs | 8 +++++--- sdk-libs/program-test/src/accounts/address_tree.rs | 3 ++- .../program-test/src/accounts/address_tree_v2.rs | 3 ++- sdk-libs/program-test/src/accounts/initialize.rs | 1 - sdk-libs/program-test/src/accounts/state_tree.rs | 3 ++- .../program-test/src/accounts/state_tree_v2.rs | 3 ++- sdk-libs/program-test/src/utils/create_account.rs | 2 +- .../src/utils/register_test_forester.rs | 6 ++---- sdk-libs/program-test/src/utils/tree_accounts.rs | 3 +-- 14 files changed, 32 insertions(+), 38 deletions(-) diff --git a/forester-utils/src/registry.rs b/forester-utils/src/registry.rs index cf2768396b..532774d690 100644 --- a/forester-utils/src/registry.rs +++ b/forester-utils/src/registry.rs @@ -27,7 +27,6 @@ use crate::{ instructions::create_account::create_account_instruction, }; - pub async fn update_test_forester( rpc: &mut R, forester_authority: &Keypair, diff --git a/program-tests/registry-test/tests/tests.rs b/program-tests/registry-test/tests/tests.rs index 537c784acc..4b4765ec1e 100644 --- a/program-tests/registry-test/tests/tests.rs +++ b/program-tests/registry-test/tests/tests.rs @@ -552,7 +552,7 @@ async fn test_custom_forester() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -635,7 +635,7 @@ async fn test_custom_forester_batched() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_test_forester(true)) .await .unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -1027,7 +1027,7 @@ async fn failing_test_forester() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -1422,7 +1422,7 @@ async fn test_migrate_state() { let mut rpc = LightProgramTest::new(ProgramTestConfig::default_with_batched_trees(true)) .await .unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -1695,7 +1695,7 @@ async fn test_rollover_batch_state_tree() { config.v2_state_tree_config = Some(params); let mut rpc = LightProgramTest::new(config).await.unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -1890,7 +1890,7 @@ async fn test_batch_address_tree() { CREATE_ADDRESS_TEST_PROGRAM_ID, )]); let mut rpc = LightProgramTest::new(config).await.unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); @@ -2070,7 +2070,7 @@ async fn test_rollover_batch_address_tree() { )]); config.v2_address_tree_config = Some(tree_params); let mut rpc = LightProgramTest::new(config).await.unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); + let protocol_config = rpc.config.protocol_config; setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); diff --git a/program-tests/system-test/tests/test.rs b/program-tests/system-test/tests/test.rs index b983f34edd..f1cfba0f1f 100644 --- a/program-tests/system-test/tests/test.rs +++ b/program-tests/system-test/tests/test.rs @@ -1712,14 +1712,8 @@ async fn regenerate_accounts() { "registered_forester_pda", env.protocol.registered_forester_pda, ), - ( - "forester_epoch_pda", - forester_epoch.forester_epoch_pda, - ), - ( - "epoch_pda", - forester_epoch.epoch_pda, - ), + ("forester_epoch_pda", forester_epoch.forester_epoch_pda), + ("epoch_pda", forester_epoch.epoch_pda), ("batch_state_merkle_tree", env.v2_state_trees[0].merkle_tree), ("batched_output_queue", env.v2_state_trees[0].output_queue), ("batch_address_merkle_tree", env.v2_address_trees[0]), @@ -1846,8 +1840,8 @@ async fn batch_invoke_test() { let config = ProgramTestConfig::default_test_forester(false); let mut rpc = LightProgramTest::new(config).await.unwrap(); - let protocol_config = rpc.config.protocol_config.clone(); - let forester_epoch = setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + let protocol_config = rpc.config.protocol_config; + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) .await .unwrap(); diff --git a/program-tests/utils/src/e2e_test_env.rs b/program-tests/utils/src/e2e_test_env.rs index d4be1945fc..59396c6887 100644 --- a/program-tests/utils/src/e2e_test_env.rs +++ b/program-tests/utils/src/e2e_test_env.rs @@ -78,7 +78,6 @@ use forester_utils::{ forester_epoch::{Epoch, Forester, TreeAccounts}, utils::airdrop_lamports, }; -use light_program_test::utils::register_test_forester::register_test_forester; use light_batched_merkle_tree::{ batch::BatchState, constants::{DEFAULT_BATCH_ADDRESS_TREE_HEIGHT, TEST_DEFAULT_BATCH_SIZE}, @@ -132,6 +131,7 @@ use light_program_test::{ TestIndexerExtensions, }, program_test::{LightProgramTest, TestRpc}, + utils::register_test_forester::register_test_forester, }; use light_prover_client::{ constants::{PROVE_PATH, SERVER_ADDRESS}, diff --git a/program-tests/utils/src/lib.rs b/program-tests/utils/src/lib.rs index e9b415bd0f..5a581bbb4b 100644 --- a/program-tests/utils/src/lib.rs +++ b/program-tests/utils/src/lib.rs @@ -47,19 +47,18 @@ pub use forester_utils::{ forester_epoch::{Epoch, TreeAccounts}, registry::{ create_rollover_address_merkle_tree_instructions, - create_rollover_state_merkle_tree_instructions, - update_test_forester, + create_rollover_state_merkle_tree_instructions, update_test_forester, }, }; -pub use light_program_test::utils::register_test_forester::register_test_forester; -pub use setup_forester::setup_forester_and_advance_to_epoch; pub use light_client::{ fee::{FeeConfig, TransactionParams}, rpc::{client::RpcUrl, LightClient, Rpc, RpcError}, }; use light_hasher::Poseidon; use light_program_test::accounts::address_tree::create_address_merkle_tree_and_queue_account; +pub use light_program_test::utils::register_test_forester::register_test_forester; use light_registry::account_compression_cpi::sdk::get_registered_program_pda; +pub use setup_forester::setup_forester_and_advance_to_epoch; use crate::assert_queue::assert_address_queue_initialized; diff --git a/program-tests/utils/src/setup_forester.rs b/program-tests/utils/src/setup_forester.rs index b8fad631ea..616ecad7ab 100644 --- a/program-tests/utils/src/setup_forester.rs +++ b/program-tests/utils/src/setup_forester.rs @@ -1,11 +1,13 @@ use forester_utils::forester_epoch::{Epoch, TreeAccounts}; use light_client::rpc::{Rpc, RpcError}; use light_compressed_account::TreeType; -use light_program_test::utils::register_test_forester::register_test_forester; -use light_program_test::{accounts::test_keypairs::TestKeypairs, program_test::TestRpc}; -use light_registry::ForesterConfig; +use light_program_test::{ + accounts::test_keypairs::TestKeypairs, program_test::TestRpc, + utils::register_test_forester::register_test_forester, +}; use light_registry::{ protocol_config::state::ProtocolConfig, sdk::create_finalize_registration_instruction, + ForesterConfig, }; use solana_sdk::signature::Signer; diff --git a/sdk-libs/program-test/src/accounts/address_tree.rs b/sdk-libs/program-test/src/accounts/address_tree.rs index 797af3286e..0807e352af 100644 --- a/sdk-libs/program-test/src/accounts/address_tree.rs +++ b/sdk-libs/program-test/src/accounts/address_tree.rs @@ -2,7 +2,6 @@ use account_compression::{ instruction::InitializeAddressMerkleTreeAndQueue, AddressMerkleTreeConfig, AddressQueueConfig, }; use anchor_lang::InstructionData; -use crate::utils::create_account::create_account_instruction; use light_client::rpc::{errors::RpcError, Rpc}; use solana_sdk::{ compute_budget::ComputeBudgetInstruction, @@ -12,6 +11,8 @@ use solana_sdk::{ transaction::Transaction, }; +use crate::utils::create_account::create_account_instruction; + #[allow(clippy::too_many_arguments)] pub fn create_initialize_address_merkle_tree_and_queue_instruction( index: u64, diff --git a/sdk-libs/program-test/src/accounts/address_tree_v2.rs b/sdk-libs/program-test/src/accounts/address_tree_v2.rs index 3d96c565d8..fe9bccee9b 100644 --- a/sdk-libs/program-test/src/accounts/address_tree_v2.rs +++ b/sdk-libs/program-test/src/accounts/address_tree_v2.rs @@ -1,4 +1,3 @@ -use crate::utils::create_account::create_account_instruction; use light_batched_merkle_tree::{ initialize_address_tree::InitAddressTreeAccountsInstructionData, merkle_tree::get_merkle_tree_account_size, @@ -7,6 +6,8 @@ use light_client::rpc::{Rpc, RpcError}; use light_registry::account_compression_cpi::sdk::create_initialize_batched_address_merkle_tree_instruction; use solana_sdk::signature::{Keypair, Signature, Signer}; +use crate::utils::create_account::create_account_instruction; + pub async fn create_batch_address_merkle_tree( rpc: &mut R, payer: &Keypair, diff --git a/sdk-libs/program-test/src/accounts/initialize.rs b/sdk-libs/program-test/src/accounts/initialize.rs index af12ac68c1..7781a87af9 100644 --- a/sdk-libs/program-test/src/accounts/initialize.rs +++ b/sdk-libs/program-test/src/accounts/initialize.rs @@ -99,7 +99,6 @@ pub async fn initialize_accounts( )); } - #[cfg(feature = "devenv")] if !_skip_register_programs { register_program_with_registry_program( diff --git a/sdk-libs/program-test/src/accounts/state_tree.rs b/sdk-libs/program-test/src/accounts/state_tree.rs index df1be45042..d43f7f768e 100644 --- a/sdk-libs/program-test/src/accounts/state_tree.rs +++ b/sdk-libs/program-test/src/accounts/state_tree.rs @@ -3,7 +3,6 @@ use account_compression::{ StateMerkleTreeConfig, }; use anchor_lang::{InstructionData, ToAccountMetas}; -use crate::utils::create_account::create_account_instruction; use light_client::rpc::{errors::RpcError, Rpc}; use light_compressed_account::instruction_data::insert_into_queues::InsertIntoQueuesInstructionDataMut; use light_registry::protocol_config::state::ProtocolConfig; @@ -14,6 +13,8 @@ use solana_sdk::{ transaction::Transaction, }; +use crate::utils::create_account::create_account_instruction; + #[allow(clippy::too_many_arguments)] pub fn create_initialize_merkle_tree_instruction( payer: Pubkey, diff --git a/sdk-libs/program-test/src/accounts/state_tree_v2.rs b/sdk-libs/program-test/src/accounts/state_tree_v2.rs index 8d74b70d76..b3c4bb6184 100644 --- a/sdk-libs/program-test/src/accounts/state_tree_v2.rs +++ b/sdk-libs/program-test/src/accounts/state_tree_v2.rs @@ -1,5 +1,4 @@ use anchor_lang::{AnchorSerialize, InstructionData, ToAccountMetas}; -use crate::utils::create_account::create_account_instruction; use light_batched_merkle_tree::{ initialize_state_tree::InitStateTreeAccountsInstructionData, merkle_tree::get_merkle_tree_account_size, queue::get_output_queue_account_size, @@ -13,6 +12,8 @@ use solana_instruction::Instruction; use solana_pubkey::Pubkey; use solana_sdk::signature::{Keypair, Signature, Signer}; +use crate::utils::create_account::create_account_instruction; + pub async fn create_batched_state_merkle_tree( payer: &Keypair, registry: bool, diff --git a/sdk-libs/program-test/src/utils/create_account.rs b/sdk-libs/program-test/src/utils/create_account.rs index 2ad469c0af..55cecf673e 100644 --- a/sdk-libs/program-test/src/utils/create_account.rs +++ b/sdk-libs/program-test/src/utils/create_account.rs @@ -14,4 +14,4 @@ pub fn create_account_instruction( None => Keypair::new(), }; system_instruction::create_account(payer, &keypair.pubkey(), rent, size as u64, id) -} \ No newline at end of file +} diff --git a/sdk-libs/program-test/src/utils/register_test_forester.rs b/sdk-libs/program-test/src/utils/register_test_forester.rs index 8953f317b8..41cbe8a063 100644 --- a/sdk-libs/program-test/src/utils/register_test_forester.rs +++ b/sdk-libs/program-test/src/utils/register_test_forester.rs @@ -1,8 +1,6 @@ use light_client::rpc::{Rpc, RpcError}; use light_registry::{ - sdk::create_register_forester_instruction, - utils::get_forester_pda, - ForesterConfig, ForesterPda, + sdk::create_register_forester_instruction, utils::get_forester_pda, ForesterConfig, ForesterPda, }; use solana_sdk::{ pubkey::Pubkey, @@ -55,4 +53,4 @@ async fn assert_registered_forester( ))); } Ok(()) -} \ No newline at end of file +} diff --git a/sdk-libs/program-test/src/utils/tree_accounts.rs b/sdk-libs/program-test/src/utils/tree_accounts.rs index 59c33d4f2d..61ef8ff33a 100644 --- a/sdk-libs/program-test/src/utils/tree_accounts.rs +++ b/sdk-libs/program-test/src/utils/tree_accounts.rs @@ -23,5 +23,4 @@ impl TreeAccounts { is_rolledover, } } - -} \ No newline at end of file +} From 58882c0cb892a7bba236399d220cd0b7d881d6c9 Mon Sep 17 00:00:00 2001 From: ananas Date: Mon, 14 Jul 2025 19:38:00 +0100 Subject: [PATCH 07/10] fix tests --- .gitignore | 1 + .../system-cpi-test/tests/test_program_owned_trees.rs | 11 +++++++++-- programs/registry/src/protocol_config/state.rs | 7 +++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index b7e754f3b1..9943415324 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,4 @@ output1.txt .zed **/.claude/**/* +**/~/ diff --git a/program-tests/system-cpi-test/tests/test_program_owned_trees.rs b/program-tests/system-cpi-test/tests/test_program_owned_trees.rs index ddbdda14de..1fdf5636d0 100644 --- a/program-tests/system-cpi-test/tests/test_program_owned_trees.rs +++ b/program-tests/system-cpi-test/tests/test_program_owned_trees.rs @@ -31,8 +31,8 @@ use light_registry::{ }; use light_test_utils::{ airdrop_lamports, assert_custom_error_or_program_error, create_account_instruction, - get_concurrent_merkle_tree, spl::create_mint_helper, FeeConfig, Rpc, RpcError, - TransactionParams, + get_concurrent_merkle_tree, setup_forester_and_advance_to_epoch, spl::create_mint_helper, + FeeConfig, Rpc, RpcError, TransactionParams, }; use serial_test::serial; use solana_sdk::{ @@ -211,6 +211,13 @@ async fn test_invalid_registered_program() { airdrop_lamports(&mut rpc, &payer.pubkey(), 100_000_000_000) .await .unwrap(); + + // Setup forester to ensure registered_forester_pda is initialized + let protocol_config = rpc.config.protocol_config; + setup_forester_and_advance_to_epoch(&mut rpc, &protocol_config) + .await + .unwrap(); + let group_seed_keypair = Keypair::new(); let program_id_keypair = Keypair::from_bytes(&CPI_SYSTEM_TEST_PROGRAM_ID_KEYPAIR).unwrap(); println!("program_id_keypair: {:?}", program_id_keypair.pubkey()); diff --git a/programs/registry/src/protocol_config/state.rs b/programs/registry/src/protocol_config/state.rs index e938d8c9f1..3c65b897ca 100644 --- a/programs/registry/src/protocol_config/state.rs +++ b/programs/registry/src/protocol_config/state.rs @@ -176,10 +176,9 @@ impl ProtocolConfig { } pub fn get_current_active_epoch_progress(&self, slot: u64) -> u64 { - (slot - .checked_sub(self.genesis_slot + self.registration_phase_length) - .unwrap()) - % self.active_phase_length + slot.checked_sub(self.genesis_slot + self.registration_phase_length) + .map(|s| s % self.active_phase_length) + .unwrap_or(0) } /// In the last part of the active phase the registration phase starts. From 7dad150d7d494e671eaa814a16ee062a139e2438 Mon Sep 17 00:00:00 2001 From: ananas-block Date: Mon, 14 Jul 2025 21:59:17 +0200 Subject: [PATCH 08/10] chore: bump light-program-test version 0.13.1 -> 0.13.2 --- Cargo.lock | 2 +- Cargo.toml | 2 +- sdk-libs/program-test/Cargo.toml | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d70d146368..301eae03fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3554,7 +3554,7 @@ dependencies = [ [[package]] name = "light-program-test" -version = "0.13.1" +version = "0.13.2" dependencies = [ "account-compression", "anchor-lang", diff --git a/Cargo.toml b/Cargo.toml index 176115adb1..b58870a631 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,7 +184,7 @@ light-registry = { path = "programs/registry", version = "2.0.0", features = [ create-address-test-program = { path = "program-tests/create-address-test-program", version = "1.0.0", features = [ "cpi", ] } -light-program-test = { path = "sdk-libs/program-test", version = "0.13.1" } +light-program-test = { path = "sdk-libs/program-test", version = "0.13.2" } light-batched-merkle-tree = { path = "program-libs/batched-merkle-tree", version = "0.3.0" } light-merkle-tree-metadata = { path = "program-libs/merkle-tree-metadata", version = "0.3.0" } aligned-sized = { path = "program-libs/aligned-sized", version = "1.1.0" } diff --git a/sdk-libs/program-test/Cargo.toml b/sdk-libs/program-test/Cargo.toml index c673cacb60..c9a826ebc7 100644 --- a/sdk-libs/program-test/Cargo.toml +++ b/sdk-libs/program-test/Cargo.toml @@ -1,17 +1,13 @@ [package] name = "light-program-test" -version = "0.13.1" +version = "0.13.2" description = "A fast local test environment for Solana programs using compressed accounts and tokens." license = "MIT" edition = "2021" [features] default = [] -devenv = [ - "v2", - "light-client/devenv", - "light-prover-client/devenv", -] +devenv = ["v2", "light-client/devenv", "light-prover-client/devenv"] v2 = ["light-client/v2"] [dependencies] From 3631d00d4b36fc7b547647f1fabd543e38a41b27 Mon Sep 17 00:00:00 2001 From: ananas-block <58553958+ananas-block@users.noreply.github.com> Date: Mon, 14 Jul 2025 21:30:04 +0100 Subject: [PATCH 09/10] Update program-tests/utils/src/setup_forester.rs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- program-tests/utils/src/setup_forester.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program-tests/utils/src/setup_forester.rs b/program-tests/utils/src/setup_forester.rs index 616ecad7ab..6604c510f1 100644 --- a/program-tests/utils/src/setup_forester.rs +++ b/program-tests/utils/src/setup_forester.rs @@ -43,7 +43,7 @@ pub async fn setup_forester_and_advance_to_epoch( &test_keypairs.forester.pubkey(), ) .await? - .unwrap(); + .ok_or_else(|| RpcError::Custom("Failed to register epoch".to_string()))?; // Advance to active phase context.warp_to_slot(registered_epoch.phases.active.start)?; From e7560c57bb8404f1a66cb0afb548eb8d86fd370e Mon Sep 17 00:00:00 2001 From: ananas Date: Mon, 14 Jul 2025 22:23:42 +0100 Subject: [PATCH 10/10] refactor: move forester_update -> light-test-utils" --- program-tests/utils/src/setup_forester.rs | 2 +- .../utils/src/update_test_forester.rs | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 program-tests/utils/src/update_test_forester.rs diff --git a/program-tests/utils/src/setup_forester.rs b/program-tests/utils/src/setup_forester.rs index 6604c510f1..6f1fc17630 100644 --- a/program-tests/utils/src/setup_forester.rs +++ b/program-tests/utils/src/setup_forester.rs @@ -43,7 +43,7 @@ pub async fn setup_forester_and_advance_to_epoch( &test_keypairs.forester.pubkey(), ) .await? - .ok_or_else(|| RpcError::Custom("Failed to register epoch".to_string()))?; + .ok_or_else(|| RpcError::CustomError("Failed to register epoch".to_string()))?; // Advance to active phase context.warp_to_slot(registered_epoch.phases.active.start)?; diff --git a/program-tests/utils/src/update_test_forester.rs b/program-tests/utils/src/update_test_forester.rs new file mode 100644 index 0000000000..57afe6eeaa --- /dev/null +++ b/program-tests/utils/src/update_test_forester.rs @@ -0,0 +1,60 @@ +use light_client::rpc::{Rpc, RpcError}; +use light_registry::{ + sdk::create_update_forester_pda_instruction, utils::get_forester_pda, ForesterConfig, + ForesterPda, +}; +use solana_sdk::{ + pubkey::Pubkey, + signature::{Keypair, Signer}, +}; + +pub async fn update_test_forester( + rpc: &mut R, + forester_authority: &Keypair, + derivation_key: &Pubkey, + new_forester_authority: Option<&Keypair>, + config: ForesterConfig, +) -> Result<(), RpcError> { + let mut pre_account_state = rpc + .get_anchor_account::(&get_forester_pda(derivation_key).0) + .await? + .unwrap(); + let (signers, new_forester_authority) = if let Some(new_authority) = new_forester_authority { + pre_account_state.authority = new_authority.pubkey(); + + ( + vec![forester_authority, &new_authority], + Some(new_authority.pubkey()), + ) + } else { + (vec![forester_authority], None) + }; + let ix = create_update_forester_pda_instruction( + &forester_authority.pubkey(), + derivation_key, + new_forester_authority, + Some(config), + ); + + rpc.create_and_send_transaction(&[ix], &forester_authority.pubkey(), &signers) + .await?; + + pre_account_state.config = config; + assert_registered_forester(rpc, derivation_key, pre_account_state).await +} + +async fn assert_registered_forester( + rpc: &mut R, + forester: &Pubkey, + expected_account: ForesterPda, +) -> Result<(), RpcError> { + let pda = get_forester_pda(forester).0; + let account_data = rpc.get_anchor_account::(&pda).await?.unwrap(); + if account_data != expected_account { + return Err(RpcError::AssertRpcError(format!( + "Expected account data: {:?}, got: {:?}", + expected_account, account_data + ))); + } + Ok(()) +}