Verify Token-2022 settlement against the relevant test suite wholistically - #121
Open
kaze-cow wants to merge 1 commit into
Open
Verify Token-2022 settlement against the relevant test suite wholistically#121kaze-cow wants to merge 1 commit into
kaze-cow wants to merge 1 commit into
Conversation
kaze-cow
changed the base branch from
kaze/sc-153-token-2022-program
to
kaze/sc-153-token-2022-settle
August 28, 2026 07:22
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-tests
branch
from
August 28, 2026 07:22
b667e36 to
9f512c4
Compare
This was referenced Aug 28, 2026
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-settle
branch
from
August 28, 2026 08:29
7af181d to
35bb3fe
Compare
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-tests
branch
from
August 28, 2026 08:30
9f512c4 to
223bd0d
Compare
Contributor
Author
|
add an extension for metadata to ensure we have full token2022 situational coverage also double check that test suggestions from base pr have been addressed. |
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-tests
branch
from
September 4, 2026 08:04
223bd0d to
2e22761
Compare
kaze-cow
changed the base branch from
kaze/sc-153-token-2022-settle
to
kaze/sc-153-token-2022-program
September 4, 2026 08:04
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-tests
branch
from
September 4, 2026 14:11
3351e6d to
c47c7f2
Compare
kaze-cow
marked this pull request as ready for review
September 4, 2026 14:55
kaze-cow
added a commit
that referenced
this pull request
Sep 7, 2026
Adds the most basic level of Token-2022 support which widens the accepted token programs and focuses on dealing with the edge cases of `CreateBuffers` and `ReclaimBuffers`. ## What changes `CreateBuffer` and `ReclaimBuffer` each take a `token_program` account and, until now, rejected anything that wasn't the legacy SPL Token program. They now accept Token-2022 too and issue all of their CPIs — `InitializeAccount3`, `CloseAccount` — against whichever of the two they were handed. Token2022 accounts may have dynamic length. Previously, a buffer could only hold 165 bytes (the length of SPL token account), but now it is now allocated at the length its mint actually needs. `GetAccountDataSize` is used to verify the length of the token required before creating it. For `CreateBuffers` creation of token accounts, We looked into the possibility of making the account longer than it needs to be and then shrinking it, but this doesn't work well because a extra CPI call is necessary to shrink the account back down to the correct size. But this requires a CPI call to `Reallocate` on the token program, and that is more expensive than just getting hte length. There is an early return on `token_account_len` which allows for skipping the `GetTokenAccountLength` CPI call. We originally did the early return if the Mint size was th ebase size (the logic being that a base size mint is either a canonical SPL token *OR* a token2022 mint with no required extensions), but since the vast majority of token2022 mints *DO* actually have extensions, there is very little benefit in having this broader check. So we decided to only do the early return for SPL tokens. ## Library Handling Changes `spl-token-2022-interface = "3"`, a library [published by anza-team](https://crates.io/crates/spl-token-2022-interface), and `pinocchio-token-2022 = "0.4"`, another library [published by anza-team](https://crates.io/crates/pinocchio-token-2022), are added for hopefully obvious reasons. ~~`spl-token-interface` was removed from the settlement program because it is no longer needed (later it will also be removed from test-cli, eliminating it as a direct dependency from the repo).~~ ended up being re-added after adding new tests because apparently a lot of mint creation utilities need to be recreated without it. `pinocchio-token` is bumped to `0.7` in order to gain access to the `invoke_with_unverified_program(token_program)` instruction builder function (prior to this release, there was no way to specify an alternative program). Its also the version that `pinnochio-token-2022` transitively depends on. Most of the functions in both `pinnochio-token` and `pinnochio-token-2022` are close to identical. For now most of the interfaces continue to use `pinnochio-token` because we never actually work with token 2022 tokens directly and the interfaces usually have slightly less dependencies (ex. not specifying the extension information). ## Out of Scope `BeginSettle` / `FinalizeSettle` require a different methodology to support simultaneous settlement from both token programs, so those follow in #128. `test-cli` is covered separately in #134 . The integration tests for both this PR and #128 are in #121, as we want to expand coverage with 2022 across as many tests as possible. At this time, only one token program can be supplied to the buffer functions. Two separate calls to `CreateBuffers` is required if it is necessary to create buffers for tokens on two separate prgorams. ## Compute cost `bench-report.json` is regenerated. The buffer instructions shift by roughly +0.2% to +0.4% from the added dispatch (`reclaim_buffer/max_buffers_in_one_instruction` 136,501 → 137,046 is the largest); the one- and two-unit drift on the unrelated settle and transfer-authority lines is codegen, not behaviour. ## Test Plan Verify the methodology. In particular, it would be good to verify the library dependency status as described above, because it is a bit awckward. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
The Token-2022 paths are worth little if they only hold for the handful of cases someone thought to write twice, so instead of a parallel suite this reruns the suite that already exists against the second program. `common::also_under_token_2022!(some_test)` sits in front of a test and generates `some_test_token_2022`, which runs the same body with Token-2022 as the thread-local active program. Nothing in the body changes: the token helpers build against the program that owns the account they are handed, and `payer_signed_tx` / `signed_tx` repoint the legacy program id in every instruction they assemble. 19 tests are covered this way, across buffer creation and reclamation -- error paths as much as happy ones. `CreateBuffer` and `ReclaimBuffer` name their token program as an account, so repointing reaches them. `common::buffer::ensure_buffer_exists` reads the program off the mint instead of taking it as a parameter, a buffer being a token account of its mint and so bound to the mint's own program; that also lets one test build buffers under both programs at once, which is what `ensure_buffer_exists_for` used to be for. Naming the test in front of it, rather than wrapping the body, keeps the indentation and makes a stale name a compile error instead of a test that quietly stopped being generated. A test that can only hold under one program goes without and says why -- the one pinned to the legacy native mint. Three tests are Token-2022-only, covering what has no legacy analogue -- a buffer for a mint with a `TransferFeeConfig`, which needs a `TransferFeeAmount` on every account holding it and so must be longer than the base layout: - `creates_buffer_sized_for_a_mint_with_extensions` - `recreating_an_extension_mint_buffer_is_idempotent` - `reclaims_a_buffer_sized_for_an_extension_mint` `bench-report.json` gains the CU, account, and transaction-byte readings for every generated test that is benched. The settlement pair is deliberately left out. `BeginSettle` and `FinalizeSettle` name their token programs by value rather than by account, so rerunning their tests needs the slot handling from #128 and belongs on that branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
kaze-cow
force-pushed
the
kaze/sc-153-token-2022-tests
branch
from
September 7, 2026 14:32
f451dd5 to
aa656ca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a macro to run any token-moving tests against both SPL token and Token 2022.
Stacked on #120.
Approach
The Token-2022 paths in #120 are worth little if they only hold for the handful of cases someone thought to write twice. So rather than a parallel Token-2022 suite, this reruns the suite that already exists against the second program.
common::also_under_token_2022!(some_test)sits in front of a test and generatessome_test_token_2022, which runs the same body with Token-2022 as the thread-local active program:The body of the function can be used as is. The token helpers in
tests/common/token.rsbuild against the program that owns the account they are handed (token::program_of), andpayer_signed_tx/signed_txrepoint the legacy program id in every instruction they assemble.A regular macro with
pasteywas used instead of aproc_macroto reduce the weight and maintenance that comes with needing to write an entire program to execute a macro. The only major downside I see with this approach is that the test name needs to be repeated in the macro parameters.The
max_buffers*tests were also included in this. In the case ofCreateBuffers, we hit the CPI token account limit, so the limit is actually lower there.Compute cost
bench-report.jsongains readings for every generated test. Token-2022 costs more per instruction, as expected from the longer accounts and the extension-aware transfer path — e.g.settle/settles_multiple_orders23,257 → 27,350 CU,create_buffers/happy_path_creates_initialized_buffer_token_account10,361 → 11,695 CU. Transaction bytes and account counts are identical between the two.Verification
Verify the approach. Confirm new tests are generating benchmarks and behavior as expected.
There may be cases where other non-generated tests are needed specific to token2022. If so, please say!
🤖 Generated with Claude Code