Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions js/stateless.js/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ export const ADDRESS_QUEUE_ROLLOVER_FEE = featureFlags.isV2()
export const STATE_MERKLE_TREE_NETWORK_FEE = new BN(5000);

/**
* Is charged if the transaction creates at least one address.
* Is charged per address the transaction creates.
*/
export const ADDRESS_TREE_NETWORK_FEE = new BN(5000);
export const ADDRESS_TREE_NETWORK_FEE_V1 = new BN(5000);

/**
* Is charged per address the transaction creates.
*/
export const ADDRESS_TREE_NETWORK_FEE_V2 = new BN(10000);
31 changes: 23 additions & 8 deletions js/stateless.js/tests/e2e/compress.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {
STATE_MERKLE_TREE_NETWORK_FEE,
ADDRESS_QUEUE_ROLLOVER_FEE,
STATE_MERKLE_TREE_ROLLOVER_FEE,
ADDRESS_TREE_NETWORK_FEE,
ADDRESS_TREE_NETWORK_FEE_V1,
ADDRESS_TREE_NETWORK_FEE_V2,
featureFlags,
} from '../../src/constants';
import { newAccountWithLamports } from '../../src/test-helpers/test-utils';
import { Rpc } from '../../src/rpc';
Expand Down Expand Up @@ -44,12 +46,24 @@ function txFees(
: bn(0);

/// Fee if the tx nullifies at least one input account
const networkInFee =
tx.in || tx.out ? STATE_MERKLE_TREE_NETWORK_FEE : bn(0);

/// Fee if the tx creates at least one address
const networkAddressFee = tx.addr ? ADDRESS_TREE_NETWORK_FEE : bn(0);

const networkInFee = tx.in
? featureFlags.isV2()
? STATE_MERKLE_TREE_NETWORK_FEE
: STATE_MERKLE_TREE_NETWORK_FEE.mul(bn(tx.in))
: tx.out && featureFlags.isV2()
? STATE_MERKLE_TREE_NETWORK_FEE
: bn(0);

/// Network fee charged per address created
const networkAddressFee = tx.addr
? ADDRESS_TREE_NETWORK_FEE_V1.mul(bn(tx.addr))
: bn(0);
// TODO: adapt once we use v2 address trees in tests.
// tx.addr
// ? featureFlags.isV2()
// ? ADDRESS_TREE_NETWORK_FEE_V2.mul(bn(tx.addr))
// : ADDRESS_TREE_NETWORK_FEE_V1.mul(bn(tx.addr))
// : bn(0);
totalFee = totalFee.add(
solanaBaseFee
.add(stateOutFee)
Expand Down Expand Up @@ -230,9 +244,10 @@ describe('compress', () => {
);

const postCreateAccountBalance = await rpc.getBalance(payer.publicKey);
let expectedTxFees = txFees([{ in: 1, out: 2, addr: 1 }]);
assert.equal(
postCreateAccountBalance,
postCompressBalance - txFees([{ in: 1, out: 2, addr: 1 }]),
postCompressBalance - expectedTxFees,
);
});

Expand Down
5 changes: 4 additions & 1 deletion js/stateless.js/tests/e2e/test-rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,15 @@ describe('test-rpc', () => {
assert.equal(compressedTestAccount.data?.data, null);

postCompressBalance = await rpc.getBalance(payer.publicKey);
let expectedFee = featureFlags.isV2()
? STATE_MERKLE_TREE_NETWORK_FEE.toNumber()
: 0;
assert.equal(
postCompressBalance,
preCompressBalance -
compressLamportsAmount -
5000 -
5000 -
expectedFee -
STATE_MERKLE_TREE_ROLLOVER_FEE.toNumber(),
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl Default for InitAddressTreeAccountsInstructionData {
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: DEFAULT_BATCH_SIZE * 8,
network_fee: Some(5000),
network_fee: Some(10000),
rollover_threshold: Some(95),
close_threshold: None,
}
Expand Down Expand Up @@ -202,7 +202,7 @@ pub mod test_utils {
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: 20_000 * 8,
network_fee: Some(5000),
network_fee: Some(10000),
rollover_threshold: Some(95),
close_threshold: None,
}
Expand All @@ -219,7 +219,7 @@ pub mod test_utils {
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: 20_000 * 8,
network_fee: Some(5000),
network_fee: Some(10000),
rollover_threshold: Some(95),
close_threshold: None,
}
Expand All @@ -235,7 +235,7 @@ pub mod test_utils {
height: 40,
root_history_capacity: DEFAULT_BATCH_ROOT_HISTORY_LEN,
bloom_filter_capacity: ADDRESS_BLOOM_FILTER_CAPACITY,
network_fee: Some(5000),
network_fee: Some(10000),
rollover_threshold: Some(95),
close_threshold: None,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![cfg(feature = "test-sbf")]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed on purpose, these are not necessary since we dont run non sbf tests in the same test crate and prevent rust analyzer from compiling the file.


use account_compression::{errors::AccountCompressionErrorCode, ID};
use anchor_lang::{
error::ErrorCode, prelude::AccountMeta, AnchorSerialize, InstructionData, ToAccountMetas,
Expand Down Expand Up @@ -67,6 +65,122 @@ pub enum TestMode {
InvalidRegisteredProgram,
}

#[ignore = "only execute with program compiled non test"]
#[tokio::test]
async fn test_batch_state_merkle_tree_failing() {
let config = ProgramTestConfig {
skip_protocol_init: true,
..Default::default()
};
let mut context = LightProgramTest::new(config).await.unwrap();

let merkle_tree_keypair = Keypair::new();
let merkle_tree_pubkey = merkle_tree_keypair.pubkey();
let nullifier_queue_keypair = Keypair::new();
let output_queue_pubkey = nullifier_queue_keypair.pubkey();

let payer_pubkey = context.get_payer().pubkey();
let payer = context.get_payer().insecure_clone();
let params = InitStateTreeAccountsInstructionData::test_default();
let queue_account_size = get_output_queue_account_size(
params.output_queue_batch_size,
params.output_queue_zkp_batch_size,
);
let mt_account_size = get_merkle_tree_account_size(
params.input_queue_batch_size,
params.bloom_filter_capacity,
params.input_queue_zkp_batch_size,
params.root_history_capacity,
params.height,
);
let queue_rent = context
.get_minimum_balance_for_rent_exemption(queue_account_size)
.await
.unwrap();
let mt_rent = context
.get_minimum_balance_for_rent_exemption(mt_account_size)
.await
.unwrap();

// 1. Functional initialize a batched Merkle tree and output queue
{
let create_queue_account_ix = create_account_instruction(
&payer_pubkey,
queue_account_size,
queue_rent,
&ID,
Some(&nullifier_queue_keypair),
);

let create_mt_account_ix = create_account_instruction(
&payer_pubkey,
mt_account_size,
mt_rent,
&ID,
Some(&merkle_tree_keypair),
);

let instruction = account_compression::instruction::InitializeBatchedStateMerkleTree {
bytes: params.try_to_vec().unwrap(),
};
let accounts = account_compression::accounts::InitializeBatchedStateMerkleTreeAndQueue {
authority: context.get_payer().pubkey(),
merkle_tree: merkle_tree_pubkey,
queue: output_queue_pubkey,
registered_program_pda: None,
};

let instruction = Instruction {
program_id: ID,
accounts: accounts.to_account_metas(Some(true)),
data: instruction.data(),
};
let result = context
.create_and_send_transaction(
&[create_queue_account_ix, create_mt_account_ix, instruction],
&payer_pubkey,
&[&payer, &nullifier_queue_keypair, &merkle_tree_keypair],
)
.await;
println!("result {:?}", result);
// Incorrect security group
assert_rpc_error(
result,
2,
AccountCompressionErrorCode::UnsupportedParameters.into(),
)
.unwrap();
}
}

#[ignore = "only execute with program compiled non test"]
#[tokio::test]
async fn test_init_batch_address_merkle_trees_failing() {
let config = ProgramTestConfig {
skip_protocol_init: true,
with_prover: false,
skip_startup_logs: false,
no_logs: false,
..Default::default()
};
let mut context = LightProgramTest::new(config).await.unwrap();
context.config.no_logs = false;
let params = InitAddressTreeAccountsInstructionData::test_default();

let merkle_tree_keypair = Keypair::new();

let result =
perform_init_batch_address_merkle_tree(&mut context, &params, &merkle_tree_keypair).await;
println!("result {:?}", result);
// Incorrect security group
assert_rpc_error(
result,
1,
AccountCompressionErrorCode::UnsupportedParameters.into(),
)
.unwrap();
}

/// 1. init accounts - Functional: initialize a batched Merkle tree and output queue
/// 2. append leaves - Failing: Invalid signe
/// 3. append leaves - Functional insert 10 leaves into output queue
Expand Down
Loading
Loading