Browse Source

Merge branch 'master' into armani/versioning

Armani Ferrante 3 years ago
parent
commit
4ba17c7e97

+ 1 - 0
CHANGELOG.md

@@ -13,6 +13,7 @@ incremented for features.
 
 ### Breaking
 
+* lang: Enforce that the payer for an init-ed account be marked `mut` ([#1271](https://github.com/project-serum/anchor/pull/1271)).
 * ts: `BorshAccountsCoder.accountDiscriminator` method has been replaced with `BorshAccountHeader.discriminator` ([#]()).
 * lang, ts: 8 byte account discriminator has been replaced with a versioned account header ([#]()).
 

+ 62 - 32
lang/syn/src/parser/accounts/mod.rs

@@ -39,55 +39,85 @@ pub fn parse(strct: &syn::ItemStruct) -> ParseResult<AccountsStruct> {
 
 fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
     // INIT
-    let init_field = fields.iter().find(|f| {
-        if let AccountField::Field(field) = f {
-            field.constraints.init.is_some()
-        } else {
-            false
-        }
-    });
-    if let Some(init_field) = init_field {
+    let init_fields: Vec<&Field> = fields
+        .iter()
+        .filter_map(|f| match f {
+            AccountField::Field(field) if field.constraints.init.is_some() => Some(field),
+            _ => None,
+        })
+        .collect();
+
+    if !init_fields.is_empty() {
         // init needs system program.
         if fields.iter().all(|f| f.ident() != "system_program") {
             return Err(ParseError::new(
-                init_field.ident().span(),
+                init_fields[0].ident.span(),
                 "the init constraint requires \
                 the system_program field to exist in the account \
                 validation struct. Use the program type to add \
                 the system_program field to your validation struct.",
             ));
         }
-        if let AccountField::Field(field) = init_field {
-            let kind = &field.constraints.init.as_ref().unwrap().kind;
-            // init token/a_token/mint needs token program.
-            match kind {
-                InitKind::Program { .. } => (),
-                InitKind::Token { .. }
-                | InitKind::AssociatedToken { .. }
-                | InitKind::Mint { .. } => {
-                    if fields.iter().all(|f| f.ident() != "token_program") {
-                        return Err(ParseError::new(
-                            init_field.ident().span(),
-                            "the init constraint requires \
+
+        let kind = &init_fields[0].constraints.init.as_ref().unwrap().kind;
+        // init token/a_token/mint needs token program.
+        match kind {
+            InitKind::Program { .. } => (),
+            InitKind::Token { .. } | InitKind::AssociatedToken { .. } | InitKind::Mint { .. } => {
+                if fields.iter().all(|f| f.ident() != "token_program") {
+                    return Err(ParseError::new(
+                        init_fields[0].ident.span(),
+                        "the init constraint requires \
                             the token_program field to exist in the account \
                             validation struct. Use the program type to add \
                             the token_program field to your validation struct.",
-                        ));
-                    }
+                    ));
                 }
             }
-            // a_token needs associated token program.
-            if let InitKind::AssociatedToken { .. } = kind {
-                if fields
-                    .iter()
-                    .all(|f| f.ident() != "associated_token_program")
-                {
-                    return Err(ParseError::new(
-                        init_field.ident().span(),
-                        "the init constraint requires \
+        }
+        // a_token needs associated token program.
+        if let InitKind::AssociatedToken { .. } = kind {
+            if fields
+                .iter()
+                .all(|f| f.ident() != "associated_token_program")
+            {
+                return Err(ParseError::new(
+                    init_fields[0].ident.span(),
+                    "the init constraint requires \
                     the associated_token_program field to exist in the account \
                     validation struct. Use the program type to add \
                     the associated_token_program field to your validation struct.",
+                ));
+            }
+        }
+
+        for field in init_fields {
+            // Get payer for init-ed account
+            let associated_payer_name = match field.constraints.init.clone().unwrap().payer.unwrap()
+            {
+                // composite payer, check not supported
+                Expr::Field(_) => continue,
+                field_name => field_name.to_token_stream().to_string(),
+            };
+
+            // Check payer is mutable
+            let associated_payer_field = fields.iter().find_map(|f| match f {
+                AccountField::Field(field) if *f.ident() == associated_payer_name => Some(field),
+                _ => None,
+            });
+            match associated_payer_field {
+                Some(associated_payer_field) => {
+                    if !associated_payer_field.constraints.is_mutable() {
+                        return Err(ParseError::new(
+                            field.ident.span(),
+                            "the payer specified for an init constraint must be mutable.",
+                        ));
+                    }
+                }
+                _ => {
+                    return Err(ParseError::new(
+                        field.ident.span(),
+                        "the payer specified does not exist.",
                     ));
                 }
             }

+ 1 - 1
tests/auction-house

@@ -1 +1 @@
-Subproject commit 09c911a53fd710d7d56972089c64de19d54ecf37
+Subproject commit 2bfe49bdac2333d0e413a1e452c0ab7b502266fa

+ 2 - 4
tests/cashiers-check/programs/cashiers-check/src/lib.rs

@@ -130,8 +130,7 @@ pub struct CashCheck<'info> {
     check_signer: AccountInfo<'info>,
     #[account(mut, has_one = owner)]
     to: Account<'info, TokenAccount>,
-    #[account(signer)]
-    owner: AccountInfo<'info>,
+    owner: Signer<'info>,
     token_program: AccountInfo<'info>,
 }
 
@@ -148,8 +147,7 @@ pub struct CancelCheck<'info> {
     check_signer: AccountInfo<'info>,
     #[account(mut, has_one = owner)]
     from: Account<'info, TokenAccount>,
-    #[account(signer)]
-    owner: AccountInfo<'info>,
+    owner: Signer<'info>,
     token_program: AccountInfo<'info>,
 }
 

+ 2 - 0
tests/cfo/programs/cfo/src/lib.rs

@@ -362,6 +362,7 @@ pub struct CreateOfficer<'info> {
         token::authority = officer,
     )]
     treasury: Box<Account<'info, TokenAccount>>,
+    #[account(mut)]
     authority: Signer<'info>,
     #[cfg_attr(
         not(feature = "test"),
@@ -393,6 +394,7 @@ pub struct AuthorizeMarket<'info> {
         bump,
     )]
     market_auth: Account<'info, MarketAuth>,
+    #[account(mut)]
     payer: Signer<'info>,
     // Not read or written to so not validated.
     market: UncheckedAccount<'info>,

+ 3 - 4
tests/chat/programs/chat/src/lib.rs

@@ -49,8 +49,8 @@ pub struct CreateUser<'info> {
         space = 320,
     )]
     user: Account<'info, User>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    #[account(mut)]
+    authority: Signer<'info>,
     system_program: AccountInfo<'info>,
 }
 
@@ -68,8 +68,7 @@ pub struct SendMessage<'info> {
         has_one = authority,
     )]
     user: Account<'info, User>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
     #[account(mut)]
     chat_room: Loader<'info, ChatRoom>,
 }

+ 1 - 2
tests/errors/programs/errors/src/lib.rs

@@ -60,8 +60,7 @@ pub struct HasOneError<'info> {
 
 #[derive(Accounts)]
 pub struct SignerError<'info> {
-    #[account(signer)]
-    my_account: AccountInfo<'info>,
+    my_account: Signer<'info>,
 }
 
 #[account]

+ 1 - 1
tests/errors/tests/errors.js

@@ -108,7 +108,7 @@ describe("errors", () => {
       assert.ok(false);
     } catch (err) {
       const errMsg =
-        "Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0x7d2";
+        "Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: custom program error: 0xbc2";
       assert.equal(err.toString(), errMsg);
     }
   });

+ 3 - 3
tests/escrow/programs/escrow/src/lib.rs

@@ -102,8 +102,8 @@ pub mod escrow {
 #[derive(Accounts)]
 #[instruction(initializer_amount: u64)]
 pub struct InitializeEscrow<'info> {
-    #[account(signer)]
-    pub initializer: AccountInfo<'info>,
+    #[account(mut)]
+    pub initializer: Signer<'info>,
     #[account(
         mut,
         constraint = initializer_deposit_token_account.amount >= initializer_amount
@@ -181,7 +181,7 @@ impl<'info> From<&mut InitializeEscrow<'info>>
                 .initializer_deposit_token_account
                 .to_account_info()
                 .clone(),
-            current_authority: accounts.initializer.clone(),
+            current_authority: accounts.initializer.to_account_info().clone(),
         };
         let cpi_program = accounts.token_program.to_account_info();
         CpiContext::new(cpi_program, cpi_accounts)

+ 2 - 4
tests/lockup/programs/lockup/src/lib.rs

@@ -250,8 +250,7 @@ pub struct Withdraw<'info> {
     // Vesting.
     #[account(mut, has_one = beneficiary, has_one = vault)]
     vesting: Account<'info, Vesting>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(mut)]
     vault: Account<'info, TokenAccount>,
     #[account(
@@ -281,8 +280,7 @@ pub struct WhitelistDeposit<'info> {
 #[derive(Accounts)]
 pub struct WhitelistTransfer<'info> {
     lockup: ProgramState<'info, Lockup>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     whitelisted_program: AccountInfo<'info>,
 
     // Whitelist interface.

+ 16 - 31
tests/lockup/programs/registry/src/lib.rs

@@ -596,8 +596,7 @@ impl<'info> Initialize<'info> {
 pub struct UpdateRegistrar<'info> {
     #[account(mut, has_one = authority)]
     registrar: Account<'info, Registrar>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -607,8 +606,7 @@ pub struct CreateMember<'info> {
     // Member.
     #[account(zero)]
     member: Box<Account<'info, Member>>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(
         "&balances.spt.owner == member_signer.key",
         "balances.spt.mint == registrar.pool_mint",
@@ -672,8 +670,7 @@ pub struct Ctor<'info> {
 
 #[derive(Accounts)]
 pub struct SetLockupProgram<'info> {
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -691,8 +688,7 @@ pub struct IsRealized<'info> {
 pub struct UpdateMember<'info> {
     #[account(mut, has_one = beneficiary)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -700,8 +696,7 @@ pub struct Deposit<'info> {
     // Member.
     #[account(has_one = beneficiary)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(mut, constraint = vault.to_account_info().key == &member.balances.vault)]
     vault: Account<'info, TokenAccount>,
     // Depositor.
@@ -726,8 +721,7 @@ pub struct DepositLocked<'info> {
     vesting_vault: AccountInfo<'info>,
     // Note: no need to verify the depositor_authority since the SPL program
     //       will fail the transaction if it's not correct.
-    #[account(signer)]
-    depositor_authority: AccountInfo<'info>,
+    pub depositor_authority: Signer<'info>,
     #[account(constraint = token_program.key == &token::ID)]
     token_program: AccountInfo<'info>,
     #[account(
@@ -746,8 +740,7 @@ pub struct DepositLocked<'info> {
     registrar: Box<Account<'info, Registrar>>,
     #[account(has_one = registrar, has_one = beneficiary)]
     member: Box<Account<'info, Member>>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -762,8 +755,7 @@ pub struct Stake<'info> {
     // Member.
     #[account(mut, has_one = beneficiary, has_one = registrar)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(constraint = BalanceSandbox::from(&balances) == member.balances)]
     balances: BalanceSandboxAccounts<'info>,
     #[account(constraint = BalanceSandbox::from(&balances_locked) == member.balances_locked)]
@@ -801,8 +793,7 @@ pub struct StartUnstake<'info> {
     pending_withdrawal: Account<'info, PendingWithdrawal>,
     #[account(has_one = beneficiary, has_one = registrar)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(constraint = BalanceSandbox::from(&balances) == member.balances)]
     balances: BalanceSandboxAccounts<'info>,
     #[account(constraint = BalanceSandbox::from(&balances_locked) == member.balances_locked)]
@@ -827,8 +818,7 @@ pub struct EndUnstake<'info> {
 
     #[account(has_one = registrar, has_one = beneficiary)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(mut, has_one = registrar, has_one = member, constraint = !pending_withdrawal.burned)]
     pending_withdrawal: Account<'info, PendingWithdrawal>,
 
@@ -859,8 +849,7 @@ pub struct Withdraw<'info> {
     // Member.
     #[account(has_one = registrar, has_one = beneficiary)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(mut, constraint = vault.to_account_info().key == &member.balances.vault)]
     vault: Account<'info, TokenAccount>,
     #[account(
@@ -886,8 +875,7 @@ pub struct WithdrawLocked<'info> {
     vesting: Box<Account<'info, Vesting>>,
     #[account(mut, constraint = vesting_vault.key == &vesting.vault)]
     vesting_vault: AccountInfo<'info>,
-    #[account(signer)]
-    vesting_signer: AccountInfo<'info>,
+    vesting_signer: Signer<'info>,
     #[account(constraint = token_program.key == &token::ID)]
     token_program: AccountInfo<'info>,
     #[account(
@@ -906,8 +894,7 @@ pub struct WithdrawLocked<'info> {
     registrar: Box<Account<'info, Registrar>>,
     #[account(has_one = registrar, has_one = beneficiary)]
     member: Box<Account<'info, Member>>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -977,8 +964,7 @@ pub struct ClaimRewardCommon<'info> {
     // Member.
     #[account(mut, has_one = registrar, has_one = beneficiary)]
     member: Account<'info, Member>,
-    #[account(signer)]
-    beneficiary: AccountInfo<'info>,
+    beneficiary: Signer<'info>,
     #[account(constraint = BalanceSandbox::from(&balances) == member.balances)]
     balances: BalanceSandboxAccounts<'info>,
     #[account(constraint = BalanceSandbox::from(&balances_locked) == member.balances_locked)]
@@ -1014,8 +1000,7 @@ pub struct ExpireReward<'info> {
     )]
     vendor_signer: AccountInfo<'info>,
     // Receiver.
-    #[account(signer)]
-    expiry_receiver: AccountInfo<'info>,
+    expiry_receiver: Signer<'info>,
     #[account(mut)]
     expiry_receiver_token: AccountInfo<'info>,
     // Misc.
@@ -1263,7 +1248,7 @@ impl<'a, 'b, 'c, 'info> From<&mut DepositLocked<'info>>
         let cpi_accounts = Transfer {
             from: accounts.vesting_vault.clone(),
             to: accounts.member_vault.to_account_info(),
-            authority: accounts.depositor_authority.clone(),
+            authority: accounts.depositor_authority.to_account_info().clone(),
         };
         let cpi_program = accounts.token_program.clone();
         CpiContext::new(cpi_program, cpi_accounts)

+ 38 - 28
tests/misc/programs/misc/src/context.rs

@@ -27,10 +27,11 @@ pub struct TestTokenSeedsInit<'info> {
         token::authority = authority,
     )]
     pub my_pda: Account<'info, TokenAccount>,
+    #[account(mut)]
     pub authority: AccountInfo<'info>,
-    pub system_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
     pub rent: Sysvar<'info, Rent>,
-    pub token_program: AccountInfo<'info>,
+    pub token_program: Program<'info, Token>,
 }
 
 #[derive(Accounts)]
@@ -43,6 +44,7 @@ pub struct TestInitAssociatedToken<'info> {
     )]
     pub token: Account<'info, TokenAccount>,
     pub mint: Account<'info, Mint>,
+    #[account(mut)]
     pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
     pub system_program: Program<'info, System>,
@@ -82,9 +84,10 @@ pub struct TestPdaInit<'info> {
         payer = my_payer,
     )]
     pub my_pda: Account<'info, DataU16>,
