Lang: feature flag for init_if_needed (#1258)

Co-authored-by: Armani Ferrante <armaniferrante@gmail.com>
This commit is contained in:
Paul 2022-01-30 21:59:25 +01:00 committed by GitHub
parent e9c2a57541
commit 17c9463592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 30 additions and 5 deletions

View File

@ -14,13 +14,14 @@ incremented for features.
### Features
* lang: Add `seeds::program` constraint for specifying which program_id to use when deriving PDAs.([#1197](https://github.com/project-serum/anchor/pull/1197))
* lang: `Context` now has a new `bumps: BTree<String, u8>` argument, mapping account name to bump seed "found" by the accounts context. This allows one to access bump seeds without having to pass them in from the client or recalculate them in the handler ([#1367](calculated )).
* lang: `Context` now has a new `bumps: BTree<String, u8>` argument, mapping account name to bump seed "found" by the accounts context. This allows one to access bump seeds without having to pass them in from the client or recalculate them in the handler ([#1367](https://github.com/project-serum/anchor/pull/1367)).
* ts: Remove error logging in the event parser when log websocket encounters a program error ([#1313](https://github.com/project-serum/anchor/pull/1313)).
* ts: Add new `methods` namespace to the program client, introducing a more ergonomic builder API ([#1324](https://github.com/project-serum/anchor/pull/1324)).
* ts: Add registry utility for fetching the latest verified build ([#1371](https://github.com/project-serum/anchor/pull/1371)).
### Breaking
* lang: Put `init_if_needed` behind a feature flag to decrease wrong usage ([#1258](https://github.com/project-serum/anchor/pull/1258)).
* lang: rename `loader_account` module to `account_loader` module ([#1279](https://github.com/project-serum/anchor/pull/1279))
* lang: The `Accounts` trait's `try_accounts` method now has an additional `bumps: &mut BTreeMap<String, u8>` argument, which accumulates bump seeds ([#1367](https://github.com/project-serum/anchor/pull/1367)).
* ts: `Coder` is now an interface and the existing class has been renamed to `BorshCoder`. This change allows the generation of Anchor clients for non anchor programs ([#1259](https://github.com/project-serum/anchor/pull/1259/files)).

View File

@ -18,7 +18,7 @@ anyhow = "1.0.32"
syn = { version = "1.0.60", features = ["full", "extra-traits"] }
anchor-lang = { path = "../lang" }
anchor-client = { path = "../client" }
anchor-syn = { path = "../lang/syn", features = ["idl"] }
anchor-syn = { path = "../lang/syn", features = ["idl", "init-if-needed"] }
serde_json = "1.0"
shellexpand = "2.1.0"
toml = "0.5.8"

View File

@ -8,6 +8,7 @@ license = "Apache-2.0"
description = "Solana Sealevel eDSL"
[features]
init-if-needed = ["anchor-derive-accounts/init-if-needed"]
derive = []
default = []
anchor-debug = [

View File

@ -11,6 +11,7 @@ edition = "2018"
proc-macro = true
[features]
init-if-needed = ["anchor-syn/init-if-needed"]
default = []
anchor-debug = ["anchor-syn/anchor-debug"]

View File

@ -200,8 +200,18 @@ use syn::parse_macro_input;
/// </td>
/// <td>
/// Exact same functionality as the <code>init</code> constraint but only runs if the account does not exist yet.<br>
/// If it does exist, it still checks whether the given init constraints are correct,
/// e.g. that the account has the expected amount of space and, if it's a PDA, the correct seeds etc.
/// If the account does exist, it still checks whether the given init constraints are correct,
/// e.g. that the account has the expected amount of space and, if it's a PDA, the correct seeds etc.<br><br>
/// This feature should be used with care and is therefore behind a feature flag.
/// You can enable it by importing <code>anchor-lang</code> with the <code>init-if-needed</code> cargo feature.<br>
/// When using <code>init_if_needed</code>, you need to make sure you properly protect yourself
/// against re-initialization attacks. You need to include checks in your code that check
/// that the initialized account cannot be reset to its initial settings after the first time it was
/// initialized (unless that it what you want).<br>
/// Because of the possibility of re-initialization attacks and the general guideline that instructions
/// should avoid having multiple execution flows (which is important so they remain easy to understand),
/// consider breaking up your instruction into two instructions - one for initializing and one for using
/// the account - unless you have a good reason not to do so.
/// <br><br>
/// Example:
/// <pre>

View File

@ -8,6 +8,7 @@ description = "Anchor syntax parsing and code generation tools"
edition = "2018"
[features]
init-if-needed = []
idl = []
hash = []
default = []

View File

@ -373,6 +373,17 @@ impl<'ty> ConstraintGroupBuilder<'ty> {
pub fn build(mut self) -> ParseResult<ConstraintGroup> {
// Init.
if let Some(i) = &self.init {
if cfg!(not(feature = "init-if-needed")) && i.if_needed {
return Err(ParseError::new(
i.span(),
"init_if_needed requires that anchor-lang be imported \
with the init-if-needed cargo feature enabled. \
Carefully read the init_if_needed docs before using this feature \
to make sure you know how to protect yourself against \
re-initialization attacks.",
));
}
match self.mutable {
Some(m) => {
return Err(ParseError::new(

View File

@ -15,7 +15,7 @@ cpi = ["no-entrypoint"]
default = []
[dependencies]
anchor-lang = { path = "../../../../lang" }
anchor-lang = { path = "../../../../lang", features = ["init-if-needed"] }
anchor-spl = { path = "../../../../spl" }
misc2 = { path = "../misc2", features = ["cpi"] }
spl-associated-token-account = "=1.0.3"