Skip to content

Commit b667e36

Browse files
kaze-cowclaude
andcommitted
Verify Token-2022 settlement against the whole existing suite
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 `token::active()`, and `payer_signed_tx` / `signed_tx` repoint the legacy program id in every instruction they assemble. 75 tests are covered this way, across buffer creation, reclamation, order settlement, pushes, and limit prices -- error paths as much as happy ones. 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 (one pinned to the legacy native mint) goes without and says why, as do the suites whose instructions name no token program at all. 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. Token-2022 costs more per instruction, as expected from the longer accounts and the extension-aware transfer path. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 818938f commit b667e36

12 files changed

Lines changed: 629 additions & 63 deletions

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ hex-literal = "1"
3030
litesvm = "0.15"
3131
litesvm-token = "0.15"
3232
num_enum = "0.7"
33+
pastey = "0.2"
3334
pinocchio = "0.11"
3435
pinocchio-system = "0.6"
3536
pinocchio-token = "0.7"

bench-report.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,114 @@
11
{
22
"accounts": {
33
"create_buffers/happy_path_creates_initialized_buffer_token_account": 6,
4+
"create_buffers/happy_path_creates_initialized_buffer_token_account_token_2022": 6,
45
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction": 10,
6+
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction_token_2022": 10,
57
"create_buffers/max_buffers_in_one_instruction": 64,
68
"create_order/happy_path_creates_order_pda_with_expected_body": 4,
79
"initialize/happy_path_initializes_state_pda_with_expected_data": 4,
810
"reclaim_buffer/funded_buffer_is_skipped": 7,
11+
"reclaim_buffer/funded_buffer_is_skipped_token_2022": 7,
912
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself": 7,
13+
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself_token_2022": 7,
1014
"reclaim_buffer/max_buffers_in_one_instruction": 64,
1115
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 9,
16+
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded_token_2022": 9,
1217
"reclaim_order/happy_path_returns_lamports_and_closes_pda": 4,
1318
"settle/finalizes_with_no_pushes": 5,
19+
"settle/finalizes_with_no_pushes_token_2022": 5,
1420
"settle/pulls_from_multiple_orders": 15,
21+
"settle/pulls_from_multiple_orders_token_2022": 15,
1522
"settle/pulls_funds_to_destination": 10,
23+
"settle/pulls_funds_to_destination_token_2022": 10,
1624
"settle/pulls_to_multiple_destinations": 11,
25+
"settle/pulls_to_multiple_destinations_token_2022": 11,
1726
"settle/pushes_a_single_order": 9,
27+
"settle/pushes_a_single_order_token_2022": 9,
1828
"settle/pushes_several_orders_from_different_buffers": 13,
29+
"settle/pushes_several_orders_from_different_buffers_token_2022": 13,
1930
"settle/pushes_several_orders_from_one_buffer": 12,
31+
"settle/pushes_several_orders_from_one_buffer_token_2022": 12,
2032
"settle/settles_a_single_order": 9,
33+
"settle/settles_a_single_order_token_2022": 9,
2134
"settle/settles_multiple_orders": 17,
35+
"settle/settles_multiple_orders_token_2022": 17,
2236
"transfer_authority/manager_can_transfer_manager": 4,
2337
"transfer_authority/manager_can_transfer_reclaim_authority": 4,
2438
"transfer_authority/reclaim_authority_can_transfer_itself": 4
2539
},
2640
"compute_units": {
2741
"create_buffers/happy_path_creates_initialized_buffer_token_account": 10360,
42+
"create_buffers/happy_path_creates_initialized_buffer_token_account_token_2022": 11694,
2843
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction": 21789,
44+
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction_token_2022": 25787,
2945
"create_buffers/max_buffers_in_one_instruction": 177518,
3046
"create_order/happy_path_creates_order_pda_with_expected_body": 7916,
3147
"initialize/happy_path_initializes_state_pda_with_expected_data": 4519,
3248
"reclaim_buffer/funded_buffer_is_skipped": 6363,
49+
"reclaim_buffer/funded_buffer_is_skipped_token_2022": 6367,
3350
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself": 7511,
51+
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself_token_2022": 8747,
3452
"reclaim_buffer/max_buffers_in_one_instruction": 138392,
3553
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 18170,
54+
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded_token_2022": 19408,
3655
"reclaim_order/happy_path_returns_lamports_and_closes_pda": 2127,
3756
"settle/finalizes_with_no_pushes": 7049,
57+
"settle/finalizes_with_no_pushes_token_2022": 7053,
3858
"settle/pulls_from_multiple_orders": 20034,
59+
"settle/pulls_from_multiple_orders_token_2022": 25634,
3960
"settle/pulls_funds_to_destination": 13564,
61+
"settle/pulls_funds_to_destination_token_2022": 16366,
4062
"settle/pulls_to_multiple_destinations": 14712,
63+
"settle/pulls_to_multiple_destinations_token_2022": 18927,
4164
"settle/pushes_a_single_order": 12410,
65+
"settle/pushes_a_single_order_token_2022": 13799,
4266
"settle/pushes_several_orders_from_different_buffers": 17727,
67+
"settle/pushes_several_orders_from_different_buffers_token_2022": 20501,
4368
"settle/pushes_several_orders_from_one_buffer": 17728,
69+
"settle/pushes_several_orders_from_one_buffer_token_2022": 20502,
4470
"settle/settles_a_single_order": 12428,
71+
"settle/settles_a_single_order_token_2022": 13799,
4572
"settle/settles_multiple_orders": 23088,
73+
"settle/settles_multiple_orders_token_2022": 27193,
4674
"transfer_authority/manager_can_transfer_manager": 3163,
4775
"transfer_authority/manager_can_transfer_reclaim_authority": 3165,
4876
"transfer_authority/reclaim_authority_can_transfer_itself": 3168
4977
},
5078
"transaction_bytes": {
5179
"create_buffers/happy_path_creates_initialized_buffer_token_account": 303,
80+
"create_buffers/happy_path_creates_initialized_buffer_token_account_token_2022": 303,
5281
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction": 435,
82+
"create_buffers/happy_path_creates_multiple_buffers_in_one_instruction_token_2022": 435,
5383
"create_buffers/max_buffers_in_one_instruction": 331,
5484
"create_order/happy_path_creates_order_pda_with_expected_body": 389,
5585
"initialize/happy_path_initializes_state_pda_with_expected_data": 301,
5686
"reclaim_buffer/funded_buffer_is_skipped": 400,
87+
"reclaim_buffer/funded_buffer_is_skipped_token_2022": 400,
5788
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself": 400,
89+
"reclaim_buffer/happy_path_reclaims_empty_buffer_to_the_authority_itself_token_2022": 400,
5890
"reclaim_buffer/max_buffers_in_one_instruction": 332,
5991
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded": 466,
92+
"reclaim_buffer/reclaims_multiple_buffers_skipping_funded_token_2022": 466,
6093
"reclaim_order/happy_path_returns_lamports_and_closes_pda": 236,
6194
"settle/finalizes_with_no_pushes": 289,
95+
"settle/finalizes_with_no_pushes_token_2022": 289,
6296
"settle/pulls_from_multiple_orders": 655,
97+
"settle/pulls_from_multiple_orders_token_2022": 655,
6398
"settle/pulls_funds_to_destination": 472,
99+
"settle/pulls_funds_to_destination_token_2022": 472,
64100
"settle/pulls_to_multiple_destinations": 513,
101+
"settle/pulls_to_multiple_destinations_token_2022": 513,
65102
"settle/pushes_a_single_order": 431,
103+
"settle/pushes_a_single_order_token_2022": 431,
66104
"settle/pushes_several_orders_from_different_buffers": 573,
105+
"settle/pushes_several_orders_from_different_buffers_token_2022": 573,
67106
"settle/pushes_several_orders_from_one_buffer": 541,
107+
"settle/pushes_several_orders_from_one_buffer_token_2022": 541,
68108
"settle/settles_a_single_order": 431,
109+
"settle/settles_a_single_order_token_2022": 431,
69110
"settle/settles_multiple_orders": 715,
111+
"settle/settles_multiple_orders_token_2022": 715,
70112
"transfer_authority/manager_can_transfer_manager": 333,
71113
"transfer_authority/manager_can_transfer_reclaim_authority": 333,
72114
"transfer_authority/reclaim_authority_can_transfer_itself": 333

programs/settlement/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ arrayref.workspace = true
3030
bincode.workspace = true
3131
litesvm.workspace = true
3232
litesvm-token.workspace = true
33+
pastey.workspace = true
3334
proptest.workspace = true
3435
cow-settlement-client.workspace = true
3536
cow-settlement-interface = { workspace = true, features = ["test-fixtures"] }
@@ -39,6 +40,8 @@ solana-instructions-sysvar.workspace = true
3940
solana-program-pack.workspace = true
4041
solana-sdk.workspace = true
4142
solana-sha256-hasher.workspace = true
43+
spl-associated-token-account-interface.workspace = true
44+
spl-token-2022-interface.workspace = true
4245
solana-system-interface.workspace = true
4346

4447
[lints]

programs/settlement/tests/begin_settle_orders.rs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use solana_sdk::{
4545
instruction::{AccountMeta, InstructionError},
4646
pubkey::Pubkey,
4747
signature::{Keypair, Signer},
48-
transaction::{Transaction, TransactionError},
48+
transaction::TransactionError,
4949
};
5050

5151
mod common;
@@ -139,6 +139,7 @@ fn settle_and_pay_amounts(
139139
vec![begin.into(), finalize.into()]
140140
}
141141

142+
common::also_under_token_2022!(settles_a_single_order);
142143
#[test]
143144
fn settles_a_single_order() {
144145
let (mut svm, program_id, payer) = setup();
@@ -157,6 +158,7 @@ fn settles_a_single_order() {
157158
.expect("settlement should succeed");
158159
}
159160

161+
common::also_under_token_2022!(settles_multiple_orders);
160162
#[test]
161163
fn settles_multiple_orders() {
162164
let (mut svm, program_id, payer) = setup();
@@ -179,6 +181,7 @@ fn settles_multiple_orders() {
179181
.expect("multi-order settlement should succeed");
180182
}
181183

184+
common::also_under_token_2022!(rejects_wrong_stored_bump);
182185
#[test]
183186
fn rejects_wrong_stored_bump() {
184187
let (mut svm, program_id, payer) = setup();
@@ -213,6 +216,7 @@ fn rejects_wrong_stored_bump() {
213216
);
214217
}
215218

219+
common::also_under_token_2022!(rejects_fabricated_program_owned_account);
216220
#[test]
217221
fn rejects_fabricated_program_owned_account() {
218222
let (mut svm, program_id, payer) = setup();
@@ -262,6 +266,7 @@ fn rejects_fabricated_program_owned_account() {
262266
);
263267
}
264268

269+
common::also_under_token_2022!(rejects_non_order_account_in_order_slot);
265270
#[test]
266271
fn rejects_non_order_account_in_order_slot() {
267272
let (mut svm, program_id, payer) = setup();
@@ -300,6 +305,7 @@ fn rejects_non_order_account_in_order_slot() {
300305
);
301306
}
302307

308+
common::also_under_token_2022!(rejects_sell_token_account_mismatch);
303309
#[test]
304310
fn rejects_sell_token_account_mismatch() {
305311
let (mut svm, program_id, payer) = setup();
@@ -329,6 +335,7 @@ fn rejects_sell_token_account_mismatch() {
329335
);
330336
}
331337

338+
common::also_under_token_2022!(rejects_sell_token_owner_mismatch);
332339
#[test]
333340
fn rejects_sell_token_owner_mismatch() {
334341
let (mut svm, program_id, payer) = setup();
@@ -360,6 +367,7 @@ fn rejects_sell_token_owner_mismatch() {
360367
);
361368
}
362369

370+
common::also_under_token_2022!(rejects_non_token_sell_account);
363371
#[test]
364372
fn rejects_non_token_sell_account() {
365373
let (mut svm, program_id, payer) = setup();
@@ -389,6 +397,7 @@ fn rejects_non_token_sell_account() {
389397
);
390398
}
391399

400+
common::also_under_token_2022!(rejects_duplicate_orders);
392401
#[test]
393402
fn rejects_duplicate_orders() {
394403
let (mut svm, program_id, payer) = setup();
@@ -415,6 +424,7 @@ fn rejects_duplicate_orders() {
415424
);
416425
}
417426

427+
common::also_under_token_2022!(rejects_orders_in_wrong_address_order);
418428
#[test]
419429
fn rejects_orders_in_wrong_address_order() {
420430
let (mut svm, program_id, payer) = setup();
@@ -493,6 +503,7 @@ fn rejects_orders_in_wrong_address_order() {
493503
);
494504
}
495505

506+
common::also_under_token_2022!(rejects_cancelled_order);
496507
#[test]
497508
fn rejects_cancelled_order() {
498509
let (mut svm, program_id, payer) = setup();
@@ -532,6 +543,7 @@ fn rejects_cancelled_order() {
532543
);
533544
}
534545

546+
common::also_under_token_2022!(rejects_expired_order);
535547
#[test]
536548
fn rejects_expired_order() {
537549
let (mut svm, program_id, payer) = setup();
@@ -558,6 +570,7 @@ fn rejects_expired_order() {
558570
);
559571
}
560572

573+
common::also_under_token_2022!(settles_order_at_exact_valid_to);
561574
#[test]
562575
fn settles_order_at_exact_valid_to() {
563576
let (mut svm, program_id, payer) = setup();
@@ -580,6 +593,7 @@ fn settles_order_at_exact_valid_to() {
580593
send(&mut svm, &payer, instructions).expect("an order is still settleable at exactly valid_to");
581594
}
582595

596+
common::also_under_token_2022!(pulls_funds_to_destination);
583597
#[test]
584598
fn pulls_funds_to_destination() {
585599
let (mut svm, program_id, payer) = setup();
@@ -622,6 +636,7 @@ fn pulls_funds_to_destination() {
622636
);
623637
}
624638

639+
common::also_under_token_2022!(pulls_to_multiple_destinations);
625640
#[test]
626641
fn pulls_to_multiple_destinations() {
627642
let (mut svm, program_id, payer) = setup();
@@ -674,6 +689,7 @@ fn pulls_to_multiple_destinations() {
674689
);
675690
}
676691

692+
common::also_under_token_2022!(pulls_from_multiple_orders);
677693
#[test]
678694
fn pulls_from_multiple_orders() {
679695
let (mut svm, program_id, payer) = setup();
@@ -750,6 +766,7 @@ fn pulls_from_multiple_orders() {
750766
);
751767
}
752768

769+
common::also_under_token_2022!(rejects_pulls_summing_beyond_u64);
753770
#[test]
754771
fn rejects_pulls_summing_beyond_u64() {
755772
let (mut svm, program_id, payer) = setup();
@@ -791,6 +808,7 @@ fn rejects_pulls_summing_beyond_u64() {
791808
);
792809
}
793810

811+
common::also_under_token_2022!(zero_pulls_moves_nothing);
794812
#[test]
795813
fn zero_pulls_moves_nothing() {
796814
let (mut svm, program_id, payer) = setup();
@@ -822,12 +840,7 @@ fn zero_pulls_moves_nothing() {
822840
pulls: &[],
823841
}],
824842
);
825-
let transaction = Transaction::new_signed_with_payer(
826-
&instructions,
827-
Some(&payer.pubkey()),
828-
&[&payer],
829-
svm.latest_blockhash(),
830-
);
843+
let transaction = common::payer_signed_tx(&svm, &payer, instructions);
831844
let account_keys = transaction.message.account_keys.clone();
832845
let transaction = svm
833846
.send_transaction(transaction)
@@ -840,6 +853,7 @@ fn zero_pulls_moves_nothing() {
840853
assert_eq!(token::balance(&svm, &sell_token), initial_amount);
841854
}
842855

856+
common::also_under_token_2022!(rejects_wrong_state_pda);
843857
#[test]
844858
fn rejects_wrong_state_pda() {
845859
let (mut svm, program_id, payer) = setup();
@@ -869,6 +883,8 @@ fn rejects_wrong_state_pda() {
869883
);
870884
}
871885

886+
// Legacy-only: this replaces the token program with an unrelated key, so a
887+
// Token-2022 run would submit the very same transaction.
872888
#[test]
873889
fn rejects_wrong_token_program() {
874890
let (mut svm, program_id, payer) = setup();
@@ -898,6 +914,7 @@ fn rejects_wrong_token_program() {
898914
);
899915
}
900916

917+
common::also_under_token_2022!(rejects_pull_delegated_to_incorrect_address);
901918
#[test]
902919
fn rejects_pull_delegated_to_incorrect_address() {
903920
let (mut svm, program_id, payer) = setup();
@@ -932,6 +949,7 @@ fn rejects_pull_delegated_to_incorrect_address() {
932949
);
933950
}
934951

952+
common::also_under_token_2022!(rejects_pull_exceeding_delegation);
935953
#[test]
936954
fn rejects_pull_exceeding_delegation() {
937955
let (mut svm, program_id, payer) = setup();
@@ -976,6 +994,7 @@ fn rejects_pull_exceeding_delegation() {
976994
assert_eq!(token::delegated_amount(&svm, &sell_token), delegated);
977995
}
978996

997+
common::also_under_token_2022!(rejects_extra_account);
979998
#[test]
980999
fn rejects_extra_account() {
9811000
let (mut svm, program_id, payer) = setup();
@@ -1003,6 +1022,7 @@ fn rejects_extra_account() {
10031022
);
10041023
}
10051024

1025+
common::also_under_token_2022!(rejects_push_to_wrong_destination);
10061026
#[test]
10071027
fn rejects_push_to_wrong_destination() {
10081028
let (mut svm, program_id, payer) = setup();
@@ -1030,6 +1050,7 @@ fn rejects_push_to_wrong_destination() {
10301050
);
10311051
}
10321052

1053+
common::also_under_token_2022!(rejects_fewer_pushes_than_orders);
10331054
#[test]
10341055
fn rejects_fewer_pushes_than_orders() {
10351056
let (mut svm, program_id, payer) = setup();
@@ -1054,6 +1075,7 @@ fn rejects_fewer_pushes_than_orders() {
10541075
);
10551076
}
10561077

1078+
common::also_under_token_2022!(rejects_more_pushes_than_orders);
10571079
#[test]
10581080
fn rejects_more_pushes_than_orders() {
10591081
let (mut svm, program_id, payer) = setup();
@@ -1078,6 +1100,7 @@ fn rejects_more_pushes_than_orders() {
10781100
);
10791101
}
10801102

1103+
common::also_under_token_2022!(rejects_partial_push_amount_in_finalize_settle);
10811104
#[test]
10821105
fn rejects_partial_push_amount_in_finalize_settle() {
10831106
let (mut svm, program_id, payer) = setup();

0 commit comments

Comments
 (0)