Переглянути джерело

Revert "lang: add `realloc` constraint group (#1943)" (#1984)

This reverts commit 7fe39c61ad3349952db9a328c4f2ad1440f5bcac.
Armani Ferrante 3 роки тому
батько
коміт
1ec9af7e21

+ 0 - 2
.github/workflows/tests.yaml

@@ -360,8 +360,6 @@ jobs:
             path: tests/escrow
           - cmd: cd tests/pyth && anchor test --skip-lint && npx tsc --noEmit
             path: tests/pyth
-          - cmd: cd tests/realloc && anchor test --skip-lint && npx tsc --noEmit
-            path: tests/realloc
           - cmd: cd tests/system-accounts && anchor test --skip-lint
             path: tests/system-accounts
           - cmd: cd tests/misc && anchor test --skip-lint && npx tsc --noEmit

+ 0 - 1
CHANGELOG.md

@@ -12,7 +12,6 @@ The minor version will be incremented upon a breaking change and the patch versi
 
 ### Features
 
-* lang: Add `realloc`, `realloc::payer`, and `realloc::zero` as a new constraint group for program accounts ([#1943](https://github.com/project-serum/anchor/pull/1943)).
 * lang: Add `PartialEq` and `Eq` for `anchor_lang::Error` ([#1544](https://github.com/project-serum/anchor/pull/1544)).
 * cli: Add `--skip-build` to `anchor publish` ([#1786](https://github.
 com/project-serum/anchor/pull/1841)).

+ 0 - 39
lang/derive/accounts/src/lib.rs

@@ -44,7 +44,6 @@ use syn::parse_macro_input;
 ///
 /// - [Normal Constraints](#normal-constraints)
 /// - [SPL Constraints](#spl-constraints)
-///
 /// # Normal Constraints
 /// <table>
 ///     <thead>
@@ -419,44 +418,6 @@ use syn::parse_macro_input;
 ///                 </code></pre>
 ///             </td>
 ///         </tr>
-///         <tr>
-///             <td>
-///                 <code>#[account(realloc = &lt;space&gt;, realloc::payer = &lt;target&gt;, realloc::zero = &lt;bool&gt;)]</code>
-///             </td>
-///             <td>
-///                 Used to <a href="https://docs.rs/solana-program/latest/solana_program/account_info/struct.AccountInfo.html#method.realloc" target = "_blank" rel = "noopener noreferrer">realloc</a>
-///                 program account space at the beginning of an instruction.
-///                 <br><br>
-///                 The account must be marked as <code>mut</code> and applied to either <code>Account</code> or <code>AccountLoader</code> types.
-///                 <br><br>
-///                 If the change in account data length is additive, lamports will be transferred from the <code>realloc::payer</code> into the
-///                 program account in order to maintain rent exemption. Likewise, if the change is subtractive, lamports will be transferred from
-///                 the program account back into the <code>realloc::payer</code>.
-///                 <br><br>
-///                 The <code>realloc::zero</code> constraint is required in order to determine whether the new memory should be zero initialized after
-///                 reallocation. Please read the documentation on the <code>AccountInfo::realloc</code> function linked above to understand the
-///                 caveats regarding compute units when providing <code>true</code or <code>false</code> to this flag.
-///                 <br><br>
-///                 Example:
-///                 <pre>
-/// #[derive(Accounts)]
-/// pub struct Example {
-///     #[account(mut)]
-///     pub payer: Signer<'info>,
-///     #[account(
-///         mut,
-///         seeds = [b"example"],
-///         bump,
-///         realloc = 8 + std::mem::size_of::<MyType>() + 100,
-///         realloc::payer = payer,
-///         realloc::zero = false,
-///     )]
-///     pub acc: Account<'info, MyType>,
-///     pub system_program: Program<'info, System>,
-/// }
-///                 </pre>
-///             </td>
-///         </tr>
 ///     </tbody>
 /// </table>
 ///

+ 0 - 45
lang/syn/src/codegen/accounts/constraints.rs

@@ -59,7 +59,6 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
         associated_token,
         token_account,
         mint,
-        realloc,
     } = c_group.clone();
 
     let mut constraints = Vec::new();
@@ -70,9 +69,6 @@ pub fn linearize(c_group: &ConstraintGroup) -> Vec<Constraint> {
     if let Some(c) = init {
         constraints.push(Constraint::Init(c));
     }
-    if let Some(c) = realloc {
-        constraints.push(Constraint::Realloc(c));
-    }
     if let Some(c) = seeds {
         constraints.push(Constraint::Seeds(c));
     }
@@ -134,7 +130,6 @@ fn generate_constraint(f: &Field, c: &Constraint) -> proc_macro2::TokenStream {
         Constraint::AssociatedToken(c) => generate_constraint_associated_token(f, c),
         Constraint::TokenAccount(c) => generate_constraint_token_account(f, c),
         Constraint::Mint(c) => generate_constraint_mint(f, c),
-        Constraint::Realloc(c) => generate_constraint_realloc(f, c),
     }
 }
 
@@ -325,46 +320,6 @@ pub fn generate_constraint_rent_exempt(
     }
 }
 
-fn generate_constraint_realloc(f: &Field, c: &ConstraintReallocGroup) -> proc_macro2::TokenStream {
-    let field = &f.ident;
-    let new_space = &c.space;
-    let payer = &c.payer;
-    let zero = &c.zero;
-
-    quote! {
-        let __anchor_rent = Rent::get()?;
-        let __field_info = #field.to_account_info();
-        let __additive = #new_space > __field_info.data_len();
-
-        let __delta_space = if __additive {
-            #new_space.checked_sub(__field_info.data_len()).unwrap()
-        } else {
-            __field_info.data_len().checked_sub(#new_space).unwrap()
-        };
-
-        if __delta_space > 0 {
-            if __additive {
-                anchor_lang::system_program::transfer(
-                    anchor_lang::context::CpiContext::new(
-                        system_program.to_account_info(),
-                        anchor_lang::system_program::Transfer {
-                            from: #payer.to_account_info(),
-                            to: __field_info.clone(),
-                        },
-                    ),
-                    __anchor_rent.minimum_balance(#new_space).checked_sub(__field_info.lamports()).unwrap(),
-                )?;
-            } else {
-                let __lamport_amt = __field_info.lamports().checked_sub(__anchor_rent.minimum_balance(#new_space)).unwrap();
-                **#payer.to_account_info().lamports.borrow_mut() = #payer.to_account_info().lamports().checked_add(__lamport_amt).unwrap();
-                **__field_info.lamports.borrow_mut() = __field_info.lamports().checked_sub(__lamport_amt).unwrap();
-            }
-
-            #field.to_account_info().realloc(#new_space, #zero)?;
-        }
-    }
-}
-
 fn generate_constraint_init_group(f: &Field, c: &ConstraintInitGroup) -> proc_macro2::TokenStream {
     let field = &f.ident;
     let name_str = f.ident.to_string();

+ 0 - 27
lang/syn/src/lib.rs

@@ -635,7 +635,6 @@ pub struct ConstraintGroup {
     associated_token: Option<ConstraintAssociatedToken>,
     token_account: Option<ConstraintTokenAccountGroup>,
     mint: Option<ConstraintTokenMintGroup>,
-    realloc: Option<ConstraintReallocGroup>,
 }
 
 impl ConstraintGroup {
@@ -679,7 +678,6 @@ pub enum Constraint {
     Address(ConstraintAddress),
     TokenAccount(ConstraintTokenAccountGroup),
     Mint(ConstraintTokenMintGroup),
-    Realloc(ConstraintReallocGroup),
 }
 
 // Constraint token is a single keyword in a `#[account(<TOKEN>)]` attribute.
@@ -711,9 +709,6 @@ pub enum ConstraintToken {
     MintDecimals(Context<ConstraintMintDecimals>),
     Bump(Context<ConstraintTokenBump>),
     ProgramSeed(Context<ConstraintProgramSeed>),
-    Realloc(Context<ConstraintRealloc>),
-    ReallocPayer(Context<ConstraintReallocPayer>),
-    ReallocZero(Context<ConstraintReallocZero>),
 }
 
 impl Parse for ConstraintToken {
@@ -738,28 +733,6 @@ pub struct ConstraintMut {
     pub error: Option<Expr>,
 }
 
-#[derive(Debug, Clone)]
-pub struct ConstraintReallocGroup {
-    pub payer: Expr,
-    pub space: Expr,
-    pub zero: Expr,
-}
-
-#[derive(Debug, Clone)]
-pub struct ConstraintRealloc {
-    pub space: Expr,
-}
-
-#[derive(Debug, Clone)]
-pub struct ConstraintReallocPayer {
-    pub target: Expr,
-}
-
-#[derive(Debug, Clone)]
-pub struct ConstraintReallocZero {
-    pub zero: Expr,
-}
-
 #[derive(Debug, Clone)]
 pub struct ConstraintSigner {
     pub error: Option<Expr>,

+ 0 - 124
lang/syn/src/parser/accounts/constraints.rs

@@ -196,47 +196,6 @@ pub fn parse_token(stream: ParseStream) -> ParseResult<ConstraintToken> {
                 ))
             }
         }
-        "realloc" => {
-            if stream.peek(Token![=]) {
-                stream.parse::<Token![=]>()?;
-                let span = ident
-                    .span()
-                    .join(stream.span())
-                    .unwrap_or_else(|| ident.span());
-                ConstraintToken::Realloc(Context::new(
-                    span,
-                    ConstraintRealloc {
-                        space: stream.parse()?,
-                    },
-                ))
-            } else {
-                stream.parse::<Token![:]>()?;
-                stream.parse::<Token![:]>()?;
-                let kw = stream.call(Ident::parse_any)?.to_string();
-                stream.parse::<Token![=]>()?;
-
-                let span = ident
-                    .span()
-                    .join(stream.span())
-                    .unwrap_or_else(|| ident.span());
-
-                match kw.as_str() {
-                    "payer" => ConstraintToken::ReallocPayer(Context::new(
-                        span,
-                        ConstraintReallocPayer {
-                            target: stream.parse()?,
-                        },
-                    )),
-                    "zero" => ConstraintToken::ReallocZero(Context::new(
-                        span,
-                        ConstraintReallocZero {
-                            zero: stream.parse()?,
-                        },
-                    )),
-                    _ => return Err(ParseError::new(ident.span(), "Invalid attribute. realloc::payer and realloc::zero are the only valid attributes")),
-                }
-            }
-        }
         _ => {
             stream.parse::<Token![=]>()?;
             let span = ident
@@ -354,9 +313,6 @@ pub struct ConstraintGroupBuilder<'ty> {
     pub mint_decimals: Option<Context<ConstraintMintDecimals>>,
     pub bump: Option<Context<ConstraintTokenBump>>,
     pub program_seed: Option<Context<ConstraintProgramSeed>>,
-    pub realloc: Option<Context<ConstraintRealloc>>,
-    pub realloc_payer: Option<Context<ConstraintReallocPayer>>,
-    pub realloc_zero: Option<Context<ConstraintReallocZero>>,
 }
 
 impl<'ty> ConstraintGroupBuilder<'ty> {
@@ -388,9 +344,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             mint_decimals: None,
             bump: None,
             program_seed: None,
-            realloc: None,
-            realloc_payer: None,
-            realloc_zero: None,
         }
     }
 
@@ -486,22 +439,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             }
         }
 
-        // Realloc.
-        if let Some(r) = &self.realloc {
-            if self.realloc_payer.is_none() {
-                return Err(ParseError::new(
-                    r.span(),
-                    "realloc::payer must be provided when using realloc",
-                ));
-            }
-            if self.realloc_zero.is_none() {
-                return Err(ParseError::new(
-                    r.span(),
-                    "realloc::zero must be provided when using realloc",
-                ));
-            }
-        }
-
         // Zero.
         if let Some(z) = &self.zeroed {
             match self.mutable {
@@ -589,9 +526,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             mint_decimals,
             bump,
             program_seed,
-            realloc,
-            realloc_payer,
-            realloc_zero,
         } = self;
 
         // Converts Option<Context<T>> -> Option<T>.
@@ -710,11 +644,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
                     }
                 },
             })).transpose()?,
-            realloc: realloc.as_ref().map(|r| ConstraintReallocGroup {
-                payer: into_inner!(realloc_payer).unwrap().target,
-                space: r.space.clone(),
-                zero: into_inner!(realloc_zero).unwrap().zero,
-            }),
             zeroed: into_inner!(zeroed),
             mutable: into_inner!(mutable),
             signer: into_inner!(signer),
@@ -761,9 +690,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
             ConstraintToken::MintDecimals(c) => self.add_mint_decimals(c),
             ConstraintToken::Bump(c) => self.add_bump(c),
             ConstraintToken::ProgramSeed(c) => self.add_program_seed(c),
-            ConstraintToken::Realloc(c) => self.add_realloc(c),
-            ConstraintToken::ReallocPayer(c) => self.add_realloc_payer(c),
-            ConstraintToken::ReallocZero(c) => self.add_realloc_zero(c),
         }
     }
 
