Skip to content

Commit

Permalink
lang: remove default space calc (#1519)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-schaaf authored and NBNARADHYA committed Mar 8, 2022
1 parent 7d931e2 commit 7d99492
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 148 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -31,6 +31,10 @@ incremented for features.

* cli: Fix rust template ([#1488](https://github.com/project-serum/anchor/pull/1488)).

### Breaking

* lang: Remove space calculation using [`#[derive(Default)]`] (https://github.com/project-serum/anchor/pull/1519).

## [0.22.0] - 2022-02-20

### Features
Expand Down
26 changes: 8 additions & 18 deletions lang/derive/accounts/src/lib.rs
Expand Up @@ -89,7 +89,6 @@ use syn::parse_macro_input;
/// </tr>
/// <tr>
/// <td>
/// <code>#[account(init, payer = &lt;target_account&gt;)]</code><br><br>
/// <code>#[account(init, payer = &lt;target_account&gt;, space = &lt;num_bytes&gt;)]</code>
/// </td>
/// <td>
Expand All @@ -110,14 +109,12 @@ use syn::parse_macro_input;
/// and be called <code>system_program</code>.
/// </li>
/// <li>
/// Requires that the <code>space</code> constraint is specified
/// or, if creating an <code>Account</code> type, the <code>T</code> of <code>Account</code>
/// to implement the rust std <code>Default</code> trait.<br>
/// Requires that the <code>space</code> constraint is specified.
/// When using the <code>space</code> constraint, one must remember to add 8 to it
/// which is the size of the account discriminator.<br>
/// The given number is the size of the account in bytes, so accounts that hold
/// a variable number of items such as a <code>Vec</code> should use the <code>space</code>
/// constraint instead of using the <code>Default</code> trait and allocate sufficient space for all items that may
/// which is the size of the account discriminator. This only has to be done
/// for accounts owned by anchor programs.<br>
/// The given space number is the size of the account in bytes, so accounts that hold
/// a variable number of items such as a <code>Vec</code> should allocate sufficient space for all items that may
/// be added to the data structure because account size is fixed. Check out the <a href = "https://borsh.io/" target = "_blank" rel = "noopener noreferrer">borsh library</a>
/// (which anchor uses under the hood for serialization) specification to learn how much
/// space different data structures require.
Expand All @@ -126,20 +123,13 @@ use syn::parse_macro_input;
/// Example:
/// <pre>
/// #[account]
/// #[derive(Default)]
/// pub struct MyData {
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
/// }&#10;
/// #[account]
/// pub struct OtherData {
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
/// }&#10;
/// #[derive(Accounts)]
/// pub struct Initialize<'info> {
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init, payer = payer)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account: Account<'info, MyData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init, payer = payer, space = 8 + 8)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account<'info, OtherData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account<'info, MyData>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(mut)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub payer: Signer<'info>,
/// &nbsp;&nbsp;&nbsp;&nbsp;pub system_program: Program<'info, System>,
Expand Down Expand Up @@ -172,7 +162,7 @@ use syn::parse_macro_input;
/// #[instruction(bump: u8)]
/// pub struct Initialize<'info> {
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"example_seed".as_ref()], bump = bump
/// &nbsp;&nbsp;&nbsp;&nbsp;)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub pda_data_account: Account<'info, MyData>,
Expand All @@ -182,7 +172,7 @@ use syn::parse_macro_input;
/// &nbsp;&nbsp;&nbsp;&nbsp;)]
/// &nbsp;&nbsp;&nbsp;&nbsp;pub account_for_other_program: AccountInfo<'info>,
/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init,payer = payer, space = 8 + 8,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8,
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;owner = other_program.key(),
/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"other_seed".as_ref()], bump
/// &nbsp;&nbsp;&nbsp;&nbsp;)]
Expand Down
24 changes: 1 addition & 23 deletions lang/syn/src/codegen/accounts/constraints.rs
Expand Up @@ -480,29 +480,7 @@ fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_ma
}
InitKind::Program { owner } => {
// Define the space variable.
let space = match space {
// If no explicit space param was given, serialize the type to bytes
// and take the length (with +8 for the discriminator.)
None => {
let account_ty = f.account_ty();
match matches!(f.ty, Ty::Loader(_) | Ty::AccountLoader(_)) {
false => {
quote! {
let space = 8 + #account_ty::default().try_to_vec().unwrap().len();
}
}
true => {
quote! {
let space = 8 + anchor_lang::__private::bytemuck::bytes_of(&#account_ty::default()).len();
}
}
}
}
// Explicit account size given. Use it.
Some(s) => quote! {
let space = #s;
},
};
let space = quote! {let space = #space;};

// Define the owner of the account being created. If not specified,
// default to the currently executing program.
Expand Down
2 changes: 1 addition & 1 deletion lang/syn/src/lib.rs
Expand Up @@ -721,7 +721,7 @@ pub enum ConstraintRentExempt {
pub struct ConstraintInitGroup {
pub if_needed: bool,
pub seeds: Option<ConstraintSeedsGroup>,
pub payer: Option<Expr>,
pub payer: Expr,
pub space: Option<Expr>,
pub kind: InitKind,
}
Expand Down
35 changes: 23 additions & 12 deletions lang/syn/src/parser/accounts/constraints.rs
Expand Up @@ -505,17 +505,28 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
}
}

// SPL Space.
if self.init.is_some()
&& self.seeds.is_some()
&& self.token_mint.is_some()
&& (self.mint_authority.is_some() || self.token_authority.is_some())
&& self.space.is_some()
{
return Err(ParseError::new(
self.space.as_ref().unwrap().span(),
"space is not required for initializing an spl account",
));
// Space.
if let Some(i) = &self.init {
let initializing_token_program_acc = self.token_mint.is_some()
|| self.mint_authority.is_some()
|| self.token_authority.is_some()
|| self.associated_token_authority.is_some();

match (self.space.is_some(), initializing_token_program_acc) {
(true, true) => {
return Err(ParseError::new(
self.space.as_ref().unwrap().span(),
"space is not required for initializing an spl account",
));
}
(false, false) => {
return Err(ParseError::new(
i.span(),
"space must be provided with init",
));
}
_ => (),
}
}

let ConstraintGroupBuilder {
Expand Down Expand Up @@ -593,7 +604,7 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
init: init.as_ref().map(|i| Ok(ConstraintInitGroup {
if_needed: i.if_needed,
seeds: seeds.clone(),
payer: into_inner!(payer.clone()).map(|a| a.target),
payer: into_inner!(payer.clone()).unwrap().target,
space: space.clone().map(|s| s.space.clone()),
kind: if let Some(tm) = &token_mint {
InitKind::Token {
Expand Down
3 changes: 1 addition & 2 deletions lang/syn/src/parser/accounts/mod.rs
Expand Up @@ -93,8 +93,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {

for field in init_fields {
// Get payer for init-ed account
let associated_payer_name = match field.constraints.init.clone().unwrap().payer.unwrap()
{
let associated_payer_name = match field.constraints.init.clone().unwrap().payer {
// composite payer, check not supported
Expr::Field(_) => continue,
field_name => field_name.to_token_stream().to_string(),
Expand Down
Expand Up @@ -32,11 +32,14 @@ pub mod bpf_upgradeable_state {
}

#[account]
#[derive(Default, Debug)]
pub struct Settings {
admin_data: u64,
}

impl Settings {
pub const LEN: usize = 8;
}

#[error_code]
pub enum CustomError {
InvalidProgramDataAddress,
Expand All @@ -49,7 +52,7 @@ pub struct SetAdminSettings<'info> {
// In a real program, this should be a PDA,
// so the authority cannot create multiple settings accounts.
// Not done here for easier testing
#[account(init, payer = authority)]
#[account(init, payer = authority, space = Settings::LEN + 8)]
pub settings: Account<'info, Settings>,
#[account(mut)]
pub authority: Signer<'info>,
Expand All @@ -65,7 +68,7 @@ pub struct SetAdminSettingsUseProgramState<'info> {
// In a real program, this should be a PDA,
// so the authority cannot create multiple settings accounts.
// Not done here for easier testing
#[account(init, payer = authority)]
#[account(init, payer = authority, space = Settings::LEN + 8)]
pub settings: Account<'info, Settings>,
#[account(mut)]
pub authority: Signer<'info>,
Expand Down
68 changes: 42 additions & 26 deletions tests/cfo/programs/cfo/src/lib.rs
Expand Up @@ -324,6 +324,7 @@ pub struct CreateOfficer<'info> {
seeds = [dex_program.key.as_ref()],
bump,
payer = authority,
space = Officer::LEN + 8
)]
officer: Box<Account<'info, Officer>>,
#[account(
Expand All @@ -332,7 +333,7 @@ pub struct CreateOfficer<'info> {
bump,
payer = authority,
token::mint = srm_mint,
token::authority = officer,
token::authority = officer
)]
srm_vault: Box<Account<'info, TokenAccount>>,
#[account(
Expand All @@ -341,7 +342,7 @@ pub struct CreateOfficer<'info> {
bump,
payer = authority,
token::mint = usdc_mint,
token::authority = officer,
token::authority = officer
)]
usdc_vault: Box<Account<'info, TokenAccount>>,
#[account(
Expand All @@ -350,7 +351,7 @@ pub struct CreateOfficer<'info> {
bump,
payer = authority,
token::mint = srm_mint,
token::authority = officer,
token::authority = officer
)]
stake: Box<Account<'info, TokenAccount>>,
#[account(
Expand All @@ -359,7 +360,7 @@ pub struct CreateOfficer<'info> {
bump,
payer = authority,
token::mint = srm_mint,
token::authority = officer,
token::authority = officer
)]
treasury: Box<Account<'info, TokenAccount>>,
#[account(mut)]
Expand Down Expand Up @@ -392,6 +393,7 @@ pub struct AuthorizeMarket<'info> {
payer = payer,
seeds = [b"market-auth", officer.key().as_ref(), market.key.as_ref()],
bump,
space = MarketAuth::LEN + 8
)]
market_auth: Account<'info, MarketAuth>,
#[account(mut)]
Expand Down Expand Up @@ -421,7 +423,7 @@ pub struct CreateOfficerToken<'info> {
bump,
token::mint = mint,
token::authority = officer,
payer = payer,
payer = payer
)]
token: Account<'info, TokenAccount>,
mint: Account<'info, Mint>,
Expand Down Expand Up @@ -666,28 +668,31 @@ pub struct DropStakeRewardPool<'info> {
///
/// PDA - [dex_program_id].
#[account]
#[derive(Default)]
pub struct Officer {
// Priviledged account.
pub authority: Pubkey,
pub authority: Pubkey, // 32
// Vault holding the officer's SRM tokens prior to distribution.
pub srm_vault: Pubkey,
pub srm_vault: Pubkey, // 32
// Escrow SRM vault holding tokens which are dropped onto stakers.
pub stake: Pubkey,
pub stake: Pubkey, // 32
// SRM token account to send treasury earned tokens to.
pub treasury: Pubkey,
pub treasury: Pubkey, // 32
// Defines the fee distribution, i.e., what percent each fee category gets.
pub distribution: Distribution,
pub distribution: Distribution, // Distribution::LEN
// Swap frontend for the dex.
pub swap_program: Pubkey,
pub swap_program: Pubkey, // 32
// Dex program the officer is associated with.
pub dex_program: Pubkey,
pub dex_program: Pubkey, // 32
// SRM stake pool address
pub registrar: Pubkey,
pub registrar: Pubkey, // 32
// MSRM stake pool address.
pub msrm_registrar: Pubkey,
pub msrm_registrar: Pubkey, // 32
// Bump seeds for pdas.
pub bumps: OfficerBumps,
pub bumps: OfficerBumps, // OfficerBumps::LEN
}

