From 5910dd3e2f72b8241e3f0573849d1eb0f7ef0ca0 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Mon, 24 Apr 2023 10:33:11 +0200 Subject: [PATCH 01/11] Add benchmarking for compute units usage (#2466) --- .github/workflows/reusable-tests.yaml | 2 + CHANGELOG.md | 3 + bench/COMPUTE_UNITS.md | 200 ++++ tests/bench/Anchor.toml | 15 + tests/bench/Cargo.toml | 4 + tests/bench/README.md | 27 + tests/bench/bench.json | 184 ++++ tests/bench/package.json | 19 + tests/bench/programs/bench/Cargo.toml | 16 + tests/bench/programs/bench/Xargo.toml | 2 + tests/bench/programs/bench/src/lib.rs | 1212 +++++++++++++++++++++++++ tests/bench/scripts/bump-version.ts | 25 + tests/bench/scripts/generate-ix.ts | 225 +++++ tests/bench/scripts/update-bench.ts | 67 ++ tests/bench/scripts/utils.ts | 298 ++++++ tests/bench/tests/compute-units.ts | 248 +++++ tests/bench/tsconfig.json | 12 + tests/package.json | 1 + version-bump.sh | 22 +- 19 files changed, 2575 insertions(+), 7 deletions(-) create mode 100644 bench/COMPUTE_UNITS.md create mode 100644 tests/bench/Anchor.toml create mode 100644 tests/bench/Cargo.toml create mode 100644 tests/bench/README.md create mode 100644 tests/bench/bench.json create mode 100644 tests/bench/package.json create mode 100644 tests/bench/programs/bench/Cargo.toml create mode 100644 tests/bench/programs/bench/Xargo.toml create mode 100644 tests/bench/programs/bench/src/lib.rs create mode 100644 tests/bench/scripts/bump-version.ts create mode 100644 tests/bench/scripts/generate-ix.ts create mode 100644 tests/bench/scripts/update-bench.ts create mode 100644 tests/bench/scripts/utils.ts create mode 100644 tests/bench/tests/compute-units.ts create mode 100644 tests/bench/tsconfig.json diff --git a/.github/workflows/reusable-tests.yaml b/.github/workflows/reusable-tests.yaml index 76fdd576a7..e69c38a7da 100644 --- a/.github/workflows/reusable-tests.yaml +++ b/.github/workflows/reusable-tests.yaml @@ -437,6 +437,8 @@ jobs: path: tests/anchor-cli-idl - cmd: cd tests/anchor-cli-account && anchor test --skip-lint path: tests/anchor-cli-account + - cmd: cd tests/bench && anchor test --skip-lint + path: tests/bench steps: - uses: actions/checkout@v3 - uses: ./.github/actions/setup/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 546ce3fd5f..10e4703c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,15 @@ The minor version will be incremented upon a breaking change and the patch versi - spl: Add metadata wrappers `approve_collection_authority`, `bubblegum_set_collection_size`, `burn_edition_nft`, `burn_nft`, `revoke_collection_authority`, `set_token_standard`, `utilize`, `unverify_sized_collection_item`, `unverify_collection` ([#2430](https://github.com/coral-xyz/anchor/pull/2430)) - spl: Add `token_program` constraint to `Token`, `Mint`, and `AssociatedToken` accounts in order to override required `token_program` fields and use different token interface implementations in the same instruction ([#2460](https://github.com/coral-xyz/anchor/pull/2460)) - cli: Add support for Solidity programs. `anchor init` and `anchor new` take an option `--solidity` which creates solidity code rather than rust. `anchor build` and `anchor test` work accordingly ([#2421](https://github.com/coral-xyz/anchor/pull/2421)) +- bench: Add benchmarking for compute units usage ([#2466](https://github.com/coral-xyz/anchor/pull/2466)) ### Fixes + - ts: Narrowed `AccountClient` type to it's appropriate account type ([#2440](https://github.com/coral-xyz/anchor/pull/2440)) - lang: Fix inability to use identifiers `program_id`, `accounts`, `ix_data`, `remaining_accounts` in instruction arguments ([#2464](https://github.com/coral-xyz/anchor/pull/2464)) ### Breaking + - lang: Identifiers that are intended for internal usage(`program_id`, `accounts`, `ix_data`, `remaining_accounts`) have been renamed with `__` prefix ([#2464](https://github.com/coral-xyz/anchor/pull/2464)) ## [0.27.0] - 2023-03-08 diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md new file mode 100644 index 0000000000..0e68f3a312 --- /dev/null +++ b/bench/COMPUTE_UNITS.md @@ -0,0 +1,200 @@ +# Compute Units + +All notable changes in compute units usage will be documented in this file. + +The changes are calculated by comparing the current results with the last version's results. Increase in usage is shown with 🔴 and decrease is shown with 🟢. + +The programs and their tests are located in [/tests/bench](https://github.com/coral-xyz/anchor/tree/master/tests/bench). + +> **Note** +> The results documented in this file are autogenerated. Running the tests will update the current results when necessary, manually editing the results should be avoided. + +## [Unreleased] + +| Instruction | Compute Units | +/- | +| --------------------------- | ------------- | --- | +| accountInfo1 | 954 | - | +| accountInfo2 | 1567 | - | +| accountInfo4 | 2059 | - | +| accountInfo8 | 3856 | - | +| accountEmptyInit1 | 5958 | - | +| accountEmpty1 | 1090 | - | +| accountEmptyInit2 | 10583 | - | +| accountEmpty2 | 1852 | - | +| accountEmptyInit4 | 19557 | - | +| accountEmpty4 | 2646 | - | +| accountEmptyInit8 | 37541 | - | +| accountEmpty8 | 5043 | - | +| accountSizedInit1 | 6063 | - | +| accountSized1 | 1135 | - | +| accountSizedInit2 | 10783 | - | +| accountSized2 | 1966 | - | +| accountSizedInit4 | 19975 | - | +| accountSized4 | 2787 | - | +| accountSizedInit8 | 38381 | - | +| accountSized8 | 5359 | - | +| accountUnsizedInit1 | 6193 | - | +| accountUnsized1 | 1243 | - | +| accountUnsizedInit2 | 11042 | - | +| accountUnsized2 | 1893 | - | +| accountUnsizedInit4 | 20495 | - | +| accountUnsized4 | 3104 | - | +| accountUnsizedInit8 | 39419 | - | +| accountUnsized8 | 6051 | - | +| boxedAccountEmptyInit1 | 6160 | - | +| boxedAccountEmpty1 | 976 | - | +| boxedAccountEmptyInit2 | 10784 | - | +| boxedAccountEmpty2 | 1499 | - | +| boxedAccountEmptyInit4 | 19500 | - | +| boxedAccountEmpty4 | 2530 | - | +| boxedAccountEmptyInit8 | 37415 | - | +| boxedAccountEmpty8 | 4780 | - | +| boxedAccountSizedInit1 | 6256 | - | +| boxedAccountSized1 | 1003 | - | +| boxedAccountSizedInit2 | 10975 | - | +| boxedAccountSized2 | 1554 | - | +| boxedAccountSizedInit4 | 19884 | - | +| boxedAccountSized4 | 2642 | - | +| boxedAccountSizedInit8 | 38182 | - | +| boxedAccountSized8 | 5003 | - | +| boxedAccountUnsizedInit1 | 6374 | - | +| boxedAccountUnsized1 | 1069 | - | +| boxedAccountUnsizedInit2 | 11211 | - | +| boxedAccountUnsized2 | 1679 | - | +| boxedAccountUnsizedInit4 | 20351 | - | +| boxedAccountUnsized4 | 2899 | - | +| boxedAccountUnsizedInit8 | 39118 | - | +| boxedAccountUnsized8 | 5517 | - | +| boxedInterfaceAccountMint1 | 2299 | - | +| boxedInterfaceAccountMint2 | 4053 | - | +| boxedInterfaceAccountMint4 | 7538 | - | +| boxedInterfaceAccountMint8 | 14699 | - | +| boxedInterfaceAccountToken1 | 1737 | - | +| boxedInterfaceAccountToken2 | 2928 | - | +| boxedInterfaceAccountToken4 | 5291 | - | +| boxedInterfaceAccountToken8 | 10205 | - | +| interfaceAccountMint1 | 2530 | - | +| interfaceAccountMint2 | 4726 | - | +| interfaceAccountMint4 | 9431 | - | +| interfaceAccountMint8 | 17709 | - | +| interfaceAccountToken1 | 1755 | - | +| interfaceAccountToken2 | 3211 | - | +| interfaceAccountToken4 | 6006 | - | +| interface1 | 999 | - | +| interface2 | 1574 | - | +| interface4 | 1996 | - | +| interface8 | 3651 | - | +| program1 | 999 | - | +| program2 | 1573 | - | +| program4 | 1998 | - | +| program8 | 3651 | - | +| signer1 | 958 | - | +| signer2 | 1576 | - | +| signer4 | 2079 | - | +| signer8 | 3895 | - | +| systemAccount1 | 1013 | - | +| systemAccount2 | 1686 | - | +| systemAccount4 | 2298 | - | +| systemAccount8 | 4336 | - | +| uncheckedAccount1 | 953 | - | +| uncheckedAccount2 | 1567 | - | +| uncheckedAccount4 | 2060 | - | +| uncheckedAccount8 | 3855 | - | + +### Notable changes + +--- + +## [0.27.0] + +| Instruction | Compute Units | +/- | +| --------------------------- | ------------- | --- | +| accountInfo1 | 954 | N/A | +| accountInfo2 | 1567 | N/A | +| accountInfo4 | 2059 | N/A | +| accountInfo8 | 3856 | N/A | +| accountEmptyInit1 | 5958 | N/A | +| accountEmpty1 | 1090 | N/A | +| accountEmptyInit2 | 10574 | N/A | +| accountEmpty2 | 1852 | N/A | +| accountEmptyInit4 | 19557 | N/A | +| accountEmpty4 | 2646 | N/A | +| accountEmptyInit8 | 37541 | N/A | +| accountEmpty8 | 5043 | N/A | +| accountSizedInit1 | 6063 | N/A | +| accountSized1 | 1135 | N/A | +| accountSizedInit2 | 10783 | N/A | +| accountSized2 | 1966 | N/A | +| accountSizedInit4 | 19975 | N/A | +| accountSized4 | 2787 | N/A | +| accountSizedInit8 | 38381 | N/A | +| accountSized8 | 5359 | N/A | +| accountUnsizedInit1 | 6193 | N/A | +| accountUnsized1 | 1243 | N/A | +| accountUnsizedInit2 | 11042 | N/A | +| accountUnsized2 | 1893 | N/A | +| accountUnsizedInit4 | 20495 | N/A | +| accountUnsized4 | 3104 | N/A | +| accountUnsizedInit8 | 39419 | N/A | +| accountUnsized8 | 6051 | N/A | +| boxedAccountEmptyInit1 | 6160 | N/A | +| boxedAccountEmpty1 | 976 | N/A | +| boxedAccountEmptyInit2 | 10784 | N/A | +| boxedAccountEmpty2 | 1499 | N/A | +| boxedAccountEmptyInit4 | 19500 | N/A | +| boxedAccountEmpty4 | 2530 | N/A | +| boxedAccountEmptyInit8 | 37415 | N/A | +| boxedAccountEmpty8 | 4780 | N/A | +| boxedAccountSizedInit1 | 6256 | N/A | +| boxedAccountSized1 | 1003 | N/A | +| boxedAccountSizedInit2 | 10975 | N/A | +| boxedAccountSized2 | 1554 | N/A | +| boxedAccountSizedInit4 | 19884 | N/A | +| boxedAccountSized4 | 2642 | N/A | +| boxedAccountSizedInit8 | 38182 | N/A | +| boxedAccountSized8 | 5003 | N/A | +| boxedAccountUnsizedInit1 | 6374 | N/A | +| boxedAccountUnsized1 | 1069 | N/A | +| boxedAccountUnsizedInit2 | 11211 | N/A | +| boxedAccountUnsized2 | 1679 | N/A | +| boxedAccountUnsizedInit4 | 20351 | N/A | +| boxedAccountUnsized4 | 2899 | N/A | +| boxedAccountUnsizedInit8 | 39118 | N/A | +| boxedAccountUnsized8 | 5517 | N/A | +| boxedInterfaceAccountMint1 | 2299 | N/A | +| boxedInterfaceAccountMint2 | 4053 | N/A | +| boxedInterfaceAccountMint4 | 7538 | N/A | +| boxedInterfaceAccountMint8 | 14699 | N/A | +| boxedInterfaceAccountToken1 | 1737 | N/A | +| boxedInterfaceAccountToken2 | 2928 | N/A | +| boxedInterfaceAccountToken4 | 5291 | N/A | +| boxedInterfaceAccountToken8 | 10205 | N/A | +| interfaceAccountMint1 | 2530 | N/A | +| interfaceAccountMint2 | 4726 | N/A | +| interfaceAccountMint4 | 9431 | N/A | +| interfaceAccountMint8 | 17709 | N/A | +| interfaceAccountToken1 | 1755 | N/A | +| interfaceAccountToken2 | 3211 | N/A | +| interfaceAccountToken4 | 6006 | N/A | +| interface1 | 999 | N/A | +| interface2 | 1574 | N/A | +| interface4 | 1996 | N/A | +| interface8 | 3651 | N/A | +| program1 | 999 | N/A | +| program2 | 1573 | N/A | +| program4 | 1998 | N/A | +| program8 | 3651 | N/A | +| signer1 | 958 | N/A | +| signer2 | 1576 | N/A | +| signer4 | 2079 | N/A | +| signer8 | 3895 | N/A | +| systemAccount1 | 1013 | N/A | +| systemAccount2 | 1686 | N/A | +| systemAccount4 | 2298 | N/A | +| systemAccount8 | 4336 | N/A | +| uncheckedAccount1 | 953 | N/A | +| uncheckedAccount2 | 1567 | N/A | +| uncheckedAccount4 | 2060 | N/A | +| uncheckedAccount8 | 3855 | N/A | + +--- diff --git a/tests/bench/Anchor.toml b/tests/bench/Anchor.toml new file mode 100644 index 0000000000..8e0cf1d521 --- /dev/null +++ b/tests/bench/Anchor.toml @@ -0,0 +1,15 @@ +[provider] +cluster = "localnet" +wallet = "~/.config/solana/id.json" + +[programs.localnet] +bench = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" + +[workspace] +members = ["programs/bench"] + +[scripts] +test = "yarn run ts-mocha -t 1000000 -p ./tsconfig.json -t 1000000 tests/**/*.ts" +update-bench = "yarn run ts-node scripts/update-bench.ts" +generate-ix = "yarn run ts-node scripts/generate-ix.ts" +bump-version = "yarn run ts-node scripts/bump-version.ts" diff --git a/tests/bench/Cargo.toml b/tests/bench/Cargo.toml new file mode 100644 index 0000000000..a60de986d3 --- /dev/null +++ b/tests/bench/Cargo.toml @@ -0,0 +1,4 @@ +[workspace] +members = [ + "programs/*" +] diff --git a/tests/bench/README.md b/tests/bench/README.md new file mode 100644 index 0000000000..b57b50d0f8 --- /dev/null +++ b/tests/bench/README.md @@ -0,0 +1,27 @@ +# Benchmark tests + +The bench program and its tests are used to measure the performance of Anchor programs. + +## How + +Create a program -> Write tests that measure usage -> Compare the results -> Save the new result + +The script will check whether there is a difference between the current result and the last saved result(in `bench.json`) at the end of the tests. If the difference between the results is greater than 1%, the new data will be saved in `bench.json` and Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) will be updated accordingly. + +## Scripts + +`anchor test --skip-lint`: Run all tests and update benchmark files when necessary. This is the only command that needs to be run for most use cases. + +--- + +The following scripts are useful when making changes to how benchmarking works. + +`anchor run update-bench`: Update Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) based on the data from `bench.json`. + +`anchor run generate-ix`: Generate instructions with repetitive accounts. + +--- + +The following script is only for the maintainer(s) of Anchor. + +`anchor run bump-version -- `: Bump the version in all benchmark files. diff --git a/tests/bench/bench.json b/tests/bench/bench.json new file mode 100644 index 0000000000..28cf6152fd --- /dev/null +++ b/tests/bench/bench.json @@ -0,0 +1,184 @@ +{ + "0.27.0": { + "computeUnits": { + "accountInfo1": 954, + "accountInfo2": 1567, + "accountInfo4": 2059, + "accountInfo8": 3856, + "accountEmptyInit1": 5958, + "accountEmpty1": 1090, + "accountEmptyInit2": 10574, + "accountEmpty2": 1852, + "accountEmptyInit4": 19557, + "accountEmpty4": 2646, + "accountEmptyInit8": 37541, + "accountEmpty8": 5043, + "accountSizedInit1": 6063, + "accountSized1": 1135, + "accountSizedInit2": 10783, + "accountSized2": 1966, + "accountSizedInit4": 19975, + "accountSized4": 2787, + "accountSizedInit8": 38381, + "accountSized8": 5359, + "accountUnsizedInit1": 6193, + "accountUnsized1": 1243, + "accountUnsizedInit2": 11042, + "accountUnsized2": 1893, + "accountUnsizedInit4": 20495, + "accountUnsized4": 3104, + "accountUnsizedInit8": 39419, + "accountUnsized8": 6051, + "boxedAccountEmptyInit1": 6160, + "boxedAccountEmpty1": 976, + "boxedAccountEmptyInit2": 10784, + "boxedAccountEmpty2": 1499, + "boxedAccountEmptyInit4": 19500, + "boxedAccountEmpty4": 2530, + "boxedAccountEmptyInit8": 37415, + "boxedAccountEmpty8": 4780, + "boxedAccountSizedInit1": 6256, + "boxedAccountSized1": 1003, + "boxedAccountSizedInit2": 10975, + "boxedAccountSized2": 1554, + "boxedAccountSizedInit4": 19884, + "boxedAccountSized4": 2642, + "boxedAccountSizedInit8": 38182, + "boxedAccountSized8": 5003, + "boxedAccountUnsizedInit1": 6374, + "boxedAccountUnsized1": 1069, + "boxedAccountUnsizedInit2": 11211, + "boxedAccountUnsized2": 1679, + "boxedAccountUnsizedInit4": 20351, + "boxedAccountUnsized4": 2899, + "boxedAccountUnsizedInit8": 39118, + "boxedAccountUnsized8": 5517, + "boxedInterfaceAccountMint1": 2299, + "boxedInterfaceAccountMint2": 4053, + "boxedInterfaceAccountMint4": 7538, + "boxedInterfaceAccountMint8": 14699, + "boxedInterfaceAccountToken1": 1737, + "boxedInterfaceAccountToken2": 2928, + "boxedInterfaceAccountToken4": 5291, + "boxedInterfaceAccountToken8": 10205, + "interfaceAccountMint1": 2530, + "interfaceAccountMint2": 4726, + "interfaceAccountMint4": 9431, + "interfaceAccountMint8": 17709, + "interfaceAccountToken1": 1755, + "interfaceAccountToken2": 3211, + "interfaceAccountToken4": 6006, + "interface1": 999, + "interface2": 1574, + "interface4": 1996, + "interface8": 3651, + "program1": 999, + "program2": 1573, + "program4": 1998, + "program8": 3651, + "signer1": 958, + "signer2": 1576, + "signer4": 2079, + "signer8": 3895, + "systemAccount1": 1013, + "systemAccount2": 1686, + "systemAccount4": 2298, + "systemAccount8": 4336, + "uncheckedAccount1": 953, + "uncheckedAccount2": 1567, + "uncheckedAccount4": 2060, + "uncheckedAccount8": 3855 + } + }, + "unreleased": { + "computeUnits": { + "accountInfo1": 954, + "accountInfo2": 1567, + "accountInfo4": 2059, + "accountInfo8": 3856, + "accountEmptyInit1": 5958, + "accountEmpty1": 1090, + "accountEmptyInit2": 10583, + "accountEmpty2": 1852, + "accountEmptyInit4": 19557, + "accountEmpty4": 2646, + "accountEmptyInit8": 37541, + "accountEmpty8": 5043, + "accountSizedInit1": 6063, + "accountSized1": 1135, + "accountSizedInit2": 10783, + "accountSized2": 1966, + "accountSizedInit4": 19975, + "accountSized4": 2787, + "accountSizedInit8": 38381, + "accountSized8": 5359, + "accountUnsizedInit1": 6193, + "accountUnsized1": 1243, + "accountUnsizedInit2": 11042, + "accountUnsized2": 1893, + "accountUnsizedInit4": 20495, + "accountUnsized4": 3104, + "accountUnsizedInit8": 39419, + "accountUnsized8": 6051, + "boxedAccountEmptyInit1": 6160, + "boxedAccountEmpty1": 976, + "boxedAccountEmptyInit2": 10784, + "boxedAccountEmpty2": 1499, + "boxedAccountEmptyInit4": 19500, + "boxedAccountEmpty4": 2530, + "boxedAccountEmptyInit8": 37415, + "boxedAccountEmpty8": 4780, + "boxedAccountSizedInit1": 6256, + "boxedAccountSized1": 1003, + "boxedAccountSizedInit2": 10975, + "boxedAccountSized2": 1554, + "boxedAccountSizedInit4": 19884, + "boxedAccountSized4": 2642, + "boxedAccountSizedInit8": 38182, + "boxedAccountSized8": 5003, + "boxedAccountUnsizedInit1": 6374, + "boxedAccountUnsized1": 1069, + "boxedAccountUnsizedInit2": 11211, + "boxedAccountUnsized2": 1679, + "boxedAccountUnsizedInit4": 20351, + "boxedAccountUnsized4": 2899, + "boxedAccountUnsizedInit8": 39118, + "boxedAccountUnsized8": 5517, + "boxedInterfaceAccountMint1": 2299, + "boxedInterfaceAccountMint2": 4053, + "boxedInterfaceAccountMint4": 7538, + "boxedInterfaceAccountMint8": 14699, + "boxedInterfaceAccountToken1": 1737, + "boxedInterfaceAccountToken2": 2928, + "boxedInterfaceAccountToken4": 5291, + "boxedInterfaceAccountToken8": 10205, + "interfaceAccountMint1": 2530, + "interfaceAccountMint2": 4726, + "interfaceAccountMint4": 9431, + "interfaceAccountMint8": 17709, + "interfaceAccountToken1": 1755, + "interfaceAccountToken2": 3211, + "interfaceAccountToken4": 6006, + "interface1": 999, + "interface2": 1574, + "interface4": 1996, + "interface8": 3651, + "program1": 999, + "program2": 1573, + "program4": 1998, + "program8": 3651, + "signer1": 958, + "signer2": 1576, + "signer4": 2079, + "signer8": 3895, + "systemAccount1": 1013, + "systemAccount2": 1686, + "systemAccount4": 2298, + "systemAccount8": 4336, + "uncheckedAccount1": 953, + "uncheckedAccount2": 1567, + "uncheckedAccount4": 2060, + "uncheckedAccount8": 3855 + } + } +} \ No newline at end of file diff --git a/tests/bench/package.json b/tests/bench/package.json new file mode 100644 index 0000000000..1562b32fdf --- /dev/null +++ b/tests/bench/package.json @@ -0,0 +1,19 @@ +{ + "name": "bench", + "version": "0.27.0", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + }, + "scripts": { + "test": "anchor test" + } +} diff --git a/tests/bench/programs/bench/Cargo.toml b/tests/bench/programs/bench/Cargo.toml new file mode 100644 index 0000000000..d7b162620b --- /dev/null +++ b/tests/bench/programs/bench/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "bench" +version = "0.1.0" +description = "Created with Anchor" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] + +[features] +no-entrypoint = [] +cpi = ["no-entrypoint"] + +[dependencies] +anchor-lang = { path = "../../../../lang" } +anchor-spl = { path = "../../../../spl" } diff --git a/tests/bench/programs/bench/Xargo.toml b/tests/bench/programs/bench/Xargo.toml new file mode 100644 index 0000000000..1744f098ae --- /dev/null +++ b/tests/bench/programs/bench/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] \ No newline at end of file diff --git a/tests/bench/programs/bench/src/lib.rs b/tests/bench/programs/bench/src/lib.rs new file mode 100644 index 0000000000..e9a2a6b8e1 --- /dev/null +++ b/tests/bench/programs/bench/src/lib.rs @@ -0,0 +1,1212 @@ +//! This program is used to measure the performance of Anchor programs. + +use anchor_lang::prelude::*; +use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; + +declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); + +#[program] +pub mod bench { + use super::*; + + pub fn account_info1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_info2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_info4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_info8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_empty8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_sized8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn account_unsized8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_empty8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_sized8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized_init1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized_init2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized_init4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized_init8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_account_unsized8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_mint1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_mint2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_mint4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_mint8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_token1( + _ctx: Context, + ) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_token2( + _ctx: Context, + ) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_token4( + _ctx: Context, + ) -> Result<()> { + Ok(()) + } + + pub fn boxed_interface_account_token8( + _ctx: Context, + ) -> Result<()> { + Ok(()) + } + + pub fn interface_account_mint1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_mint2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_mint4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_mint8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_token1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_token2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface_account_token4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn interface8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn program1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn program2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn program4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn program8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn signer1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn signer2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn signer4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn signer8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn system_account1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn system_account2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn system_account4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn system_account8(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn unchecked_account1(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn unchecked_account2(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn unchecked_account4(_ctx: Context) -> Result<()> { + Ok(()) + } + + pub fn unchecked_account8(_ctx: Context) -> Result<()> { + Ok(()) + } +} + +#[account] +pub struct Empty {} + +#[account] +pub struct Sized { + pub field: [u8; 8], +} + +#[account] +pub struct Unsized { + pub field: Vec, +} + +#[derive(Accounts)] +pub struct AccountInfo1<'info> { + pub account1: AccountInfo<'info>, +} + +#[derive(Accounts)] +pub struct AccountInfo2<'info> { + pub account1: AccountInfo<'info>, + pub account2: AccountInfo<'info>, +} + +#[derive(Accounts)] +pub struct AccountInfo4<'info> { + pub account1: AccountInfo<'info>, + pub account2: AccountInfo<'info>, + pub account3: AccountInfo<'info>, + pub account4: AccountInfo<'info>, +} + +#[derive(Accounts)] +pub struct AccountInfo8<'info> { + pub account1: AccountInfo<'info>, + pub account2: AccountInfo<'info>, + pub account3: AccountInfo<'info>, + pub account4: AccountInfo<'info>, + pub account5: AccountInfo<'info>, + pub account6: AccountInfo<'info>, + pub account7: AccountInfo<'info>, + pub account8: AccountInfo<'info>, +} + +#[derive(Accounts)] +pub struct AccountEmptyInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmptyInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account2: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmptyInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account2: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account3: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account4: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmptyInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account2: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account3: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account4: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account5: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account6: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account7: Account<'info, Empty>, + #[account(init, payer = payer, space = 8)] + pub account8: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmpty1<'info> { + pub account1: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmpty2<'info> { + pub account1: Account<'info, Empty>, + pub account2: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmpty4<'info> { + pub account1: Account<'info, Empty>, + pub account2: Account<'info, Empty>, + pub account3: Account<'info, Empty>, + pub account4: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountEmpty8<'info> { + pub account1: Account<'info, Empty>, + pub account2: Account<'info, Empty>, + pub account3: Account<'info, Empty>, + pub account4: Account<'info, Empty>, + pub account5: Account<'info, Empty>, + pub account6: Account<'info, Empty>, + pub account7: Account<'info, Empty>, + pub account8: Account<'info, Empty>, +} + +#[derive(Accounts)] +pub struct AccountSizedInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSizedInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSizedInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSizedInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account5: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account6: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account7: Account<'info, Sized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account8: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSized1<'info> { + pub account1: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSized2<'info> { + pub account1: Account<'info, Sized>, + pub account2: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSized4<'info> { + pub account1: Account<'info, Sized>, + pub account2: Account<'info, Sized>, + pub account3: Account<'info, Sized>, + pub account4: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountSized8<'info> { + pub account1: Account<'info, Sized>, + pub account2: Account<'info, Sized>, + pub account3: Account<'info, Sized>, + pub account4: Account<'info, Sized>, + pub account5: Account<'info, Sized>, + pub account6: Account<'info, Sized>, + pub account7: Account<'info, Sized>, + pub account8: Account<'info, Sized>, +} + +#[derive(Accounts)] +pub struct AccountUnsizedInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsizedInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsizedInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsizedInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account5: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account6: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account7: Account<'info, Unsized>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account8: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsized1<'info> { + pub account1: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsized2<'info> { + pub account1: Account<'info, Unsized>, + pub account2: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsized4<'info> { + pub account1: Account<'info, Unsized>, + pub account2: Account<'info, Unsized>, + pub account3: Account<'info, Unsized>, + pub account4: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct AccountUnsized8<'info> { + pub account1: Account<'info, Unsized>, + pub account2: Account<'info, Unsized>, + pub account3: Account<'info, Unsized>, + pub account4: Account<'info, Unsized>, + pub account5: Account<'info, Unsized>, + pub account6: Account<'info, Unsized>, + pub account7: Account<'info, Unsized>, + pub account8: Account<'info, Unsized>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmptyInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmptyInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Box>, + #[account(init, payer = payer, space = 8)] + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmptyInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Box>, + #[account(init, payer = payer, space = 8)] + pub account2: Box>, + #[account(init, payer = payer, space = 8)] + pub account3: Box>, + #[account(init, payer = payer, space = 8)] + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmptyInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8)] + pub account1: Box>, + #[account(init, payer = payer, space = 8)] + pub account2: Box>, + #[account(init, payer = payer, space = 8)] + pub account3: Box>, + #[account(init, payer = payer, space = 8)] + pub account4: Box>, + #[account(init, payer = payer, space = 8)] + pub account5: Box>, + #[account(init, payer = payer, space = 8)] + pub account6: Box>, + #[account(init, payer = payer, space = 8)] + pub account7: Box>, + #[account(init, payer = payer, space = 8)] + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmpty1<'info> { + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmpty2<'info> { + pub account1: Box>, + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmpty4<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountEmpty8<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, + pub account5: Box>, + pub account6: Box>, + pub account7: Box>, + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSizedInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSizedInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSizedInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSizedInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account5: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account6: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account7: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSized1<'info> { + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSized2<'info> { + pub account1: Box>, + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSized4<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountSized8<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, + pub account5: Box>, + pub account6: Box>, + pub account7: Box>, + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsizedInit1<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsizedInit2<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsizedInit4<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsizedInit8<'info> { + #[account(mut)] + pub payer: Signer<'info>, + pub system_program: Program<'info, System>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account1: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account2: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account3: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account4: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account5: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account6: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account7: Box>, + #[account(init, payer = payer, space = 8 + std::mem::size_of::())] + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsized1<'info> { + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsized2<'info> { + pub account1: Box>, + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsized4<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedAccountUnsized8<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, + pub account5: Box>, + pub account6: Box>, + pub account7: Box>, + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountMint1<'info> { + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountMint2<'info> { + pub account1: Box>, + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountMint4<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountMint8<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, + pub account5: Box>, + pub account6: Box>, + pub account7: Box>, + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountToken1<'info> { + pub account1: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountToken2<'info> { + pub account1: Box>, + pub account2: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountToken4<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, +} + +#[derive(Accounts)] +pub struct BoxedInterfaceAccountToken8<'info> { + pub account1: Box>, + pub account2: Box>, + pub account3: Box>, + pub account4: Box>, + pub account5: Box>, + pub account6: Box>, + pub account7: Box>, + pub account8: Box>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountMint1<'info> { + pub account1: InterfaceAccount<'info, Mint>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountMint2<'info> { + pub account1: InterfaceAccount<'info, Mint>, + pub account2: InterfaceAccount<'info, Mint>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountMint4<'info> { + pub account1: InterfaceAccount<'info, Mint>, + pub account2: InterfaceAccount<'info, Mint>, + pub account3: InterfaceAccount<'info, Mint>, + pub account4: InterfaceAccount<'info, Mint>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountMint8<'info> { + pub account1: InterfaceAccount<'info, Mint>, + pub account2: InterfaceAccount<'info, Mint>, + pub account3: InterfaceAccount<'info, Mint>, + pub account4: InterfaceAccount<'info, Mint>, + pub account5: InterfaceAccount<'info, Mint>, + pub account6: InterfaceAccount<'info, Mint>, + pub account7: InterfaceAccount<'info, Mint>, + pub account8: InterfaceAccount<'info, Mint>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountToken1<'info> { + pub account1: InterfaceAccount<'info, TokenAccount>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountToken2<'info> { + pub account1: InterfaceAccount<'info, TokenAccount>, + pub account2: InterfaceAccount<'info, TokenAccount>, +} + +#[derive(Accounts)] +pub struct InterfaceAccountToken4<'info> { + pub account1: InterfaceAccount<'info, TokenAccount>, + pub account2: InterfaceAccount<'info, TokenAccount>, + pub account3: InterfaceAccount<'info, TokenAccount>, + pub account4: InterfaceAccount<'info, TokenAccount>, +} + +#[derive(Accounts)] +pub struct Interface1<'info> { + pub account1: Interface<'info, TokenInterface>, +} + +#[derive(Accounts)] +pub struct Interface2<'info> { + pub account1: Interface<'info, TokenInterface>, + pub account2: Interface<'info, TokenInterface>, +} + +#[derive(Accounts)] +pub struct Interface4<'info> { + pub account1: Interface<'info, TokenInterface>, + pub account2: Interface<'info, TokenInterface>, + pub account3: Interface<'info, TokenInterface>, + pub account4: Interface<'info, TokenInterface>, +} + +#[derive(Accounts)] +pub struct Interface8<'info> { + pub account1: Interface<'info, TokenInterface>, + pub account2: Interface<'info, TokenInterface>, + pub account3: Interface<'info, TokenInterface>, + pub account4: Interface<'info, TokenInterface>, + pub account5: Interface<'info, TokenInterface>, + pub account6: Interface<'info, TokenInterface>, + pub account7: Interface<'info, TokenInterface>, + pub account8: Interface<'info, TokenInterface>, +} + +#[derive(Accounts)] +pub struct Program1<'info> { + pub account1: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Program2<'info> { + pub account1: Program<'info, System>, + pub account2: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Program4<'info> { + pub account1: Program<'info, System>, + pub account2: Program<'info, System>, + pub account3: Program<'info, System>, + pub account4: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Program8<'info> { + pub account1: Program<'info, System>, + pub account2: Program<'info, System>, + pub account3: Program<'info, System>, + pub account4: Program<'info, System>, + pub account5: Program<'info, System>, + pub account6: Program<'info, System>, + pub account7: Program<'info, System>, + pub account8: Program<'info, System>, +} + +#[derive(Accounts)] +pub struct Signer1<'info> { + pub account1: Signer<'info>, +} + +#[derive(Accounts)] +pub struct Signer2<'info> { + pub account1: Signer<'info>, + pub account2: Signer<'info>, +} + +#[derive(Accounts)] +pub struct Signer4<'info> { + pub account1: Signer<'info>, + pub account2: Signer<'info>, + pub account3: Signer<'info>, + pub account4: Signer<'info>, +} + +#[derive(Accounts)] +pub struct Signer8<'info> { + pub account1: Signer<'info>, + pub account2: Signer<'info>, + pub account3: Signer<'info>, + pub account4: Signer<'info>, + pub account5: Signer<'info>, + pub account6: Signer<'info>, + pub account7: Signer<'info>, + pub account8: Signer<'info>, +} + +#[derive(Accounts)] +pub struct SystemAccount1<'info> { + pub account1: SystemAccount<'info>, +} + +#[derive(Accounts)] +pub struct SystemAccount2<'info> { + pub account1: SystemAccount<'info>, + pub account2: SystemAccount<'info>, +} + +#[derive(Accounts)] +pub struct SystemAccount4<'info> { + pub account1: SystemAccount<'info>, + pub account2: SystemAccount<'info>, + pub account3: SystemAccount<'info>, + pub account4: SystemAccount<'info>, +} + +#[derive(Accounts)] +pub struct SystemAccount8<'info> { + pub account1: SystemAccount<'info>, + pub account2: SystemAccount<'info>, + pub account3: SystemAccount<'info>, + pub account4: SystemAccount<'info>, + pub account5: SystemAccount<'info>, + pub account6: SystemAccount<'info>, + pub account7: SystemAccount<'info>, + pub account8: SystemAccount<'info>, +} + +#[derive(Accounts)] +pub struct UncheckedAccount1<'info> { + pub account1: UncheckedAccount<'info>, +} + +#[derive(Accounts)] +pub struct UncheckedAccount2<'info> { + pub account1: UncheckedAccount<'info>, + pub account2: UncheckedAccount<'info>, +} + +#[derive(Accounts)] +pub struct UncheckedAccount4<'info> { + pub account1: UncheckedAccount<'info>, + pub account2: UncheckedAccount<'info>, + pub account3: UncheckedAccount<'info>, + pub account4: UncheckedAccount<'info>, +} + +#[derive(Accounts)] +pub struct UncheckedAccount8<'info> { + pub account1: UncheckedAccount<'info>, + pub account2: UncheckedAccount<'info>, + pub account3: UncheckedAccount<'info>, + pub account4: UncheckedAccount<'info>, + pub account5: UncheckedAccount<'info>, + pub account6: UncheckedAccount<'info>, + pub account7: UncheckedAccount<'info>, + pub account8: UncheckedAccount<'info>, +} diff --git a/tests/bench/scripts/bump-version.ts b/tests/bench/scripts/bump-version.ts new file mode 100644 index 0000000000..2f54025b79 --- /dev/null +++ b/tests/bench/scripts/bump-version.ts @@ -0,0 +1,25 @@ +/** + * Bump the version of all benchmark related files by changing the `Unreleased` + * version to a new version and adding a new `Unreleased` version. + */ + +import { BenchData } from "./utils"; + +(async () => { + const newVersion = process.argv[2]; + + if (!newVersion) { + console.error("Usage: anchor run bump-version -- "); + process.exit(1); + } + + // Bump bench data + const bench = await BenchData.open(); + bench.bumpVersion(newVersion); + await bench.save(); + + // Bump markdown files + await BenchData.forEachMarkdown((markdown) => { + markdown.bumpVersion(newVersion); + }); +})(); diff --git a/tests/bench/scripts/generate-ix.ts b/tests/bench/scripts/generate-ix.ts new file mode 100644 index 0000000000..ba61c4a020 --- /dev/null +++ b/tests/bench/scripts/generate-ix.ts @@ -0,0 +1,225 @@ +/** + * Generate instructions with repetitive accounts and add them to the bench program. + */ + +import * as fs from "fs/promises"; +import path from "path"; + +type Instruction = { + /** Instruction name */ + name: string; + /** Each account type in accounts struct */ + accountType: string; + /** Account macro(`#[account(..)]`) */ + accountMacro?: { + init: true; + space?: number | string; + }; + /** Number of accounts to create per instruction */ + accountCounts?: number[]; +}; + +/** + * The following instructions will be added to the program. + * + * If an instruction already exists, it will be skipped. + */ +const INSTRUCTIONS: Instruction[] = [ + { + name: "account_info", + accountType: "AccountInfo<'info>", + }, + { + name: "account_empty_init", + accountType: "Account<'info, Empty>", + accountMacro: { + init: true, + }, + }, + { + name: "account_empty", + accountType: "Account<'info, Empty>", + }, + { + name: "account_sized_init", + accountType: "Account<'info, Sized>", + accountMacro: { + init: true, + space: "8 + std::mem::size_of::()", + }, + }, + { + name: "account_sized", + accountType: "Account<'info, Sized>", + }, + { + name: "account_unsized_init", + accountType: "Account<'info, Unsized>", + accountMacro: { + init: true, + space: "8 + std::mem::size_of::()", + }, + }, + { + name: "account_unsized", + accountType: "Account<'info, Unsized>", + }, + { + name: "boxed_account_empty_init", + accountType: "Box>", + accountMacro: { + init: true, + }, + }, + { + name: "boxed_account_empty", + accountType: "Box>", + }, + { + name: "boxed_account_sized_init", + accountType: "Box>", + accountMacro: { + init: true, + space: "8 + std::mem::size_of::()", + }, + }, + { + name: "boxed_account_sized", + accountType: "Box>", + }, + { + name: "boxed_account_unsized_init", + accountType: "Box>", + accountMacro: { + init: true, + space: "8 + std::mem::size_of::()", + }, + }, + { + name: "boxed_account_unsized", + accountType: "Box>", + }, + { + name: "boxed_interface_account_mint", + accountType: "Box>", + }, + { + name: "boxed_interface_account_token", + accountType: "Box>", + }, + { + name: "interface_account_mint", + accountType: "InterfaceAccount<'info, Mint>", + }, + { + name: "interface_account_token", + accountType: "InterfaceAccount<'info, TokenAccount>", + accountCounts: [1, 2, 4], + }, + { + name: "interface", + accountType: "Interface<'info, TokenInterface>", + }, + { + name: "program", + accountType: "Program<'info, System>", + }, + { + name: "signer", + accountType: "Signer<'info>", + }, + { + name: "system_account", + accountType: "SystemAccount<'info>", + }, + { + name: "unchecked_account", + accountType: "UncheckedAccount<'info>", + }, +]; + +(async () => { + // Get the program file + const programPath = path.join("programs", "bench", "src", "lib.rs"); + let file = await fs.readFile(programPath, { + encoding: "utf8", + }); + + const create = ( + ix: Omit & { count: number } + ) => { + // Get the title case of the name for the accounts struct + const accountsName = + ix.name[0].toUpperCase() + + ix.name.slice(1).replace(/_\w/g, (match) => match[1].toUpperCase()); + + // Generate accounts + let accounts = ""; + let accountMacro = ""; + const INDENT = "\n "; + + if (ix.accountMacro?.init) { + accounts += `${INDENT}#[account(mut)]${INDENT}pub payer: Signer<'info>,`; + accounts += `${INDENT}pub system_program: Program<'info, System>,`; + accountMacro += `init, payer = payer, space = ${ + ix.accountMacro.space ?? 8 + }`; + } + + accountMacro = `${INDENT}#[account(${accountMacro})]`; + + for (let i = 0; i < ix.count; i++) { + if (ix.accountMacro) { + accounts += accountMacro; + } + + accounts += `${INDENT}pub account${i + 1}: ${ix.accountType},`; + } + + return { + ix: ` + pub fn ${ix.name}(_ctx: Context<${accountsName}>) -> Result<()> { + Ok(()) + }`, + accounts: ` +#[derive(Accounts)] +pub struct ${accountsName}<'info> {${accounts}\n}`, + }; + }; + + const insert = (index: number, text: string) => { + file = file.slice(0, index) + "\n" + text + file.slice(index); + }; + + for (const instruction of INSTRUCTIONS) { + // Default count + instruction.accountCounts ??= [1, 2, 4, 8]; + + for (const count of instruction.accountCounts) { + // Append count to the end of the instruction name + const ixName = instruction.name + count; + + // Skip existing instructions + if (file.includes(`fn ${ixName}`)) { + continue; + } + + const { ix, accounts } = create({ ...instruction, name: ixName, count }); + + // Get the ix index to start from + const programIndex = file.indexOf("#[program]"); + const fileStartingFromProgram = file.slice(programIndex); + + // Add instruction + const ixIndex = programIndex + fileStartingFromProgram.indexOf("\n}"); + insert(ixIndex, ix); + + // Add accounts + const accountsIndex = file.length - 1; + insert(accountsIndex, accounts); + } + } + + // Save + await fs.writeFile(programPath, file); +})(); diff --git a/tests/bench/scripts/update-bench.ts b/tests/bench/scripts/update-bench.ts new file mode 100644 index 0000000000..9b6cd063bb --- /dev/null +++ b/tests/bench/scripts/update-bench.ts @@ -0,0 +1,67 @@ +/** Update Markdown files in /bench */ + +import { BenchData, Markdown } from "./utils"; + +(async () => { + const bench = await BenchData.open(); + + await BenchData.forEachMarkdown((markdown, fileName) => { + if (fileName === "COMPUTE_UNITS.md") { + const versions = bench.getVersions(); + + // On the first version, compare with itself to update it with no changes + versions.unshift(versions[0]); + + for (const i in versions) { + const currentVersion = versions[i]; + const nextVersion = versions[+i + 1]; + + if (currentVersion === "unreleased") { + return; + } + + const newComputeUnitsResult = bench.get(nextVersion).computeUnits; + const oldComputeUnitsResult = bench.get(currentVersion).computeUnits; + + // Create table + const table = Markdown.createTable( + "Instruction", + "Compute Units", + "+/-" + ); + + bench.compareComputeUnits( + newComputeUnitsResult, + oldComputeUnitsResult, + (ixName, newComputeUnits, oldComputeUnits) => { + const percentChange = ( + (newComputeUnits / oldComputeUnits - 1) * + 100 + ).toFixed(2); + + let changeText; + if (isNaN(oldComputeUnits)) { + changeText = "N/A"; + } else if (+percentChange > 0) { + changeText = `🔴 **+${percentChange}%**`; + } else { + changeText = `🟢 **${percentChange}%**`; + } + + table.insert(ixName, newComputeUnits.toString(), changeText); + }, + (ixName, computeUnits) => { + table.insert( + ixName, + computeUnits.toString(), + +i === 0 ? "N/A" : "-" + ); + } + ); + + // Update version's table + markdown.updateTable(nextVersion, table); + } + } + }); +})(); diff --git a/tests/bench/scripts/utils.ts b/tests/bench/scripts/utils.ts new file mode 100644 index 0000000000..8350cbbb61 --- /dev/null +++ b/tests/bench/scripts/utils.ts @@ -0,0 +1,298 @@ +import * as fs from "fs/promises"; +import path from "path"; +import { spawnSync } from "child_process"; + +/** Persistent benchmark data(mapping of `Version -> Data`) */ +type Bench = { + [key: string]: { + /** Benchmark result for compute units consumed */ + computeUnits: ComputeUnits; + }; +}; + +/** `instruction name -> compute units consumed` */ +export type ComputeUnits = { [key: string]: number }; + +/** + * How much of a percentage difference between the current and the previous data + * should be significant. Any difference above this number should be noted in + * the benchmark file. + */ +export const THRESHOLD_PERCENTAGE = 1; + +/** Path to the benchmark Markdown files */ +export const BENCH_DIR_PATH = "../../bench"; + +/** Utility class to handle benchmark data related operations */ +export class BenchData { + /** Benchmark data filepath */ + static #PATH = "bench.json"; + + /** Benchmark data */ + #data: Bench; + + constructor(data: Bench) { + this.#data = data; + } + + /** Open the benchmark data file */ + static async open() { + let bench: Bench; + try { + const benchFile = await fs.readFile(BenchData.#PATH, { + encoding: "utf8", + }); + bench = JSON.parse(benchFile); + } catch { + bench = {}; + } + + return new BenchData(bench); + } + + /** Save the benchmark data file */ + async save() { + await fs.writeFile(BenchData.#PATH, JSON.stringify(this.#data, null, 2)); + } + + /** Get the stored results based on version */ + get(version: string) { + return this.#data[version]; + } + + /** Get unreleased version results */ + getUnreleased() { + return this.get("unreleased"); + } + + /** Get all versions */ + getVersions() { + return Object.keys(this.#data); + } + + /** Compare and update compute units changes */ + compareComputeUnits( + newComputeUnitsResult: ComputeUnits, + oldComputeUnitsResult: ComputeUnits, + changeCb: ( + ixName: string, + newComputeUnits: number, + oldComputeUnits: number + ) => void, + noChangeCb?: (ixName: string, computeUnits: number) => void + ) { + let needsUpdate = false; + + // Compare compute units changes + for (const ixName in newComputeUnitsResult) { + const oldComputeUnits = oldComputeUnitsResult[ixName]; + const newComputeUnits = newComputeUnitsResult[ixName]; + if (!oldComputeUnits) { + console.log(`New instruction '${ixName}'`); + needsUpdate = true; + changeCb(ixName, newComputeUnits, NaN); + continue; + } + + const percentage = THRESHOLD_PERCENTAGE / 100; + const oldMaximumAllowedDelta = oldComputeUnits * percentage; + const newMaximumAllowedDelta = newComputeUnits * percentage; + + const delta = newComputeUnits - oldComputeUnits; + const absDelta = Math.abs(delta); + + if ( + absDelta > oldMaximumAllowedDelta || + absDelta > newMaximumAllowedDelta + ) { + // Throw in CI + if (process.env.CI) { + throw new Error( + [ + `Compute units for instruction '${ixName}' has changed more than ${THRESHOLD_PERCENTAGE}% but is not saved.`, + "Run `anchor test --skip-lint` in tests/bench and commit the changes.", + ].join(" ") + ); + } + + console.log( + `Compute units change '${ixName}' (${oldComputeUnits} -> ${newComputeUnits})` + ); + + needsUpdate = true; + changeCb(ixName, newComputeUnits, oldComputeUnits); + } else { + noChangeCb?.(ixName, newComputeUnits); + } + } + + return { needsUpdate }; + } + + /** Bump benchmark data version to the given version */ + bumpVersion(newVersion: string) { + const versions = Object.keys(this.#data); + const unreleasedVersion = versions[versions.length - 1]; + + if (this.#data[newVersion]) { + console.error(`Version '${newVersion}' already exists!`); + process.exit(1); + } + + // Add the new version + this.#data[newVersion] = this.get(unreleasedVersion); + + // Delete the unreleased version + delete this.#data[unreleasedVersion]; + + // Add new unreleased version + this.#data[unreleasedVersion] = this.#data[newVersion]; + } + + /** + * Loop through all of the markdown files and run the given callback before + * saving the file. + */ + static async forEachMarkdown( + cb: (markdown: Markdown, fileName: string) => void + ) { + const fileNames = await fs.readdir(BENCH_DIR_PATH); + const markdownFileNames = fileNames.filter((n) => n.endsWith(".md")); + + for (const fileName of markdownFileNames) { + const markdown = await Markdown.open(path.join(BENCH_DIR_PATH, fileName)); + cb(markdown, fileName); + await markdown.save(); + } + + // Format + spawnSync("yarn", [ + "run", + "prettier", + "--write", + path.join(BENCH_DIR_PATH, "*.md"), + ]); + } +} + +/** Utility class to handle markdown related operations */ +export class Markdown { + /** Unreleased version string */ + static #UNRELEASED_VERSION = "[Unreleased]"; + + /** Markdown filepath */ + #path: string; + + /** Markdown text */ + #text: string; + + constructor(path: string, text: string) { + this.#path = path; + this.#text = text; + } + + /** Open the markdown file */ + static async open(path: string) { + const text = await fs.readFile(path, { encoding: "utf8" }); + return new Markdown(path, text); + } + + /** Create a markdown table */ + static createTable(...args: string[]) { + return new MarkdownTable([args]); + } + + /** Save the markdown file */ + async save() { + await fs.writeFile(this.#path, this.#text); + } + + /** Change version table with the given table */ + updateTable(version: string, table: MarkdownTable) { + const md = this.#text; + + let titleStartIndex = md.indexOf(`[${version}]`); + if (titleStartIndex === -1) { + titleStartIndex = md.indexOf(Markdown.#UNRELEASED_VERSION); + } + + const startIndex = titleStartIndex + md.slice(titleStartIndex).indexOf("|"); + const endIndex = startIndex + md.slice(startIndex).indexOf("\n\n"); + + this.#text = + md.slice(0, startIndex) + table.toString() + md.slice(endIndex + 1); + } + + /** Bump the version to the given version */ + bumpVersion(newVersion: string) { + newVersion = `[${newVersion}]`; + if (this.#text.includes(newVersion)) { + console.error(`Version '${newVersion}' already exists!`); + process.exit(1); + } + + const startIndex = this.#text.indexOf(`## ${Markdown.#UNRELEASED_VERSION}`); + const endIndex = + startIndex + this.#text.slice(startIndex).indexOf("\n---") + 4; + let unreleasedSection = this.#text.slice(startIndex, endIndex); + + // Update unreleased version to `newVersion` + const newSection = unreleasedSection.replace( + Markdown.#UNRELEASED_VERSION, + newVersion + ); + + // Reset unreleased version changes + unreleasedSection = unreleasedSection + .split("\n") + .map((line, i) => { + // First 4 lines don't change + if ([0, 1, 2, 3].includes(i)) return line; + + const regex = /\|.*\|.*\|(.*)\|/; + const result = regex.exec(line); + + const changeStr = result?.[1]; + if (!changeStr) { + if (line.startsWith("#")) return line; + else if (line.startsWith("---")) return line + "\n"; + else return ""; + } + + return line.replace(changeStr, "-"); + }) + .join("\n"); + + // Update the text + this.#text = + this.#text.slice(0, startIndex) + + unreleasedSection + + newSection + + this.#text.slice(endIndex); + } +} + +/** Utility class to handle markdown table related operations */ +class MarkdownTable { + /** Markdown rows stored as array of arrays */ + #rows: string[][]; + + constructor(rows: string[][]) { + this.#rows = rows; + this.insert("-", "-", "-"); + } + + /** Insert a new row to the markdown table */ + insert(...args: string[]) { + this.#rows.push(args); + } + + /** Convert the stored rows to a markdown table */ + toString() { + return this.#rows.reduce( + (acc, row) => + acc + row.reduce((acc, cur) => `${acc} ${cur} |`, "|") + "\n", + "" + ); + } +} diff --git a/tests/bench/tests/compute-units.ts b/tests/bench/tests/compute-units.ts new file mode 100644 index 0000000000..4b5c8fbc2a --- /dev/null +++ b/tests/bench/tests/compute-units.ts @@ -0,0 +1,248 @@ +import * as anchor from "@coral-xyz/anchor"; +import * as token from "@coral-xyz/spl-token"; +import { spawnSync } from "child_process"; + +import { Bench, IDL } from "../target/types/bench"; +import { BenchData, ComputeUnits } from "../scripts/utils"; + +describe(IDL.name, () => { + // Configure the client to use the local cluster + anchor.setProvider(anchor.AnchorProvider.env()); + + const program = anchor.workspace.Bench as anchor.Program; + const owner = program.provider.publicKey!; + + let mintPk: anchor.web3.PublicKey; + let tokenPk: anchor.web3.PublicKey; + + const computeUnits: ComputeUnits = {}; + + const measureComputeUnits = async ( + ixName: string, + options?: Partial<{ + accountCounts: number[]; + generateKeypair: (accountName: string) => anchor.web3.Keypair; + generatePublicKey: (accountName: string) => anchor.web3.PublicKey; + }> + ) => { + options ??= {}; + options.accountCounts ??= [1, 2, 4, 8]; + options.generateKeypair ??= () => anchor.web3.Keypair.generate(); + + for (const accountCount of options.accountCounts) { + // Check whether the init version of the instruction exists + const ixNameInit = `${ixName}Init`; + const hasInitVersion = IDL.instructions.some((ix) => + ix.name.startsWith(ixNameInit) + ); + + const ixNames = [ixName]; + if (hasInitVersion) { + // Init version has priority + ixNames.unshift(ixNameInit); + } + + const accounts: { [key: string]: anchor.web3.PublicKey } = {}; + const signers = []; + + for (const ixName of ixNames) { + const method = + `${ixName}${accountCount}` as keyof typeof program.methods; + + // Remove signers when it's not init instruction + if (ixName !== ixNameInit) { + signers.splice(0); + } + + for (const ix of IDL.instructions) { + if (ix.name !== method) continue; + + for (const account of ix.accounts) { + // Only set account keys if it hasn't been set before + if (accounts[account.name]) { + continue; + } + + if (account.name === "payer") { + accounts[account.name] = owner; + continue; + } + + // Skip other accounts to not override Anchor defaults + if (!account.name.startsWith("account")) { + continue; + } + + if (options.generatePublicKey) { + accounts[account.name] = options.generatePublicKey(account.name); + continue; + } + + const keypair = options.generateKeypair(account.name); + accounts[account.name] = keypair.publicKey; + + if (account.isSigner) { + signers.push(keypair); + } + } + } + + // Send tx + console.log({ method }); + const txHash = await program.methods[method]() + .accounts(accounts) + .signers(signers) + .rpc(); + + // Confirm tx + await program.provider.connection.confirmTransaction( + txHash, + "confirmed" + ); + + // Get tx + const tx = await program.provider.connection.getTransaction(txHash, { + commitment: "confirmed", + }); + + computeUnits[method] = tx!.meta!.computeUnitsConsumed!; + } + } + }; + + before(async () => { + const tokenProgram = token.splTokenProgram({ + provider: anchor.AnchorProvider.local(), + }); + + const tx = new anchor.web3.Transaction(); + + // Create mint account + const mintKp = new anchor.web3.Keypair(); + mintPk = mintKp.publicKey; + const createMintIx = await tokenProgram.account.mint.createInstruction( + mintKp + ); + const initMintIx = await tokenProgram.methods + .initializeMint2(0, owner, null) + .accounts({ mint: mintPk }) + .instruction(); + tx.add(createMintIx, initMintIx); + + // Create token account + const tokenKp = new anchor.web3.Keypair(); + tokenPk = tokenKp.publicKey; + const createTokenIx = await tokenProgram.account.account.createInstruction( + tokenKp + ); + const initTokenIx = await tokenProgram.methods + .initializeAccount3(owner) + .accounts({ account: tokenPk, mint: mintPk }) + .instruction(); + tx.add(createTokenIx, initTokenIx); + + await tokenProgram.provider.sendAndConfirm!(tx, [mintKp, tokenKp]); + }); + + it("AccountInfo", async () => { + await measureComputeUnits("accountInfo"); + }); + + it("Account Empty", async () => { + await measureComputeUnits("accountEmpty"); + }); + + it("Account Sized", async () => { + await measureComputeUnits("accountSized"); + }); + + it("Account Unsized", async () => { + await measureComputeUnits("accountUnsized"); + }); + + it("Boxed Account Empty", async () => { + await measureComputeUnits("boxedAccountEmpty"); + }); + + it("Boxed Account Sized", async () => { + await measureComputeUnits("boxedAccountSized"); + }); + + it("Boxed Account Unsized", async () => { + await measureComputeUnits("boxedAccountUnsized"); + }); + + it("Boxed Interface Account Mint", async () => { + await measureComputeUnits("boxedInterfaceAccountMint", { + generatePublicKey: () => mintPk, + }); + }); + + it("Boxed Interface Account Token", async () => { + await measureComputeUnits("boxedInterfaceAccountToken", { + generatePublicKey: () => tokenPk, + }); + }); + + it("Interface Account Mint", async () => { + await measureComputeUnits("interfaceAccountMint", { + generatePublicKey: () => mintPk, + }); + }); + + it("Interface Account Token", async () => { + await measureComputeUnits("interfaceAccountToken", { + generatePublicKey: () => tokenPk, + accountCounts: [1, 2, 4], + }); + }); + + it("Interface", async () => { + await measureComputeUnits("interface", { + generatePublicKey: () => token.SPL_TOKEN_PROGRAM_ID, + }); + }); + + it("Program", async () => { + await measureComputeUnits("program", { + generatePublicKey: () => anchor.web3.SystemProgram.programId, + }); + }); + + it("Signer", async () => { + await measureComputeUnits("signer"); + }); + + it("SystemAccount", async () => { + await measureComputeUnits("systemAccount"); + }); + + it("UncheckedAccount", async () => { + await measureComputeUnits("uncheckedAccount"); + }); + + after(async () => { + // Read the bench data file + const bench = await BenchData.open(); + + // Compare and update compute units changes + const oldComputeUnits = bench.getUnreleased().computeUnits; + const { needsUpdate } = bench.compareComputeUnits( + computeUnits, + oldComputeUnits, + (ixName, newComputeUnits) => { + oldComputeUnits[ixName] = newComputeUnits; + } + ); + + if (needsUpdate) { + console.log("Updating benchmark files..."); + + // Save bench data file + // (needs to happen before running the `update-bench` script) + await bench.save(); + + spawnSync("anchor", ["run", "update-bench"]); + } + }); +}); diff --git a/tests/bench/tsconfig.json b/tests/bench/tsconfig.json new file mode 100644 index 0000000000..3ffb85198f --- /dev/null +++ b/tests/bench/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai", "node"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015", "dom"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true + } +} diff --git a/tests/package.json b/tests/package.json index 0c6795a1a7..64befea791 100644 --- a/tests/package.json +++ b/tests/package.json @@ -8,6 +8,7 @@ "workspaces": [ "anchor-cli-account", "anchor-cli-idl", + "bench", "cashiers-check", "cfo", "chat", diff --git a/version-bump.sh b/version-bump.sh index 4ad0df5da8..b99524571d 100755 --- a/version-bump.sh +++ b/version-bump.sh @@ -7,7 +7,9 @@ if [ $# -eq 0 ]; then exit 1 fi -echo "Bumping versions to $1" +version=$1 + +echo "Bumping versions to $version" # GNU/BSD compat sedi=(-i) @@ -16,28 +18,34 @@ case "$(uname)" in Darwin*) sedi=(-i "") esac -git grep -l $(cat VERSION) -- ':!**/yarn.lock' ':!CHANGELOG.md' ':!Cargo.lock' ':!package.json' | \ +# Don't replace version with the following globs +skip_globs=":!**/yarn.lock :!Cargo.lock :!package.json :!tests/bench/bench.json :!bench/*.md" + +git grep -l $(cat VERSION) -- $skip_globs | xargs sed "${sedi[@]}" \ - -e "s/$(cat VERSION)/$1/g" + -e "s/$(cat VERSION)/$version/g" # Potential for collisions in package.json files, handle those separately # Replace only matching "version": "x.xx.x" and "@coral-xyz/anchor": "x.xx.x" git grep -l $(cat VERSION) -- '**/package.json' | \ xargs sed "${sedi[@]}" \ - -e "s/@coral-xyz\/anchor\": \"$(cat VERSION)\"/@coral-xyz\/anchor\": \"$1\"/g" \ - -e "s/\"version\": \"$(cat VERSION)\"/\"version\": \"$1\"/g" + -e "s/@coral-xyz\/anchor\": \"$(cat VERSION)\"/@coral-xyz\/anchor\": \"$version\"/g" \ + -e "s/\"version\": \"$(cat VERSION)\"/\"version\": \"$version\"/g" # Potential for collisions in Cargo.lock, use cargo update to update it cargo update --workspace # Insert version number into CHANGELOG.md -sed "${sedi[@]}" -e "s/## \[Unreleased\]/## [Unreleased]\n\n## [$1] - $(date '+%Y-%m-%d')/g" CHANGELOG.md +sed "${sedi[@]}" -e "s/## \[Unreleased\]/## [Unreleased]\n\n## [$version] - $(date '+%Y-%m-%d')/g" CHANGELOG.md pushd ts && yarn && popd pushd tests && yarn && popd pushd examples && yarn && pushd tutorial && yarn && popd && popd -echo $1 > VERSION +# Bump benchmark files +pushd tests/bench && anchor run bump-version -- $version && popd + +echo $version > VERSION echo "$(git diff --stat | tail -n1) files modified" From c14ae6b4f8ac284c155cb146436c6de6e59c4603 Mon Sep 17 00:00:00 2001 From: Tuan Pham Minh Date: Wed, 26 Apr 2023 00:07:39 +0700 Subject: [PATCH 02/11] Fix typo of `is_signer` field in intro-to-solana docs page (#2469) --- docs/src/pages/docs/intro-to-solana.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/pages/docs/intro-to-solana.md b/docs/src/pages/docs/intro-to-solana.md index dd0e4b52d7..a491e0270e 100644 --- a/docs/src/pages/docs/intro-to-solana.md +++ b/docs/src/pages/docs/intro-to-solana.md @@ -31,7 +31,7 @@ The first point means that even if in theory the program may read and write to a > This design is partly responsible for Solana’s high throughput. The runtime can look at all the incoming transactions of a program (and even across programs) and can check whether the memory regions in the first argument of the transactions overlap. If they don’t, the runtime can run these transactions in parallel because they don’t conflict with each other. Even better, if the runtime sees that two transactions access overlapping memory regions but only read and don’t write, it can also parallelize those transactions because they do not conflict with each other. -How exactly can a transaction specify a memory region/account? To answer that, we need to look deeper into what properties an account has ([docs here](https://docs.rs/solana-program/latest/solana_program/account_info/struct.AccountInfo.html)). This is the data structure for an account in a transaction. The `is_signer` and `is_writable` fields are set per transaction (e.g. `is_signed` is set if the corresponding private key of the account's `key` field signed the transaction) and are not part of the metadata that is saved in the heap). In front of the user data that the account can store (in the `data` field) , there is some metadata connected to each account. First, it has a key property which is a ed25519 public key and serves as the address of the account. This is how the transaction can specify which accounts the program may access in the transaction. +How exactly can a transaction specify a memory region/account? To answer that, we need to look deeper into what properties an account has ([docs here](https://docs.rs/solana-program/latest/solana_program/account_info/struct.AccountInfo.html)). This is the data structure for an account in a transaction. The `is_signer` and `is_writable` fields are set per transaction (e.g. `is_signer` is set if the corresponding private key of the account's `key` field signed the transaction) and are not part of the metadata that is saved in the heap). In front of the user data that the account can store (in the `data` field) , there is some metadata connected to each account. First, it has a key property which is a ed25519 public key and serves as the address of the account. This is how the transaction can specify which accounts the program may access in the transaction. ![Transaction](/transaction.svg) From 876ef416107355b4ac4c0a31b8048c471ae09675 Mon Sep 17 00:00:00 2001 From: Proph3t Date: Thu, 27 Apr 2023 08:53:04 +0000 Subject: [PATCH 03/11] docs: fix broken links in `AccountLoader` docs (#2473) --- lang/src/accounts/account_loader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/src/accounts/account_loader.rs b/lang/src/accounts/account_loader.rs index 1d2d2861bd..5305b7fa44 100644 --- a/lang/src/accounts/account_loader.rs +++ b/lang/src/accounts/account_loader.rs @@ -21,7 +21,7 @@ use std::ops::DerefMut; /// Type facilitating on demand zero copy deserialization. /// /// Note that using accounts in this way is distinctly different from using, -/// for example, the [`Account`](./struct.Account.html). Namely, +/// for example, the [`Account`](crate::accounts::account::Account). Namely, /// one must call /// - `load_init` after initializing an account (this will ignore the missing /// account discriminator that gets added only after the user's instruction code) @@ -29,7 +29,7 @@ use std::ops::DerefMut; /// - `load_mut` when the account is mutable /// /// For more details on zero-copy-deserialization, see the -/// [`account`](./attr.account.html) attribute. +/// [`account`](crate::account) attribute. ///

/// ⚠️ When using this type it's important to be mindful /// of any calls to the load functions so as not to From 03b1e4df6b3b70895b3ce29118f8b3c7c483ce12 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Thu, 27 Apr 2023 12:10:23 +0200 Subject: [PATCH 04/11] Upgrade `clap` to 4.2.4 (#2474) --- Cargo.lock | 437 ++++++++++++++++++++++++-------------- avm/Cargo.lock | 338 ++++++++++++++++++++--------- avm/Cargo.toml | 6 +- cli/Cargo.toml | 2 +- client/example/Cargo.toml | 2 +- 5 files changed, 525 insertions(+), 260 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8fb158eb4..89efdfbf63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,8 +101,8 @@ version = "0.27.0" dependencies = [ "anchor-syn", "anyhow", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "regex", "syn 1.0.109", ] @@ -114,8 +114,8 @@ dependencies = [ "anchor-syn", "anyhow", "bs58 0.4.0", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "rustversion", "syn 1.0.109", ] @@ -125,7 +125,7 @@ name = "anchor-attribute-constant" version = "0.27.0" dependencies = [ "anchor-syn", - "proc-macro2 1.0.47", + "proc-macro2 1.0.56", "syn 1.0.109", ] @@ -134,8 +134,8 @@ name = "anchor-attribute-error" version = "0.27.0" dependencies = [ "anchor-syn", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -145,8 +145,8 @@ version = "0.27.0" dependencies = [ "anchor-syn", "anyhow", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -156,8 +156,8 @@ version = "0.27.0" dependencies = [ "anchor-syn", "anyhow", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -171,7 +171,7 @@ dependencies = [ "anyhow", "cargo_toml", "chrono", - "clap 4.0.26", + "clap 4.2.4", "dirs", "flate2", "heck 0.4.0", @@ -216,8 +216,8 @@ version = "0.27.0" dependencies = [ "anchor-syn", "anyhow", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -225,8 +225,8 @@ dependencies = [ name = "anchor-derive-space" version = "0.27.0" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -272,8 +272,8 @@ dependencies = [ "anyhow", "bs58 0.3.1", "heck 0.3.3", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "serde", "serde_json", "sha2 0.9.9", @@ -299,6 +299,55 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "anyhow" version = "1.0.66" @@ -354,7 +403,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.109", ] @@ -366,7 +415,7 @@ checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ "num-bigint 0.4.3", "num-traits", - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.109", ] @@ -445,8 +494,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", "synstructure", ] @@ -457,8 +506,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -497,8 +546,8 @@ version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -634,7 +683,7 @@ dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.47", + "proc-macro2 1.0.56", "syn 1.0.109", ] @@ -644,8 +693,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -655,8 +704,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -724,8 +773,8 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9e1f5fa78f69496407a27ae9ed989e3c3b072310286f5ef385525e4cbc24a9" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -844,30 +893,38 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.26" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", - "clap_lex 0.3.0", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex 0.4.1", "strsim 0.10.0", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck 0.4.0", - "proc-macro-error", - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.109", + "proc-macro2 1.0.56", + "quote 1.0.26", + "syn 2.0.15", ] [[package]] @@ -881,12 +938,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "codespan-reporting" @@ -898,6 +952,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "combine" version = "3.8.1" @@ -1104,8 +1164,8 @@ dependencies = [ "cc", "codespan-reporting", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "scratch", "syn 1.0.109", ] @@ -1122,8 +1182,8 @@ version = "1.0.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1145,8 +1205,8 @@ checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "strsim 0.10.0", "syn 1.0.109", ] @@ -1158,7 +1218,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ "darling_core", - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.109", ] @@ -1203,8 +1263,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1292,8 +1352,8 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1406,8 +1466,8 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "355f93763ef7b0ae1c43c4d8eccc9d5848d84ad1a1d8ce61c421d1ac85a19d05" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1418,8 +1478,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eb359f1476bf611266ac1f5355bc14aeca37b299d0ebccc038ee7058891c9cb" dependencies = [ "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1438,8 +1498,8 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1458,13 +1518,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1605,8 +1665,8 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -1770,12 +1830,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "histogram" @@ -1988,12 +2045,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.4" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ + "hermit-abi 0.3.1", "libc", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -2004,14 +2062,14 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" [[package]] name = "is-terminal" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -2117,9 +2175,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libloading" @@ -2190,9 +2248,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "lock_api" @@ -2345,7 +2403,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12989bc45715b0ee91944855130131479f9c772e198a910c3eb0ea327d5bffc3" dependencies = [ - "quote 1.0.21", + "quote 1.0.26", "syn 1.0.109", ] @@ -2443,8 +2501,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -2516,8 +2574,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" dependencies = [ "proc-macro-crate 1.2.1", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -2694,8 +2752,8 @@ checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" dependencies = [ "phf_generator", "phf_shared 0.11.1", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -2811,30 +2869,6 @@ dependencies = [ "toml", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2 1.0.47", - "quote 1.0.21", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", - "version_check", -] - [[package]] name = "proc-macro2" version = "0.4.30" @@ -2846,9 +2880,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -2923,11 +2957,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ - "proc-macro2 1.0.47", + "proc-macro2 1.0.56", ] [[package]] @@ -3233,16 +3267,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.7" +version = "0.37.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -3342,8 +3376,8 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdbda6ac5cd1321e724fa9cee216f3a61885889b896f073b8f82322789c5250e" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -3428,8 +3462,8 @@ version = "1.0.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -3473,8 +3507,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1966009f3c05f095697c537312f5415d1e3ed31ce0a56942bac4c771c5c335e" dependencies = [ "darling", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -3586,8 +3620,8 @@ version = "0.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63927d22a1e8b74bda98cc6e151fcdf178b7abb0dc6c4f81e0bbf5ffe2fc4ec8" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "shank_macro_impl", "syn 1.0.109", ] @@ -3599,8 +3633,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce03403df682f80f4dc1efafa87a4d0cb89b03726d0565e6364bdca5b9a441" dependencies = [ "anyhow", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "serde", "syn 1.0.109", ] @@ -3883,8 +3917,8 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06395428329810ade1d2518a7e75d8a6f02d01fe548aabb60ff1ba6a2eaebbe5" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "rustc_version 0.4.0", "syn 1.0.109", ] @@ -4258,8 +4292,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f809319358d5da7c3a0ac08ebf4d87b21170d928dbb7260254e8f3061f7f9e0e" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "rustversion", "syn 1.0.109", ] @@ -4608,8 +4642,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2 1.0.56", + "quote 1.0.26", "unicode-ident", ] @@ -4619,8 +4664,8 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", "unicode-xid 0.2.4", ] @@ -4710,8 +4755,8 @@ version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -4824,8 +4869,8 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -4914,8 +4959,8 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", ] @@ -5089,6 +5134,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "vec_map" version = "0.8.2" @@ -5165,8 +5216,8 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", "wasm-bindgen-shared", ] @@ -5189,7 +5240,7 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" dependencies = [ - "quote 1.0.21", + "quote 1.0.26", "wasm-bindgen-macro-support", ] @@ -5199,8 +5250,8 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -5291,21 +5342,51 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", + "windows_aarch64_gnullvm 0.42.0", "windows_aarch64_msvc 0.42.0", "windows_i686_gnu 0.42.0", "windows_i686_msvc 0.42.0", "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", + "windows_x86_64_gnullvm 0.42.0", "windows_x86_64_msvc 0.42.0", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -5318,6 +5399,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.36.1" @@ -5330,6 +5417,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.36.1" @@ -5342,6 +5435,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" @@ -5354,12 +5453,24 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" @@ -5372,6 +5483,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winreg" version = "0.10.1" @@ -5442,8 +5559,8 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ - "proc-macro2 1.0.47", - "quote 1.0.21", + "proc-macro2 1.0.56", + "quote 1.0.26", "syn 1.0.109", "synstructure", ] diff --git a/avm/Cargo.lock b/avm/Cargo.lock index 6ec821b121..f47d50f177 100644 --- a/avm/Cargo.lock +++ b/avm/Cargo.lock @@ -3,22 +3,60 @@ version = 3 [[package]] -name = "anyhow" -version = "1.0.66" +name = "anstream" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] [[package]] -name = "atty" -version = "0.2.14" +name = "anstyle" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "utf8parse", ] +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" + [[package]] name = "autocfg" version = "1.1.0" @@ -86,40 +124,51 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.0.26" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", - "clap_lex", "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "dirs" @@ -150,6 +199,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.8.0" @@ -273,6 +343,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "http" version = "0.2.8" @@ -373,12 +449,35 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "ipnet" version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "itoa" version = "1.0.4" @@ -396,9 +495,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" + +[[package]] +name = "linux-raw-sys" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "log" @@ -430,7 +535,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -439,7 +544,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -449,12 +554,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - [[package]] name = "percent-encoding" version = "2.2.0" @@ -473,44 +572,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -598,6 +673,20 @@ dependencies = [ "winapi", ] +[[package]] +name = "rustix" +version = "0.37.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustls" version = "0.20.8" @@ -658,7 +747,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -726,6 +815,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tempfile" version = "3.3.0" @@ -740,15 +840,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.37" @@ -766,7 +857,7 @@ checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", ] [[package]] @@ -798,7 +889,7 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -897,10 +988,10 @@ dependencies = [ ] [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "want" @@ -939,7 +1030,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.103", "wasm-bindgen-shared", ] @@ -973,7 +1064,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.103", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1029,15 +1120,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1050,13 +1132,37 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.0", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm 0.42.0", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -1065,42 +1171,84 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "winreg" version = "0.10.1" diff --git a/avm/Cargo.toml b/avm/Cargo.toml index 40ddf76067..dc314cdec0 100644 --- a/avm/Cargo.toml +++ b/avm/Cargo.toml @@ -13,16 +13,16 @@ name = "anchor" path = "src/anchor/main.rs" [dependencies] -clap = { version = "4.0.26", features = [ "derive" ]} +clap = { version = "4.2.4", features = ["derive"]} cfg-if = "1.0.0" anyhow = "1.0.32" dirs = "4.0.0" semver = "1.0.4" -serde = { version = "1.0.136", features = [ "derive" ]} +serde = { version = "1.0.136", features = ["derive"] } serde_json = "1.0.78" thiserror = "1.0.30" once_cell = { version = "1.8.0" } -reqwest = { version = "0.11.9", default-features = false, features = ['blocking', 'json', 'rustls-tls'] } +reqwest = { version = "0.11.9", default-features = false, features = ["blocking", "json", "rustls-tls"] } tempfile = "3.3.0" [workspace] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 6daa019eca..63537baf59 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -17,7 +17,7 @@ dev = [] default = [] [dependencies] -clap = { version = "4.0.26", features = ["derive"] } +clap = { version = "4.2.4", features = ["derive"] } anyhow = "1.0.32" syn = { version = "1.0.60", features = ["full", "extra-traits"] } anchor-lang = { path = "../lang", version = "0.27.0" } diff --git a/client/example/Cargo.toml b/client/example/Cargo.toml index 5af6efd894..56768daab0 100644 --- a/client/example/Cargo.toml +++ b/client/example/Cargo.toml @@ -16,5 +16,5 @@ optional = { path = "../../tests/optional/programs/optional", features = ["no-en events = { path = "../../tests/events/programs/events", features = ["no-entrypoint"] } shellexpand = "2.1.0" anyhow = "1.0.32" -clap = { version = "4.0.26", features = ["derive"] } +clap = { version = "4.2.4", features = ["derive"] } solana-sdk = "1.14.16" From a195106117ebaa6ab97e8963b7f1d66225eee4bc Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Mon, 1 May 2023 13:39:50 +0200 Subject: [PATCH 05/11] spl: Use fixed version for `winnow` crate to fix new builds (#2478) --- Cargo.lock | 10 ++++++++++ spl/Cargo.toml | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 89efdfbf63..38b49d6f22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -263,6 +263,7 @@ dependencies = [ "spl-associated-token-account", "spl-token", "spl-token-2022", + "winnow", ] [[package]] @@ -5489,6 +5490,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/spl/Cargo.toml b/spl/Cargo.toml index 0c4f21af13..659503c80f 100644 --- a/spl/Cargo.toml +++ b/spl/Cargo.toml @@ -29,3 +29,8 @@ spl-token = { version = "3.5.0", features = ["no-entrypoint"], optional = true } spl-token-2022 = { version = "0.5.0", features = ["no-entrypoint"], optional = true } spl-associated-token-account = { version = "1.1.1", features = ["no-entrypoint"], optional = true } mpl-token-metadata = { version = "^1.9.0", optional = true, features = ["no-entrypoint"] } + +# TODO: Remove after updating to latest version of platform-tools. +# Latest solana version(1.14.17) as of 2023-05-01 comes with rustc 1.62.0-dev but MSRV for latest +# version of this crate is 1.64.0. See https://github.com/solana-labs/solana/pull/31418 +winnow = "=0.4.1" From c1667120e6d44d4a9a2ed4d49f20443ca99ce41e Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Wed, 3 May 2023 09:09:41 +0200 Subject: [PATCH 06/11] bench: Add a script to sync benchmark results for all versions (#2477) --- tests/bench/Anchor.toml | 7 +- tests/bench/README.md | 14 +- tests/bench/programs/bench/Cargo.toml | 5 + tests/bench/programs/bench/src/lib.rs | 4 +- .../{update-bench.ts => sync-markdown.ts} | 28 ++-- tests/bench/scripts/sync.ts | 66 +++++++++ tests/bench/scripts/utils.ts | 140 +++++++++++++++--- tests/bench/tests/compute-units.ts | 20 ++- 8 files changed, 236 insertions(+), 48 deletions(-) rename tests/bench/scripts/{update-bench.ts => sync-markdown.ts} (68%) create mode 100644 tests/bench/scripts/sync.ts diff --git a/tests/bench/Anchor.toml b/tests/bench/Anchor.toml index 8e0cf1d521..661873a265 100644 --- a/tests/bench/Anchor.toml +++ b/tests/bench/Anchor.toml @@ -3,13 +3,14 @@ cluster = "localnet" wallet = "~/.config/solana/id.json" [programs.localnet] -bench = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" +bench = "Bench11111111111111111111111111111111111111" [workspace] members = ["programs/bench"] [scripts] -test = "yarn run ts-mocha -t 1000000 -p ./tsconfig.json -t 1000000 tests/**/*.ts" -update-bench = "yarn run ts-node scripts/update-bench.ts" +test = "yarn run ts-mocha -t 1000000 -p ./tsconfig.json tests/**/*.ts" +sync = "yarn run ts-node scripts/sync.ts" +sync-markdown = "yarn run ts-node scripts/sync-markdown.ts" generate-ix = "yarn run ts-node scripts/generate-ix.ts" bump-version = "yarn run ts-node scripts/bump-version.ts" diff --git a/tests/bench/README.md b/tests/bench/README.md index b57b50d0f8..061e1d54ac 100644 --- a/tests/bench/README.md +++ b/tests/bench/README.md @@ -4,21 +4,25 @@ The bench program and its tests are used to measure the performance of Anchor pr ## How -Create a program -> Write tests that measure usage -> Compare the results -> Save the new result - -The script will check whether there is a difference between the current result and the last saved result(in `bench.json`) at the end of the tests. If the difference between the results is greater than 1%, the new data will be saved in `bench.json` and Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) will be updated accordingly. +We run the same tests that measure some metric for each Anchor version starting from `0.27.0`. If the difference between the results is greater than 1%, the new data will be saved in `bench.json` and Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) will be updated accordingly. ## Scripts +| :memo: TL;DR | +| :----------------------------------------------------------------------------------------------------------------------------- | +| If you've made changes to programs or tests in this directory, run `anchor run sync`, otherwise run `anchor test --skip-lint`. | + `anchor test --skip-lint`: Run all tests and update benchmark files when necessary. This is the only command that needs to be run for most use cases. --- The following scripts are useful when making changes to how benchmarking works. -`anchor run update-bench`: Update Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) based on the data from `bench.json`. +`anchor run sync`: Sync all benchmark files by running tests for each version. If you've made changes to the bench program or its tests, you should run this command to sync the results. + +`anchor run sync-markdown`: Sync Markdown files in [/bench](https://github.com/coral-xyz/anchor/tree/master/bench) based on the data from `bench.json`. -`anchor run generate-ix`: Generate instructions with repetitive accounts. +`anchor run generate-ix`: Generate program instructions with repetitive accounts. --- diff --git a/tests/bench/programs/bench/Cargo.toml b/tests/bench/programs/bench/Cargo.toml index d7b162620b..1d21010acf 100644 --- a/tests/bench/programs/bench/Cargo.toml +++ b/tests/bench/programs/bench/Cargo.toml @@ -14,3 +14,8 @@ cpi = ["no-entrypoint"] [dependencies] anchor-lang = { path = "../../../../lang" } anchor-spl = { path = "../../../../spl" } + +# TODO: Remove this and store lock files for each version instead. +# Latest solana version(1.14.17) as of 2023-05-01 comes with rustc 1.62.0-dev but MSRV for latest +# version of this crate is 1.64.0. See https://github.com/solana-labs/solana/pull/31418 +winnow = "=0.4.1" diff --git a/tests/bench/programs/bench/src/lib.rs b/tests/bench/programs/bench/src/lib.rs index e9a2a6b8e1..acfa1bd5d6 100644 --- a/tests/bench/programs/bench/src/lib.rs +++ b/tests/bench/programs/bench/src/lib.rs @@ -1,9 +1,11 @@ //! This program is used to measure the performance of Anchor programs. +//! +//! If you are making a change to this program, run `anchor run sync`. use anchor_lang::prelude::*; use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface}; -declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); +declare_id!("Bench11111111111111111111111111111111111111"); #[program] pub mod bench { diff --git a/tests/bench/scripts/update-bench.ts b/tests/bench/scripts/sync-markdown.ts similarity index 68% rename from tests/bench/scripts/update-bench.ts rename to tests/bench/scripts/sync-markdown.ts index 9b6cd063bb..1c8e1eab3d 100644 --- a/tests/bench/scripts/update-bench.ts +++ b/tests/bench/scripts/sync-markdown.ts @@ -1,4 +1,4 @@ -/** Update Markdown files in /bench */ +/** Sync Markdown files in /bench based on the data from bench.json */ import { BenchData, Markdown } from "./utils"; @@ -33,19 +33,27 @@ import { BenchData, Markdown } from "./utils"; bench.compareComputeUnits( newComputeUnitsResult, oldComputeUnitsResult, - (ixName, newComputeUnits, oldComputeUnits) => { - const percentChange = ( - (newComputeUnits / oldComputeUnits - 1) * - 100 - ).toFixed(2); + ({ ixName, newComputeUnits, oldComputeUnits }) => { + if (newComputeUnits === null) { + // Deleted instruction + return; + } let changeText; - if (isNaN(oldComputeUnits)) { + if (oldComputeUnits === null) { + // New instruction changeText = "N/A"; - } else if (+percentChange > 0) { - changeText = `🔴 **+${percentChange}%**`; } else { - changeText = `🟢 **${percentChange}%**`; + const percentChange = ( + (newComputeUnits / oldComputeUnits - 1) * + 100 + ).toFixed(2); + + if (+percentChange > 0) { + changeText = `🔴 **+${percentChange}%**`; + } else { + changeText = `🟢 **${percentChange}%**`; + } } table.insert(ixName, newComputeUnits.toString(), changeText); diff --git a/tests/bench/scripts/sync.ts b/tests/bench/scripts/sync.ts new file mode 100644 index 0000000000..b535921d18 --- /dev/null +++ b/tests/bench/scripts/sync.ts @@ -0,0 +1,66 @@ +/** + * Sync all saved data by re-running the tests for each version. + * + * This script should be used when the bench program or its tests has changed + * and all data needs to be updated. + */ + +import path from "path"; +import { spawnSync } from "child_process"; + +import { ANCHOR_VERSION_ARG, BenchData, Toml } from "./utils"; + +(async () => { + const bench = await BenchData.open(); + + const cargoToml = await Toml.open( + path.join("..", "programs", "bench", "Cargo.toml") + ); + const anchorToml = await Toml.open(path.join("..", "Anchor.toml")); + + for (const version of bench.getVersions()) { + console.log(`Updating '${version}'...`); + + const isUnreleased = version === "unreleased"; + + // Update the anchor dependency versions + for (const dependency of ["lang", "spl"]) { + cargoToml.replaceValue(`anchor-${dependency}`, () => { + return isUnreleased + ? `{ path = "../../../../${dependency}" }` + : `"${version}"`; + }); + } + + // Save Cargo.toml + await cargoToml.save(); + + // Update `anchor test` command to pass version in Anchor.toml + anchorToml.replaceValue( + "test", + (cmd) => { + return cmd.includes(ANCHOR_VERSION_ARG) + ? cmd.replace( + new RegExp(`\\s*${ANCHOR_VERSION_ARG}\\s+(.+)`), + (arg, ver) => (isUnreleased ? "" : arg.replace(ver, version)) + ) + : `${cmd} ${ANCHOR_VERSION_ARG} ${version}`; + }, + { insideQuotes: true } + ); + + // Save Anchor.toml + await anchorToml.save(); + + // Run the command to update the current version's results + const result = spawnSync("anchor", ["test", "--skip-lint"]); + console.log(result.output.toString()); + + // Check for failure + if (result.status !== 0) { + console.error("Please fix the error and re-run this command."); + process.exitCode = 1; + return; + } + } +})(); diff --git a/tests/bench/scripts/utils.ts b/tests/bench/scripts/utils.ts index 8350cbbb61..02bd38804d 100644 --- a/tests/bench/scripts/utils.ts +++ b/tests/bench/scripts/utils.ts @@ -2,6 +2,9 @@ import * as fs from "fs/promises"; import path from "path"; import { spawnSync } from "child_process"; +/** Version that is used in bench data file */ +export type Version = "unreleased" | (`${number}.${number}.${number}` & {}); + /** Persistent benchmark data(mapping of `Version -> Data`) */ type Bench = { [key: string]: { @@ -21,7 +24,10 @@ export type ComputeUnits = { [key: string]: number }; export const THRESHOLD_PERCENTAGE = 1; /** Path to the benchmark Markdown files */ -export const BENCH_DIR_PATH = "../../bench"; +export const BENCH_DIR_PATH = path.join("..", "..", "bench"); + +/** Command line argument for Anchor version */ +export const ANCHOR_VERSION_ARG = "--anchor-version"; /** Utility class to handle benchmark data related operations */ export class BenchData { @@ -56,43 +62,74 @@ export class BenchData { } /** Get the stored results based on version */ - get(version: string) { + get(version: Version) { return this.#data[version]; } - /** Get unreleased version results */ - getUnreleased() { - return this.get("unreleased"); - } - /** Get all versions */ getVersions() { - return Object.keys(this.#data); + return Object.keys(this.#data) as Version[]; } /** Compare and update compute units changes */ compareComputeUnits( newComputeUnitsResult: ComputeUnits, oldComputeUnitsResult: ComputeUnits, - changeCb: ( - ixName: string, - newComputeUnits: number, - oldComputeUnits: number - ) => void, + changeCb: (args: { + ixName: string; + newComputeUnits: number | null; + oldComputeUnits: number | null; + }) => void, noChangeCb?: (ixName: string, computeUnits: number) => void ) { let needsUpdate = false; + const checkIxs = ( + comparedFrom: ComputeUnits, + comparedTo: ComputeUnits, + cb: (ixName: string, computeUnits: number) => void + ) => { + for (const ixName in comparedFrom) { + if (comparedTo[ixName] === undefined) { + cb(ixName, comparedFrom[ixName]); + } + } + }; + + // New instruction + checkIxs( + newComputeUnitsResult, + oldComputeUnitsResult, + (ixName, computeUnits) => { + console.log(`New instruction '${ixName}'`); + changeCb({ + ixName, + newComputeUnits: computeUnits, + oldComputeUnits: null, + }); + needsUpdate = true; + } + ); + + // Deleted instruction + checkIxs( + oldComputeUnitsResult, + newComputeUnitsResult, + (ixName, computeUnits) => { + console.log(`Deleted instruction '${ixName}'`); + changeCb({ + ixName, + newComputeUnits: null, + oldComputeUnits: computeUnits, + }); + needsUpdate = true; + } + ); + // Compare compute units changes for (const ixName in newComputeUnitsResult) { const oldComputeUnits = oldComputeUnitsResult[ixName]; const newComputeUnits = newComputeUnitsResult[ixName]; - if (!oldComputeUnits) { - console.log(`New instruction '${ixName}'`); - needsUpdate = true; - changeCb(ixName, newComputeUnits, NaN); - continue; - } const percentage = THRESHOLD_PERCENTAGE / 100; const oldMaximumAllowedDelta = oldComputeUnits * percentage; @@ -119,8 +156,12 @@ export class BenchData { `Compute units change '${ixName}' (${oldComputeUnits} -> ${newComputeUnits})` ); + changeCb({ + ixName, + newComputeUnits, + oldComputeUnits, + }); needsUpdate = true; - changeCb(ixName, newComputeUnits, oldComputeUnits); } else { noChangeCb?.(ixName, newComputeUnits); } @@ -131,14 +172,14 @@ export class BenchData { /** Bump benchmark data version to the given version */ bumpVersion(newVersion: string) { - const versions = Object.keys(this.#data); - const unreleasedVersion = versions[versions.length - 1]; - if (this.#data[newVersion]) { console.error(`Version '${newVersion}' already exists!`); process.exit(1); } + const versions = this.getVersions(); + const unreleasedVersion = versions[versions.length - 1]; + // Add the new version this.#data[newVersion] = this.get(unreleasedVersion); @@ -296,3 +337,56 @@ class MarkdownTable { ); } } + +/** Utility class to handle TOML related operations */ +export class Toml { + /** TOML filepath */ + #path: string; + + /** TOML text */ + #text: string; + + constructor(path: string, text: string) { + this.#path = path; + this.#text = text; + } + + /** Open the TOML file */ + static async open(tomlPath: string) { + tomlPath = path.join(__dirname, tomlPath); + const text = await fs.readFile(tomlPath, { + encoding: "utf8", + }); + return new Toml(tomlPath, text); + } + + /** Save the TOML file */ + async save() { + await fs.writeFile(this.#path, this.#text); + } + + /** Replace the value for the given key */ + replaceValue( + key: string, + cb: (previous: string) => string, + opts?: { insideQuotes: boolean } + ) { + this.#text = this.#text.replace( + new RegExp(`${key}\\s*=\\s*${opts?.insideQuotes ? `"(.*)"` : "(.*)"}`), + (line, value) => line.replace(value, cb(value)) + ); + } +} + +/** + * Get Anchor version from the passed arguments. + * + * Defaults to `unreleased`. + */ +export const getVersionFromArgs = () => { + const args = process.argv; + const anchorVersionArgIndex = args.indexOf(ANCHOR_VERSION_ARG); + return anchorVersionArgIndex === -1 + ? "unreleased" + : (args[anchorVersionArgIndex + 1] as Version); +}; diff --git a/tests/bench/tests/compute-units.ts b/tests/bench/tests/compute-units.ts index 4b5c8fbc2a..77e0a778d8 100644 --- a/tests/bench/tests/compute-units.ts +++ b/tests/bench/tests/compute-units.ts @@ -3,7 +3,7 @@ import * as token from "@coral-xyz/spl-token"; import { spawnSync } from "child_process"; import { Bench, IDL } from "../target/types/bench"; -import { BenchData, ComputeUnits } from "../scripts/utils"; +import { BenchData, ComputeUnits, getVersionFromArgs } from "../scripts/utils"; describe(IDL.name, () => { // Configure the client to use the local cluster @@ -226,12 +226,17 @@ describe(IDL.name, () => { const bench = await BenchData.open(); // Compare and update compute units changes - const oldComputeUnits = bench.getUnreleased().computeUnits; + const version = getVersionFromArgs(); + const oldComputeUnits = bench.get(version).computeUnits; const { needsUpdate } = bench.compareComputeUnits( computeUnits, oldComputeUnits, - (ixName, newComputeUnits) => { - oldComputeUnits[ixName] = newComputeUnits; + ({ ixName, newComputeUnits: newValue }) => { + if (newValue === null) { + delete oldComputeUnits[ixName]; + } else { + oldComputeUnits[ixName] = newValue; + } } ); @@ -239,10 +244,13 @@ describe(IDL.name, () => { console.log("Updating benchmark files..."); // Save bench data file - // (needs to happen before running the `update-bench` script) + // (needs to happen before running the `sync-markdown` script) await bench.save(); - spawnSync("anchor", ["run", "update-bench"]); + // Only update markdown files on `unreleased` version + if (version === "unreleased") { + spawnSync("anchor", ["run", "sync-markdown"]); + } } }); }); From ac86e15756b8bde5d15fde5ebe0f46f47bcb5049 Mon Sep 17 00:00:00 2001 From: Matthew Callens Date: Wed, 3 May 2023 17:53:46 -0500 Subject: [PATCH 07/11] spl: remove mpl `create_metadata_account_v2` wrapper that were removed from program (#2480) * remove mpl ix wrappers that were removed from program * update changelog --- CHANGELOG.md | 1 + Cargo.lock | 8 +++---- spl/Cargo.toml | 2 +- spl/src/metadata.rs | 57 ++------------------------------------------- 4 files changed, 8 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10e4703c31..68c1b397e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ The minor version will be incremented upon a breaking change and the patch versi ### Breaking - lang: Identifiers that are intended for internal usage(`program_id`, `accounts`, `ix_data`, `remaining_accounts`) have been renamed with `__` prefix ([#2464](https://github.com/coral-xyz/anchor/pull/2464)) +- spl: Remove the `metadata::create_metadata_account_v2` deprecated wrapper since it was removed from token metadata program ([#2480](https://github.com/coral-xyz/anchor/pull/2480)) ## [0.27.0] - 2023-03-08 diff --git a/Cargo.lock b/Cargo.lock index 38b49d6f22..a56e49d6c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2380,9 +2380,9 @@ dependencies = [ [[package]] name = "mpl-token-metadata" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8831a402e72f24052d019a83d72b70c38673caaf198e6e345575a77f98166b1" +checksum = "aed414104154928aa995a44a0a474c449d04ce5a4ee6c975ad41c5d2912f0dfe" dependencies = [ "arrayref", "borsh", @@ -2410,9 +2410,9 @@ dependencies = [ [[package]] name = "mpl-utils" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc48e64c50dba956acb46eec86d6968ef0401ef37031426da479f1f2b592066" +checksum = "822133b6cba8f9a43e5e0e189813be63dd795858f54155c729833be472ffdb51" dependencies = [ "arrayref", "borsh", diff --git a/spl/Cargo.toml b/spl/Cargo.toml index 659503c80f..3d4b200632 100644 --- a/spl/Cargo.toml +++ b/spl/Cargo.toml @@ -28,7 +28,7 @@ solana-program = "1.14.16" spl-token = { version = "3.5.0", features = ["no-entrypoint"], optional = true } spl-token-2022 = { version = "0.5.0", features = ["no-entrypoint"], optional = true } spl-associated-token-account = { version = "1.1.1", features = ["no-entrypoint"], optional = true } -mpl-token-metadata = { version = "^1.9.0", optional = true, features = ["no-entrypoint"] } +mpl-token-metadata = { version = "^1.11.0", optional = true, features = ["no-entrypoint"] } # TODO: Remove after updating to latest version of platform-tools. # Latest solana version(1.14.17) as of 2023-05-01 comes with rustc 1.62.0-dev but MSRV for latest diff --git a/spl/src/metadata.rs b/spl/src/metadata.rs index 98e1672e65..9e2020d57e 100644 --- a/spl/src/metadata.rs +++ b/spl/src/metadata.rs @@ -1,5 +1,6 @@ use anchor_lang::context::CpiContext; -use anchor_lang::{Accounts, ErrorCode, Result, ToAccountInfos}; +use anchor_lang::error::ErrorCode; +use anchor_lang::{Accounts, Result, ToAccountInfos}; use mpl_token_metadata::state::{CollectionDetails, DataV2, TokenMetadataAccount}; use mpl_token_metadata::ID; use solana_program::account_info::AccountInfo; @@ -50,7 +51,6 @@ pub fn bubblegum_set_collection_size<'info>( pub fn burn_edition_nft<'info>( ctx: CpiContext<'_, '_, '_, 'info, BurnEditionNft<'info>>, - collection_metadata: Option, ) -> Result<()> { let ix = mpl_token_metadata::instruction::burn_edition_nft( ID, @@ -95,47 +95,6 @@ pub fn burn_nft<'info>( .map_err(Into::into) } -#[deprecated(note = "internal instructions deprecated by Metaplex")] -pub fn create_metadata_accounts_v2<'info>( - ctx: CpiContext<'_, '_, '_, 'info, CreateMetadataAccountsV2<'info>>, - data: DataV2, - is_mutable: bool, - update_authority_is_signer: bool, -) -> Result<()> { - let DataV2 { - name, - symbol, - uri, - creators, - seller_fee_basis_points, - collection, - uses, - } = data; - let ix = mpl_token_metadata::instruction::create_metadata_accounts_v2( - ID, - *ctx.accounts.metadata.key, - *ctx.accounts.mint.key, - *ctx.accounts.mint_authority.key, - *ctx.accounts.payer.key, - *ctx.accounts.update_authority.key, - name, - symbol, - uri, - creators, - seller_fee_basis_points, - update_authority_is_signer, - is_mutable, - collection, - uses, - ); - solana_program::program::invoke_signed( - &ix, - &ToAccountInfos::to_account_infos(&ctx), - ctx.signer_seeds, - ) - .map_err(Into::into) -} - pub fn create_metadata_accounts_v3<'info>( ctx: CpiContext<'_, '_, '_, 'info, CreateMetadataAccountsV3<'info>>, data: DataV2, @@ -595,18 +554,6 @@ pub struct BurnNft<'info> { pub spl_token: AccountInfo<'info>, } -#[deprecated(note = "internal instructions deprecated by Metaplex")] -#[derive(Accounts)] -pub struct CreateMetadataAccountsV2<'info> { - pub metadata: AccountInfo<'info>, - pub mint: AccountInfo<'info>, - pub mint_authority: AccountInfo<'info>, - pub payer: AccountInfo<'info>, - pub update_authority: AccountInfo<'info>, - pub system_program: AccountInfo<'info>, - pub rent: AccountInfo<'info>, -} - #[derive(Accounts)] pub struct CreateMetadataAccountsV3<'info> { pub metadata: AccountInfo<'info>, From d1ddf002935efedb3fcb4a28aa580afd3d1f88a6 Mon Sep 17 00:00:00 2001 From: CanardMandarin Date: Sun, 7 May 2023 11:03:37 +0200 Subject: [PATCH 08/11] lang: Fix incorrectly checking the first init constraint (#2483) --- lang/syn/src/parser/accounts/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/syn/src/parser/accounts/mod.rs b/lang/syn/src/parser/accounts/mod.rs index d0c8aee763..19a525b8b5 100644 --- a/lang/syn/src/parser/accounts/mod.rs +++ b/lang/syn/src/parser/accounts/mod.rs @@ -162,7 +162,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> { )); } } - match kind { + match &field.constraints.init.as_ref().unwrap().kind { // This doesn't catch cases like account.key() or account.key. // My guess is that doesn't happen often and we can revisit // this if I'm wrong. From 9a93a2eccce37b3d3e3c390966ec11589a16d7ef Mon Sep 17 00:00:00 2001 From: James Date: Mon, 8 May 2023 10:17:51 +0100 Subject: [PATCH 09/11] ts: Improve IDL typing (#2482) * Use XOR pattern for enum variants to prevent two variants being used at the same time. * Fix unknown for types like Option<[u8; 32]> --- .../anchor/src/program/namespace/types.ts | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/ts/packages/anchor/src/program/namespace/types.ts b/ts/packages/anchor/src/program/namespace/types.ts index dd8a0ae94a..ecf9e9c304 100644 --- a/ts/packages/anchor/src/program/namespace/types.ts +++ b/ts/packages/anchor/src/program/namespace/types.ts @@ -124,24 +124,20 @@ type TypeMap = { [K in "u64" | "i64" | "u128" | "i128" | "u256" | "i256"]: BN; }; -export type DecodeType = T extends keyof TypeMap +export type DecodeType = IdlType extends T + ? unknown + : T extends keyof TypeMap ? TypeMap[T] : T extends { defined: keyof Defined } ? Defined[T["defined"]] - : T extends { option: { defined: keyof Defined } } - ? Defined[T["option"]["defined"]] | null - : T extends { option: keyof TypeMap } - ? TypeMap[T["option"]] | null - : T extends { coption: { defined: keyof Defined } } - ? Defined[T["coption"]["defined"]] | null - : T extends { coption: keyof TypeMap } - ? TypeMap[T["coption"]] | null - : T extends { vec: keyof TypeMap } - ? TypeMap[T["vec"]][] - : T extends { vec: { defined: keyof Defined } } - ? Defined[T["vec"]["defined"]][] - : T extends { array: [defined: keyof TypeMap, size: number] } - ? TypeMap[T["array"][0]][] + : T extends { option: IdlType } + ? DecodeType | null + : T extends { coption: IdlType } + ? DecodeType | null + : T extends { vec: IdlType } + ? DecodeType[] + : T extends { array: [defined: IdlType, size: number] } + ? DecodeType[] : unknown; /** @@ -196,18 +192,24 @@ declare type DecodeEnumFields< } : Record; -/** - * Since TypeScript do not provide OneOf helper we can - * simply mark enum variants with +? - */ -declare type DecodeEnum = { - // X = IdlEnumVariant - [X in K["variants"][number] as Uncapitalize]+?: DecodeEnumFields< - NonNullable, +type DecodeEnumVariants = { + [V in I["variants"][number] as Uncapitalize]: DecodeEnumFields< + NonNullable, Defined >; }; +type ValueOf = T[keyof T]; +type XorEnumVariants> = ValueOf<{ + [K1 in keyof T]: { + [K2 in Exclude]?: never; + } & { [K2 in K1]: T[K2] }; +}>; + +type DecodeEnum = XorEnumVariants< + DecodeEnumVariants +>; + type DecodeStruct = { [F in I["fields"][number] as F["name"]]: DecodeType; }; From 714d5248636493a3d1db1481f16052836ee59e94 Mon Sep 17 00:00:00 2001 From: CanardMandarin Date: Tue, 9 May 2023 16:17:11 +0200 Subject: [PATCH 10/11] lang: Add error message when Mint and TokenAccount with `init` are not ordered correctly (#2484) --- lang/syn/src/parser/accounts/mod.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/lang/syn/src/parser/accounts/mod.rs b/lang/syn/src/parser/accounts/mod.rs index 19a525b8b5..dedb6cdb92 100644 --- a/lang/syn/src/parser/accounts/mod.rs +++ b/lang/syn/src/parser/accounts/mod.rs @@ -126,7 +126,7 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> { } } - for field in init_fields { + for (pos, field) in init_fields.iter().enumerate() { // Get payer for init-ed account let associated_payer_name = match field.constraints.init.clone().unwrap().payer { // composite payer, check not supported @@ -178,6 +178,24 @@ fn constraints_cross_checks(fields: &[AccountField]) -> ParseResult<()> { )); } } + + // Make sure initialiazed token accounts are always declared after their corresponding mint. + InitKind::Mint { .. } => { + if init_fields.iter().enumerate().any(|(f_pos, f)| { + match &f.constraints.init.as_ref().unwrap().kind { + InitKind::Token { mint, .. } + | InitKind::AssociatedToken { mint, .. } => { + field.ident == mint.to_token_stream().to_string() && pos > f_pos + } + _ => false, + } + }) { + return Err(ParseError::new( + field.ident.span(), + "because of the init constraint, the mint has to be declared before the corresponding token account", + )); + } + } _ => (), } } From 89e94d1d6ae3c7af79ec1e329b8755c4a8155dfa Mon Sep 17 00:00:00 2001 From: Ryan De La O Date: Sat, 13 May 2023 02:17:47 -0700 Subject: [PATCH 11/11] cli: Fix incorrect metadata.address generation (#2485) Currently when running 'anchor deploy --program-name --program-keypair ' the cli still uses the auto-generated keypair when fetching the program id to add to the IDL metadata at the end. It should instead use the address from the specified keypair. --------- Co-authored-by: acheron --- CHANGELOG.md | 1 + cli/src/lib.rs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68c1b397e8..398f7d1de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The minor version will be incremented upon a breaking change and the patch versi - ts: Narrowed `AccountClient` type to it's appropriate account type ([#2440](https://github.com/coral-xyz/anchor/pull/2440)) - lang: Fix inability to use identifiers `program_id`, `accounts`, `ix_data`, `remaining_accounts` in instruction arguments ([#2464](https://github.com/coral-xyz/anchor/pull/2464)) +- cli: Fix incorrect `metadata.address` generation in IDL after deploying with a custom keypair ([#2485](https://github.com/coral-xyz/anchor/pull/2485)) ### Breaking diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 0f70c8fcf2..b63dbc7a4f 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -3024,9 +3024,17 @@ fn deploy( println!("Program path: {binary_path}..."); - let program_keypair_filepath = match &program_keypair { - Some(program_keypair) => program_keypair.clone(), - None => program.keypair_file()?.path().display().to_string(), + let (program_keypair_filepath, program_id) = match &program_keypair { + Some(path) => ( + path.clone(), + solana_sdk::signature::read_keypair_file(path) + .map_err(|_| anyhow!("Unable to read keypair file"))? + .pubkey(), + ), + None => ( + program.keypair_file()?.path().display().to_string(), + program.pubkey()?, + ), }; // Send deploy transactions. @@ -3049,11 +3057,10 @@ fn deploy( std::process::exit(exit.status.code().unwrap_or(1)); } - let program_pubkey = program.pubkey()?; if let Some(mut idl) = program.idl.as_mut() { // Add program address to the IDL. idl.metadata = Some(serde_json::to_value(IdlTestMetadata { - address: program_pubkey.to_string(), + address: program_id.to_string(), })?); // Persist it.