@@ -831,56 +757,6 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
         Ok(())
     }
 
-    fn add_realloc(&mut self, c: Context<ConstraintRealloc>) -> ParseResult<()> {
-        if !matches!(self.f_ty, Some(Ty::Account(_)))
-            && !matches!(self.f_ty, Some(Ty::AccountLoader(_)))
-        {
-            return Err(ParseError::new(
-                c.span(),
-                "realloc must be on an Account or AccountLoader",
-            ));
-        }
-        if self.mutable.is_none() {
-            return Err(ParseError::new(
-                c.span(),
-                "mut must be provided before realloc",
-            ));
-        }
-        if self.realloc.is_some() {
-            return Err(ParseError::new(c.span(), "realloc already provided"));
-        }
-        self.realloc.replace(c);
-        Ok(())
-    }
-
-    fn add_realloc_payer(&mut self, c: Context<ConstraintReallocPayer>) -> ParseResult<()> {
-        if self.realloc.is_none() {
-            return Err(ParseError::new(
-                c.span(),
-                "realloc must be provided before realloc::payer",
-            ));
-        }
-        if self.realloc_payer.is_some() {
-            return Err(ParseError::new(c.span(), "realloc::payer already provided"));
-        }
-        self.realloc_payer.replace(c);
-        Ok(())
-    }
-
-    fn add_realloc_zero(&mut self, c: Context<ConstraintReallocZero>) -> ParseResult<()> {
-        if self.realloc.is_none() {
-            return Err(ParseError::new(
-                c.span(),
-                "realloc must be provided before realloc::zero",
-            ));
-        }
-        if self.realloc_zero.is_some() {
-            return Err(ParseError::new(c.span(), "realloc::zero already provided"));
-        }
-        self.realloc_zero.replace(c);
-        Ok(())
-    }
-
     fn add_close(&mut self, c: Context<ConstraintClose>) -> ParseResult<()> {
         if !matches!(self.f_ty, Some(Ty::ProgramAccount(_)))
             && !matches!(self.f_ty, Some(Ty::Account(_)))

+ 3 - 58
lang/syn/src/parser/accounts/mod.rs

@@ -55,7 +55,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
                 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 \
+                validation struct. Use the program type to add \
                 the system_program field to your validation struct.",
             ));
         }