-    pub my_payer: AccountInfo<'info>,
+    #[account(mut)]
+    pub my_payer: Signer<'info>,
     pub foo: AccountInfo<'info>,
-    pub system_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
 }
 
 #[derive(Accounts)]
@@ -96,8 +99,9 @@ pub struct TestPdaInitZeroCopy<'info> {
         payer = my_payer,
     )]
     pub my_pda: Loader<'info, DataZeroCopy>,
-    pub my_payer: AccountInfo<'info>,
-    pub system_program: AccountInfo<'info>,
+    #[account(mut)]
+    pub my_payer: Signer<'info>,
+    pub system_program: Program<'info, System>,
 }
 
 #[derive(Accounts)]
@@ -189,29 +193,29 @@ pub struct TestI8<'info> {
 pub struct TestInit<'info> {
     #[account(init, payer = payer)]
     pub data: Account<'info, DataI8>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
-    pub system_program: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
+    pub system_program: Program<'info, System>,
 }
 
 #[derive(Accounts)]
 pub struct TestInitZeroCopy<'info> {
     #[account(init, payer = payer, space = 8 + size_of::<DataZeroCopy>())]
     pub data: Loader<'info, DataZeroCopy>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
-    pub system_program: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
+    pub system_program: Program<'info, System>,
 }
 
 #[derive(Accounts)]
 pub struct TestInitMint<'info> {
     #[account(init, mint::decimals = 6, mint::authority = payer, mint::freeze_authority = payer, payer = payer)]
     pub mint: Account<'info, Mint>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
