@@ -109,9 +109,10 @@ pub(in crate::parse_token) fn parse_confidential_mint_burn_instruction(
109109 } ) ;
110110 let mut offset = 2 ;
111111 let map = value. as_object_mut ( ) . unwrap ( ) ;
112- if mint_data. equality_proof_instruction_offset != 0
113- || mint_data. ciphertext_validity_proof_instruction_offset != 0
114- || mint_data. range_proof_instruction_offset != 0
112+ if offset < account_indexes. len ( ) - 1
113+ && ( mint_data. equality_proof_instruction_offset != 0
114+ || mint_data. ciphertext_validity_proof_instruction_offset != 0
115+ || mint_data. range_proof_instruction_offset != 0 )
115116 {
116117 map. insert (
117118 "instructionsSysvar" . to_string ( ) ,
@@ -189,9 +190,10 @@ pub(in crate::parse_token) fn parse_confidential_mint_burn_instruction(
189190 } ) ;
190191 let mut offset = 2 ;
191192 let map = value. as_object_mut ( ) . unwrap ( ) ;
192- if burn_data. equality_proof_instruction_offset != 0
193- || burn_data. ciphertext_validity_proof_instruction_offset != 0
194- || burn_data. range_proof_instruction_offset != 0
193+ if offset < account_indexes. len ( ) - 1
194+ && ( burn_data. equality_proof_instruction_offset != 0
195+ || burn_data. ciphertext_validity_proof_instruction_offset != 0
196+ || burn_data. range_proof_instruction_offset != 0 )
195197 {
196198 map. insert (
197199 "instructionsSysvar" . to_string ( ) ,
@@ -254,3 +256,211 @@ pub(in crate::parse_token) fn parse_confidential_mint_burn_instruction(
254256 }
255257 }
256258}
259+
260+ #[ cfg( test) ]
261+ mod test {
262+ use {
263+ super :: * ,
264+ bytemuck:: Zeroable ,
265+ solana_sdk:: {
266+ instruction:: { AccountMeta , Instruction } ,
267+ pubkey:: Pubkey ,
268+ } ,
269+ spl_token_2022:: {
270+ extension:: confidential_mint_burn:: instruction:: {
271+ confidential_burn_with_split_proofs, confidential_mint_with_split_proofs,
272+ initialize_mint,
273+ } ,
274+ solana_program:: message:: Message ,
275+ solana_zk_sdk:: {
276+ encryption:: {
277+ auth_encryption:: AeCiphertext ,
278+ elgamal:: ElGamalPubkey ,
279+ pod:: { auth_encryption:: PodAeCiphertext , elgamal:: PodElGamalPubkey } ,
280+ } ,
281+ zk_elgamal_proof_program:: proof_data:: {
282+ BatchedGroupedCiphertext3HandlesValidityProofData , BatchedRangeProofU128Data ,
283+ CiphertextCiphertextEqualityProofData , CiphertextCommitmentEqualityProofData ,
284+ } ,
285+ } ,
286+ } ,
287+ spl_token_confidential_transfer_proof_extraction:: instruction:: { ProofData , ProofLocation } ,
288+ std:: num:: NonZero ,
289+ } ;
290+
291+ fn check_no_panic ( mut instruction : Instruction ) {
292+ let account_meta = AccountMeta :: new_readonly ( Pubkey :: new_unique ( ) , false ) ;
293+ for i in 0 ..20 {
294+ instruction. accounts = vec ! [ account_meta. clone( ) ; i] ;
295+ let message = Message :: new ( & [ instruction. clone ( ) ] , None ) ;
296+ let compiled_instruction = & message. instructions [ 0 ] ;
297+ let _ = parse_token (
298+ compiled_instruction,
299+ & AccountKeys :: new ( & message. account_keys , None ) ,
300+ ) ;
301+ }
302+ }
303+
304+ #[ test]
305+ fn test_initialize ( ) {
306+ let instruction = initialize_mint (
307+ & spl_token_2022:: id ( ) ,
308+ & Pubkey :: new_unique ( ) ,
309+ PodElGamalPubkey :: default ( ) ,
310+ PodAeCiphertext :: default ( ) ,
311+ )
312+ . unwrap ( ) ;
313+ check_no_panic ( instruction) ;
314+ }
315+
316+ #[ test]
317+ fn test_update ( ) {
318+ let instruction = update_decryptable_supply (
319+ & spl_token_2022:: id ( ) ,
320+ & Pubkey :: new_unique ( ) ,
321+ & Pubkey :: new_unique ( ) ,
322+ & [ ] ,
323+ AeCiphertext :: default ( ) ,
324+ )
325+ . unwrap ( ) ;
326+ check_no_panic ( instruction) ;
327+ }
328+
329+ #[ test]
330+ fn test_rotate ( ) {
331+ for location in [
332+ ProofLocation :: InstructionOffset (
333+ NonZero :: new ( 1 ) . unwrap ( ) ,
334+ ProofData :: InstructionData ( & CiphertextCiphertextEqualityProofData :: zeroed ( ) ) ,
335+ ) ,
336+ ProofLocation :: InstructionOffset (
337+ NonZero :: new ( 1 ) . unwrap ( ) ,
338+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
339+ ) ,
340+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
341+ ] {
342+ let instructions = rotate_supply_elgamal_pubkey (
343+ & spl_token_2022:: id ( ) ,
344+ & Pubkey :: new_unique ( ) ,
345+ & Pubkey :: new_unique ( ) ,
346+ & [ ] ,
347+ ElGamalPubkey :: default ( ) ,
348+ location,
349+ )
350+ . unwrap ( ) ;
351+ check_no_panic ( instructions[ 0 ] . clone ( ) ) ;
352+ }
353+ }
354+
355+ #[ test]
356+ fn test_mint ( ) {
357+ for ( equality_proof_location, ciphertext_validity_proof_location, range_proof_location) in [
358+ (
359+ ProofLocation :: InstructionOffset (
360+ NonZero :: new ( 1 ) . unwrap ( ) ,
361+ ProofData :: InstructionData ( & CiphertextCommitmentEqualityProofData :: zeroed ( ) ) ,
362+ ) ,
363+ ProofLocation :: InstructionOffset (
364+ NonZero :: new ( 2 ) . unwrap ( ) ,
365+ ProofData :: InstructionData (
366+ & BatchedGroupedCiphertext3HandlesValidityProofData :: zeroed ( ) ,
367+ ) ,
368+ ) ,
369+ ProofLocation :: InstructionOffset (
370+ NonZero :: new ( 3 ) . unwrap ( ) ,
371+ ProofData :: InstructionData ( & BatchedRangeProofU128Data :: zeroed ( ) ) ,
372+ ) ,
373+ ) ,
374+ (
375+ ProofLocation :: InstructionOffset (
376+ NonZero :: new ( 1 ) . unwrap ( ) ,
377+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
378+ ) ,
379+ ProofLocation :: InstructionOffset (
380+ NonZero :: new ( 2 ) . unwrap ( ) ,
381+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
382+ ) ,
383+ ProofLocation :: InstructionOffset (
384+ NonZero :: new ( 3 ) . unwrap ( ) ,
385+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
386+ ) ,
387+ ) ,
388+ (
389+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
390+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
391+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
392+ ) ,
393+ ] {
394+ let instructions = confidential_mint_with_split_proofs (
395+ & spl_token_2022:: id ( ) ,
396+ & Pubkey :: new_unique ( ) ,
397+ & Pubkey :: new_unique ( ) ,
398+ None ,
399+ & Pubkey :: new_unique ( ) ,
400+ & [ ] ,
401+ equality_proof_location,
402+ ciphertext_validity_proof_location,
403+ range_proof_location,
404+ AeCiphertext :: default ( ) ,
405+ )
406+ . unwrap ( ) ;
407+ check_no_panic ( instructions[ 0 ] . clone ( ) ) ;
408+ }
409+ }
410+
411+ #[ test]
412+ fn test_burn ( ) {
413+ for ( equality_proof_location, ciphertext_validity_proof_location, range_proof_location) in [
414+ (
415+ ProofLocation :: InstructionOffset (
416+ NonZero :: new ( 1 ) . unwrap ( ) ,
417+ ProofData :: InstructionData ( & CiphertextCommitmentEqualityProofData :: zeroed ( ) ) ,
418+ ) ,
419+ ProofLocation :: InstructionOffset (
420+ NonZero :: new ( 2 ) . unwrap ( ) ,
421+ ProofData :: InstructionData (
422+ & BatchedGroupedCiphertext3HandlesValidityProofData :: zeroed ( ) ,
423+ ) ,
424+ ) ,
425+ ProofLocation :: InstructionOffset (
426+ NonZero :: new ( 3 ) . unwrap ( ) ,
427+ ProofData :: InstructionData ( & BatchedRangeProofU128Data :: zeroed ( ) ) ,
428+ ) ,
429+ ) ,
430+ (
431+ ProofLocation :: InstructionOffset (
432+ NonZero :: new ( 1 ) . unwrap ( ) ,
433+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
434+ ) ,
435+ ProofLocation :: InstructionOffset (
436+ NonZero :: new ( 2 ) . unwrap ( ) ,
437+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
438+ ) ,
439+ ProofLocation :: InstructionOffset (
440+ NonZero :: new ( 3 ) . unwrap ( ) ,
441+ ProofData :: RecordAccount ( & Pubkey :: new_unique ( ) , 0 ) ,
442+ ) ,
443+ ) ,
444+ (
445+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
446+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
447+ ProofLocation :: ContextStateAccount ( & Pubkey :: new_unique ( ) ) ,
448+ ) ,
449+ ] {
450+ let instructions = confidential_burn_with_split_proofs (
451+ & spl_token_2022:: id ( ) ,
452+ & Pubkey :: new_unique ( ) ,
453+ & Pubkey :: new_unique ( ) ,
454+ None ,
455+ PodAeCiphertext :: default ( ) ,
456+ & Pubkey :: new_unique ( ) ,
457+ & [ ] ,
458+ equality_proof_location,
459+ ciphertext_validity_proof_location,
460+ range_proof_location,
461+ )
462+ . unwrap ( ) ;
463+ check_no_panic ( instructions[ 0 ] . clone ( ) ) ;
464+ }
465+ }
466+ }
0 commit comments