@@ -70,7 +70,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
                         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 \
+                            validation struct. Use the program type to add \
                             the token_program field to your validation struct.",
                     ));
                 }
@@ -86,7 +86,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
                     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 \
+                    validation struct. Use the program type to add \
                     the associated_token_program field to your validation struct.",
                 ));
             }
@@ -141,61 +141,6 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> {
             }
         }
     }
-
-    // REALLOC
-    let realloc_fields: Vec<&Field> = fields
-        .iter()
-        .filter_map(|f| match f {
-            AccountField::Field(field) if field.constraints.realloc.is_some() => Some(field),
-            _ => None,
-        })
-        .collect();
-
-    if !realloc_fields.is_empty() {
-        // realloc needs system program.
-        if fields.iter().all(|f| f.ident() != "system_program") {
-            return Err(ParseError::new(
-                realloc_fields[0].ident.span(),
-                "the realloc 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.",
-            ));
-        }
-
-        for field in realloc_fields {
-            // Get allocator for realloc-ed account
-            let associated_payer_name = match field.constraints.realloc.clone().unwrap().payer {
-                // composite allocator, check not supported
-                Expr::Field(_) => continue,
-                field_name => field_name.to_token_stream().to_string(),
-            };
-
-            // Check allocator 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 realloc::payer specified for an realloc constraint must be mutable.",
-                        ));
-                    }
-                }
-                _ => {
-                    return Err(ParseError::new(
-                        field.ident.span(),
-                        "the realloc::payer specified does not exist.",
-                    ));
-                }
-            }
-        }
-    }
-
     Ok(())
 }
 

