-
Notifications
You must be signed in to change notification settings - Fork 90
chore: light client add more tests #2307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -515,9 +515,16 @@ async fn test_indexer_interface_scenarios() { | |||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| println!(" PASSED: Token account interface resolved with correct token data"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // ============ Test 3: getMultipleAccountInterfaces batch lookup ============ | ||||||||||||||||||||||||||||||||||
| println!("\nTest 3: getMultipleAccountInterfaces batch lookup..."); | ||||||||||||||||||||||||||||||||||
| let batch_addresses = vec![&decompressed_mint_pda, &compressible_token_account]; | ||||||||||||||||||||||||||||||||||
| // ============ Test 3: getMultipleAccountInterfaces batch lookup (4 accounts) ============ | ||||||||||||||||||||||||||||||||||
| println!("\nTest 3: getMultipleAccountInterfaces batch lookup (4 accounts)..."); | ||||||||||||||||||||||||||||||||||
| // Include: decompressed mint PDA, compressible token account, compressed mint PDA (not found), | ||||||||||||||||||||||||||||||||||
| // and the compressed mint seed pubkey (not a known on-chain account). | ||||||||||||||||||||||||||||||||||
| let batch_addresses = vec![ | ||||||||||||||||||||||||||||||||||
| &decompressed_mint_pda, | ||||||||||||||||||||||||||||||||||
| &compressible_token_account, | ||||||||||||||||||||||||||||||||||
| &bob_ata, | ||||||||||||||||||||||||||||||||||
| &charlie_ata, | ||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+520
to
+527
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stale comment describes the wrong accounts The comment at lines 520–521 still refers to the previous batch contents ( ✏️ Suggested fix- // Include: decompressed mint PDA, compressible token account, compressed mint PDA (not found),
- // and the compressed mint seed pubkey (not a known on-chain account).
+ // Include: decompressed mint PDA (on-chain CMint), compressible token account (on-chain),
+ // Bob's ATA (on-chain), and Charlie's ATA (on-chain).
let batch_addresses = vec![📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| let batch_response = photon_indexer | ||||||||||||||||||||||||||||||||||
| .get_multiple_account_interfaces(batch_addresses.clone(), None) | ||||||||||||||||||||||||||||||||||
|
|
@@ -526,8 +533,8 @@ async fn test_indexer_interface_scenarios() { | |||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||||||
| batch_response.value.len(), | ||||||||||||||||||||||||||||||||||
| 2, | ||||||||||||||||||||||||||||||||||
| "Batch response should have exactly 2 results" | ||||||||||||||||||||||||||||||||||
| 4, | ||||||||||||||||||||||||||||||||||
| "Batch response should have exactly 4 results" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // First result: decompressed mint | ||||||||||||||||||||||||||||||||||
|
|
@@ -560,7 +567,36 @@ async fn test_indexer_interface_scenarios() { | |||||||||||||||||||||||||||||||||
| batch_token.account.lamports > 0, | ||||||||||||||||||||||||||||||||||
| "Batch token account should have lamports > 0" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| println!(" PASSED: Batch lookup returned correct results"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Third result: Bob's ATA (on-chain token account) | ||||||||||||||||||||||||||||||||||
| let batch_bob_ata = batch_response.value[2] | ||||||||||||||||||||||||||||||||||
| .as_ref() | ||||||||||||||||||||||||||||||||||
| .expect("Bob's ATA should be found in batch"); | ||||||||||||||||||||||||||||||||||
| assert!(batch_bob_ata.is_hot(), "Bob's ATA should be hot (on-chain)"); | ||||||||||||||||||||||||||||||||||
| assert_eq!(batch_bob_ata.key, bob_ata, "Bob's ATA key should match"); | ||||||||||||||||||||||||||||||||||
| assert!( | ||||||||||||||||||||||||||||||||||
| batch_bob_ata.account.lamports > 0, | ||||||||||||||||||||||||||||||||||
| "Bob's ATA should have lamports > 0" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // Fourth result: Charlie's ATA (on-chain token account) | ||||||||||||||||||||||||||||||||||
| let batch_charlie_ata = batch_response.value[3] | ||||||||||||||||||||||||||||||||||
| .as_ref() | ||||||||||||||||||||||||||||||||||
| .expect("Charlie's ATA should be found in batch"); | ||||||||||||||||||||||||||||||||||
| assert!( | ||||||||||||||||||||||||||||||||||
| batch_charlie_ata.is_hot(), | ||||||||||||||||||||||||||||||||||
| "Charlie's ATA should be hot (on-chain)" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| assert_eq!( | ||||||||||||||||||||||||||||||||||
| batch_charlie_ata.key, charlie_ata, | ||||||||||||||||||||||||||||||||||
| "Charlie's ATA key should match" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
| assert!( | ||||||||||||||||||||||||||||||||||
| batch_charlie_ata.account.lamports > 0, | ||||||||||||||||||||||||||||||||||
| "Charlie's ATA should have lamports > 0" | ||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| println!(" PASSED: Batch lookup returned correct results for 4 accounts"); | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| // ============ Test 4: Verify fully compressed mint via getAccountInterface returns None ============ | ||||||||||||||||||||||||||||||||||
| // Fully compressed mints (after CompressAndCloseMint) have full mint data in the compressed DB. | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,6 +153,93 @@ mod tests { | |
|
|
||
| use super::*; | ||
|
|
||
| #[test] | ||
| fn test_empty_input_returns_empty_batches() { | ||
| let payer = Pubkey::new_unique(); | ||
| let result = split_by_tx_size(vec![], &payer, None).unwrap(); | ||
| assert_eq!(result, vec![] as Vec<Vec<Instruction>>); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_single_small_instruction_one_batch() { | ||
| let payer = Pubkey::new_unique(); | ||
| let ix = Instruction { | ||
| program_id: Pubkey::new_unique(), | ||
| accounts: vec![AccountMeta::new(Pubkey::new_unique(), false)], | ||
| data: vec![0u8; 10], | ||
| }; | ||
| let batches = split_by_tx_size(vec![ix], &payer, None).unwrap(); | ||
| assert_eq!(batches.len(), 1); | ||
| assert_eq!(batches[0].len(), 1); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_multiple_small_instructions_fit_in_one_batch() { | ||
| let payer = Pubkey::new_unique(); | ||
| // Three tiny instructions that easily fit in one tx | ||
| let instructions: Vec<Instruction> = (0..3) | ||
| .map(|_| Instruction { | ||
| program_id: Pubkey::new_unique(), | ||
| accounts: vec![AccountMeta::new(Pubkey::new_unique(), false)], | ||
| data: vec![0u8; 5], | ||
| }) | ||
| .collect(); | ||
| let batches = split_by_tx_size(instructions, &payer, None).unwrap(); | ||
| assert_eq!(batches.len(), 1); | ||
| assert_eq!(batches[0].len(), 3); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_instructions_split_into_multiple_batches_with_small_max_size() { | ||
| let payer = Pubkey::new_unique(); | ||
| // Use a very small max_size to force each instruction into its own batch. | ||
| // Each instruction has 1 account + 10 bytes data. Estimate: | ||
| // header(3) + accounts(compact+32*2) + blockhash(32) + ixs + sigs ~ 200 bytes | ||
| // Set max_size=250 to allow one instruction per tx but not two. | ||
| let max_size = 250usize; | ||
|
Comment on lines
+196
to
+199
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Inaccurate account-count estimate in comment The inline comment says ✏️ Suggested comment fix- // Each instruction has 1 account + 10 bytes data. Estimate:
- // header(3) + accounts(compact+32*2) + blockhash(32) + ixs + sigs ~ 200 bytes
- // Set max_size=250 to allow one instruction per tx but not two.
+ // Each instruction has 1 account (non-signer) + 10 bytes data. Estimate per single tx:
+ // header(3) + accounts(compact+3×32=97) + blockhash(32) + ix(~14) + sigs(65) ≈ 211 bytes
+ // Two instructions share no accounts → ≈ 290 bytes.
+ // max_size=250 allows one instruction per batch but not two → 3 batches for 3 instructions.🤖 Prompt for AI Agents |
||
| let instructions: Vec<Instruction> = (0..3) | ||
| .map(|_| Instruction { | ||
| program_id: Pubkey::new_unique(), | ||
| accounts: vec![AccountMeta::new(Pubkey::new_unique(), false)], | ||
| data: vec![0u8; 10], | ||
| }) | ||
| .collect(); | ||
| let batches = split_by_tx_size(instructions, &payer, Some(max_size)).unwrap(); | ||
| assert_eq!( | ||
| batches.len(), | ||
| 3, | ||
| "each of 3 instructions should be in its own batch at max_size=250" | ||
| ); | ||
| for batch in &batches { | ||
| assert_eq!( | ||
| batch.len(), | ||
| 1, | ||
| "each batch should contain exactly one instruction" | ||
| ); | ||
| assert!(estimate_tx_size(batch, &payer) <= max_size); | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_single_instruction_exceeding_max_size_returns_error() { | ||
| let payer = Pubkey::new_unique(); | ||
| let oversized_ix = Instruction { | ||
| program_id: Pubkey::new_unique(), | ||
| accounts: vec![AccountMeta::new(Pubkey::new_unique(), false)], | ||
| data: vec![0u8; 100], | ||
| }; | ||
| // Set max_size to 50 - smaller than any valid instruction | ||
| let result = split_by_tx_size(vec![oversized_ix], &payer, Some(50)); | ||
| assert!(result.is_err()); | ||
| let err = result.unwrap_err(); | ||
| assert_eq!(err.instruction_index, 0); | ||
| assert_eq!(err.max_size, 50); | ||
| assert!(err.estimated_size > 50); | ||
| // Display impl sanity check | ||
| let msg = err.to_string(); | ||
| assert!(msg.contains("instruction at index 0")); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_split_by_tx_size() { | ||
| let payer = Pubkey::new_unique(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tautological
extensionscomparison inassert_eq!Line 340 sets
extensions: account_state.account.extensions.clone(), so that field trivially matches and contributes nothing to the equality assertion. The test looks as though it's verifying the extensions value, but it's only verifying all the other fields.The separate
is_some()guard on lines 343–346 is the sole real assertion for extensions. To make the intent clear:🔧 Suggested refactor
assert_eq!( account_state.account, Token { mint: mint.to_bytes().into(), owner: owner_keypair.pubkey().to_bytes().into(), amount: 0, delegate: None, state: AccountState::Initialized, is_native: None, delegated_amount: 0, close_authority: None, account_type: ACCOUNT_TYPE_TOKEN_ACCOUNT, - extensions: account_state.account.extensions.clone(), + // extensions is not asserted here; verified separately below + ..account_state.account.clone() } );Or, if
Tokensupports a field-by-field comparison without struct-literal syntax, excludeextensionsentirely and keep the dedicatedis_some()check:+assert!(account_state.account.extensions.is_some(), "compressible token account should have extensions"); assert_eq!(account_state.account.amount, 0); assert_eq!(account_state.account.state, AccountState::Initialized); // … individual field assertions …🤖 Prompt for AI Agents