-    pub system_program: AccountInfo<'info>,
-    pub token_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    pub token_program: Program<'info, Token>,
 }
 
 #[derive(Accounts)]
@@ -219,11 +223,11 @@ pub struct TestInitToken<'info> {
     #[account(init, token::mint = mint, token::authority = payer, payer = payer)]
     pub token: Account<'info, TokenAccount>,
     pub mint: Account<'info, Mint>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
-    pub system_program: AccountInfo<'info>,
-    pub token_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    pub token_program: Program<'info, Token>,
 }
 
 #[derive(Accounts)]
@@ -238,6 +242,7 @@ pub struct TestCompositePayer<'info> {
 pub struct TestFetchAll<'info> {
     #[account(init, payer = authority)]
     pub data: Account<'info, DataWithFilter>,
+    #[account(mut)]
     pub authority: Signer<'info>,
     pub system_program: Program<'info, System>,
 }
@@ -246,6 +251,7 @@ pub struct TestFetchAll<'info> {
 pub struct TestInitWithEmptySeeds<'info> {
     #[account(init, seeds = [], bump, payer = authority, space = 8 + size_of::<Data>())]
     pub pda: Account<'info, Data>,
+    #[account(mut)]
     pub authority: Signer<'info>,
     pub system_program: Program<'info, System>,
 }