+ 0 - 1
tests/package.json

@@ -24,7 +24,6 @@
     "permissioned-markets",
     "pda-derivation",
     "pyth",
-    "realloc",
     "spl/token-proxy",
     "swap",
     "system-accounts",

+ 0 - 15
tests/realloc/Anchor.toml

@@ -1,15 +0,0 @@
-[features]
-seeds = false
-
-[programs.localnet]
-realloc = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"
-
-[registry]
-url = "https://anchor.projectserum.com"
-
-[provider]
-cluster = "localnet"
-wallet = "~/.config/solana/id.json"
-
-[scripts]
-test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

+ 0 - 4
tests/realloc/Cargo.toml

@@ -1,4 +0,0 @@
-[workspace]
-members = [
-    "programs/*"
-]

+ 0 - 20
tests/realloc/package.json

@@ -1,20 +0,0 @@
-{
-    "name": "realloc",
-    "version": "0.24.2",
-    "license": "(MIT OR Apache-2.0)",
-    "homepage": "https://github.com/project-serum/anchor#readme",
-    "bugs": {
-      "url": "https://github.com/project-serum/anchor/issues"
-    },
-    "repository": {
-      "type": "git",
-      "url": "https://github.com/project-serum/anchor.git"
-    },
-    "engines": {
-      "node": ">=11"
-    },
-    "scripts": {
-      "test": "anchor test"
-    }
-  }
-  

