1use solana_keypair::Keypair;
2use solana_pubkey::Pubkey;
3
4use crate::rpc::{Rpc, RpcError};
5
6#[derive(Debug, Clone, PartialEq)]
7pub struct FeeConfig {
8 pub state_merkle_tree_rollover: u64,
9 pub address_queue_rollover: u64,
10 pub network_fee: u64,
14 pub address_network_fee: u64,
15 pub solana_network_fee: i64,
16}
17
18impl Default for FeeConfig {
19 fn default() -> Self {
20 Self {
21 state_merkle_tree_rollover: 300,
23 address_queue_rollover: 392,
24 network_fee: 5000,
28 address_network_fee: 5000,
29 solana_network_fee: 5000,
30 }
31 }
32}
33
34impl FeeConfig {
35 pub fn test_batched() -> Self {
36 Self {
37 state_merkle_tree_rollover: 1,
39 address_queue_rollover: 392, network_fee: 5000,
41 address_network_fee: 10000,
42 solana_network_fee: 5000,
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq)]
48pub struct TransactionParams {
49 pub v1_input_compressed_accounts: u8,
50 pub v2_input_compressed_accounts: bool,
51 pub v1_output_compressed_accounts: u8,
52 pub num_output_compressed_accounts: u8,
53 pub num_new_addresses: u8,
54 pub compress: i64,
55 pub fee_config: FeeConfig,
56}
57
58pub async fn assert_transaction_params(
59 rpc: &mut impl Rpc,
60 payer: &Pubkey,
61 signers: &[&Keypair],
62 pre_balance: u64,
63 params: Option<TransactionParams>,
64) -> Result<(), RpcError> {
65 if let Some(transaction_params) = params {
66 let mut deduped_signers = signers.to_vec();
67 deduped_signers.dedup();
68 let post_balance = rpc.get_account(*payer).await?.unwrap().lamports;
69
70 let mut network_fee: i64 = 0;
72
73 if transaction_params.v1_input_compressed_accounts != 0 {
75 network_fee += transaction_params.fee_config.network_fee as i64
76 * transaction_params.v1_input_compressed_accounts as i64;
77 } else if transaction_params.v2_input_compressed_accounts {
78 network_fee += transaction_params.fee_config.network_fee as i64;
79 }
80 if transaction_params.v1_output_compressed_accounts != 0 {
82 network_fee += transaction_params.fee_config.network_fee as i64
83 * transaction_params.v1_output_compressed_accounts as i64;
84 }
85 if transaction_params.num_new_addresses != 0 {
87 network_fee += transaction_params.fee_config.address_network_fee as i64
88 * transaction_params.num_new_addresses as i64;
89 }
90 let expected_post_balance = pre_balance as i64
91 - i64::from(transaction_params.num_new_addresses)
92 * transaction_params.fee_config.address_queue_rollover as i64
93 - i64::from(transaction_params.num_output_compressed_accounts)
94 * transaction_params.fee_config.state_merkle_tree_rollover as i64
95 - transaction_params.compress
96 - transaction_params.fee_config.solana_network_fee * deduped_signers.len() as i64
97 - network_fee;
98
99 if post_balance as i64 != expected_post_balance {
100 println!("transaction_params: {:?}", transaction_params);
101 println!("pre_balance: {}", pre_balance);
102 println!("post_balance: {}", post_balance);
103 println!("expected post_balance: {}", expected_post_balance);
104 println!(
105 "diff post_balance: {}",
106 post_balance as i64 - expected_post_balance
107 );
108 println!(
109 "rollover fee: {}",
110 transaction_params.fee_config.state_merkle_tree_rollover
111 );
112 println!(
113 "address_network_fee: {}",
114 transaction_params.fee_config.address_network_fee
115 );
116 println!("network_fee: {}", network_fee);
117 println!("num signers {}", deduped_signers.len());
118 println!(
119 "transaction_params.fee_config {:?}",
120 transaction_params.fee_config
121 );
122 return Err(RpcError::CustomError("Transaction fee error.".to_string()));
123 }
124 }
125 Ok(())
126}