@@ -260,6 +266,7 @@ pub struct TestEmptySeedsConstraint<'info> {
 pub struct InitWithSpace<'info> {
     #[account(init, payer = payer)]
     pub data: Account<'info, DataU16>,
+    #[account(mut)]
     pub payer: Signer<'info>,
     pub system_program: Program<'info, System>,
 }
@@ -268,6 +275,7 @@ pub struct InitWithSpace<'info> {
 pub struct TestInitIfNeeded<'info> {
     #[account(init_if_needed, payer = payer, space = 500)]
     pub data: Account<'info, DataU16>,
+    #[account(mut)]
     pub payer: Signer<'info>,
     pub system_program: Program<'info, System>,
 }
@@ -276,6 +284,7 @@ pub struct TestInitIfNeeded<'info> {
 pub struct TestInitIfNeededChecksOwner<'info> {
     #[account(init_if_needed, payer = payer, space = 100, owner = *owner.key, seeds = [b"hello"], bump)]
     pub data: UncheckedAccount<'info>,
+    #[account(mut)]
     pub payer: Signer<'info>,
     pub system_program: Program<'info, System>,
     pub owner: AccountInfo<'info>,
@@ -296,11 +305,11 @@ pub struct TestInitIfNeededChecksSeeds<'info> {
 pub struct TestInitMintIfNeeded<'info> {
     #[account(init_if_needed, mint::decimals = decimals, mint::authority = mint_authority, mint::freeze_authority = freeze_authority, payer = payer)]
     pub mint: Account<'info, Mint>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