+ 0 - 22
tests/realloc/programs/realloc/Cargo.toml

@@ -1,22 +0,0 @@
-[package]
-name = "realloc"
-version = "0.1.0"
-description = "Created with Anchor"
-edition = "2021"
-
-[lib]
-crate-type = ["cdylib", "lib"]
-name = "realloc"
-
-[features]
-no-entrypoint = []
-no-idl = []
-no-log-ix-name = []
-cpi = ["no-entrypoint"]
-default = []
-
-[profile.release]
-overflow-checks = true
-
-[dependencies]
-anchor-lang = { path = "../../../../lang" }

+ 0 - 2
tests/realloc/programs/realloc/Xargo.toml

@@ -1,2 +0,0 @@
-[target.bpfel-unknown-unknown.dependencies.std]
-features = []

+ 0 - 70
tests/realloc/programs/realloc/src/lib.rs

@@ -1,70 +0,0 @@
-use anchor_lang::prelude::*;
-
-declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
-
-#[program]
-pub mod realloc {
-    use super::*;
-
-    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
-        ctx.accounts.sample.data = vec![0];
-        ctx.accounts.sample.bump = *ctx.bumps.get("sample").unwrap();
-        Ok(())
-    }
-
-    pub fn realloc(ctx: Context<Realloc>, len: u8) -> Result<()> {
-        ctx.accounts
-            .sample
-            .data
-            .resize_with(len as usize, Default::default);
-        Ok(())
-    }
-}
-
-#[derive(Accounts)]
-pub struct Initialize<'info> {
-    #[account(mut)]
-    pub authority: Signer<'info>,
-
-    #[account(
-        init,
-        payer = authority,
-        seeds = [b"sample"],
-        bump,
-        space = Sample::space(1),
-    )]
-    pub sample: Account<'info, Sample>,
-
-    pub system_program: Program<'info, System>,
-}
-
-#[derive(Accounts)]
-#[instruction(len: u8)]
-pub struct Realloc<'info> {
-    #[account(mut)]
-    pub authority: Signer<'info>,
-
-    #[account(
-        mut,
-        seeds = [b"sample"],
-        bump = sample.bump,
-        realloc = Sample::space(len as usize),
-        realloc::payer = authority,
-        realloc::zero = false,
-    )]
-    pub sample: Account<'info, Sample>,
-
-    pub system_program: Program<'info, System>,
-}
-
-#[account]
-pub struct Sample {
-    pub data: Vec<u8>,
-    pub bump: u8,
-}
-
-impl Sample {
-    pub fn space(len: usize) -> usize {
-        8 + (4 + len) + 1
-    }
-}

