diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index adf82ad0..1a1ca3ff 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -234,6 +234,36 @@ jobs: - run: cd tests/bpf-upgradeable-state && solana program deploy --program-id program_with_different_programdata.json target/deploy/bpf_upgradeable_state.so - run: cd tests/bpf-upgradeable-state && cp bpf_upgradeable_state-keypair.json target/deploy/bpf_upgradeable_state-keypair.json && anchor deploy && anchor test --skip-deploy --skip-build --skip-lint + test-anchor-init: + needs: setup-anchor-cli + name: Test Anchor Init + runs-on: ubuntu-18.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v2 + - uses: ./.github/actions/setup/ + - uses: ./.github/actions/setup-ts/ + - uses: ./.github/actions/setup-solana/ + + - uses: actions/cache@v2 + name: Cache Cargo registry + index + id: cache-anchor + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + ./target/ + key: cargo-${{ runner.os }}-anchor-${{ hashFiles('**/Cargo.lock') }} + + - uses: actions/download-artifact@v2 + with: + name: anchor-binary + path: ~/.cargo/bin/ + + - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && anchor test + test-programs: needs: setup-anchor-cli name: Test ${{ matrix.node.path }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fae7fba..e72199a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,23 @@ incremented for features. ## [Unreleased] +### Features + +* lang: Add new `AccountSysvarMismatch` error code and test cases for sysvars ([#1535](https://github.com/project-serum/anchor/pull/1535)). +* spl: Add support for revoke instruction ([#1493](https://github.com/project-serum/anchor/pull/1493)). + +### Fixes + +* ts: Fix the loss of strict typing using the `methods` namespace on builder functions ([#1539](https://github.com/project-serum/anchor/pull/1539)). + +### Breaking + +* ts: Mark `transaction`, `instruction`, `simulate` and `rpc` program namespaces as deprecated in favor of `methods` ([#1539](https://github.com/project-serum/anchor/pull/1539)). +* ts: No longer allow manual setting of globally resolvable program public keys in `methods#accounts()`. ([#1548][https://github.com/project-serum/anchor/pull/1548]) +* lang: Remove space calculation using [`#[derive(Default)]`] (https://github.com/project-serum/anchor/pull/1519). + +## [0.22.1] - 2022-02-28 + ### Fixes * cli: Fix rust template ([#1488](https://github.com/project-serum/anchor/pull/1488)). @@ -38,7 +55,7 @@ This change will break most programs. Do the following to upgrade: * change all `ProgramResult`'s to `Result<()>` * change `#[error]` to `#[error_code]` * change all `Err(MyError::SomeError.into())` to `Err(error!(MyError::SomeError))` and all `Err(ProgramError::SomeProgramError)` to `Err(ProgramError::SomeProgramError.into())` or `Err(Error::from(ProgramError::SomeProgramError).with_source(source!()))` to provide file and line source of the error (`with_source` is most useful with `ProgramError`s. `error!` already adds source information for custom and anchor internal errors). - * change all `solana_program::program::invoke()` to `solana_program::program::invoke().map_err(Into::into)` and `solana_program::program::invoke_signed()` to `solana_program::program::invoke().map_err(Into::into)` + * change all `solana_program::program::invoke()` to `solana_program::program::invoke().map_err(Into::into)` and `solana_program::program::invoke_signed()` to `solana_program::program::invoke_signed().map_err(Into::into)` ## [0.21.0] - 2022-02-07 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bef20c82..c9e19cab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,12 +4,37 @@ Thank you for your interest in contributing to Anchor! All contributions are wel matter how big or small. This includes (but is not limited to) filing issues, adding documentation, fixing bugs, creating examples, and implementing features. -If you'd like to contribute, please claim an issue by commenting, forking, and -opening a pull request, even if empty. This allows the maintainers to track who -is working on what issue as to not overlap work. If you're looking to get started, +## Finding issues to work on + +If you're looking to get started, check out [good first issues](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) or issues where [help is wanted](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). -For simple documentation changes, feel free to just open a pull request. +For simple documentation changes or typos, feel free to just open a pull request. If you're considering larger changes or self motivated features, please file an issue -and engage with the maintainers in [Discord](https://discord.com/channels/889577356681945098). +and engage with the maintainers in [Discord](https://discord.gg/sxy4zxBckh). + +## Choosing an issue + +If you'd like to contribute, please claim an issue by commenting, forking, and +opening a pull request, even if empty. This allows the maintainers to track who +is working on what issue as to not overlap work. + +## Issue Guidelines + +Please follow these guidelines: + +Before coding: +- choose a branch name that describes the issue you're working on + +While coding: +- Submit a draft PR asap +- Only change code directly relevant to your PR. Sometimes you might find some code that could really need some refactoring. However, if it's not relevant to your PR, do not touch it. File an issue instead. This allows the reviewer to focus on a single problem at a time. +- If you write comments, do not exceed 80 chars per line. This allows contributors who work with multiple open windows to still read the comments without horizontally scrolling. +- Write adversarial tests. For example, if you're adding a new account type, do not only write tests where the instruction succeeds. Also write tests that test whether the instruction fails, if a check inside the new type is violated. + +After coding: +- If you've moved code around, build the docs with `cargo doc --open` and adjust broken links +- Adjust the cli templates if necessary +- If you made a change to anchor's periphery (avm or cli), make a PR to the `anchor-book` repo if necessary +- If you've added a new folder to the `tests` directory, add it to the [CI](./.github/workflows/tests.yaml). \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 5953bc22..2245d33e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,7 +56,7 @@ checksum = "6b2d54853319fd101b8dd81de382bcbf3e03410a64d8928bbee85a3e7dcde483" [[package]] name = "anchor-attribute-access-control" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -68,7 +68,7 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -81,7 +81,7 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "proc-macro2 1.0.32", @@ -90,7 +90,7 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "proc-macro2 1.0.32", @@ -100,7 +100,7 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -111,7 +111,7 @@ dependencies = [ [[package]] name = "anchor-attribute-interface" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -123,7 +123,7 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -134,7 +134,7 @@ dependencies = [ [[package]] name = "anchor-attribute-state" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -145,7 +145,7 @@ dependencies = [ [[package]] name = "anchor-cli" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-client", "anchor-lang", @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "anchor-client" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-lang", "anyhow", @@ -193,7 +193,7 @@ dependencies = [ [[package]] name = "anchor-derive-accounts" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-syn", "anyhow", @@ -204,7 +204,7 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "anchor-spl" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anchor-lang", "serum_dex", @@ -237,7 +237,7 @@ dependencies = [ [[package]] name = "anchor-syn" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anyhow", "bs58 0.3.1", @@ -304,7 +304,7 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "avm" -version = "0.22.0" +version = "0.22.1" dependencies = [ "anyhow", "cfg-if 1.0.0", diff --git a/README.md b/README.md index 7b4685be..5c2945a7 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ If you're familiar with developing in Ethereum's [Solidity](https://docs.solidit ## Getting Started -For a quickstart guide and in depth tutorials, see the guided [documentation](https://project-serum.github.io/anchor/getting-started/introduction.html). +For a quickstart guide and in depth tutorials, see the [anchor book](https://book.anchor-lang.com) and the older [documentation](https://project-serum.github.io/anchor/getting-started/introduction.html) that is being phased out. To jump straight to examples, go [here](https://github.com/project-serum/anchor/tree/master/examples). For the latest Rust and TypeScript API documentation, see [docs.rs](https://docs.rs/anchor-lang) and the [typedoc](https://project-serum.github.io/anchor/ts/index.html). ## Packages @@ -58,14 +58,14 @@ declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); mod counter { use super::*; - pub fn initialize(ctx: Context, start: u64) -> ProgramResult { + pub fn initialize(ctx: Context, start: u64) -> Result<()> { let counter = &mut ctx.accounts.counter; counter.authority = *ctx.accounts.authority.key; counter.count = start; Ok(()) } - pub fn increment(ctx: Context) -> ProgramResult { + pub fn increment(ctx: Context) -> Result<()> { let counter = &mut ctx.accounts.counter; counter.count += 1; Ok(()) @@ -107,19 +107,8 @@ licensed as above, without any additional terms or conditions. ## Contribution -Thank you for your interest in contributing to Anchor! All contributions are welcome no -matter how big or small. This includes (but is not limited to) filing issues, -adding documentation, fixing bugs, creating examples, and implementing features. - -If you'd like to contribute, please claim an issue by commenting, forking, and -opening a pull request, even if empty. This allows the maintainers to track who -is working on what issue as to not overlap work. If you're looking to get started, -check out [good first issues](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) -or issues where [help is wanted](https://github.com/project-serum/anchor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). -For simple documentation changes, feel free to just open a pull request. - -If you're considering larger changes or self motivated features, please file an issue -and engage with the maintainers in [Discord](https://discord.gg/sxy4zxBckh). +Thank you for your interest in contributing to Anchor! +Please see the [CONTRIBUTING.md](./CONTRIBUTING.md) to learn how. ### Thanks ❤️ diff --git a/VERSION b/VERSION index 21574090..a723ece7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.22.0 +0.22.1 diff --git a/avm/Cargo.toml b/avm/Cargo.toml index e7f3b8d9..c799601e 100644 --- a/avm/Cargo.toml +++ b/avm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "avm" -version = "0.22.0" +version = "0.22.1" edition = "2018" [[bin]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ecd31b60..93143242 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-cli" -version = "0.22.0" +version = "0.22.1" authors = ["armaniferrante "] edition = "2018" diff --git a/cli/npm-package/package.json b/cli/npm-package/package.json index 510fdec7..9b4d6e7e 100644 --- a/cli/npm-package/package.json +++ b/cli/npm-package/package.json @@ -1,6 +1,6 @@ { "name": "@project-serum/anchor-cli", - "version": "0.22.0", + "version": "0.22.1", "description": "Anchor CLI tool", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/cli/src/template.rs b/cli/src/template.rs index 4d1d0806..78ae2f52 100644 --- a/cli/src/template.rs +++ b/cli/src/template.rs @@ -237,6 +237,7 @@ pub fn ts_package_json() -> String { "chai": "^4.3.4", "mocha": "^9.0.3", "ts-mocha": "^8.0.0", + "@types/chai": "^4.3.0", "@types/mocha": "^9.0.0", "typescript": "^4.3.5" }} diff --git a/client/Cargo.toml b/client/Cargo.toml index b3403905..ee05ffca 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-client" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] edition = "2018" license = "Apache-2.0" @@ -10,7 +10,7 @@ description = "Rust client for Anchor programs" debug = [] [dependencies] -anchor-lang = { path = "../lang", version = "0.22.0" } +anchor-lang = { path = "../lang", version = "0.22.1" } anyhow = "1.0.32" regex = "1.4.5" serde = { version = "1.0.122", features = ["derive"] } diff --git a/docs/src/getting-started/installation.md b/docs/src/getting-started/installation.md index 3759de81..37edaa4d 100644 --- a/docs/src/getting-started/installation.md +++ b/docs/src/getting-started/installation.md @@ -44,7 +44,7 @@ npm i -g @project-serum/anchor-cli For now, we can use Cargo to install the CLI. ```bash -cargo install --git https://github.com/project-serum/anchor --tag v0.22.0 anchor-cli --locked +cargo install --git https://github.com/project-serum/anchor --tag v0.22.1 anchor-cli --locked ``` On Linux systems you may need to install additional dependencies if `cargo install` fails. On Ubuntu, diff --git a/docs/src/getting-started/publishing.md b/docs/src/getting-started/publishing.md index 35a3c0fe..0278b581 100644 --- a/docs/src/getting-started/publishing.md +++ b/docs/src/getting-started/publishing.md @@ -30,7 +30,7 @@ have an `Anchor.toml` to define the build. An example `Anchor.toml` config looks as follows, ```toml -anchor_version = "0.22.0" +anchor_version = "0.22.1" [workspace] members = ["programs/multisig"] diff --git a/docs/src/getting-started/verification.md b/docs/src/getting-started/verification.md index 9b72a68b..d041e847 100644 --- a/docs/src/getting-started/verification.md +++ b/docs/src/getting-started/verification.md @@ -32,10 +32,10 @@ If the program has an IDL, it will also check the IDL deployed on chain matches. ## Images -A docker image for each version of Anchor is published on [Docker Hub](https://hub.docker.com/r/projectserum/build). They are tagged in the form `projectserum/build:`. For example, to get the image for Anchor `v0.22.0` one can run +A docker image for each version of Anchor is published on [Docker Hub](https://hub.docker.com/r/projectserum/build). They are tagged in the form `projectserum/build:`. For example, to get the image for Anchor `v0.22.1` one can run ``` -docker pull projectserum/build:v0.22.0 +docker pull projectserum/build:v0.22.1 ``` ## Removing an Image diff --git a/docs/src/tutorials/tutorial-2.md b/docs/src/tutorials/tutorial-2.md index af9a1e29..e337d2a1 100644 --- a/docs/src/tutorials/tutorial-2.md +++ b/docs/src/tutorials/tutorial-2.md @@ -13,7 +13,7 @@ To address these problems, Anchor provides several types, traits, and macros. It from the untrusted `&[AccountInfo]` slice given to a Solana program into a validated struct of deserialized account types. - [#[account]](https://docs.rs/anchor-lang/latest/anchor_lang/attr.account.html): attribute macro implementing [AccountSerialize](https://docs.rs/anchor-lang/latest/anchor_lang/trait.AccountSerialize.html) and [AccountDeserialize](https://docs.rs/anchor-lang/latest/anchor_lang/trait.AnchorDeserialize.html), automatically prepending a unique 8 byte discriminator to the account array. The discriminator is defined by the first 8 bytes of the `Sha256` hash of the account's Rust identifier--i.e., the struct type name--and ensures no account can be substituted for another. -- [Account](https://docs.rs/anchor-lang/latest/anchor_lang/struct.Account.html): a wrapper type for a deserialized account implementing `AccountDeserialize`. Using this type within an `Accounts` struct will ensure the account is **owned** by the address defined by `declare_id!` where the inner account was defined. +- [Account](https://docs.rs/anchor-lang/latest/anchor_lang/accounts/account/struct.Account.html): a wrapper type for a deserialized account implementing `AccountDeserialize`. Using this type within an `Accounts` struct will ensure the account is **owned** by the address defined by `declare_id!` where the inner account was defined. With the above, we can define preconditions for any instruction handler expecting a certain set of accounts, allowing us to more easily reason about the security of our programs. diff --git a/examples/tutorial/basic-0/package.json b/examples/tutorial/basic-0/package.json index 44b07657..af63b61d 100644 --- a/examples/tutorial/basic-0/package.json +++ b/examples/tutorial/basic-0/package.json @@ -1,6 +1,6 @@ { "name": "basic-0", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-1/package.json b/examples/tutorial/basic-1/package.json index 7ad4e01b..6705849d 100644 --- a/examples/tutorial/basic-1/package.json +++ b/examples/tutorial/basic-1/package.json @@ -1,6 +1,6 @@ { "name": "basic-1", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-2/package.json b/examples/tutorial/basic-2/package.json index 9c12676c..131a2624 100644 --- a/examples/tutorial/basic-2/package.json +++ b/examples/tutorial/basic-2/package.json @@ -1,6 +1,6 @@ { "name": "basic-2", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-3/package.json b/examples/tutorial/basic-3/package.json index b596176d..dee1ed6e 100644 --- a/examples/tutorial/basic-3/package.json +++ b/examples/tutorial/basic-3/package.json @@ -1,6 +1,6 @@ { "name": "basic-3", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/basic-4/package.json b/examples/tutorial/basic-4/package.json index a4818eae..dae6300c 100644 --- a/examples/tutorial/basic-4/package.json +++ b/examples/tutorial/basic-4/package.json @@ -1,6 +1,6 @@ { "name": "basic-4", - "version": "0.22.0", + "version": "0.22.1", "license": "(MIT OR Apache-2.0)", "homepage": "https://github.com/project-serum/anchor#readme", "bugs": { diff --git a/examples/tutorial/package.json b/examples/tutorial/package.json index 860b78aa..122bee51 100644 --- a/examples/tutorial/package.json +++ b/examples/tutorial/package.json @@ -13,7 +13,7 @@ "basic-4" ], "dependencies": { - "@project-serum/anchor": "^0.22.0" + "@project-serum/anchor": "^0.22.1" }, "devDependencies": { "mocha": "^9.1.3", diff --git a/lang/Cargo.toml b/lang/Cargo.toml index ef824540..e4e889b3 100644 --- a/lang/Cargo.toml +++ b/lang/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-lang" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" edition = "2018" @@ -25,15 +25,15 @@ anchor-debug = [ ] [dependencies] -anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.22.0" } -anchor-attribute-account = { path = "./attribute/account", version = "0.22.0" } -anchor-attribute-constant = { path = "./attribute/constant", version = "0.22.0" } -anchor-attribute-error = { path = "./attribute/error", version = "0.22.0" } -anchor-attribute-program = { path = "./attribute/program", version = "0.22.0" } -anchor-attribute-state = { path = "./attribute/state", version = "0.22.0" } -anchor-attribute-interface = { path = "./attribute/interface", version = "0.22.0" } -anchor-attribute-event = { path = "./attribute/event", version = "0.22.0" } -anchor-derive-accounts = { path = "./derive/accounts", version = "0.22.0" } +anchor-attribute-access-control = { path = "./attribute/access-control", version = "0.22.1" } +anchor-attribute-account = { path = "./attribute/account", version = "0.22.1" } +anchor-attribute-constant = { path = "./attribute/constant", version = "0.22.1" } +anchor-attribute-error = { path = "./attribute/error", version = "0.22.1" } +anchor-attribute-program = { path = "./attribute/program", version = "0.22.1" } +anchor-attribute-state = { path = "./attribute/state", version = "0.22.1" } +anchor-attribute-interface = { path = "./attribute/interface", version = "0.22.1" } +anchor-attribute-event = { path = "./attribute/event", version = "0.22.1" } +anchor-derive-accounts = { path = "./derive/accounts", version = "0.22.1" } arrayref = "0.3.6" base64 = "0.13.0" borsh = "0.9" diff --git a/lang/attribute/access-control/Cargo.toml b/lang/attribute/access-control/Cargo.toml index d51f6022..1cb3a17a 100644 --- a/lang/attribute/access-control/Cargo.toml +++ b/lang/attribute/access-control/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-access-control" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,5 +18,5 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } regex = "1.0" diff --git a/lang/attribute/account/Cargo.toml b/lang/attribute/account/Cargo.toml index 6d8339ed..1cc67855 100644 --- a/lang/attribute/account/Cargo.toml +++ b/lang/attribute/account/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-account" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,6 +18,6 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0", features = ["hash"] } +anchor-syn = { path = "../../syn", version = "0.22.1", features = ["hash"] } rustversion = "1.0.3" bs58 = "0.4.0" \ No newline at end of file diff --git a/lang/attribute/account/src/lib.rs b/lang/attribute/account/src/lib.rs index fc0c445a..c31b9cbc 100644 --- a/lang/attribute/account/src/lib.rs +++ b/lang/attribute/account/src/lib.rs @@ -42,7 +42,7 @@ mod id; /// /// This can be used to conveniently implement /// [`ZeroCopy`](./trait.ZeroCopy.html) so that the account can be used -/// with [`Loader`](./struct.Loader.html). +/// with [`AccountLoader`](./accounts/account_loader/struct.AccountLoader.html). /// /// Other than being more efficient, the most salient benefit this provides is /// the ability to define account types larger than the max stack or heap size. diff --git a/lang/attribute/constant/Cargo.toml b/lang/attribute/constant/Cargo.toml index 1d0870ee..7ce36f2f 100644 --- a/lang/attribute/constant/Cargo.toml +++ b/lang/attribute/constant/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-constant" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -16,4 +16,4 @@ anchor-debug = ["anchor-syn/anchor-debug"] [dependencies] proc-macro2 = "1.0" syn = { version = "1.0.60", features = ["full"] } -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/error/Cargo.toml b/lang/attribute/error/Cargo.toml index e43a0176..d0ce963e 100644 --- a/lang/attribute/error/Cargo.toml +++ b/lang/attribute/error/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-error" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -17,4 +17,4 @@ anchor-debug = ["anchor-syn/anchor-debug"] proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/event/Cargo.toml b/lang/attribute/event/Cargo.toml index 29e41b11..8f83a072 100644 --- a/lang/attribute/event/Cargo.toml +++ b/lang/attribute/event/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-event" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0", features = ["hash"] } +anchor-syn = { path = "../../syn", version = "0.22.1", features = ["hash"] } diff --git a/lang/attribute/interface/Cargo.toml b/lang/attribute/interface/Cargo.toml index 91d95902..765cf39c 100644 --- a/lang/attribute/interface/Cargo.toml +++ b/lang/attribute/interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-interface" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,5 +18,5 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } heck = "0.3.2" diff --git a/lang/attribute/program/Cargo.toml b/lang/attribute/program/Cargo.toml index f6a0e3c1..13020a46 100644 --- a/lang/attribute/program/Cargo.toml +++ b/lang/attribute/program/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-program" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/attribute/state/Cargo.toml b/lang/attribute/state/Cargo.toml index 9b6e9500..a1121652 100644 --- a/lang/attribute/state/Cargo.toml +++ b/lang/attribute/state/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-attribute-state" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -18,4 +18,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/derive/accounts/Cargo.toml b/lang/derive/accounts/Cargo.toml index 21dc6f1d..0e63f581 100644 --- a/lang/derive/accounts/Cargo.toml +++ b/lang/derive/accounts/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "anchor-derive-accounts" -version = "0.22.0" +version = "0.22.1" authors = ["Serum Foundation "] repository = "https://github.com/project-serum/anchor" license = "Apache-2.0" @@ -20,4 +20,4 @@ proc-macro2 = "1.0" quote = "1.0" syn = { version = "1.0.60", features = ["full"] } anyhow = "1.0.32" -anchor-syn = { path = "../../syn", version = "0.22.0" } +anchor-syn = { path = "../../syn", version = "0.22.1" } diff --git a/lang/derive/accounts/src/lib.rs b/lang/derive/accounts/src/lib.rs index 02704f56..66fbdfec 100644 --- a/lang/derive/accounts/src/lib.rs +++ b/lang/derive/accounts/src/lib.rs @@ -89,7 +89,6 @@ use syn::parse_macro_input; /// /// /// -/// #[account(init, payer = <target_account>)]

/// #[account(init, payer = <target_account>, space = <num_bytes>)] /// /// @@ -110,14 +109,12 @@ use syn::parse_macro_input; /// and be called system_program. /// ///
  • -/// Requires that the space constraint is specified -/// or, if creating an Account type, the T of Account -/// to implement the rust std Default trait.
    +/// Requires that the space constraint is specified. /// When using the space constraint, one must remember to add 8 to it -/// which is the size of the account discriminator.
    -/// The given number is the size of the account in bytes, so accounts that hold -/// a variable number of items such as a Vec should use the space -/// constraint instead of using the Default 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.
    +/// The given space number is the size of the account in bytes, so accounts that hold +/// a variable number of items such as a Vec should allocate sufficient space for all items that may /// be added to the data structure because account size is fixed. Check out the borsh library /// (which anchor uses under the hood for serialization) specification to learn how much /// space different data structures require. @@ -126,20 +123,13 @@ use syn::parse_macro_input; /// Example: ///
     /// #[account]
    -/// #[derive(Default)]
     /// pub struct MyData {
     ///     pub data: u64
     /// }
    
    -/// #[account]
    -/// pub struct OtherData {
    -///     pub data: u64
    -/// }
    
     /// #[derive(Accounts)]
     /// pub struct Initialize<'info> {
    -///     #[account(init, payer = payer)]
    -///     pub data_account: Account<'info, MyData>,
     ///     #[account(init, payer = payer, space = 8 + 8)]
    -///     pub data_account_two: Account<'info, OtherData>,
    +///     pub data_account_two: Account<'info, MyData>,
     ///     #[account(mut)]
     ///     pub payer: Signer<'info>,
     ///     pub system_program: Program<'info, System>,
    @@ -172,7 +162,7 @@ use syn::parse_macro_input;
     /// #[instruction(bump: u8)]
     /// pub struct Initialize<'info> {
     ///     #[account(
    -///         init, payer = payer,
    +///         init, payer = payer, space = 8 + 8
     ///         seeds = [b"example_seed".as_ref()], bump = bump
     ///     )]
     ///     pub pda_data_account: Account<'info, MyData>,
    @@ -182,7 +172,7 @@ use syn::parse_macro_input;
     ///     )]
     ///     pub account_for_other_program: AccountInfo<'info>,
     ///     #[account(
    -///         init,payer = payer, space = 8 + 8,
    +///         init, payer = payer, space = 8 + 8,
     ///         owner = other_program.key(),
     ///         seeds = [b"other_seed".as_ref()], bump
     ///     )]
    diff --git a/lang/src/accounts/sysvar.rs b/lang/src/accounts/sysvar.rs
    index 25e8698f..3c10ee45 100644
    --- a/lang/src/accounts/sysvar.rs
    +++ b/lang/src/accounts/sysvar.rs
    @@ -46,10 +46,13 @@ impl<'info, T: solana_program::sysvar::Sysvar + fmt::Debug> fmt::Debug for Sysva
     
     impl<'info, T: solana_program::sysvar::Sysvar> Sysvar<'info, T> {
         pub fn from_account_info(acc_info: &AccountInfo<'info>) -> Result> {
    -        Ok(Sysvar {
    -            info: acc_info.clone(),
    -            account: T::from_account_info(acc_info)?,
    -        })
    +        match T::from_account_info(acc_info) {
    +            Ok(val) => Ok(Sysvar {
    +                info: acc_info.clone(),
    +                account: val,
    +            }),
    +            Err(_) => Err(ErrorCode::AccountSysvarMismatch.into()),
    +        }
         }
     }
     
    diff --git a/lang/src/error.rs b/lang/src/error.rs
    index ce2b519e..60a4bb9d 100644
    --- a/lang/src/error.rs
    +++ b/lang/src/error.rs
    @@ -152,6 +152,9 @@ pub enum ErrorCode {
         /// 3014 - The given account is not the associated token account
         #[msg("The given account is not the associated token account")]
         AccountNotAssociatedTokenAccount,
    +    /// 3015 - The given public key does not match the required sysvar
    +    #[msg("The given public key does not match the required sysvar")]
    +    AccountSysvarMismatch,
     
         // State.
         /// 4000 - The given state account does not have the correct address
    diff --git a/lang/syn/Cargo.toml b/lang/syn/Cargo.toml
    index 4b0324e7..c0e20d17 100644
    --- a/lang/syn/Cargo.toml
    +++ b/lang/syn/Cargo.toml
    @@ -1,6 +1,6 @@
     [package]
     name = "anchor-syn"
    -version = "0.22.0"
    +version = "0.22.1"
     authors = ["Serum Foundation "]
     repository = "https://github.com/project-serum/anchor"
     license = "Apache-2.0"
    diff --git a/lang/syn/src/codegen/accounts/__client_accounts.rs b/lang/syn/src/codegen/accounts/__client_accounts.rs
    index 24079e51..343239d3 100644
    --- a/lang/syn/src/codegen/accounts/__client_accounts.rs
    +++ b/lang/syn/src/codegen/accounts/__client_accounts.rs
    @@ -22,7 +22,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::CompositeField(s) => {
                     let name = &s.ident;
                     let docs = if !s.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", s.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", s.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    @@ -41,7 +42,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::Field(f) => {
                     let name = &f.ident;
                     let docs = if !f.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", f.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", f.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    diff --git a/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs b/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    index 823647c7..86adeb97 100644
    --- a/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    +++ b/lang/syn/src/codegen/accounts/__cpi_client_accounts.rs
    @@ -23,7 +23,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::CompositeField(s) => {
                     let name = &s.ident;
                     let docs = if !s.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", s.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", s.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    @@ -42,7 +43,8 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream {
                 AccountField::Field(f) => {
                     let name = &f.ident;
                     let docs = if !f.docs.is_empty() {
    -                    proc_macro2::TokenStream::from_str(&format!("#[doc = \"{}\"]", f.docs)).unwrap()
    +                    proc_macro2::TokenStream::from_str(&format!("#[doc = r#\"{}\"#]", f.docs))
    +                        .unwrap()
                     } else {
                         quote!()
                     };
    diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs
    index fc9dc792..95afd3d1 100644
    --- a/lang/syn/src/codegen/accounts/constraints.rs
    +++ b/lang/syn/src/codegen/accounts/constraints.rs
    @@ -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.
    diff --git a/lang/syn/src/idl/file.rs b/lang/syn/src/idl/file.rs
    index 8dda95f2..7814c9cb 100644
    --- a/lang/syn/src/idl/file.rs
    +++ b/lang/syn/src/idl/file.rs
    @@ -353,7 +353,7 @@ fn parse_account_derives(ctx: &CrateContext) -> HashMap
         ctx.structs()
             .filter_map(|i_strct| {
                 for attr in &i_strct.attrs {
    -                if attr.tokens.to_string().contains(DERIVE_NAME) {
    +                if attr.path.is_ident("derive") && attr.tokens.to_string().contains(DERIVE_NAME) {
                         let strct = accounts::parse(i_strct).expect("Code not parseable");
                         return Some((strct.ident.to_string(), strct));
                     }
    diff --git a/lang/syn/src/lib.rs b/lang/syn/src/lib.rs
    index ca652f81..cf00ca23 100644
    --- a/lang/syn/src/lib.rs
    +++ b/lang/syn/src/lib.rs
    @@ -721,7 +721,7 @@ pub enum ConstraintRentExempt {
     pub struct ConstraintInitGroup {
         pub if_needed: bool,
         pub seeds: Option,
    -    pub payer: Option,
    +    pub payer: Expr,
         pub space: Option,
         pub kind: InitKind,
     }
    diff --git a/lang/syn/src/parser/accounts/constraints.rs b/lang/syn/src/parser/accounts/constraints.rs
    index 533d5053..42454fec 100644
    --- a/lang/syn/src/parser/accounts/constraints.rs
    +++ b/lang/syn/src/parser/accounts/constraints.rs
    @@ -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 {
    @@ -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 {
    diff --git a/lang/syn/src/parser/accounts/mod.rs b/lang/syn/src/parser/accounts/mod.rs
    index e375cbc1..b0178af5 100644
    --- a/lang/syn/src/parser/accounts/mod.rs
    +++ b/lang/syn/src/parser/accounts/mod.rs
    @@ -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(),
    diff --git a/spl/Cargo.toml b/spl/Cargo.toml
    index dd3c13e4..7afdc779 100644
    --- a/spl/Cargo.toml
    +++ b/spl/Cargo.toml
    @@ -1,6 +1,6 @@
     [package]
     name = "anchor-spl"
    -version = "0.22.0"
    +version = "0.22.1"
     authors = ["Serum Foundation "]
     edition = "2018"
     license = "Apache-2.0"
    @@ -17,7 +17,7 @@ devnet = []
     dex = ["serum_dex"]
     
     [dependencies]
    -anchor-lang = { path = "../lang", version = "0.22.0", features = ["derive"] }
    +anchor-lang = { path = "../lang", version = "0.22.1", features = ["derive"] }
     serum_dex = { git = "https://github.com/project-serum/serum-dex", rev = "1be91f2", version = "0.4.0", features = ["no-entrypoint"], optional = true }
     solana-program = "1.8.5"
     spl-token = { version = "3.1.1", features = ["no-entrypoint"], optional = true }
    diff --git a/spl/src/associated_token.rs b/spl/src/associated_token.rs
    index 4effe4d4..c46b09b8 100644
    --- a/spl/src/associated_token.rs
    +++ b/spl/src/associated_token.rs
    @@ -1,11 +1,11 @@
     use anchor_lang::solana_program::account_info::AccountInfo;
    -use anchor_lang::solana_program::entrypoint::ProgramResult;
     use anchor_lang::solana_program::pubkey::Pubkey;
    +use anchor_lang::Result;
     use anchor_lang::{context::CpiContext, Accounts};
     
     pub use spl_associated_token_account::{get_associated_token_address, ID};
     
    -pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> ProgramResult {
    +pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> Result<()> {
         let ix = spl_associated_token_account::create_associated_token_account(
             ctx.accounts.payer.key,
             ctx.accounts.authority.key,
    @@ -24,6 +24,7 @@ pub fn create<'info>(ctx: CpiContext<'_, '_, '_, 'info, Create<'info>>) -> Progr
             ],
             ctx.signer_seeds,
         )
    +    .map_err(Into::into)
     }
     
     #[derive(Accounts)]
    diff --git a/spl/src/token.rs b/spl/src/token.rs
    index 2ed7558a..669a195b 100644
    --- a/spl/src/token.rs
    +++ b/spl/src/token.rs
    @@ -104,6 +104,21 @@ pub fn approve<'a, 'b, 'c, 'info>(
         .map_err(Into::into)
     }
     
    +pub fn revoke<'a, 'b, 'c, 'info>(ctx: CpiContext<'a, 'b, 'c, 'info, Revoke<'info>>) -> Result<()> {
    +    let ix = spl_token::instruction::revoke(
    +        &spl_token::ID,
    +        ctx.accounts.source.key,
    +        ctx.accounts.authority.key,
    +        &[],
    +    )?;
    +    solana_program::program::invoke_signed(
    +        &ix,
    +        &[ctx.accounts.source.clone(), ctx.accounts.authority.clone()],
    +        ctx.signer_seeds,
    +    )
    +    .map_err(Into::into)
    +}
    +
     pub fn initialize_account<'a, 'b, 'c, 'info>(
         ctx: CpiContext<'a, 'b, 'c, 'info, InitializeAccount<'info>>,
     ) -> Result<()> {
    @@ -270,6 +285,12 @@ pub struct Approve<'info> {
         pub authority: AccountInfo<'info>,
     }
     
    +#[derive(Accounts)]
    +pub struct Revoke<'info> {
    +    pub source: AccountInfo<'info>,
    +    pub authority: AccountInfo<'info>,
    +}
    +
     #[derive(Accounts)]
     pub struct InitializeAccount<'info> {
         pub account: AccountInfo<'info>,
    diff --git a/tests/bpf-upgradeable-state/package.json b/tests/bpf-upgradeable-state/package.json
    index f20be7b5..8af10cab 100644
    --- a/tests/bpf-upgradeable-state/package.json
    +++ b/tests/bpf-upgradeable-state/package.json
    @@ -1,6 +1,6 @@
     {
         "dependencies": {
    -        "@project-serum/anchor": "^0.22.0"
    +        "@project-serum/anchor": "^0.22.1"
         },
         "devDependencies": {
             "chai": "^4.3.4",
    diff --git a/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs b/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    index 09087114..fca03bb7 100644
    --- a/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    +++ b/tests/bpf-upgradeable-state/programs/bpf-upgradeable-state/src/lib.rs
    @@ -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,
    @@ -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>,
    @@ -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>,
    diff --git a/tests/cashiers-check/package.json b/tests/cashiers-check/package.json
    index cbf96d98..1824909e 100644
    --- a/tests/cashiers-check/package.json
    +++ b/tests/cashiers-check/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "cashiers-check",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/cfo/package.json b/tests/cfo/package.json
    index 81c62016..e404069b 100644
    --- a/tests/cfo/package.json
    +++ b/tests/cfo/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "cfo",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/cfo/programs/cfo/src/lib.rs b/tests/cfo/programs/cfo/src/lib.rs
    index 99e759ad..480cb04e 100644
    --- a/tests/cfo/programs/cfo/src/lib.rs
    +++ b/tests/cfo/programs/cfo/src/lib.rs
    @@ -195,7 +195,7 @@ pub mod cfo {
             let expiry_ts = 1853942400; // 9/30/2028.
             let expiry_receiver = *ctx.accounts.officer.to_account_info().key;
             let locked_kind = {
    -            let start_ts = 1633017600; // 9/30.22.0.
    +            let start_ts = 1633017600; // 9/30.22.1.
                 let end_ts = 1822320000; // 9/30/2027.
                 let period_count = 2191;
                 RewardVendorKind::Locked {
    @@ -324,6 +324,7 @@ pub struct CreateOfficer<'info> {
             seeds = [dex_program.key.as_ref()],
             bump,
             payer = authority,
    +        space = Officer::LEN + 8
         )]
         officer: Box>,
         #[account(
    @@ -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(
    @@ -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(
    @@ -350,7 +351,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = srm_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         stake: Box>,
         #[account(
    @@ -359,7 +360,7 @@ pub struct CreateOfficer<'info> {
             bump,
             payer = authority,
             token::mint = srm_mint,
    -        token::authority = officer,
    +        token::authority = officer
         )]
         treasury: Box>,
         #[account(mut)]
    @@ -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)]
    @@ -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>,
    @@ -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
    @@ -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.
    diff --git a/tests/chat/package.json b/tests/chat/package.json
    index bbfb9c0e..f6da52bc 100644
    --- a/tests/chat/package.json
    +++ b/tests/chat/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "chat",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/composite/package.json b/tests/composite/package.json
    index 026ff5c7..3bf8d762 100644
    --- a/tests/composite/package.json
    +++ b/tests/composite/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "composite",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/declare-id/package.json b/tests/declare-id/package.json
    index 54659e92..b01c5f11 100644
    --- a/tests/declare-id/package.json
    +++ b/tests/declare-id/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "declare-id",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/docs/package.json b/tests/docs/package.json
    index 8be73d64..1b800b8e 100644
    --- a/tests/docs/package.json
    +++ b/tests/docs/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "errors",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/docs/programs/docs/src/lib.rs b/tests/docs/programs/docs/src/lib.rs
    index fbfe0fa8..710a2fe0 100644
    --- a/tests/docs/programs/docs/src/lib.rs
    +++ b/tests/docs/programs/docs/src/lib.rs
    @@ -24,6 +24,7 @@ pub struct Hello<'info> {
         pub rent: Sysvar<'info, Rent>,
         /// Composite accounts test.
         /// Multiple lines supported.
    +    /// You can also include "double quotes".
         pub other: HelloComposite<'info>,
     }
     
    diff --git a/tests/errors/package.json b/tests/errors/package.json
    index 8be73d64..1b800b8e 100644
    --- a/tests/errors/package.json
    +++ b/tests/errors/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "errors",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/escrow/package.json b/tests/escrow/package.json
    index 44d3f5cf..bbb644d2 100644
    --- a/tests/escrow/package.json
    +++ b/tests/escrow/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "escrow",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/events/package.json b/tests/events/package.json
    index bafd6d6e..eb7e8444 100644
    --- a/tests/events/package.json
    +++ b/tests/events/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "events",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/floats/package.json b/tests/floats/package.json
    index 38ba52f2..a9be4eac 100644
    --- a/tests/floats/package.json
    +++ b/tests/floats/package.json
    @@ -1,6 +1,6 @@
     {
         "name": "floats",
    -    "version": "0.22.0",
    +    "version": "0.22.1",
         "license": "(MIT OR Apache-2.0)",
         "homepage": "https://github.com/project-serum/anchor#readme",
         "bugs": {
    diff --git a/tests/ido-pool/package.json b/tests/ido-pool/package.json
    index da2ff3bc..80459804 100644
    --- a/tests/ido-pool/package.json
    +++ b/tests/ido-pool/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "ido-pool",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/ido-pool/programs/ido-pool/src/lib.rs b/tests/ido-pool/programs/ido-pool/src/lib.rs
    index 2a2abfb7..ca7b0320 100644
    --- a/tests/ido-pool/programs/ido-pool/src/lib.rs
    +++ b/tests/ido-pool/programs/ido-pool/src/lib.rs
    @@ -295,7 +295,9 @@ pub struct InitializePool<'info> {
         #[account(init,
             seeds = [ido_name.as_bytes()],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority,
    +        space = IdoAccount::LEN + 8
    +    )]
         pub ido_account: Box>,
         // TODO Confirm USDC mint address on mainnet or leave open as an option for other stables
         #[account(constraint = usdc_mint.decimals == DECIMALS)]
    @@ -305,7 +307,8 @@ pub struct InitializePool<'info> {
             mint::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"redeemable_mint".as_ref()],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub redeemable_mint: Box>,
         #[account(constraint = watermelon_mint.key() == ido_authority_watermelon.mint)]
         pub watermelon_mint: Box>,
    @@ -314,14 +317,16 @@ pub struct InitializePool<'info> {
             token::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"pool_watermelon"],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub pool_watermelon: Box>,
         #[account(init,
             token::mint = usdc_mint,
             token::authority = ido_account,
             seeds = [ido_name.as_bytes(), b"pool_usdc"],
             bump,
    -        payer = ido_authority)]
    +        payer = ido_authority
    +    )]
         pub pool_usdc: Box>,
         // Programs and Sysvars
         pub system_program: Program<'info, System>,
    @@ -341,7 +346,8 @@ pub struct InitUserRedeemable<'info> {
                 ido_account.ido_name.as_ref().trim_ascii_whitespace(),
                 b"user_redeemable"],
             bump,
    -        payer = user_authority)]
    +        payer = user_authority
    +    )]
         pub user_redeemable: Box>,
         // IDO Accounts
         #[account(seeds = [ido_account.ido_name.as_ref().trim_ascii_whitespace()],
    @@ -401,7 +407,8 @@ pub struct InitEscrowUsdc<'info> {
                 ido_account.ido_name.as_ref().trim_ascii_whitespace(),
                 b"escrow_usdc"],
             bump,
    -        payer = user_authority)]
    +        payer = user_authority
    +    )]
         pub escrow_usdc: Box>,
         #[account(seeds = [ido_account.ido_name.as_ref().trim_ascii_whitespace()],
             bump = ido_account.bumps.ido_account,
    @@ -541,36 +548,39 @@ pub struct WithdrawFromEscrow<'info> {
     }
     
     #[account]
    -#[derive(Default)]
     pub struct IdoAccount {
    -    pub ido_name: [u8; 10], // Setting an arbitrary max of ten characters in the ido name.
    -    pub bumps: PoolBumps,
    -    pub ido_authority: Pubkey,
    +    pub ido_name: [u8; 10], // Setting an arbitrary max of ten characters in the ido name. // 10
    +    pub bumps: PoolBumps,   // 4
    +    pub ido_authority: Pubkey, // 32
     
    -    pub usdc_mint: Pubkey,
    -    pub redeemable_mint: Pubkey,
    -    pub watermelon_mint: Pubkey,
    -    pub pool_usdc: Pubkey,
    -    pub pool_watermelon: Pubkey,
    +    pub usdc_mint: Pubkey,       // 32
    +    pub redeemable_mint: Pubkey, // 32
    +    pub watermelon_mint: Pubkey, // 32
    +    pub pool_usdc: Pubkey,       // 32
    +    pub pool_watermelon: Pubkey, // 32
     
    -    pub num_ido_tokens: u64,
    -    pub ido_times: IdoTimes,
    +    pub num_ido_tokens: u64, // 8
    +    pub ido_times: IdoTimes, // 32
    +}
    +
    +impl IdoAccount {
    +    pub const LEN: usize = 10 + 4 + 32 + 5 * 32 + 8 + 32;
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Default, Clone, Copy)]
     pub struct IdoTimes {
    -    pub start_ido: i64,
    -    pub end_deposits: i64,
    -    pub end_ido: i64,
    -    pub end_escrow: i64,
    +    pub start_ido: i64,    // 8
    +    pub end_deposits: i64, // 8
    +    pub end_ido: i64,      // 8
    +    pub end_escrow: i64,   // 8
     }
     
     #[derive(AnchorSerialize, AnchorDeserialize, Default, Clone)]
     pub struct PoolBumps {
    -    pub ido_account: u8,
    -    pub redeemable_mint: u8,
    -    pub pool_watermelon: u8,
    -    pub pool_usdc: u8,
    +    pub ido_account: u8,     // 1
    +    pub redeemable_mint: u8, // 1
    +    pub pool_watermelon: u8, // 1
    +    pub pool_usdc: u8,       // 1
     }
     
     #[error_code]
    diff --git a/tests/interface/package.json b/tests/interface/package.json
    index 25fb02e5..134ec602 100644
    --- a/tests/interface/package.json
    +++ b/tests/interface/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "interface",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/lockup/package.json b/tests/lockup/package.json
    index 0d99b402..2ef3a21d 100644
    --- a/tests/lockup/package.json
    +++ b/tests/lockup/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "lockup",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/misc/package.json b/tests/misc/package.json
    index ff25b4e2..db450e64 100644
    --- a/tests/misc/package.json
    +++ b/tests/misc/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "misc",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/misc/programs/misc/src/account.rs b/tests/misc/programs/misc/src/account.rs
    index b94e1fdc..4a5fc13c 100644
    --- a/tests/misc/programs/misc/src/account.rs
    +++ b/tests/misc/programs/misc/src/account.rs
    @@ -1,50 +1,63 @@
     use anchor_lang::prelude::*;
     
    +macro_rules! size {
    +    ($name: ident, $size:expr) => {
    +        impl $name {
    +            pub const LEN: usize = $size;
    +        }
    +    };
    +}
    +
     pub const MAX_SIZE: usize = 10;
     
     #[account]
     pub struct Data {
    -    pub udata: u128,
    -    pub idata: i128,
    +    pub udata: u128, // 16
    +    pub idata: i128, // 16
     }
    +size!(Data, 32);
     
     #[account]
    -#[derive(Default)]
     pub struct DataU16 {
    -    pub data: u16,
    +    pub data: u16, // 2
     }
    +size!(DataU16, 32);
     
     #[account]
    -#[derive(Default)]
     pub struct DataI8 {
    -    pub data: i8,
    +    pub data: i8, // 1
     }
    +size!(DataI8, 1);
     
     #[account]
     pub struct DataI16 {
    -    pub data: i16,
    +    pub data: i16, // 2
     }
    +size!(DataI16, 2);
     
     #[account(zero_copy)]
    -#[derive(Default)]
     pub struct DataZeroCopy {
    -    pub data: u16,
    -    pub bump: u8,
    +    pub data: u16,    // 2
    +    pub _padding: u8, // 1
    +    pub bump: u8,     // 1
     }
    +size!(DataZeroCopy, 4);
     
     #[account]
    -#[derive(Default)]
     pub struct DataWithFilter {
    -    pub authority: Pubkey,
    -    pub filterable: Pubkey,
    +    pub authority: Pubkey,  // 32
    +    pub filterable: Pubkey, // 32
     }
    +size!(DataWithFilter, 64);
     
     #[account]
     pub struct DataMultidimensionalArray {
    -    pub data: [[u8; 10]; 10],
    +    pub data: [[u8; 10]; 10], // 100
     }
    +size!(DataMultidimensionalArray, 100);
     
     #[account]
     pub struct DataConstArraySize {
    -    pub data: [u8; MAX_SIZE],
    +    pub data: [u8; MAX_SIZE], // 10
     }
    +size!(DataConstArraySize, MAX_SIZE);
    diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs
    index cda496cb..e34c6c71 100644
    --- a/tests/misc/programs/misc/src/context.rs
    +++ b/tests/misc/programs/misc/src/context.rs
    @@ -16,15 +16,17 @@ pub struct TestTokenSeedsInit<'info> {
             payer = authority,
             mint::decimals = 6,
             mint::authority = authority,
    +        
         )]
         pub mint: Account<'info, Mint>,
         #[account(
             init,
    -        seeds = [b"my-token-seed".as_ref(),],
    +        seeds = [b"my-token-seed".as_ref()],
             bump,
             payer = authority,
             token::mint = mint,
             token::authority = authority,
    +        
         )]
         pub my_pda: Account<'info, TokenAccount>,
         #[account(mut)]
    @@ -42,6 +44,7 @@ pub struct TestInitAssociatedToken<'info> {
             payer = payer,
             associated_token::mint = mint,
             associated_token::authority = payer,
    +        
         )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
    @@ -86,6 +89,7 @@ pub struct TestPdaInit<'info> {
             seeds = [b"my-seed", domain.as_bytes(), foo.key.as_ref(), &seed],
             bump,
             payer = my_payer,
    +        space = DataU16::LEN + 8
         )]
         pub my_pda: Account<'info, DataU16>,
         #[account(mut)]
    @@ -102,8 +106,9 @@ pub struct TestPdaInitZeroCopy<'info> {
             seeds = [b"my-seed".as_ref()],
             bump,
             payer = my_payer,
    +        space = DataZeroCopy::LEN + 8
         )]
    -    pub my_pda: Loader<'info, DataZeroCopy>,
    +    pub my_pda: AccountLoader<'info, DataZeroCopy>,
         #[account(mut)]
         pub my_payer: Signer<'info>,
         pub system_program: Program<'info, System>,
    @@ -116,7 +121,7 @@ pub struct TestPdaMutZeroCopy<'info> {
             seeds = [b"my-seed".as_ref()],
             bump = my_pda.load()?.bump,
         )]
    -    pub my_pda: Loader<'info, DataZeroCopy>,
    +    pub my_pda: AccountLoader<'info, DataZeroCopy>,
         /// CHECK:
         pub my_payer: AccountInfo<'info>,
     }
    @@ -204,7 +209,7 @@ pub struct TestI8<'info> {
     
     #[derive(Accounts)]
     pub struct TestInit<'info> {
    -    #[account(init, payer = payer)]
    +    #[account(init, payer = payer, space = DataI8::LEN + 8)]
         pub data: Account<'info, DataI8>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -213,7 +218,7 @@ pub struct TestInit<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitZeroCopy<'info> {
    -    #[account(init, payer = payer, space = 8 + size_of::())]
    +    #[account(init, payer = payer, space = DataZeroCopy::LEN + 8)]
         pub data: Loader<'info, DataZeroCopy>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -222,7 +227,7 @@ pub struct TestInitZeroCopy<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitMint<'info> {
    -    #[account(init, mint::decimals = 6, mint::authority = payer, mint::freeze_authority = payer, payer = payer)]
    +    #[account(init, mint::decimals = 6, mint::authority = payer, mint::freeze_authority = payer, payer = payer, )]
         pub mint: Account<'info, Mint>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -233,7 +238,7 @@ pub struct TestInitMint<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitToken<'info> {
    -    #[account(init, token::mint = mint, token::authority = payer, payer = payer)]
    +    #[account(init, token::mint = mint, token::authority = payer, payer = payer, )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
         #[account(mut)]
    @@ -246,14 +251,14 @@ pub struct TestInitToken<'info> {
     #[derive(Accounts)]
     pub struct TestCompositePayer<'info> {
         pub composite: TestInit<'info>,
    -    #[account(init, payer = composite.payer, space = 8 + size_of::())]
    +    #[account(init, payer = composite.payer, space = Data::LEN + 8)]
         pub data: Account<'info, Data>,
         pub system_program: Program<'info, System>,
     }
     
     #[derive(Accounts)]
     pub struct TestFetchAll<'info> {
    -    #[account(init, payer = authority)]
    +    #[account(init, payer = authority, space = DataWithFilter::LEN + 8)]
         pub data: Account<'info, DataWithFilter>,
         #[account(mut)]
         pub authority: Signer<'info>,
    @@ -262,7 +267,7 @@ pub struct TestFetchAll<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitWithEmptySeeds<'info> {
    -    #[account(init, seeds = [], bump, payer = authority, space = 8 + size_of::())]
    +    #[account(init, seeds = [], bump, payer = authority, space = Data::LEN + 8)]
         pub pda: Account<'info, Data>,
         #[account(mut)]
         pub authority: Signer<'info>,
    @@ -278,7 +283,7 @@ pub struct TestEmptySeedsConstraint<'info> {
     
     #[derive(Accounts)]
     pub struct InitWithSpace<'info> {
    -    #[account(init, payer = payer)]
    +    #[account(init, payer = payer, space = DataU16::LEN + 8)]
         pub data: Account<'info, DataU16>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -287,7 +292,8 @@ pub struct InitWithSpace<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitIfNeeded<'info> {
    -    #[account(init_if_needed, payer = payer, space = 500)]
    +    // intentionally using more space (+500) to check whether space is checked when using init_if_needed
    +    #[account(init_if_needed, payer = payer, space = DataU16::LEN + 8 + 500)]
         pub data: Account<'info, DataU16>,
         #[account(mut)]
         pub payer: Signer<'info>,
    @@ -335,7 +341,7 @@ pub struct TestInitMintIfNeeded<'info> {
     
     #[derive(Accounts)]
     pub struct TestInitTokenIfNeeded<'info> {
    -    #[account(init_if_needed, token::mint = mint, token::authority = authority, payer = payer)]
    +    #[account(init_if_needed, token::mint = mint, token::authority = authority, payer = payer, )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
         #[account(mut)]
    @@ -353,7 +359,7 @@ pub struct TestInitAssociatedTokenIfNeeded<'info> {
             init_if_needed,
             payer = payer,
             associated_token::mint = mint,
    -        associated_token::authority = authority,
    +        associated_token::authority = authority
         )]
         pub token: Account<'info, TokenAccount>,
         pub mint: Account<'info, Mint>,
    diff --git a/tests/misc/tests/misc.js b/tests/misc/tests/misc.js
    index fc1b7983..3e6cd982 100644
    --- a/tests/misc/tests/misc.js
    +++ b/tests/misc/tests/misc.js
    @@ -1002,7 +1002,8 @@ describe("misc", () => {
     
       it("init_if_needed throws if account exists but is not the expected space", async () => {
         const newAcc = anchor.web3.Keypair.generate();
    -    await program.rpc.initWithSpace(3, {
    +    const _irrelevantForTest = 3;
    +    await program.rpc.initWithSpace(_irrelevantForTest, {
           accounts: {
             data: newAcc.publicKey,
             systemProgram: anchor.web3.SystemProgram.programId,
    @@ -1012,7 +1013,7 @@ describe("misc", () => {
         });
     
         try {
    -      await program.rpc.testInitIfNeeded(3, {
    +      await program.rpc.testInitIfNeeded(_irrelevantForTest, {
             accounts: {
               data: newAcc.publicKey,
               systemProgram: anchor.web3.SystemProgram.programId,
    diff --git a/tests/multisig/package.json b/tests/multisig/package.json
    index 4cc2b97c..f7a64a3f 100644
    --- a/tests/multisig/package.json
    +++ b/tests/multisig/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "multisig",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/package.json b/tests/package.json
    index a31b05b4..568c0bb2 100644
    --- a/tests/package.json
    +++ b/tests/package.json
    @@ -33,7 +33,7 @@
         "declare-id"
       ],
       "dependencies": {
    -    "@project-serum/anchor": "^0.22.0",
    +    "@project-serum/anchor": "^0.22.1",
         "@project-serum/common": "^0.0.1-beta.3",
         "@project-serum/serum": "^0.13.60",
         "@solana/spl-token": "^0.1.8"
    diff --git a/tests/pda-derivation/package.json b/tests/pda-derivation/package.json
    index b4558ec2..12dfc09c 100644
    --- a/tests/pda-derivation/package.json
    +++ b/tests/pda-derivation/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "pda-derivation",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/pyth/package.json b/tests/pyth/package.json
    index 9631a374..1f608ec2 100644
    --- a/tests/pyth/package.json
    +++ b/tests/pyth/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "pyth",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/safety-checks/programs/account-info/Cargo.toml b/tests/safety-checks/programs/account-info/Cargo.toml
    index 56dd899b..d0a91cef 100644
    --- a/tests/safety-checks/programs/account-info/Cargo.toml
    +++ b/tests/safety-checks/programs/account-info/Cargo.toml
    @@ -16,4 +16,4 @@ cpi = ["no-entrypoint"]
     default = []
     
     [dependencies]
    -anchor-lang = "0.22.0"
    +anchor-lang = "0.22.1"
    diff --git a/tests/spl/token-proxy/package.json b/tests/spl/token-proxy/package.json
    index 1493484c..4957a6a0 100644
    --- a/tests/spl/token-proxy/package.json
    +++ b/tests/spl/token-proxy/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "token-proxy",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/swap/package.json b/tests/swap/package.json
    index a9f43c5a..c9de50c4 100644
    --- a/tests/swap/package.json
    +++ b/tests/swap/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "swap",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/system-accounts/package.json b/tests/system-accounts/package.json
    index a9d4a5df..9b889d72 100644
    --- a/tests/system-accounts/package.json
    +++ b/tests/system-accounts/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "system-accounts",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/sysvars/package.json b/tests/sysvars/package.json
    index 0892a899..c8303948 100644
    --- a/tests/sysvars/package.json
    +++ b/tests/sysvars/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "sysvars",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/sysvars/tests/sysvars.js b/tests/sysvars/tests/sysvars.js
    index a0c021fd..b350472c 100644
    --- a/tests/sysvars/tests/sysvars.js
    +++ b/tests/sysvars/tests/sysvars.js
    @@ -1,18 +1,39 @@
     const anchor = require("@project-serum/anchor");
    +const assert = require("assert");
     
     describe("sysvars", () => {
       // Configure the client to use the local cluster.
       anchor.setProvider(anchor.Provider.local());
    +  const program = anchor.workspace.Sysvars;
     
       it("Is initialized!", async () => {
    -    const program = anchor.workspace.Sysvars;
    -    const tx = await program.rpc.sysvars({
    -      accounts: {
    +    const tx = await program.methods
    +      .sysvars()
    +      .accounts({
             clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
             rent: anchor.web3.SYSVAR_RENT_PUBKEY,
             stakeHistory: anchor.web3.SYSVAR_STAKE_HISTORY_PUBKEY,
    -      },
    -    });
    +      })
    +      .rpc();
         console.log("Your transaction signature", tx);
       });
    +
    +  it("Fails when the wrote pubkeys are provided", async () => {
    +    try {
    +      await program.methods
    +        .sysvars()
    +        .accounts({
    +          clock: anchor.web3.SYSVAR_CLOCK_PUBKEY,
    +          rent: anchor.web3.SYSVAR_RENT_PUBKEY,
    +          stakeHistory: anchor.web3.SYSVAR_REWARDS_PUBKEY,
    +        })
    +        .rpc();
    +      assert.ok(false);
    +    } catch (err) {
    +      const errMsg = "The given public key does not match the required sysvar";
    +      assert.strictEqual(err.toString(), errMsg);
    +      assert.strictEqual(err.msg, errMsg);
    +      assert.strictEqual(err.code, 3015);
    +    }
    +  });
     });
    diff --git a/tests/tictactoe/package.json b/tests/tictactoe/package.json
    index 2ac71d44..632d97bb 100644
    --- a/tests/tictactoe/package.json
    +++ b/tests/tictactoe/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "tictactoe",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/typescript/package.json b/tests/typescript/package.json
    index b3559539..3e37ccfb 100644
    --- a/tests/typescript/package.json
    +++ b/tests/typescript/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "typescript-example",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/zero-copy/package.json b/tests/zero-copy/package.json
    index 81c2c320..2568b8a3 100644
    --- a/tests/zero-copy/package.json
    +++ b/tests/zero-copy/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "zero-copy",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "license": "(MIT OR Apache-2.0)",
       "homepage": "https://github.com/project-serum/anchor#readme",
       "bugs": {
    diff --git a/tests/zero-copy/programs/zero-copy/src/lib.rs b/tests/zero-copy/programs/zero-copy/src/lib.rs
    index 58b1beb6..c6076ea9 100644
    --- a/tests/zero-copy/programs/zero-copy/src/lib.rs
    +++ b/tests/zero-copy/programs/zero-copy/src/lib.rs
    @@ -97,7 +97,8 @@ pub struct CreateBar<'info> {
             init,
             seeds = [authority.key().as_ref(), foo.key().as_ref()],
             bump,
    -        payer = authority, owner = *program_id
    +        payer = authority, owner = *program_id,
    +        space = Bar::LEN + 8
         )]
         bar: AccountLoader<'info, Bar>,
         #[account(mut)]
    @@ -132,8 +133,8 @@ pub struct UpdateLargeAccount<'info> {
     }
     
     #[account(zero_copy)]
    -#[derive(Default)]
     #[repr(packed)]
    +#[derive(Default)]
     pub struct Foo {
         pub authority: Pubkey,
         pub data: u64,
    @@ -143,10 +144,13 @@ pub struct Foo {
     }
     
     #[account(zero_copy)]
    -#[derive(Default)]
     pub struct Bar {
    -    pub authority: Pubkey,
    -    pub data: u64,
    +    pub authority: Pubkey, // 32
    +    pub data: u64,         // 8
    +}
    +
    +impl Bar {
    +    pub const LEN: usize = 32 + 8;
     }
     
     #[account(zero_copy)]
    diff --git a/ts/package.json b/ts/package.json
    index 9622e394..d380d0f7 100644
    --- a/ts/package.json
    +++ b/ts/package.json
    @@ -1,6 +1,6 @@
     {
       "name": "@project-serum/anchor",
    -  "version": "0.22.0",
    +  "version": "0.22.1",
       "description": "Anchor client",
       "module": "./dist/esm/index.js",
       "main": "./dist/cjs/index.js",
    diff --git a/ts/src/coder/borsh/instruction.ts b/ts/src/coder/borsh/instruction.ts
    index 224ef193..bcb152b6 100644
    --- a/ts/src/coder/borsh/instruction.ts
    +++ b/ts/src/coder/borsh/instruction.ts
    @@ -269,7 +269,8 @@ class InstructionFormatter {
             ? "null"
             : this.formatIdlData(
                 { name: "", type: (idlField.type).option },
    -            data
    +            data,
    +            types
               );
         }
         if (idlField.type.hasOwnProperty("defined")) {
    diff --git a/ts/src/error.ts b/ts/src/error.ts
    index a5084412..03ae9be1 100644
    --- a/ts/src/error.ts
    +++ b/ts/src/error.ts
    @@ -111,6 +111,7 @@ const LangErrorCode = {
       AccountNotInitialized: 3012,
       AccountNotProgramData: 3013,
       AccountNotAssociatedTokenAccount: 3014,
    +  AccountSysvarMismatch: 3015,
       // State.
       StateInvalidAddress: 4000,
     
    @@ -227,6 +228,10 @@ const LangErrorMessage = new Map([
         LangErrorCode.AccountNotAssociatedTokenAccount,
         "The given account is not the associated token account",
       ],
    +  [
    +    LangErrorCode.AccountSysvarMismatch,
    +    "The given public key does not match the required sysvar",
    +  ],
     
       // State.
       [
    diff --git a/ts/src/program/accounts-resolver.ts b/ts/src/program/accounts-resolver.ts
    index 758d54a3..a2bc005b 100644
    --- a/ts/src/program/accounts-resolver.ts
    +++ b/ts/src/program/accounts-resolver.ts
    @@ -10,6 +10,13 @@ import { coder } from "../spl/token";
     
     // Populates a given accounts context with PDAs and common missing accounts.
     export class AccountsResolver> {
    +  static readonly CONST_ACCOUNTS = {
    +    systemProgram: SystemProgram.programId,
    +    tokenProgram: TOKEN_PROGRAM_ID,
    +    associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
    +    rent: SYSVAR_RENT_PUBKEY,
    +  };
    +
       private _accountStore: AccountStore;
     
       constructor(
    @@ -40,40 +47,28 @@ export class AccountsResolver> {
           const accountDescName = camelCase(accountDesc.name);
     
           // PDA derived from IDL seeds.
    -      if (accountDesc.pda && accountDesc.pda.seeds.length > 0) {
    -        if (this._accounts[accountDescName] === undefined) {
    -          await this.autoPopulatePda(accountDesc);
    -          continue;
    -        }
    +      if (
    +        accountDesc.pda &&
    +        accountDesc.pda.seeds.length > 0 &&
    +        !this._accounts[accountDescName]
    +      ) {
    +        await this.autoPopulatePda(accountDesc);
    +        continue;
           }
     
           // Signers default to the provider.
    -      if (
    -        accountDesc.isSigner &&
    -        this._accounts[accountDescName] === undefined
    -      ) {
    +      if (accountDesc.isSigner && !this._accounts[accountDescName]) {
             this._accounts[accountDescName] = this._provider.wallet.publicKey;
             continue;
           }
     
           // Common accounts are auto populated with magic names by convention.
    -      switch (accountDescName) {
    -        case "systemProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = SystemProgram.programId;
    -          }
    -        case "rent":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = SYSVAR_RENT_PUBKEY;
    -          }
    -        case "tokenProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = TOKEN_PROGRAM_ID;
    -          }
    -        case "associatedTokenProgram":
    -          if (this._accounts[accountDescName] === undefined) {
    -            this._accounts[accountDescName] = ASSOCIATED_PROGRAM_ID;
    -          }
    +      if (
    +        Reflect.has(AccountsResolver.CONST_ACCOUNTS, accountDescName) &&
    +        !this._accounts[accountDescName]
    +      ) {
    +        this._accounts[accountDescName] =
    +          AccountsResolver.CONST_ACCOUNTS[accountDescName];
           }
         }
       }
    @@ -234,7 +229,7 @@ export class AccountStore {
         publicKey: PublicKey
       ): Promise {
         const address = publicKey.toString();
    -    if (this._cache.get(address) === undefined) {
    +    if (!this._cache.has(address)) {
           if (name === "TokenAccount") {
             const accountInfo = await this._provider.connection.getAccountInfo(
               publicKey
    diff --git a/ts/src/program/index.ts b/ts/src/program/index.ts
    index 7971fa39..04c6bca0 100644
    --- a/ts/src/program/index.ts
    +++ b/ts/src/program/index.ts
    @@ -77,6 +77,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly rpc: RpcNamespace;
     
    @@ -130,6 +131,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly instruction: InstructionNamespace;
     
    @@ -161,6 +163,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly transaction: TransactionNamespace;
     
    @@ -197,6 +200,7 @@ export class Program {
        *   },
        * });
        * ```
    +   * @deprecated
        */
       readonly simulate: SimulateNamespace;
     
    diff --git a/ts/src/program/namespace/index.ts b/ts/src/program/namespace/index.ts
    index f7e994df..e84695cf 100644
    --- a/ts/src/program/namespace/index.ts
    +++ b/ts/src/program/namespace/index.ts
    @@ -10,7 +10,6 @@ import RpcFactory, { RpcNamespace } from "./rpc.js";
     import AccountFactory, { AccountNamespace } from "./account.js";
     import SimulateFactory, { SimulateNamespace } from "./simulate.js";
     import { parseIdlErrors } from "../common.js";
    -import { AllInstructions } from "./types.js";
     import { MethodsBuilderFactory, MethodsNamespace } from "./methods";
     
     // Re-exports.
    @@ -55,8 +54,8 @@ export default class NamespaceFactory {
     
         const state = StateFactory.build(idl, coder, programId, provider);
     
    -    idl.instructions.forEach(>(idlIx: I) => {
    -      const ixItem = InstructionFactory.build(
    +    idl.instructions.forEach((idlIx) => {
    +      const ixItem = InstructionFactory.build(
             idlIx,
             (ixName, ix) => coder.instruction.encode(ixName, ix),
             programId
    @@ -72,7 +71,7 @@ export default class NamespaceFactory {
             programId,
             idl
           );
    -      const methodItem = MethodsBuilderFactory.build(
    +      const methodItem = MethodsBuilderFactory.build(
             provider,
             programId,
             idlIx,
    diff --git a/ts/src/program/namespace/methods.ts b/ts/src/program/namespace/methods.ts
    index bf28812a..d55bddee 100644
    --- a/ts/src/program/namespace/methods.ts
    +++ b/ts/src/program/namespace/methods.ts
    @@ -17,6 +17,7 @@ import { SimulateFn } from "./simulate.js";
     import Provider from "../../provider.js";
     import { AccountNamespace } from "./account.js";
     import { AccountsResolver } from "../accounts-resolver.js";
    +import { Accounts } from "../context.js";
     
     export type MethodsNamespace<
       IDL extends Idl = Idl,
    @@ -33,9 +34,9 @@ export class MethodsBuilderFactory {
         rpcFn: RpcFn,
         simulateFn: SimulateFn,
         accountNamespace: AccountNamespace
    -  ): MethodsFn {
    -    const request: MethodsFn = (...args) => {
    -      return new MethodsBuilder(
    +  ): MethodsFn> {
    +    return (...args) =>
    +      new MethodsBuilder(
             args,
             ixFn,
             txFn,
    @@ -46,13 +47,11 @@ export class MethodsBuilderFactory {
             idlIx,
             accountNamespace
           );
    -    };
    -    return request;
       }
     }
     
     export class MethodsBuilder> {
    -  readonly _accounts: { [name: string]: PublicKey } = {};
    +  private readonly _accounts: { [name: string]: PublicKey } = {};
       private _remainingAccounts: Array = [];
       private _signers: Array = [];
       private _preInstructions: Array = [];
    @@ -80,8 +79,9 @@ export class MethodsBuilder> {
         );
       }
     
    -  // TODO: don't use any.
    -  public accounts(accounts: any): MethodsBuilder {
    +  public accounts(
    +    accounts: Partial>
    +  ): MethodsBuilder {
         Object.assign(this._accounts, accounts);
         return this;
       }
    @@ -112,7 +112,7 @@ export class MethodsBuilder> {
         return this;
       }
     
    -  public async rpc(options: ConfirmOptions): Promise {
    +  public async rpc(options?: ConfirmOptions): Promise {
         await this._accountsResolver.resolve();
         // @ts-ignore
         return this._rpcFn(...this._args, {
    @@ -126,7 +126,7 @@ export class MethodsBuilder> {
       }
     
       public async simulate(
    -    options: ConfirmOptions
    +    options?: ConfirmOptions
       ): Promise> {
         await this._accountsResolver.resolve();
         // @ts-ignore
    diff --git a/ts/src/program/namespace/types.ts b/ts/src/program/namespace/types.ts
    index 1fe703a6..337adde6 100644
    --- a/ts/src/program/namespace/types.ts
    +++ b/ts/src/program/namespace/types.ts
    @@ -10,6 +10,7 @@ import {
       IdlTypeDefTyStruct,
     } from "../../idl";
     import { Accounts, Context } from "../context";
    +import { MethodsBuilder } from "./methods";
     
     /**
      * All instructions for an IDL.
    @@ -66,7 +67,11 @@ export type MakeInstructionsNamespace<
     };
     
     export type MakeMethodsNamespace = {
    -  [M in keyof InstructionMap]: MethodsFn[M], any>;
    +  [M in keyof InstructionMap]: MethodsFn<
    +    IDL,
    +    InstructionMap[M],
    +    MethodsBuilder[M]>
    +  >;
     };
     
     export type InstructionContextFn<