testsvm_quarry/
test_merge_miner.rs

1//! # Merge Miner Testing Utilities
2//!
3//! Test helpers for Quarry merge mining functionality.
4//!
5//! This module provides the `TestMergeMiner` struct which manages merge mining
6//! operations across multiple quarries. Merge mining allows miners to participate
7//! in multiple quarries simultaneously, earning rewards from both primary and
8//! replica pools.
9//!
10//! ## Features
11//!
12//! - **Primary Miner Management**: Create and manage primary miners
13//! - **Replica Pool Support**: Add and manage replica mining pools
14//! - **Unified Staking**: Stake tokens across multiple quarries
15//! - **Reward Collection**: Claim rewards from all participating pools
16
17use anyhow::Result;
18use solana_sdk::pubkey::Pubkey;
19use testsvm::prelude::*;
20
21use crate::{quarry_merge_mine, quarry_mine};
22
23/// Helper for managing a merge miner with type-safe account references
24#[derive(Debug)]
25pub struct TestMergeMiner {
26    pub merge_miner: AccountRef<quarry_merge_mine::accounts::MergeMiner>,
27    pub primary_tokens: AccountRef<anchor_spl::token::TokenAccount>,
28    pub replica_tokens: AccountRef<anchor_spl::token::TokenAccount>,
29}
30
31impl TestMergeMiner {
32    /// Create primary miner and miner vault for the merge miner
33    pub fn create_primary_miner(
34        &self,
35        env: &mut TestSVM,
36        label: &str,
37        rewarder: &Pubkey,
38        quarry: &Pubkey,
39        primary_mint: &AccountRef<anchor_spl::token::Mint>,
40    ) -> Result<(
41        AccountRef<quarry_mine::accounts::Miner>,
42        AccountRef<anchor_spl::token::TokenAccount>,
43    )> {
44        let merge_pool = self.merge_miner.load(env)?.pool;
45        // Get primary miner PDA
46        let primary_miner = env.get_pda::<quarry_mine::accounts::Miner>(
47            &format!("{label}_primary_miner"),
48            &[b"Miner", quarry.as_ref(), self.merge_miner.key.as_ref()],
49            crate::quarry_mine::ID,
50        )?;
51
52        // Create primary miner vault ATA
53        let (create_miner_vault_ix, primary_miner_vault) = env.create_ata_ix(
54            &format!("{label}_primary_miner_vault"),
55            &primary_miner.into(),
56            &primary_mint.into(),
57        )?;
58
59        // Create init_miner_v2 instruction for merge mine
60        let init_miner_ix = anchor_instruction(
61            crate::quarry_merge_mine::ID,
62            quarry_merge_mine::client::accounts::InitMinerV2 {
63                pool: merge_pool,
64                mm: self.merge_miner.key,
65                miner: primary_miner.key,
66                miner_vault: primary_miner_vault.into(),
67                token_mint: primary_mint.key,
68                quarry: *quarry,
69                payer: env.default_fee_payer(),
70                system_program: solana_sdk::system_program::ID,
71                token_program: anchor_spl::token::ID,
72                mine_program: crate::quarry_mine::ID,
73                rewarder: *rewarder,
74            },
75            quarry_merge_mine::client::args::InitMinerV2 {},
76        );
77
78        // Execute instructions
79        env.execute_ixs(&[create_miner_vault_ix, init_miner_ix])?;
80
81        Ok((primary_miner, primary_miner_vault))
82    }
83
84    /// Create replica miner and miner vault for the merge miner
85    pub fn create_replica_miner(
86        &self,
87        env: &mut TestSVM,
88        label: &str,
89        rewarder: &Pubkey,
90        quarry: &Pubkey,
91        replica_mint: &AccountRef<anchor_spl::token::Mint>,
92    ) -> Result<(
93        AccountRef<quarry_mine::accounts::Miner>,
94        AccountRef<anchor_spl::token::TokenAccount>,
95    )> {
96        let merge_pool = self.merge_miner.load(env)?.pool;
97
98        // Get replica miner PDA
99        let replica_miner = env.get_pda::<quarry_mine::accounts::Miner>(
100            &format!("{label}_replica_miner"),
101            &[b"Miner", quarry.as_ref(), self.merge_miner.key.as_ref()],
102            crate::quarry_mine::ID,
103        )?;
104
105        // Create replica miner vault ATA
106        let (create_miner_vault_ix, replica_miner_vault) = env.create_ata_ix(
107            &format!("{label}_replica_miner_vault"),
108            &replica_miner.into(),
109            &replica_mint.into(),
110        )?;
111
112        // Create init_miner_v2 instruction for merge mine
113        let init_miner_ix = anchor_instruction(
114            crate::quarry_merge_mine::ID,
115            quarry_merge_mine::client::accounts::InitMinerV2 {
116                pool: merge_pool,
117                mm: self.merge_miner.key,
118                miner: replica_miner.key,
119                miner_vault: replica_miner_vault.into(),
120                token_mint: replica_mint.key,
121                quarry: *quarry,
122                payer: env.default_fee_payer(),
123                system_program: solana_sdk::system_program::ID,
124                token_program: anchor_spl::token::ID,
125                mine_program: crate::quarry_mine::ID,
126                rewarder: *rewarder,
127            },
128            quarry_merge_mine::client::args::InitMinerV2 {},
129        );
130
131        // Execute instructions
132        env.execute_ixs(&[create_miner_vault_ix, init_miner_ix])?;
133
134        Ok((replica_miner, replica_miner_vault))
135    }
136}