+ 0 - 52
tests/realloc/tests/realloc.ts

@@ -1,52 +0,0 @@
-import * as anchor from "@project-serum/anchor";
-import { Program } from "@project-serum/anchor";
-import { assert } from "chai";
-import { Realloc } from "../target/types/realloc";
-
-describe("realloc", () => {
-  // Configure the client to use the local cluster.
-  anchor.setProvider(anchor.AnchorProvider.env());
-
-  const program = anchor.workspace.Realloc as Program<Realloc>;
-  const authority = (program.provider as any).wallet
-    .payer as anchor.web3.Keypair;
-
-  let sample: anchor.web3.PublicKey;
-
-  before(async () => {
-    [sample] = await anchor.web3.PublicKey.findProgramAddress(
-      [Buffer.from("sample")],
-      program.programId
-    );
-  });
-
-  it("Is initialized!", async () => {
-    await program.methods
-      .initialize()
-      .accounts({ authority: authority.publicKey, sample })
-      .rpc();
-
-    const s = await program.account.sample.fetch(sample);
-    assert.lengthOf(s.data, 1);
-  });
-
-  it("realloc additive", async () => {
-    await program.methods
-      .realloc(5)
-      .accounts({ authority: authority.publicKey, sample })
-      .rpc();
-
-    const s = await program.account.sample.fetch(sample);
-    assert.lengthOf(s.data, 5);
-  });
-
-  it("realloc substractive", async () => {
-    await program.methods
-      .realloc(1)
-      .accounts({ authority: authority.publicKey, sample })
-      .rpc();
-
-    const s = await program.account.sample.fetch(sample);
-    assert.lengthOf(s.data, 1);
-  });
-});

+ 0 - 10
tests/realloc/tsconfig.json

@@ -1,10 +0,0 @@
-{
-  "compilerOptions": {
-    "types": ["mocha", "chai"],
-    "typeRoots": ["./node_modules/@types"],
-    "lib": ["es2015"],
-    "module": "commonjs",
-    "target": "es6",
-    "esModuleInterop": true
-  }
-}