@@ -33,28 +33,25 @@ fn account_info_to_meta(account_info: &AccountInfo) -> AccountMeta {
3333
3434/// De-escalate an account meta if necessary
3535fn de_escalate_account_meta ( account_meta : & mut AccountMeta , account_metas : & [ AccountMeta ] ) {
36- // This is a little tricky to read, but the idea is to see if
37- // this account is marked as writable or signer anywhere in
38- // the instruction at the start. If so, DON'T escalate it to
39- // be a writer or signer in the CPI
36+ // This is a little tricky to read, but checks if this account is marked as
37+ // writable in the instruction. If it's read-only, de-escalate it to read-only
38+ // in the CPI.
4039 let maybe_highest_privileges = account_metas
4140 . iter ( )
4241 . filter ( |& x| x. pubkey == account_meta. pubkey )
43- . map ( |x| ( x . is_signer , x . is_writable ) )
44- . reduce ( |acc, x| ( acc. 0 || x. 0 , acc . 1 || x . 1 ) ) ;
42+ . map ( |x| x . is_writable )
43+ . reduce ( |acc, x| acc || x) ;
4544 // If `Some`, then the account was found somewhere in the instruction
46- if let Some ( ( is_signer, is_writable) ) = maybe_highest_privileges {
47- if !is_signer && is_signer != account_meta. is_signer {
48- // Existing account is *NOT* a signer already, but the CPI
49- // wants it to be, so de-escalate to not be a signer
50- account_meta. is_signer = false ;
51- }
45+ if let Some ( is_writable) = maybe_highest_privileges {
5246 if !is_writable && is_writable != account_meta. is_writable {
5347 // Existing account is *NOT* writable already, but the CPI
5448 // wants it to be, so de-escalate to not be writable
5549 account_meta. is_writable = false ;
5650 }
5751 }
52+
53+ // Always mark an account as a non-signer
54+ account_meta. is_signer = false ;
5855}
5956
6057/// Stateless helper for storing additional accounts required for an
@@ -400,6 +397,20 @@ mod tests {
400397 }
401398 }
402399
400+ /// Helper to convert an `AccountInfo` to an `AccountMeta`
401+ fn account_info_to_meta_non_signer ( account_info : & AccountInfo ) -> AccountMeta {
402+ AccountMeta {
403+ pubkey : * account_info. key ,
404+ is_signer : false ,
405+ is_writable : account_info. is_writable ,
406+ }
407+ }
408+
409+ fn de_escalate_signer ( mut account_meta : AccountMeta ) -> AccountMeta {
410+ account_meta. is_signer = false ;
411+ account_meta
412+ }
413+
403414 #[ tokio:: test]
404415 async fn init_with_metas ( ) {
405416 let metas = [
@@ -426,7 +437,7 @@ mod tests {
426437
427438 let check_metas = metas
428439 . iter ( )
429- . map ( |e| AccountMeta :: try_from ( e) . unwrap ( ) )
440+ . map ( |e| de_escalate_signer ( AccountMeta :: try_from ( e) . unwrap ( ) ) )
430441 . collect :: < Vec < _ > > ( ) ;
431442
432443 assert_eq ! ( instruction. accounts, check_metas, ) ;
@@ -525,9 +536,9 @@ mod tests {
525536
526537 // Convert to `AccountMeta` to check instruction
527538 let check_metas = [
528- account_info_to_meta ( & account_infos[ 0 ] ) ,
529- account_info_to_meta ( & account_infos[ 1 ] ) ,
530- account_info_to_meta ( & account_infos[ 2 ] ) ,
539+ account_info_to_meta_non_signer ( & account_infos[ 0 ] ) ,
540+ account_info_to_meta_non_signer ( & account_infos[ 1 ] ) ,
541+ account_info_to_meta_non_signer ( & account_infos[ 2 ] ) ,
531542 AccountMeta :: new ( check_required_pda, false ) ,
532543 ] ;
533544
@@ -614,10 +625,10 @@ mod tests {
614625 )
615626 . 0 ;
616627 let check_metas = [
617- ix_account1,
618- ix_account2,
619- extra_meta1,
620- extra_meta2,
628+ ix_account1, // not de-escalated since it's not extra
629+ ix_account2, // not de-escalated since it's not extra
630+ de_escalate_signer ( extra_meta1) ,
631+ de_escalate_signer ( extra_meta2) ,
621632 AccountMeta :: new ( check_extra_meta3_pubkey, false ) ,
622633 AccountMeta :: new ( check_extra_meta4_pubkey, false ) ,
623634 ] ;
@@ -743,10 +754,10 @@ mod tests {
743754 )
744755 . 0 ;
745756 let check_metas = [
746- extra_meta1,
747- extra_meta2,
748- extra_meta3,
749- extra_meta4,
757+ de_escalate_signer ( extra_meta1) ,
758+ de_escalate_signer ( extra_meta2) ,
759+ de_escalate_signer ( extra_meta3) ,
760+ de_escalate_signer ( extra_meta4) ,
750761 AccountMeta :: new ( check_extra_meta5_pubkey, false ) ,
751762 AccountMeta :: new ( check_extra_meta6_pubkey, false ) ,
752763 ] ;
@@ -940,7 +951,7 @@ mod tests {
940951
941952 let test_ix_check_metas = account_infos
942953 . iter ( )
943- . map ( account_info_to_meta )
954+ . map ( account_info_to_meta_non_signer )
944955 . collect :: < Vec < _ > > ( ) ;
945956 assert_eq ! ( instruction. accounts, test_ix_check_metas, ) ;
946957
@@ -986,10 +997,10 @@ mod tests {
986997 . 0 ;
987998
988999 let test_other_ix_check_metas = vec ! [
989- extra_meta1,
990- extra_meta2,
991- extra_meta3,
992- extra_meta4,
1000+ de_escalate_signer ( extra_meta1) ,
1001+ de_escalate_signer ( extra_meta2) ,
1002+ de_escalate_signer ( extra_meta3) ,
1003+ de_escalate_signer ( extra_meta4) ,
9931004 AccountMeta :: new( check_extra_meta5_pubkey, false ) ,
9941005 AccountMeta :: new( check_extra_meta6_pubkey, false ) ,
9951006 AccountMeta :: new( instruction_key_data_pubkey_arg, false ) ,
@@ -1471,7 +1482,7 @@ mod tests {
14711482 ] ;
14721483 let check_metas_1 = updated_metas_1
14731484 . iter ( )
1474- . map ( |e| AccountMeta :: try_from ( e) . unwrap ( ) )
1485+ . map ( |e| de_escalate_signer ( AccountMeta :: try_from ( e) . unwrap ( ) ) )
14751486 . collect :: < Vec < _ > > ( ) ;
14761487 update_and_assert_metas ( program_id, & mut buffer, & updated_metas_1, & check_metas_1) . await ;
14771488
@@ -1483,7 +1494,7 @@ mod tests {
14831494 ] ;
14841495 let check_metas_2 = updated_metas_2
14851496 . iter ( )
1486- . map ( |e| AccountMeta :: try_from ( e) . unwrap ( ) )
1497+ . map ( |e| de_escalate_signer ( AccountMeta :: try_from ( e) . unwrap ( ) ) )
14871498 . collect :: < Vec < _ > > ( ) ;
14881499 update_and_assert_metas ( program_id, & mut buffer, & updated_metas_2, & check_metas_2) . await ;
14891500
@@ -1492,7 +1503,7 @@ mod tests {
14921503 [ ExtraAccountMeta :: new_with_pubkey ( & Pubkey :: new_unique ( ) , true , true ) . unwrap ( ) ] ;
14931504 let check_metas_3 = updated_metas_3
14941505 . iter ( )
1495- . map ( |e| AccountMeta :: try_from ( e) . unwrap ( ) )
1506+ . map ( |e| de_escalate_signer ( AccountMeta :: try_from ( e) . unwrap ( ) ) )
14961507 . collect :: < Vec < _ > > ( ) ;
14971508 update_and_assert_metas ( program_id, & mut buffer, & updated_metas_3, & check_metas_3) . await ;
14981509
@@ -1521,7 +1532,7 @@ mod tests {
15211532 )
15221533 . 0 ;
15231534 let check_metas_4 = [
1524- AccountMeta :: new ( seed_pubkey, true ) ,
1535+ AccountMeta :: new ( seed_pubkey, false ) ,
15251536 AccountMeta :: new ( simple_pda, false ) ,
15261537 ] ;
15271538
0 commit comments