impl Officer {
pub const LEN: usize = 8 * 32 + Distribution::LEN + OfficerBumps::LEN;
}

/// MarketAuth represents an authorization token created by the Officer
Expand All @@ -702,26 +707,37 @@ pub struct Officer {
///
/// PDA - [b"market-auth", officer, market_address]
#[account]
#[derive(Default)]
pub struct MarketAuth {
// Bump seed for this account's PDA.
pub bump: u8,
pub bump: u8, // 1
}

impl MarketAuth {
pub const LEN: usize = 1;
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
pub struct OfficerBumps {
pub bump: u8,
pub srm: u8,
pub usdc: u8,
pub stake: u8,
pub treasury: u8,
pub bump: u8, // 1
pub srm: u8, // 1
pub usdc: u8, // 1
pub stake: u8, // 1
pub treasury: u8, // 1
}

impl OfficerBumps {
pub const LEN: usize = 5;
}

#[derive(AnchorSerialize, AnchorDeserialize, Default, Clone)]
pub struct Distribution {
burn: u8,
stake: u8,
treasury: u8,
burn: u8, // 1
stake: u8, // 1
treasury: u8, // 1
}

impl Distribution {
pub const LEN: usize = 3;
}

// CpiContext transformations.
Expand Down

0 comments on commit 7d99492

Please sign in to comment.