1+ use log:: debug;
12use solana_sdk:: {
23 hash:: hash,
34 instruction:: { AccountMeta , Instruction } ,
@@ -39,15 +40,26 @@ impl SquadsV3Program {
3940 pub fn parse_squads_v3_program < T : ParsableInstruction > (
4041 instruction : & T ,
4142 account_keys : & [ Pubkey ] ,
43+ squads_parse_errors : & mut u64 ,
4244 ) -> Option < SquadsV3Program > {
4345 let discriminator: [ u8 ; 8 ] = instruction. data ( ) . get ( ..8 ) ?. try_into ( ) . ok ( ) ?;
4446
4547 if discriminator == anchor_discriminator ( Self :: CREATE_TRANSACTION ) {
46- return Self :: parse_create_transaction_ix ( instruction, account_keys) ;
48+ let result = Self :: parse_create_transaction_ix ( instruction, account_keys) ;
49+ if result. is_none ( ) {
50+ * squads_parse_errors += 1 ;
51+ debug ! ( "SquadsV3: matched create_transaction discriminator but failed to parse (short data or invalid account index)" ) ;
52+ }
53+ return result;
4754 }
4855
4956 if discriminator == anchor_discriminator ( Self :: ACTIVATE_TRANSACTION ) {
50- return Self :: parse_activate_transaction_ix ( instruction, account_keys) ;
57+ let result = Self :: parse_activate_transaction_ix ( instruction, account_keys) ;
58+ if result. is_none ( ) {
59+ * squads_parse_errors += 1 ;
60+ debug ! ( "SquadsV3: matched activate_transaction discriminator but failed to parse (short data or invalid account index)" ) ;
61+ }
62+ return result;
5163 }
5264
5365 None
@@ -130,7 +142,7 @@ mod tests {
130142 data. extend_from_slice ( & [ 1 , 2 , 3 , 4 ] ) ;
131143 let instruction = create_compiled_instruction ( 4 , vec ! [ 0 , 1 , 2 , 3 ] , data. clone ( ) ) ;
132144
133- let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys) ;
145+ let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys, & mut 0 ) ;
134146
135147 let Some ( SquadsV3Program :: CreateTransaction {
136148 multisig,
@@ -150,7 +162,7 @@ mod tests {
150162 data. extend_from_slice ( & [ 1 , 2 , 3 , 4 ] ) ;
151163 let instruction = create_compiled_instruction ( 3 , vec ! [ 0 , 1 , 2 ] , data. clone ( ) ) ;
152164
153- let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys) ;
165+ let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys, & mut 0 ) ;
154166
155167 let Some ( SquadsV3Program :: ActivateTransaction { ix } ) = parsed else {
156168 panic ! ( "Expected ActivateTransaction variant" ) ;
@@ -167,12 +179,31 @@ mod tests {
167179 ) ;
168180 }
169181
182+ #[ test]
183+ fn test_create_transaction_with_missing_accounts_increments_error_counter ( ) {
184+ let account_keys = create_test_pubkeys ( 2 ) ;
185+ let mut data = anchor_discriminator ( "create_transaction" ) . to_vec ( ) ;
186+ data. extend_from_slice ( & [ 1 , 2 , 3 , 4 ] ) ;
187+ // No accounts provided — parse_create_transaction_ix will return None
188+ let instruction = create_compiled_instruction ( 1 , vec ! [ ] , data) ;
189+
190+ let mut errors = 0u64 ;
191+ let parsed =
192+ SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys, & mut errors) ;
193+
194+ assert ! ( parsed. is_none( ) ) ;
195+ assert_eq ! (
196+ errors, 1 ,
197+ "known discriminator with missing accounts should increment parse error counter"
198+ ) ;
199+ }
200+
170201 #[ test]
171202 fn test_unknown_data_returns_none ( ) {
172203 let account_keys = create_test_pubkeys ( 3 ) ;
173204 let instruction = create_compiled_instruction ( 0 , vec ! [ 0 , 1 , 2 ] , vec ! [ 0 ; 8 ] ) ;
174205
175- let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys) ;
206+ let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys, & mut 0 ) ;
176207
177208 assert ! ( parsed. is_none( ) ) ;
178209 }
@@ -182,7 +213,7 @@ mod tests {
182213 let account_keys = create_test_pubkeys ( 3 ) ;
183214 let instruction = create_compiled_instruction ( 0 , vec ! [ 0 , 1 , 2 ] , vec ! [ 0 ; 7 ] ) ;
184215
185- let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys) ;
216+ let parsed = SquadsV3Program :: parse_squads_v3_program ( & instruction, & account_keys, & mut 0 ) ;
186217
187218 assert ! ( parsed. is_none( ) ) ;
188219 }
0 commit comments