-    pub system_program: AccountInfo<'info>,
-    pub token_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    pub token_program: Program<'info, Token>,
     pub mint_authority: AccountInfo<'info>,
     pub freeze_authority: AccountInfo<'info>,
 }
@@ -310,11 +319,11 @@ pub struct TestInitTokenIfNeeded<'info> {
     #[account(init_if_needed, token::mint = mint, token::authority = authority, payer = payer)]
     pub token: Account<'info, TokenAccount>,
     pub mint: Account<'info, Mint>,
-    #[account(signer)]
-    pub payer: AccountInfo<'info>,
+    #[account(mut)]
+    pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
-    pub system_program: AccountInfo<'info>,
-    pub token_program: AccountInfo<'info>,
+    pub system_program: Program<'info, System>,
+    pub token_program: Program<'info, Token>,
     pub authority: AccountInfo<'info>,
 }
 
@@ -328,6 +337,7 @@ pub struct TestInitAssociatedTokenIfNeeded<'info> {
     )]
     pub token: Account<'info, TokenAccount>,
     pub mint: Account<'info, Mint>,
+    #[account(mut)]
     pub payer: Signer<'info>,
     pub rent: Sysvar<'info, Rent>,
     pub system_program: Program<'info, System>,

+ 2 - 4
tests/multisig/programs/multisig/src/lib.rs

