Skip to content

Commit

Permalink
Lang: feature flag for init_if_needed (#1258)
Browse files Browse the repository at this point in the history
Co-authored-by: Armani Ferrante <armaniferrante@gmail.com>
  • Loading branch information
paul-schaaf and armaniferrante authored Jan 30, 2022
1 parent e9c2a57 commit 17c9463
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 5 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)).
Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions lang/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
1 change: 1 addition & 0 deletions lang/derive/accounts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
14 changes: 12 additions & 2 deletions lang/derive/accounts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions lang/syn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ description = "Anchor syntax parsing and code generation tools"
edition = "2018"

[features]
init-if-needed = []
idl = []
hash = []
default = []
Expand Down
11 changes: 11 additions & 0 deletions lang/syn/src/parser/accounts/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/programs/misc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

0 comments on commit 17c9463

Please sign in to comment.