@@ -177,8 +177,7 @@ pub struct CreateTransaction<'info> {
     #[account(zero)]
     transaction: ProgramAccount<'info, Transaction>,
     // One of the owners. Checked in the handler.
-    #[account(signer)]
-    proposer: AccountInfo<'info>,
+    proposer: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -187,8 +186,7 @@ pub struct Approve<'info> {
     #[account(mut, has_one = multisig)]
     transaction: ProgramAccount<'info, Transaction>,
     // One of the multisig owners. Checked in the handler.
-    #[account(signer)]
-    owner: AccountInfo<'info>,
+    owner: Signer<'info>,
 }
 
 #[derive(Accounts)]

+ 4 - 8
tests/tictactoe/programs/tictactoe/src/lib.rs

@@ -64,14 +64,12 @@ pub struct Status<'info> {
 pub struct Initializedashboard<'info> {
     #[account(zero)]
     dashboard: Account<'info, Dashboard>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
 pub struct Initialize<'info> {
-    #[account(signer)]
-    player_x: AccountInfo<'info>,
+    player_x: Signer<'info>,
     #[account(mut)]
     dashboard: Account<'info, Dashboard>,
     #[account(zero)]
@@ -80,16 +78,14 @@ pub struct Initialize<'info> {
 
 #[derive(Accounts)]
 pub struct Playerjoin<'info> {
-    #[account(signer)]
-    player_o: AccountInfo<'info>,
+    player_o: Signer<'info>,
     #[account(mut, constraint = game.game_state != 0 && game.player_x != Pubkey::default())]
     game: Account<'info, Game>,
 }
 
 #[derive(Accounts)]
 pub struct Playermove<'info> {
-    #[account(signer)]
-    player: AccountInfo<'info>,
+    player: Signer<'info>,
     #[account(mut)]
     game: Account<'info, Game>,
 }

+ 8 - 14
tests/zero-copy/programs/zero-copy/src/lib.rs

@@ -64,24 +64,21 @@ pub mod zero_copy {
 
 #[derive(Accounts)]
 pub struct SetEvent<'info> {
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
 pub struct CreateFoo<'info> {
     #[account(zero)]
     foo: AccountLoader<'info, Foo>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
 pub struct UpdateFoo<'info> {
     #[account(mut, has_one = authority)]
     foo: AccountLoader<'info, Foo>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -91,8 +88,7 @@ pub struct UpdateFooSecond<'info> {
         constraint = &foo.load()?.get_second_authority() == second_authority.key,
     )]
     foo: AccountLoader<'info, Foo>,
-    #[account(signer)]
-    second_authority: AccountInfo<'info>,
+    second_authority: Signer<'info>,
 }
 
 #[derive(Accounts)]
@@ -104,8 +100,8 @@ pub struct CreateBar<'info> {
         payer = authority, owner = *program_id
     )]
     bar: AccountLoader<'info, Bar>,
-    #[account(signer)]
-    authority: AccountInfo<'info>,
+    #[account(mut)]
+    authority: Signer<'info>,
     foo: AccountLoader<'info, Foo>,
     system_program: AccountInfo<'info>,
 }
@@ -118,8 +114,7 @@ pub struct UpdateBar<'info> {
         bump,
     )]
     pub bar: AccountLoader<'info, Bar>,
-    #[account(signer)]
-    pub authority: AccountInfo<'info>,
+    pub authority: Signer<'info>,
     pub foo: AccountLoader<'info, Foo>,
 }
 
@@ -133,8 +128,7 @@ pub struct CreateLargeAccount<'info> {
 pub struct UpdateLargeAccount<'info> {
     #[account(mut)]
     event_q: AccountLoader<'info, EventQ>,
-    #[account(signer)]
-    from: AccountInfo<'info>,
+    from: Signer<'info>,
 }
 
 #[account(zero_copy)]