diff --git a/CHANGELOG.md b/CHANGELOG.md index b73e853b0..e6abb26f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ The minor version will be incremented upon a breaking change and the patch versi ### Breaking +- lang: Switch to type safe bumps in context ([#2542](https://github.com/coral-xyz/anchor/pull/2542)). - syn: `idl` feature has been replaced with `idl-build`, `idl-parse` and `idl-types` features ([#2011](https://github.com/coral-xyz/anchor/pull/2011)). - syn: IDL `parse` method now returns `Result` instead of `Result>` ([#2582](https://github.com/coral-xyz/anchor/pull/2582)). - spl: Update `mpl-token-metadata` dependency to use the client SDK instead of the program crate ([#2632](https://github.com/coral-xyz/anchor/pull/2632)). diff --git a/bench/BINARY_SIZE.md b/bench/BINARY_SIZE.md index ff8cc65c3..b41f94459 100644 --- a/bench/BINARY_SIZE.md +++ b/bench/BINARY_SIZE.md @@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 1.17.0 -| Program | Binary Size | +/- | -| ------- | ----------- | ---------------------- | -| bench | 1,075,688 | 🟢 **-78,048 (6.76%)** | +| Program | Binary Size | +/- | +| ------- | ----------- | ----------------------- | +| bench | 1,049,608 | 🟢 **-104,128 (9.03%)** | ### Notable changes diff --git a/bench/COMPUTE_UNITS.md b/bench/COMPUTE_UNITS.md index 07d382168..0e95e9def 100644 --- a/bench/COMPUTE_UNITS.md +++ b/bench/COMPUTE_UNITS.md @@ -18,93 +18,93 @@ Solana version: 1.17.0 | Instruction | Compute Units | +/- | | --------------------------- | ------------- | ---------------------- | -| accountInfo1 | 680 | 🟢 **-335 (33.00%)** | -| accountInfo2 | 1,083 | 🟢 **-392 (26.58%)** | -| accountInfo4 | 1,535 | 🟢 **-429 (21.84%)** | -| accountInfo8 | 2,774 | 🟢 **-1,067 (27.78%)** | +| accountInfo1 | 584 | 🟢 **-431 (42.46%)** | +| accountInfo2 | 824 | 🟢 **-651 (44.14%)** | +| accountInfo4 | 1,319 | 🟢 **-645 (32.84%)** | +| accountInfo8 | 2,531 | 🟢 **-1,310 (34.11%)** | | accountEmptyInit1 | 5,521 | 🟢 **-296 (5.09%)** | -| accountEmpty1 | 815 | 🟢 **-334 (29.07%)** | +| accountEmpty1 | 777 | 🟢 **-372 (32.38%)** | | accountEmptyInit2 | 10,111 | 🟢 **-291 (2.80%)** | -| accountEmpty2 | 1,366 | 🟢 **-388 (22.12%)** | +| accountEmpty2 | 1,207 | 🟢 **-547 (31.19%)** | | accountEmptyInit4 | 19,044 | 🟢 **-464 (2.38%)** | -| accountEmpty4 | 2,120 | 🟢 **-420 (16.54%)** | +| accountEmpty4 | 2,074 | 🟢 **-466 (18.35%)** | | accountEmptyInit8 | 37,265 | - | | accountEmpty8 | 3,967 | 🟢 **-1,049 (20.91%)** | | accountSizedInit1 | 5,626 | 🟢 **-298 (5.03%)** | -| accountSized1 | 820 | 🟢 **-394 (32.45%)** | +| accountSized1 | 786 | 🟢 **-428 (35.26%)** | | accountSizedInit2 | 10,322 | 🟢 **-358 (3.35%)** | -| accountSized2 | 1,411 | 🟢 **-462 (24.67%)** | +| accountSized2 | 1,234 | 🟢 **-639 (34.12%)** | | accountSizedInit4 | 19,462 | 🟢 **-508 (2.54%)** | -| accountSized4 | 2,181 | 🟢 **-581 (21.04%)** | +| accountSized4 | 2,135 | 🟢 **-627 (22.70%)** | | accountSizedInit8 | 38,122 | - | | accountSized8 | 4,104 | 🟢 **-1,249 (23.33%)** | | accountUnsizedInit1 | 5,742 | 🟢 **-310 (5.12%)** | -| accountUnsized1 | 859 | 🟢 **-479 (35.80%)** | +| accountUnsized1 | 821 | 🟢 **-517 (38.64%)** | | accountUnsizedInit2 | 10,551 | 🟢 **-378 (3.46%)** | -| accountUnsized2 | 1,364 | 🟢 **-414 (23.28%)** | +| accountUnsized2 | 1,312 | 🟢 **-466 (26.21%)** | | accountUnsizedInit4 | 19,927 | 🟢 **-412 (2.03%)** | -| accountUnsized4 | 2,341 | 🟢 **-795 (25.35%)** | +| accountUnsized4 | 2,315 | 🟢 **-821 (26.18%)** | | accountUnsizedInit8 | 38,699 | 🟢 **-397 (1.02%)** | | accountUnsized8 | 4,456 | 🟢 **-1,496 (25.13%)** | -| boxedAccountEmptyInit1 | 5,624 | 🟢 **-410 (6.79%)** | -| boxedAccountEmpty1 | 888 | - | -| boxedAccountEmptyInit2 | 10,221 | 🟢 **-412 (3.87%)** | -| boxedAccountEmpty2 | 1,401 | - | +| boxedAccountEmptyInit1 | 5,452 | 🟢 **-582 (9.65%)** | +| boxedAccountEmpty1 | 866 | 🟢 **-22 (2.48%)** | +| boxedAccountEmptyInit2 | 10,051 | 🟢 **-582 (5.47%)** | +| boxedAccountEmpty2 | 1,377 | 🟢 **-24 (1.71%)** | | boxedAccountEmptyInit4 | 19,030 | 🟢 **-281 (1.46%)** | -| boxedAccountEmpty4 | 2,424 | - | +| boxedAccountEmpty4 | 2,396 | 🟢 **-28 (1.16%)** | | boxedAccountEmptyInit8 | 37,136 | - | -| boxedAccountEmpty8 | 4,527 | 🟢 **-132 (2.83%)** | -| boxedAccountSizedInit1 | 5,718 | 🟢 **-412 (6.72%)** | -| boxedAccountSized1 | 917 | - | -| boxedAccountSizedInit2 | 10,412 | 🟢 **-416 (3.84%)** | -| boxedAccountSized2 | 1,463 | - | +| boxedAccountEmpty8 | 4,472 | 🟢 **-187 (4.01%)** | +| boxedAccountSizedInit1 | 5,546 | 🟢 **-584 (9.53%)** | +| boxedAccountSized1 | 895 | 🟢 **-22 (2.40%)** | +| boxedAccountSizedInit2 | 10,242 | 🟢 **-586 (5.41%)** | +| boxedAccountSized2 | 1,439 | 🟢 **-24 (1.64%)** | | boxedAccountSizedInit4 | 19,414 | 🟢 **-289 (1.47%)** | -| boxedAccountSized4 | 2,543 | - | +| boxedAccountSized4 | 2,515 | 🟢 **-28 (1.10%)** | | boxedAccountSizedInit8 | 37,919 | - | -| boxedAccountSized8 | 4,766 | 🟢 **-132 (2.69%)** | +| boxedAccountSized8 | 4,711 | 🟢 **-187 (3.82%)** | | boxedAccountUnsizedInit1 | 5,823 | 🟢 **-417 (6.68%)** | -| boxedAccountUnsized1 | 972 | - | +| boxedAccountUnsized1 | 950 | 🟢 **-22 (2.26%)** | | boxedAccountUnsizedInit2 | 10,621 | 🟢 **-427 (3.86%)** | -| boxedAccountUnsized2 | 1,570 | - | +| boxedAccountUnsized2 | 1,549 | 🟢 **-21 (1.34%)** | | boxedAccountUnsizedInit4 | 19,825 | 🟢 **-313 (1.55%)** | -| boxedAccountUnsized4 | 2,768 | - | +| boxedAccountUnsized4 | 2,737 | 🟢 **-31 (1.12%)** | | boxedAccountUnsizedInit8 | 38,791 | 🟢 **-9 (0.02%)** | | boxedAccountUnsized8 | 5,207 | 🟢 **-140 (2.62%)** | -| boxedInterfaceAccountMint1 | 2,159 | 🟢 **-137 (5.97%)** | +| boxedInterfaceAccountMint1 | 2,137 | 🟢 **-159 (6.93%)** | | boxedInterfaceAccountMint2 | 3,849 | 🟢 **-280 (6.78%)** | | boxedInterfaceAccountMint4 | 7,215 | 🟢 **-568 (7.30%)** | | boxedInterfaceAccountMint8 | 14,044 | 🟢 **-1,237 (8.10%)** | -| boxedInterfaceAccountToken1 | 2,088 | 🔴 **+65 (3.21%)** | +| boxedInterfaceAccountToken1 | 2,066 | 🔴 **+43 (2.13%)** | | boxedInterfaceAccountToken2 | 3,706 | 🔴 **+124 (3.46%)** | | boxedInterfaceAccountToken4 | 6,932 | 🔴 **+240 (3.59%)** | | boxedInterfaceAccountToken8 | 13,477 | 🔴 **+379 (2.89%)** | -| interfaceAccountMint1 | 2,574 | 🔴 **+210 (8.88%)** | -| interfaceAccountMint2 | 4,410 | 🟢 **-620 (12.33%)** | -| interfaceAccountMint4 | 8,313 | 🟢 **-1,490 (15.20%)** | +| interfaceAccountMint1 | 2,313 | 🟢 **-51 (2.16%)** | +| interfaceAccountMint2 | 4,270 | 🟢 **-760 (15.11%)** | +| interfaceAccountMint4 | 8,185 | 🟢 **-1,618 (16.51%)** | | interfaceAccountMint8 | 16,007 | 🟢 **-2,393 (13.01%)** | -| interfaceAccountToken1 | 2,137 | 🔴 **+46 (2.20%)** | -| interfaceAccountToken2 | 4,032 | 🔴 **+84 (2.13%)** | +| interfaceAccountToken1 | 2,059 | 🟢 **-32 (1.53%)** | +| interfaceAccountToken2 | 3,958 | 🔴 **+10 (0.25%)** | | interfaceAccountToken4 | 7,816 | 🔴 **+269 (3.56%)** | -| interface1 | 726 | 🟢 **-333 (31.44%)** | -| interface2 | 1,093 | 🟢 **-386 (26.10%)** | -| interface4 | 1,484 | 🟢 **-416 (21.89%)** | +| interface1 | 691 | 🟢 **-368 (34.75%)** | +| interface2 | 940 | 🟢 **-539 (36.44%)** | +| interface4 | 1,450 | 🟢 **-450 (23.68%)** | | interface8 | 2,605 | 🟢 **-1,041 (28.55%)** | -| program1 | 720 | 🟢 **-333 (31.62%)** | -| program2 | 1,081 | 🟢 **-386 (26.31%)** | -| program4 | 1,462 | 🟢 **-416 (22.15%)** | +| program1 | 685 | 🟢 **-368 (34.95%)** | +| program2 | 928 | 🟢 **-539 (36.74%)** | +| program4 | 1,428 | 🟢 **-450 (23.96%)** | | program8 | 2,557 | 🟢 **-1,041 (28.93%)** | -| signer1 | 683 | 🟢 **-335 (32.91%)** | -| signer2 | 1,092 | 🟢 **-392 (26.42%)** | -| signer4 | 1,555 | 🟢 **-429 (21.62%)** | -| signer8 | 2,813 | 🟢 **-1,067 (27.50%)** | -| systemAccount1 | 737 | 🟢 **-335 (31.25%)** | -| systemAccount2 | 1,198 | 🟢 **-392 (24.65%)** | -| systemAccount4 | 1,766 | 🟢 **-429 (19.54%)** | -| systemAccount8 | 3,238 | 🟢 **-1,067 (24.79%)** | -| uncheckedAccount1 | 679 | 🟢 **-335 (33.04%)** | -| uncheckedAccount2 | 1,083 | 🟢 **-392 (26.58%)** | -| uncheckedAccount4 | 1,536 | 🟢 **-429 (21.83%)** | -| uncheckedAccount8 | 2,774 | 🟢 **-1,067 (27.78%)** | +| signer1 | 621 | 🟢 **-397 (39.00%)** | +| signer2 | 895 | 🟢 **-589 (39.69%)** | +| signer4 | 1,455 | 🟢 **-529 (26.66%)** | +| signer8 | 2,721 | 🟢 **-1,159 (29.87%)** | +| systemAccount1 | 675 | 🟢 **-397 (37.03%)** | +| systemAccount2 | 1,001 | 🟢 **-589 (37.04%)** | +| systemAccount4 | 1,666 | 🟢 **-529 (24.10%)** | +| systemAccount8 | 3,146 | 🟢 **-1,159 (26.92%)** | +| uncheckedAccount1 | 583 | 🟢 **-431 (42.50%)** | +| uncheckedAccount2 | 824 | 🟢 **-651 (44.14%)** | +| uncheckedAccount4 | 1,320 | 🟢 **-645 (32.82%)** | +| uncheckedAccount8 | 2,531 | 🟢 **-1,310 (34.11%)** | ### Notable changes diff --git a/bench/STACK_MEMORY.md b/bench/STACK_MEMORY.md index d6d71739e..f99f713ad 100644 --- a/bench/STACK_MEMORY.md +++ b/bench/STACK_MEMORY.md @@ -16,95 +16,95 @@ The programs and their tests are located in [/tests/bench](https://github.com/co Solana version: 1.17.0 -| Instruction | Stack Memory | +/- | -| ------------------------------ | ------------ | -------------------- | -| account_info1 | 272 | 🟢 **-56 (17.07%)** | -| account_info2 | 320 | 🟢 **-56 (14.89%)** | -| account_info4 | 416 | 🟢 **-144 (25.71%)** | -| account_info8 | 608 | 🟢 **-120 (16.48%)** | -| account_empty_init1 | 400 | 🟢 **-192 (32.43%)** | -| account_empty_init2 | 480 | 🟢 **-80 (14.29%)** | -| account_empty_init4 | 528 | 🟢 **-104 (16.46%)** | -| account_empty_init8 | 720 | 🟢 **-104 (12.62%)** | -| account_empty1 | 272 | 🟢 **-48 (15.00%)** | -| account_empty2 | 320 | 🟢 **-48 (13.04%)** | -| account_empty4 | 416 | 🟢 **-136 (24.64%)** | -| account_empty8 | 608 | 🟢 **-120 (16.48%)** | -| account_sized_init1 | 408 | 🟢 **-192 (32.00%)** | -| account_sized_init2 | 496 | 🟢 **-56 (10.14%)** | -| account_sized_init4 | 560 | 🟢 **-104 (15.66%)** | -| account_sized_init8 | 784 | 🟢 **-104 (11.71%)** | -| account_sized1 | 280 | 🟢 **-48 (14.63%)** | -| account_sized2 | 336 | 🟢 **-56 (14.29%)** | -| account_sized4 | 448 | 🟢 **-120 (21.13%)** | -| account_sized8 | 672 | 🟢 **-120 (15.15%)** | -| account_unsized_init1 | 424 | 🟢 **-200 (32.05%)** | -| account_unsized_init2 | 528 | 🟢 **-56 (9.59%)** | -| account_unsized_init4 | 624 | 🟢 **-104 (14.29%)** | -| account_unsized_init8 | 912 | 🟢 **-104 (10.24%)** | -| account_unsized1 | 296 | 🟢 **-48 (13.95%)** | -| account_unsized2 | 368 | 🟢 **-88 (19.30%)** | -| account_unsized4 | 512 | 🟢 **-120 (18.99%)** | -| account_unsized8 | 800 | 🟢 **-120 (13.04%)** | -| boxed_account_empty_init1 | 360 | 🟢 **-192 (34.78%)** | -| boxed_account_empty_init2 | 400 | - | -| boxed_account_empty_init4 | 368 | 🟢 **-64 (14.81%)** | -| boxed_account_empty_init8 | 400 | 🟢 **-96 (19.35%)** | -| boxed_account_empty1 | 232 | 🟢 **-88 (27.50%)** | -| boxed_account_empty2 | 240 | 🟢 **-80 (25.00%)** | -| boxed_account_empty4 | 256 | 🟢 **-64 (20.00%)** | -| boxed_account_empty8 | 288 | 🟢 **-48 (14.29%)** | -| boxed_account_sized_init1 | 360 | 🟢 **-192 (34.78%)** | -| boxed_account_sized_init2 | 400 | - | -| boxed_account_sized_init4 | 368 | 🟢 **-64 (14.81%)** | -| boxed_account_sized_init8 | 400 | 🟢 **-96 (19.35%)** | -| boxed_account_sized1 | 232 | 🟢 **-88 (27.50%)** | -| boxed_account_sized2 | 240 | 🟢 **-80 (25.00%)** | -| boxed_account_sized4 | 256 | 🟢 **-64 (20.00%)** | -| boxed_account_sized8 | 288 | 🟢 **-48 (14.29%)** | -| boxed_account_unsized_init1 | 360 | 🟢 **-192 (34.78%)** | -| boxed_account_unsized_init2 | 400 | - | -| boxed_account_unsized_init4 | 368 | 🟢 **-64 (14.81%)** | -| boxed_account_unsized_init8 | 400 | 🟢 **-96 (19.35%)** | -| boxed_account_unsized1 | 232 | 🟢 **-88 (27.50%)** | -| boxed_account_unsized2 | 240 | 🟢 **-80 (25.00%)** | -| boxed_account_unsized4 | 256 | 🟢 **-64 (20.00%)** | -| boxed_account_unsized8 | 288 | 🟢 **-48 (14.29%)** | -| boxed_interface_account_mint1 | 232 | 🟢 **-88 (27.50%)** | -| boxed_interface_account_mint2 | 240 | 🟢 **-80 (25.00%)** | -| boxed_interface_account_mint4 | 256 | 🟢 **-64 (20.00%)** | -| boxed_interface_account_mint8 | 288 | 🟢 **-48 (14.29%)** | -| boxed_interface_account_token1 | 232 | 🟢 **-88 (27.50%)** | -| boxed_interface_account_token2 | 240 | 🟢 **-80 (25.00%)** | -| boxed_interface_account_token4 | 256 | 🟢 **-64 (20.00%)** | -| boxed_interface_account_token8 | 288 | 🟢 **-48 (14.29%)** | -| interface_account_mint1 | 392 | 🟢 **-112 (22.22%)** | -| interface_account_mint2 | 560 | 🟢 **-120 (17.65%)** | -| interface_account_mint4 | 896 | 🟢 **-120 (11.81%)** | -| interface_account_mint8 | 1,568 | 🟢 **-120 (7.11%)** | -| interface_account_token1 | 480 | 🟢 **-200 (29.41%)** | -| interface_account_token2 | 736 | 🟢 **-120 (14.02%)** | -| interface_account_token4 | 1,248 | 🟢 **-120 (8.77%)** | -| interface1 | 272 | 🟢 **-48 (15.00%)** | -| interface2 | 320 | 🟢 **-48 (13.04%)** | -| interface4 | 416 | 🟢 **-136 (24.64%)** | -| interface8 | 608 | 🟢 **-120 (16.48%)** | -| program1 | 272 | 🟢 **-48 (15.00%)** | -| program2 | 320 | 🟢 **-48 (13.04%)** | -| program4 | 416 | 🟢 **-136 (24.64%)** | -| program8 | 608 | 🟢 **-120 (16.48%)** | -| signer1 | 272 | 🟢 **-56 (17.07%)** | -| signer2 | 320 | 🟢 **-56 (14.89%)** | -| signer4 | 416 | 🟢 **-144 (25.71%)** | -| signer8 | 608 | 🟢 **-120 (16.48%)** | -| system_account1 | 272 | 🟢 **-56 (17.07%)** | -| system_account2 | 320 | 🟢 **-56 (14.89%)** | -| system_account4 | 416 | 🟢 **-144 (25.71%)** | -| system_account8 | 608 | 🟢 **-120 (16.48%)** | -| unchecked_account1 | 272 | 🟢 **-56 (17.07%)** | -| unchecked_account2 | 320 | 🟢 **-56 (14.89%)** | -| unchecked_account4 | 416 | 🟢 **-144 (25.71%)** | -| unchecked_account8 | 608 | 🟢 **-120 (16.48%)** | +| Instruction | Stack Memory | +/- | +| ------------------------------ | ------------ | ---------------------- | +| account_info1 | 128 | 🟢 **-200 (60.98%)** | +| account_info2 | 128 | 🟢 **-248 (65.96%)** | +| account_info4 | 128 | 🟢 **-432 (77.14%)** | +| account_info8 | 128 | 🟢 **-600 (82.42%)** | +| account_empty_init1 | 320 | 🟢 **-272 (45.95%)** | +| account_empty_init2 | 400 | 🟢 **-160 (28.57%)** | +| account_empty_init4 | 448 | 🟢 **-184 (29.11%)** | +| account_empty_init8 | 640 | 🟢 **-184 (22.33%)** | +| account_empty1 | 128 | 🟢 **-192 (60.00%)** | +| account_empty2 | 128 | 🟢 **-240 (65.22%)** | +| account_empty4 | 128 | 🟢 **-424 (76.81%)** | +| account_empty8 | 128 | 🟢 **-600 (82.42%)** | +| account_sized_init1 | 328 | 🟢 **-272 (45.33%)** | +| account_sized_init2 | 416 | 🟢 **-136 (24.64%)** | +| account_sized_init4 | 480 | 🟢 **-184 (27.71%)** | +| account_sized_init8 | 704 | 🟢 **-184 (20.72%)** | +| account_sized1 | 128 | 🟢 **-200 (60.98%)** | +| account_sized2 | 128 | 🟢 **-264 (67.35%)** | +| account_sized4 | 128 | 🟢 **-440 (77.46%)** | +| account_sized8 | 128 | 🟢 **-664 (83.84%)** | +| account_unsized_init1 | 344 | 🟢 **-280 (44.87%)** | +| account_unsized_init2 | 448 | 🟢 **-136 (23.29%)** | +| account_unsized_init4 | 544 | 🟢 **-184 (25.27%)** | +| account_unsized_init8 | 832 | 🟢 **-184 (18.11%)** | +| account_unsized1 | 128 | 🟢 **-216 (62.79%)** | +| account_unsized2 | 128 | 🟢 **-328 (71.93%)** | +| account_unsized4 | 128 | 🟢 **-504 (79.75%)** | +| account_unsized8 | 128 | 🟢 **-792 (86.09%)** | +| boxed_account_empty_init1 | 176 | 🟢 **-376 (68.12%)** | +| boxed_account_empty_init2 | 208 | 🟢 **-192 (48.00%)** | +| boxed_account_empty_init4 | 288 | 🟢 **-144 (33.33%)** | +| boxed_account_empty_init8 | 320 | 🟢 **-176 (35.48%)** | +| boxed_account_empty1 | 128 | 🟢 **-192 (60.00%)** | +| boxed_account_empty2 | 144 | 🟢 **-176 (55.00%)** | +| boxed_account_empty4 | 144 | 🟢 **-176 (55.00%)** | +| boxed_account_empty8 | 128 | 🟢 **-208 (61.90%)** | +| boxed_account_sized_init1 | 176 | 🟢 **-376 (68.12%)** | +| boxed_account_sized_init2 | 208 | 🟢 **-192 (48.00%)** | +| boxed_account_sized_init4 | 288 | 🟢 **-144 (33.33%)** | +| boxed_account_sized_init8 | 320 | 🟢 **-176 (35.48%)** | +| boxed_account_sized1 | 128 | 🟢 **-192 (60.00%)** | +| boxed_account_sized2 | 144 | 🟢 **-176 (55.00%)** | +| boxed_account_sized4 | 144 | 🟢 **-176 (55.00%)** | +| boxed_account_sized8 | 128 | 🟢 **-208 (61.90%)** | +| boxed_account_unsized_init1 | 280 | 🟢 **-272 (49.28%)** | +| boxed_account_unsized_init2 | 320 | 🟢 **-80 (20.00%)** | +| boxed_account_unsized_init4 | 288 | 🟢 **-144 (33.33%)** | +| boxed_account_unsized_init8 | 320 | 🟢 **-176 (35.48%)** | +| boxed_account_unsized1 | 152 | 🟢 **-168 (52.50%)** | +| boxed_account_unsized2 | 144 | 🟢 **-176 (55.00%)** | +| boxed_account_unsized4 | 176 | 🟢 **-144 (45.00%)** | +| boxed_account_unsized8 | 192 | 🟢 **-144 (42.86%)** | +| boxed_interface_account_mint1 | 128 | 🟢 **-192 (60.00%)** | +| boxed_interface_account_mint2 | 144 | 🟢 **-176 (55.00%)** | +| boxed_interface_account_mint4 | 144 | 🟢 **-176 (55.00%)** | +| boxed_interface_account_mint8 | 128 | 🟢 **-208 (61.90%)** | +| boxed_interface_account_token1 | 128 | 🟢 **-192 (60.00%)** | +| boxed_interface_account_token2 | 144 | 🟢 **-176 (55.00%)** | +| boxed_interface_account_token4 | 144 | 🟢 **-176 (55.00%)** | +| boxed_interface_account_token8 | 128 | 🟢 **-208 (61.90%)** | +| interface_account_mint1 | 128 | 🟢 **-376 (74.60%)** | +| interface_account_mint2 | 128 | 🟢 **-552 (81.18%)** | +| interface_account_mint4 | 128 | 🟢 **-888 (87.40%)** | +| interface_account_mint8 | 128 | 🟢 **-1,560 (92.42%)** | +| interface_account_token1 | 128 | 🟢 **-552 (81.18%)** | +| interface_account_token2 | 128 | 🟢 **-728 (85.05%)** | +| interface_account_token4 | 128 | 🟢 **-1,240 (90.64%)** | +| interface1 | 128 | 🟢 **-192 (60.00%)** | +| interface2 | 128 | 🟢 **-240 (65.22%)** | +| interface4 | 128 | 🟢 **-424 (76.81%)** | +| interface8 | 128 | 🟢 **-600 (82.42%)** | +| program1 | 128 | 🟢 **-192 (60.00%)** | +| program2 | 128 | 🟢 **-240 (65.22%)** | +| program4 | 128 | 🟢 **-424 (76.81%)** | +| program8 | 128 | 🟢 **-600 (82.42%)** | +| signer1 | 128 | 🟢 **-200 (60.98%)** | +| signer2 | 128 | 🟢 **-248 (65.96%)** | +| signer4 | 128 | 🟢 **-432 (77.14%)** | +| signer8 | 128 | 🟢 **-600 (82.42%)** | +| system_account1 | 128 | 🟢 **-200 (60.98%)** | +| system_account2 | 128 | 🟢 **-248 (65.96%)** | +| system_account4 | 128 | 🟢 **-432 (77.14%)** | +| system_account8 | 128 | 🟢 **-600 (82.42%)** | +| unchecked_account1 | 128 | 🟢 **-200 (60.98%)** | +| unchecked_account2 | 128 | 🟢 **-248 (65.96%)** | +| unchecked_account4 | 128 | 🟢 **-432 (77.14%)** | +| unchecked_account8 | 128 | 🟢 **-600 (82.42%)** | ### Notable changes diff --git a/docs/src/pages/docs/pdas.md b/docs/src/pages/docs/pdas.md index 6f0496dc6..06ed54033 100644 --- a/docs/src/pages/docs/pdas.md +++ b/docs/src/pages/docs/pdas.md @@ -128,7 +128,7 @@ pub mod game { panic!(); } user_stats.name = name; - user_stats.bump = *ctx.bumps.get("user_stats").unwrap(); + user_stats.bump = ctx.bumps.user_stats; Ok(()) } } @@ -158,7 +158,7 @@ pub struct CreateUserStats<'info> { In the account validation struct we use `seeds` together with `init` to create a PDA with the desired seeds. Additionally, we add an empty `bump` constraint to signal to anchor that it should find the canonical bump itself. -Then, in the handler, we call `ctx.bumps.get("user_stats")` to get the bump anchor found and save it to the user stats +Then, in the handler, we call `ctx.bumps.user_stats` to get the bump anchor found and save it to the user stats account as an extra property. If we then want to use the created pda in a different instruction, we can add a new validation struct (This will check that the `user_stats` account is the pda created by running `hash(seeds, user_stats.bump, game_program_id)`): diff --git a/examples/tutorial/basic-4/programs/basic-4/src/lib.rs b/examples/tutorial/basic-4/programs/basic-4/src/lib.rs index 34b4cf71e..e8281f8dc 100644 --- a/examples/tutorial/basic-4/programs/basic-4/src/lib.rs +++ b/examples/tutorial/basic-4/programs/basic-4/src/lib.rs @@ -9,7 +9,7 @@ pub mod basic_4 { pub fn initialize(ctx: Context) -> Result<()> { let counter = ctx.accounts.counter.deref_mut(); - let bump = *ctx.bumps.get("counter").ok_or(ErrorCode::CannotGetBump)?; + let bump = ctx.bumps.counter; *counter = Counter { authority: *ctx.accounts.authority.key, @@ -73,6 +73,4 @@ impl Counter { pub enum ErrorCode { #[msg("You are not authorized to perform this action.")] Unauthorized, - #[msg("Cannot get the bump.")] - CannotGetBump, } diff --git a/lang/attribute/event/src/lib.rs b/lang/attribute/event/src/lib.rs index 994dc498d..cbe7705d8 100644 --- a/lang/attribute/event/src/lib.rs +++ b/lang/attribute/event/src/lib.rs @@ -154,13 +154,12 @@ pub fn emit_cpi(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let authority = EventAuthority::get(); let authority_name = authority.name_token_stream(); - let authority_name_str = authority.name; let authority_seeds = authority.seeds; proc_macro::TokenStream::from(quote! { { let authority_info = ctx.accounts.#authority_name.to_account_info(); - let authority_bump = *ctx.bumps.get(#authority_name_str).unwrap(); + let authority_bump = ctx.bumps.#authority_name; let disc = anchor_lang::event::EVENT_IX_TAG_LE; let inner_data = anchor_lang::Event::data(&#event_struct); diff --git a/lang/src/accounts/account.rs b/lang/src/accounts/account.rs index 684b22e58..e9edb0bcd 100644 --- a/lang/src/accounts/account.rs +++ b/lang/src/accounts/account.rs @@ -10,7 +10,7 @@ use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; use solana_program::system_program; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::fmt; use std::ops::{Deref, DerefMut}; @@ -334,7 +334,7 @@ impl<'a, T: AccountSerialize + AccountDeserialize + Owner + Clone> Account<'a, T } } -impl<'info, T: AccountSerialize + AccountDeserialize + Owner + Clone> Accounts<'info> +impl<'info, B, T: AccountSerialize + AccountDeserialize + Owner + Clone> Accounts<'info, B> for Account<'info, T> where T: AccountSerialize + AccountDeserialize + Owner + Clone, @@ -344,7 +344,7 @@ where _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/account_info.rs b/lang/src/accounts/account_info.rs index 54d6cc80b..56922a78a 100644 --- a/lang/src/accounts/account_info.rs +++ b/lang/src/accounts/account_info.rs @@ -7,14 +7,14 @@ use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas} use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; -impl<'info> Accounts<'info> for AccountInfo<'info> { +impl<'info, B> Accounts<'info, B> for AccountInfo<'info> { fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/account_loader.rs b/lang/src/accounts/account_loader.rs index 5305b7fa4..b4cbe42d5 100644 --- a/lang/src/accounts/account_loader.rs +++ b/lang/src/accounts/account_loader.rs @@ -11,7 +11,7 @@ use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; use std::cell::{Ref, RefMut}; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::fmt; use std::io::Write; use std::marker::PhantomData; @@ -214,13 +214,13 @@ impl<'info, T: ZeroCopy + Owner> AccountLoader<'info, T> { } } -impl<'info, T: ZeroCopy + Owner> Accounts<'info> for AccountLoader<'info, T> { +impl<'info, B, T: ZeroCopy + Owner> Accounts<'info, B> for AccountLoader<'info, T> { #[inline(never)] fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/boxed.rs b/lang/src/accounts/boxed.rs index b143024ea..6905ab285 100644 --- a/lang/src/accounts/boxed.rs +++ b/lang/src/accounts/boxed.rs @@ -17,15 +17,15 @@ use crate::{Accounts, AccountsClose, AccountsExit, Result, ToAccountInfos, ToAcc use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::ops::Deref; -impl<'info, T: Accounts<'info>> Accounts<'info> for Box { +impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Box { fn try_accounts( program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], ix_data: &[u8], - bumps: &mut BTreeMap, + bumps: &mut B, reallocs: &mut BTreeSet, ) -> Result { T::try_accounts(program_id, accounts, ix_data, bumps, reallocs).map(Box::new) diff --git a/lang/src/accounts/interface.rs b/lang/src/accounts/interface.rs index 2c3e4dac8..b98d8f089 100644 --- a/lang/src/accounts/interface.rs +++ b/lang/src/accounts/interface.rs @@ -9,7 +9,7 @@ use crate::{ use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::ops::Deref; /// Type validating that the account is one of a set of given Programs @@ -105,13 +105,13 @@ impl<'info, T> AsRef> for Interface<'info, T> { } } -impl<'info, T: CheckId> Accounts<'info> for Interface<'info, T> { +impl<'info, B, T: CheckId> Accounts<'info, B> for Interface<'info, T> { #[inline(never)] fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/interface_account.rs b/lang/src/accounts/interface_account.rs index 44817a29e..eebbd5bde 100644 --- a/lang/src/accounts/interface_account.rs +++ b/lang/src/accounts/interface_account.rs @@ -10,7 +10,7 @@ use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; use solana_program::system_program; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::fmt; use std::ops::{Deref, DerefMut}; @@ -241,7 +241,7 @@ impl<'a, T: AccountSerialize + AccountDeserialize + CheckOwner + Clone> Interfac } } -impl<'info, T: AccountSerialize + AccountDeserialize + CheckOwner + Clone> Accounts<'info> +impl<'info, B, T: AccountSerialize + AccountDeserialize + CheckOwner + Clone> Accounts<'info, B> for InterfaceAccount<'info, T> { #[inline(never)] @@ -249,7 +249,7 @@ impl<'info, T: AccountSerialize + AccountDeserialize + CheckOwner + Clone> Accou _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/option.rs b/lang/src/accounts/option.rs index 095871623..8ade56e80 100644 --- a/lang/src/accounts/option.rs +++ b/lang/src/accounts/option.rs @@ -8,7 +8,7 @@ //! } //! ``` -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; @@ -18,12 +18,12 @@ use crate::{ error::ErrorCode, Accounts, AccountsClose, AccountsExit, Result, ToAccountInfos, ToAccountMetas, }; -impl<'info, T: Accounts<'info>> Accounts<'info> for Option { +impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Option { fn try_accounts( program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], ix_data: &[u8], - bumps: &mut BTreeMap, + bumps: &mut B, reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/program.rs b/lang/src/accounts/program.rs index 2aa8b9f7e..25d7189dc 100644 --- a/lang/src/accounts/program.rs +++ b/lang/src/accounts/program.rs @@ -8,7 +8,7 @@ use solana_program::account_info::AccountInfo; use solana_program::bpf_loader_upgradeable::{self, UpgradeableLoaderState}; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::convert::TryFrom; use std::fmt; use std::marker::PhantomData; @@ -140,13 +140,13 @@ impl<'a, T: Id> TryFrom<&AccountInfo<'a>> for Program<'a, T> { } } -impl<'info, T: Id> Accounts<'info> for Program<'info, T> { +impl<'info, B, T: Id> Accounts<'info, B> for Program<'info, T> { #[inline(never)] fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/signer.rs b/lang/src/accounts/signer.rs index 7d757024a..6ce5c2239 100644 --- a/lang/src/accounts/signer.rs +++ b/lang/src/accounts/signer.rs @@ -4,7 +4,7 @@ use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas} use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::ops::Deref; /// Type validating that the account signed the transaction. No other ownership @@ -54,13 +54,13 @@ impl<'info> Signer<'info> { } } -impl<'info> Accounts<'info> for Signer<'info> { +impl<'info, B> Accounts<'info, B> for Signer<'info> { #[inline(never)] fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/system_account.rs b/lang/src/accounts/system_account.rs index 8c90fd537..66c786e0e 100644 --- a/lang/src/accounts/system_account.rs +++ b/lang/src/accounts/system_account.rs @@ -6,7 +6,7 @@ use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; use solana_program::system_program; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::ops::Deref; /// Type validating that the account is owned by the system program @@ -33,13 +33,13 @@ impl<'info> SystemAccount<'info> { } } -impl<'info> Accounts<'info> for SystemAccount<'info> { +impl<'info, B> Accounts<'info, B> for SystemAccount<'info> { #[inline(never)] fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/sysvar.rs b/lang/src/accounts/sysvar.rs index c955ff9c1..7edfcf622 100644 --- a/lang/src/accounts/sysvar.rs +++ b/lang/src/accounts/sysvar.rs @@ -5,7 +5,7 @@ use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas} use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::fmt; use std::ops::{Deref, DerefMut}; @@ -65,12 +65,12 @@ impl<'info, T: solana_program::sysvar::Sysvar> Clone for Sysvar<'info, T> { } } -impl<'info, T: solana_program::sysvar::Sysvar> Accounts<'info> for Sysvar<'info, T> { +impl<'info, B, T: solana_program::sysvar::Sysvar> Accounts<'info, B> for Sysvar<'info, T> { fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/accounts/unchecked_account.rs b/lang/src/accounts/unchecked_account.rs index 5a0012757..562690d91 100644 --- a/lang/src/accounts/unchecked_account.rs +++ b/lang/src/accounts/unchecked_account.rs @@ -6,7 +6,7 @@ use crate::{Accounts, AccountsExit, Key, Result, ToAccountInfos, ToAccountMetas} use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; use std::ops::Deref; /// Explicit wrapper for AccountInfo types to emphasize @@ -20,12 +20,12 @@ impl<'info> UncheckedAccount<'info> { } } -impl<'info> Accounts<'info> for UncheckedAccount<'info> { +impl<'info, B> Accounts<'info, B> for UncheckedAccount<'info> { fn try_accounts( _program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], _ix_data: &[u8], - _bumps: &mut BTreeMap, + _bumps: &mut B, _reallocs: &mut BTreeSet, ) -> Result { if accounts.is_empty() { diff --git a/lang/src/context.rs b/lang/src/context.rs index 786ab926d..6c2b7dfe9 100644 --- a/lang/src/context.rs +++ b/lang/src/context.rs @@ -1,10 +1,9 @@ //! Data structures that are used to provide non-argument inputs to program endpoints -use crate::{Accounts, ToAccountInfos, ToAccountMetas}; +use crate::{Accounts, Bumps, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::BTreeMap; use std::fmt; /// Provides non-argument inputs to the program. @@ -22,7 +21,7 @@ use std::fmt; /// Ok(()) /// } /// ``` -pub struct Context<'a, 'b, 'c, 'info, T> { +pub struct Context<'a, 'b, 'c, 'info, T: Bumps> { /// Currently executing program id. pub program_id: &'a Pubkey, /// Deserialized accounts. @@ -33,10 +32,14 @@ pub struct Context<'a, 'b, 'c, 'info, T> { /// Bump seeds found during constraint validation. This is provided as a /// convenience so that handlers don't have to recalculate bump seeds or /// pass them in as arguments. - pub bumps: BTreeMap, + /// Type is the bumps struct generated by #[derive(Accounts)] + pub bumps: T::Bumps, } -impl<'a, 'b, 'c, 'info, T: fmt::Debug> fmt::Debug for Context<'a, 'b, 'c, 'info, T> { +impl<'a, 'b, 'c, 'info, T> fmt::Debug for Context<'a, 'b, 'c, 'info, T> +where + T: fmt::Debug + Bumps, +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Context") .field("program_id", &self.program_id) @@ -47,12 +50,15 @@ impl<'a, 'b, 'c, 'info, T: fmt::Debug> fmt::Debug for Context<'a, 'b, 'c, 'info, } } -impl<'a, 'b, 'c, 'info, T: Accounts<'info>> Context<'a, 'b, 'c, 'info, T> { +impl<'a, 'b, 'c, 'info, T> Context<'a, 'b, 'c, 'info, T> +where + T: Bumps + Accounts<'info, T::Bumps>, +{ pub fn new( program_id: &'a Pubkey, accounts: &'b mut T, remaining_accounts: &'c [AccountInfo<'info>], - bumps: BTreeMap, + bumps: T::Bumps, ) -> Self { Self { program_id, diff --git a/lang/src/lib.rs b/lang/src/lib.rs index 99bc2a0fe..0e5afa260 100644 --- a/lang/src/lib.rs +++ b/lang/src/lib.rs @@ -27,8 +27,7 @@ use bytemuck::{Pod, Zeroable}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; -use std::io::Write; +use std::{collections::BTreeSet, fmt::Debug, io::Write}; mod account_meta; pub mod accounts; @@ -74,7 +73,30 @@ pub type Result = std::result::Result; /// maintain any invariants required for the program to run securely. In most /// cases, it's recommended to use the [`Accounts`](./derive.Accounts.html) /// derive macro to implement this trait. -pub trait Accounts<'info>: ToAccountMetas + ToAccountInfos<'info> + Sized { +/// +/// Generics: +/// - `B`: the type of the PDA bumps cache struct generated by the `Accounts` struct. +/// For example, +/// ```rust,ignore +/// pub struct Example<'info> { +/// #[account( +/// init, +/// seeds = [...], +/// bump, +/// )] +/// pub pda_1: UncheckedAccount<'info>, +/// pub not_pda: UncheckedAccount<'info>, +/// } +/// ``` +/// +/// generates: +/// +/// ```rust,ignore +/// pub struct ExampleBumps { +/// pub pda_1: u8, +/// } +/// ``` +pub trait Accounts<'info, B>: ToAccountMetas + ToAccountInfos<'info> + Sized { /// Returns the validated accounts struct. What constitutes "valid" is /// program dependent. However, users of these types should never have to /// worry about account substitution attacks. For example, if a program @@ -90,11 +112,17 @@ pub trait Accounts<'info>: ToAccountMetas + ToAccountInfos<'info> + Sized { program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], ix_data: &[u8], - bumps: &mut BTreeMap, + bumps: &mut B, reallocs: &mut BTreeSet, ) -> Result; } +/// Associated bump seeds for `Accounts`. +pub trait Bumps { + /// Struct to hold account bump seeds. + type Bumps: Sized + Debug; +} + /// The exit procedure for an account. Any cleanup or persistence to storage /// should be done here. pub trait AccountsExit<'info>: ToAccountMetas + ToAccountInfos<'info> { diff --git a/lang/src/vec.rs b/lang/src/vec.rs index 44c132be6..150cd570f 100644 --- a/lang/src/vec.rs +++ b/lang/src/vec.rs @@ -2,7 +2,7 @@ use crate::{Accounts, Result, ToAccountInfos, ToAccountMetas}; use solana_program::account_info::AccountInfo; use solana_program::instruction::AccountMeta; use solana_program::pubkey::Pubkey; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeSet; impl<'info, T: ToAccountInfos<'info>> ToAccountInfos<'info> for Vec { fn to_account_infos(&self) -> Vec> { @@ -20,12 +20,12 @@ impl ToAccountMetas for Vec { } } -impl<'info, T: Accounts<'info>> Accounts<'info> for Vec { +impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Vec { fn try_accounts( program_id: &Pubkey, accounts: &mut &[AccountInfo<'info>], ix_data: &[u8], - bumps: &mut BTreeMap, + bumps: &mut B, reallocs: &mut BTreeSet, ) -> Result { let mut vec: Vec = Vec::new(); @@ -79,7 +79,7 @@ mod tests { false, Epoch::default(), ); - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = TestBumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = &[account1, account2][..]; let parsed_accounts = @@ -93,7 +93,7 @@ mod tests { #[should_panic] fn test_accounts_trait_for_vec_empty() { let program_id = Pubkey::default(); - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = TestBumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = &[][..]; Vec::::try_accounts(&program_id, &mut accounts, &[], &mut bumps, &mut reallocs) diff --git a/lang/syn/src/codegen/accounts/bumps.rs b/lang/syn/src/codegen/accounts/bumps.rs new file mode 100644 index 000000000..762907356 --- /dev/null +++ b/lang/syn/src/codegen/accounts/bumps.rs @@ -0,0 +1,89 @@ +use crate::{ + codegen::accounts::{generics, ParsedGenerics}, + *, +}; +use std::fmt::Display; + +use super::constraints; + +pub fn generate_bumps_name(anchor_ident: &T) -> Ident { + Ident::new(&format!("{}Bumps", anchor_ident), Span::call_site()) +} + +pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { + let name = &accs.ident; + let bumps_name = generate_bumps_name(name); + let ParsedGenerics { + combined_generics, + trait_generics: _, + struct_generics, + where_clause, + } = generics(accs); + + let (bump_fields, bump_default_fields): ( + Vec, + Vec, + ) = accs + .fields + .iter() + .filter_map(|af| { + let ident = af.ident(); + + match af { + AccountField::Field(f) => { + let constraints = constraints::linearize(&f.constraints); + let bump_field = quote!(pub #ident: u8); + let bump_default_field = quote!(#ident: u8::MAX); + + for c in constraints.iter() { + // Verify this in super::constraints + // The bump is only cached if + // - PDA is marked as init + // - PDA is not init, but marked with bump without a target + + match c { + Constraint::Seeds(c) => { + if !c.is_init && c.bump.is_none() { + return Some((bump_field, bump_default_field)); + } + } + Constraint::Init(c) => { + if c.seeds.is_some() { + return Some((bump_field, bump_default_field)); + } + } + _ => (), + } + } + None + } + AccountField::CompositeField(s) => { + let comp_bumps_struct = generate_bumps_name(&s.symbol); + let bumps = quote!(pub #ident: #comp_bumps_struct); + let bumps_default = quote!(#ident: #comp_bumps_struct::default()); + + Some((bumps, bumps_default)) + } + } + }) + .unzip(); + + quote! { + #[derive(Debug)] + pub struct #bumps_name { + #(#bump_fields),* + } + + impl Default for #bumps_name { + fn default() -> Self { + #bumps_name { + #(#bump_default_fields),* + } + } + } + + impl<#combined_generics> anchor_lang::Bumps for #name<#struct_generics> #where_clause { + type Bumps = #bumps_name; + } + } +} diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index 63f22bd33..f1178453f 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -482,7 +482,7 @@ fn generate_constraint_init_group( &[#maybe_seeds_plus_comma], __program_id, ); - __bumps.insert(#name_str.to_string(), __bump); + __bumps.#field = __bump; #validate_pda }, quote! { @@ -882,7 +882,7 @@ fn generate_constraint_seeds(f: &Field, c: &ConstraintSeedsGroup) -> proc_macro2 &[#maybe_seeds_plus_comma], &#deriving_program_id, ); - __bumps.insert(#name_str.to_string(), __bump); + __bumps.#name = __bump; }, // Bump target given. Use it. Some(b) => quote! { diff --git a/lang/syn/src/codegen/accounts/mod.rs b/lang/syn/src/codegen/accounts/mod.rs index 5e10febcf..2e0c3d5b3 100644 --- a/lang/syn/src/codegen/accounts/mod.rs +++ b/lang/syn/src/codegen/accounts/mod.rs @@ -7,6 +7,7 @@ use syn::{GenericParam, PredicateLifetime, WhereClause, WherePredicate}; mod __client_accounts; mod __cpi_client_accounts; +mod bumps; mod constraints; mod exit; mod to_account_infos; @@ -18,6 +19,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { let impl_to_account_infos = to_account_infos::generate(accs); let impl_to_account_metas = to_account_metas::generate(accs); let impl_exit = exit::generate(accs); + let bumps_struct = bumps::generate(accs); let __client_accounts_mod = __client_accounts::generate(accs); let __cpi_client_accounts_mod = __cpi_client_accounts::generate(accs); @@ -27,6 +29,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { #impl_to_account_infos #impl_to_account_metas #impl_exit + #bumps_struct #__client_accounts_mod #__cpi_client_accounts_mod diff --git a/lang/syn/src/codegen/accounts/try_accounts.rs b/lang/syn/src/codegen/accounts/try_accounts.rs index 0c284634d..469a447c2 100644 --- a/lang/syn/src/codegen/accounts/try_accounts.rs +++ b/lang/syn/src/codegen/accounts/try_accounts.rs @@ -1,4 +1,4 @@ -use crate::codegen::accounts::{constraints, generics, ParsedGenerics}; +use crate::codegen::accounts::{bumps, constraints, generics, ParsedGenerics}; use crate::{AccountField, AccountsStruct}; use quote::quote; use syn::Expr; @@ -25,7 +25,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { quote! { #[cfg(feature = "anchor-debug")] ::solana_program::log::sol_log(stringify!(#name)); - let #name: #ty = anchor_lang::Accounts::try_accounts(__program_id, __accounts, __ix_data, __bumps, __reallocs)?; + let #name: #ty = anchor_lang::Accounts::try_accounts(__program_id, __accounts, __ix_data, &mut __bumps.#name, __reallocs)?; } } AccountField::Field(f) => { @@ -82,6 +82,7 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { let constraints = generate_constraints(accs); let accounts_instance = generate_accounts_instance(accs); + let bumps_struct_name = bumps::generate_bumps_name(&accs.ident); let ix_de = match &accs.instruction_api { None => quote! {}, @@ -115,13 +116,13 @@ pub fn generate(accs: &AccountsStruct) -> proc_macro2::TokenStream { quote! { #[automatically_derived] - impl<#combined_generics> anchor_lang::Accounts<#trait_generics> for #name<#struct_generics> #where_clause { + impl<#combined_generics> anchor_lang::Accounts<#trait_generics, #bumps_struct_name> for #name<#struct_generics> #where_clause { #[inline(never)] fn try_accounts( __program_id: &anchor_lang::solana_program::pubkey::Pubkey, __accounts: &mut &[anchor_lang::solana_program::account_info::AccountInfo<'info>], __ix_data: &[u8], - __bumps: &mut std::collections::BTreeMap, + __bumps: &mut #bumps_struct_name, __reallocs: &mut std::collections::BTreeSet, ) -> anchor_lang::Result { // Deserialize instruction, if declared. diff --git a/lang/syn/src/codegen/program/handlers.rs b/lang/syn/src/codegen/program/handlers.rs index 07ee097b4..b9b8962ac 100644 --- a/lang/syn/src/codegen/program/handlers.rs +++ b/lang/syn/src/codegen/program/handlers.rs @@ -29,7 +29,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { match ix { anchor_lang::idl::IdlInstruction::Create { data_len } => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlCreateAccounts::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -37,7 +37,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::Resize { data_len } => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlResizeAccount::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -45,7 +45,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::Close => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlCloseAccount::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -53,7 +53,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::CreateBuffer => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlCreateBuffer::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -61,7 +61,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::Write { data } => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlAccounts::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -69,7 +69,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::SetAuthority { new_authority } => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlAccounts::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -77,7 +77,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { accounts.exit(program_id)?; }, anchor_lang::idl::IdlInstruction::SetBuffer => { - let mut bumps = std::collections::BTreeMap::new(); + let mut bumps = ::Bumps::default(); let mut reallocs = std::collections::BTreeSet::new(); let mut accounts = IdlSetBuffer::try_accounts(program_id, &mut accounts, &[], &mut bumps, &mut reallocs)?; @@ -126,7 +126,7 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream { let instruction::#variant_arm = ix; // Bump collector. - let mut __bumps = std::collections::BTreeMap::new(); + let mut __bumps = <#anchor as anchor_lang::Bumps>::Bumps::default(); let mut __reallocs = std::collections::BTreeSet::new(); diff --git a/tests/auction-house/programs/auction-house/src/lib.rs b/tests/auction-house/programs/auction-house/src/lib.rs index 32aa1c7ed..aff27a38d 100644 --- a/tests/auction-house/programs/auction-house/src/lib.rs +++ b/tests/auction-house/programs/auction-house/src/lib.rs @@ -51,9 +51,9 @@ pub mod auction_house { let associated_token_program = &ctx.accounts.associated_token_program; let rent = &ctx.accounts.rent; - auction_house.treasury_bump = *ctx.bumps.get("auction_house_treasury").unwrap(); - auction_house.bump = *ctx.bumps.get("auction_house").unwrap(); - auction_house.fee_payer_bump = *ctx.bumps.get("auction_house_fee_account").unwrap(); + auction_house.treasury_bump = ctx.bumps.auction_house_treasury; + auction_house.bump = ctx.bumps.auction_house; + auction_house.fee_payer_bump = ctx.bumps.auction_house_fee_account; if seller_fee_basis_points > 10000 { return err!(ErrorCode::InvalidBasisPoints); @@ -147,7 +147,7 @@ pub mod auction_house { ]; let wallet_key = wallet.key(); - let escrow_payment_bump = *ctx.bumps.get("escrow_payment_account").unwrap(); + let escrow_payment_bump = ctx.bumps.escrow_payment_account; let escrow_signer_seeds = [ PREFIX.as_bytes(), auction_house_key.as_ref(), @@ -254,7 +254,7 @@ pub mod auction_house { return err!(ErrorCode::NoValidSignerPresent); } - let escrow_payment_bump = *ctx.bumps.get("escrow_payment_account").unwrap(); + let escrow_payment_bump = ctx.bumps.escrow_payment_account; let escrow_signer_seeds = [ PREFIX.as_bytes(), @@ -419,7 +419,7 @@ pub mod auction_house { )?; } - let trade_state_bump = *ctx.bumps.get("seller_trade_state").unwrap(); + let trade_state_bump = ctx.bumps.seller_trade_state; let ts_info = seller_trade_state.to_account_info(); if ts_info.data_is_empty() { @@ -536,8 +536,8 @@ pub mod auction_house { let system_program = &ctx.accounts.system_program; let rent = &ctx.accounts.rent; - let trade_state_bump = *ctx.bumps.get("buyer_trade_state").unwrap(); - let escrow_payment_bump = *ctx.bumps.get("escrow_payment_account").unwrap(); + let trade_state_bump = ctx.bumps.buyer_trade_state; + let escrow_payment_bump = ctx.bumps.escrow_payment_account; let auction_house_key = auction_house.key(); let seeds = [ @@ -671,7 +671,7 @@ pub mod auction_house { let token_account = &ctx.accounts.token_account; let token_mint = &ctx.accounts.token_mint; let metadata = &ctx.accounts.metadata; - let treasury_mint = &ctx.accounts.treasury_mint; + let treasury_mint = &ctx.accounts.treasury_mint.to_account_info(); let seller_payment_receipt_account = &ctx.accounts.seller_payment_receipt_account; let buyer_receipt_token_account = &ctx.accounts.buyer_receipt_token_account; let escrow_payment_account = &ctx.accounts.escrow_payment_account; @@ -691,8 +691,8 @@ pub mod auction_house { let ata_clone = associated_token_program.to_account_info(); let token_clone = token_program.to_account_info(); - let escrow_payment_bump = *ctx.bumps.get("escrow_payment_account").unwrap(); - let program_as_signer_bump = *ctx.bumps.get("program_as_signer").unwrap(); + let escrow_payment_bump = ctx.bumps.escrow_payment_account; + let program_as_signer_bump = ctx.bumps.program_as_signer; let is_native = treasury_mint.key() == spl_token::native_mint::id(); @@ -1450,7 +1450,8 @@ pub struct ExecuteSale<'info> { token_mint: UncheckedAccount<'info>, metadata: UncheckedAccount<'info>, // cannot mark these as real Accounts or else we blow stack size limit - treasury_mint: UncheckedAccount<'info>, + //TODO revert this change in a near future + treasury_mint: Box>, #[account(mut)] seller_payment_receipt_account: UncheckedAccount<'info>, #[account(mut)] @@ -1461,7 +1462,7 @@ pub struct ExecuteSale<'info> { seeds=[ PREFIX.as_bytes(), authority.key.as_ref(), - treasury_mint.key.as_ref(), + treasury_mint.key().as_ref(), ], bump=auction_house.bump, has_one=authority, diff --git a/tests/bench/bench.json b/tests/bench/bench.json index 488397217..393109301 100644 --- a/tests/bench/bench.json +++ b/tests/bench/bench.json @@ -375,185 +375,185 @@ "solanaVersion": "1.17.0", "result": { "binarySize": { - "bench": 1075688 + "bench": 1049608 }, "computeUnits": { - "accountInfo1": 680, - "accountInfo2": 1083, - "accountInfo4": 1535, - "accountInfo8": 2774, + "accountInfo1": 584, + "accountInfo2": 824, + "accountInfo4": 1319, + "accountInfo8": 2531, "accountEmptyInit1": 5521, - "accountEmpty1": 815, + "accountEmpty1": 777, "accountEmptyInit2": 10111, - "accountEmpty2": 1366, + "accountEmpty2": 1207, "accountEmptyInit4": 19044, - "accountEmpty4": 2120, + "accountEmpty4": 2074, "accountEmptyInit8": 37265, "accountEmpty8": 3967, "accountSizedInit1": 5626, - "accountSized1": 820, + "accountSized1": 786, "accountSizedInit2": 10322, - "accountSized2": 1411, + "accountSized2": 1234, "accountSizedInit4": 19462, - "accountSized4": 2181, + "accountSized4": 2135, "accountSizedInit8": 38122, "accountSized8": 4104, "accountUnsizedInit1": 5742, - "accountUnsized1": 859, + "accountUnsized1": 821, "accountUnsizedInit2": 10551, - "accountUnsized2": 1364, + "accountUnsized2": 1312, "accountUnsizedInit4": 19927, - "accountUnsized4": 2341, + "accountUnsized4": 2315, "accountUnsizedInit8": 38699, "accountUnsized8": 4456, - "boxedAccountEmptyInit1": 5624, - "boxedAccountEmpty1": 888, - "boxedAccountEmptyInit2": 10221, - "boxedAccountEmpty2": 1401, + "boxedAccountEmptyInit1": 5452, + "boxedAccountEmpty1": 866, + "boxedAccountEmptyInit2": 10051, + "boxedAccountEmpty2": 1377, "boxedAccountEmptyInit4": 19030, - "boxedAccountEmpty4": 2424, + "boxedAccountEmpty4": 2396, "boxedAccountEmptyInit8": 37136, - "boxedAccountEmpty8": 4527, - "boxedAccountSizedInit1": 5718, - "boxedAccountSized1": 917, - "boxedAccountSizedInit2": 10412, - "boxedAccountSized2": 1463, + "boxedAccountEmpty8": 4472, + "boxedAccountSizedInit1": 5546, + "boxedAccountSized1": 895, + "boxedAccountSizedInit2": 10242, + "boxedAccountSized2": 1439, "boxedAccountSizedInit4": 19414, - "boxedAccountSized4": 2543, + "boxedAccountSized4": 2515, "boxedAccountSizedInit8": 37919, - "boxedAccountSized8": 4766, + "boxedAccountSized8": 4711, "boxedAccountUnsizedInit1": 5823, - "boxedAccountUnsized1": 972, + "boxedAccountUnsized1": 950, "boxedAccountUnsizedInit2": 10621, - "boxedAccountUnsized2": 1570, + "boxedAccountUnsized2": 1549, "boxedAccountUnsizedInit4": 19825, - "boxedAccountUnsized4": 2768, + "boxedAccountUnsized4": 2737, "boxedAccountUnsizedInit8": 38791, "boxedAccountUnsized8": 5207, - "boxedInterfaceAccountMint1": 2159, + "boxedInterfaceAccountMint1": 2137, "boxedInterfaceAccountMint2": 3849, "boxedInterfaceAccountMint4": 7215, "boxedInterfaceAccountMint8": 14044, - "boxedInterfaceAccountToken1": 2088, + "boxedInterfaceAccountToken1": 2066, "boxedInterfaceAccountToken2": 3706, "boxedInterfaceAccountToken4": 6932, "boxedInterfaceAccountToken8": 13477, - "interfaceAccountMint1": 2574, - "interfaceAccountMint2": 4410, - "interfaceAccountMint4": 8313, + "interfaceAccountMint1": 2313, + "interfaceAccountMint2": 4270, + "interfaceAccountMint4": 8185, "interfaceAccountMint8": 16007, - "interfaceAccountToken1": 2137, - "interfaceAccountToken2": 4032, + "interfaceAccountToken1": 2059, + "interfaceAccountToken2": 3958, "interfaceAccountToken4": 7816, - "interface1": 726, - "interface2": 1093, - "interface4": 1484, + "interface1": 691, + "interface2": 940, + "interface4": 1450, "interface8": 2605, - "program1": 720, - "program2": 1081, - "program4": 1462, + "program1": 685, + "program2": 928, + "program4": 1428, "program8": 2557, - "signer1": 683, - "signer2": 1092, - "signer4": 1555, - "signer8": 2813, - "systemAccount1": 737, - "systemAccount2": 1198, - "systemAccount4": 1766, - "systemAccount8": 3238, - "uncheckedAccount1": 679, - "uncheckedAccount2": 1083, - "uncheckedAccount4": 1536, - "uncheckedAccount8": 2774 + "signer1": 621, + "signer2": 895, + "signer4": 1455, + "signer8": 2721, + "systemAccount1": 675, + "systemAccount2": 1001, + "systemAccount4": 1666, + "systemAccount8": 3146, + "uncheckedAccount1": 583, + "uncheckedAccount2": 824, + "uncheckedAccount4": 1320, + "uncheckedAccount8": 2531 }, "stackMemory": { - "account_info1": 272, - "account_info2": 320, - "account_info4": 416, - "account_info8": 608, - "account_empty_init1": 400, - "account_empty_init2": 480, - "account_empty_init4": 528, - "account_empty_init8": 720, - "account_empty1": 272, - "account_empty2": 320, - "account_empty4": 416, - "account_empty8": 608, - "account_sized_init1": 408, - "account_sized_init2": 496, - "account_sized_init4": 560, - "account_sized_init8": 784, - "account_sized1": 280, - "account_sized2": 336, - "account_sized4": 448, - "account_sized8": 672, - "account_unsized_init1": 424, - "account_unsized_init2": 528, - "account_unsized_init4": 624, - "account_unsized_init8": 912, - "account_unsized1": 296, - "account_unsized2": 368, - "account_unsized4": 512, - "account_unsized8": 800, - "boxed_account_empty_init1": 360, - "boxed_account_empty_init2": 400, - "boxed_account_empty_init4": 368, - "boxed_account_empty_init8": 400, - "boxed_account_empty1": 232, - "boxed_account_empty2": 240, - "boxed_account_empty4": 256, - "boxed_account_empty8": 288, - "boxed_account_sized_init1": 360, - "boxed_account_sized_init2": 400, - "boxed_account_sized_init4": 368, - "boxed_account_sized_init8": 400, - "boxed_account_sized1": 232, - "boxed_account_sized2": 240, - "boxed_account_sized4": 256, - "boxed_account_sized8": 288, - "boxed_account_unsized_init1": 360, - "boxed_account_unsized_init2": 400, - "boxed_account_unsized_init4": 368, - "boxed_account_unsized_init8": 400, - "boxed_account_unsized1": 232, - "boxed_account_unsized2": 240, - "boxed_account_unsized4": 256, - "boxed_account_unsized8": 288, - "boxed_interface_account_mint1": 232, - "boxed_interface_account_mint2": 240, - "boxed_interface_account_mint4": 256, - "boxed_interface_account_mint8": 288, - "boxed_interface_account_token1": 232, - "boxed_interface_account_token2": 240, - "boxed_interface_account_token4": 256, - "boxed_interface_account_token8": 288, - "interface_account_mint1": 392, - "interface_account_mint2": 560, - "interface_account_mint4": 896, - "interface_account_mint8": 1568, - "interface_account_token1": 480, - "interface_account_token2": 736, - "interface_account_token4": 1248, - "interface1": 272, - "interface2": 320, - "interface4": 416, - "interface8": 608, - "program1": 272, - "program2": 320, - "program4": 416, - "program8": 608, - "signer1": 272, - "signer2": 320, - "signer4": 416, - "signer8": 608, - "system_account1": 272, - "system_account2": 320, - "system_account4": 416, - "system_account8": 608, - "unchecked_account1": 272, - "unchecked_account2": 320, - "unchecked_account4": 416, - "unchecked_account8": 608 + "account_info1": 128, + "account_info2": 128, + "account_info4": 128, + "account_info8": 128, + "account_empty_init1": 320, + "account_empty_init2": 400, + "account_empty_init4": 448, + "account_empty_init8": 640, + "account_empty1": 128, + "account_empty2": 128, + "account_empty4": 128, + "account_empty8": 128, + "account_sized_init1": 328, + "account_sized_init2": 416, + "account_sized_init4": 480, + "account_sized_init8": 704, + "account_sized1": 128, + "account_sized2": 128, + "account_sized4": 128, + "account_sized8": 128, + "account_unsized_init1": 344, + "account_unsized_init2": 448, + "account_unsized_init4": 544, + "account_unsized_init8": 832, + "account_unsized1": 128, + "account_unsized2": 128, + "account_unsized4": 128, + "account_unsized8": 128, + "boxed_account_empty_init1": 176, + "boxed_account_empty_init2": 208, + "boxed_account_empty_init4": 288, + "boxed_account_empty_init8": 320, + "boxed_account_empty1": 128, + "boxed_account_empty2": 144, + "boxed_account_empty4": 144, + "boxed_account_empty8": 128, + "boxed_account_sized_init1": 176, + "boxed_account_sized_init2": 208, + "boxed_account_sized_init4": 288, + "boxed_account_sized_init8": 320, + "boxed_account_sized1": 128, + "boxed_account_sized2": 144, + "boxed_account_sized4": 144, + "boxed_account_sized8": 128, + "boxed_account_unsized_init1": 280, + "boxed_account_unsized_init2": 320, + "boxed_account_unsized_init4": 288, + "boxed_account_unsized_init8": 320, + "boxed_account_unsized1": 152, + "boxed_account_unsized2": 144, + "boxed_account_unsized4": 176, + "boxed_account_unsized8": 192, + "boxed_interface_account_mint1": 128, + "boxed_interface_account_mint2": 144, + "boxed_interface_account_mint4": 144, + "boxed_interface_account_mint8": 128, + "boxed_interface_account_token1": 128, + "boxed_interface_account_token2": 144, + "boxed_interface_account_token4": 144, + "boxed_interface_account_token8": 128, + "interface_account_mint1": 128, + "interface_account_mint2": 128, + "interface_account_mint4": 128, + "interface_account_mint8": 128, + "interface_account_token1": 128, + "interface_account_token2": 128, + "interface_account_token4": 128, + "interface1": 128, + "interface2": 128, + "interface4": 128, + "interface8": 128, + "program1": 128, + "program2": 128, + "program4": 128, + "program8": 128, + "signer1": 128, + "signer2": 128, + "signer4": 128, + "signer8": 128, + "system_account1": 128, + "system_account2": 128, + "system_account4": 128, + "system_account8": 128, + "unchecked_account1": 128, + "unchecked_account2": 128, + "unchecked_account4": 128, + "unchecked_account8": 128 } } } diff --git a/tests/chat/programs/chat/src/lib.rs b/tests/chat/programs/chat/src/lib.rs index 8dff89241..e1b850d19 100644 --- a/tests/chat/programs/chat/src/lib.rs +++ b/tests/chat/programs/chat/src/lib.rs @@ -11,7 +11,7 @@ pub mod chat { pub fn create_user(ctx: Context, name: String) -> Result<()> { ctx.accounts.user.name = name; ctx.accounts.user.authority = *ctx.accounts.authority.key; - ctx.accounts.user.bump = *ctx.bumps.get("user").unwrap(); + ctx.accounts.user.bump = ctx.bumps.user; Ok(()) } pub fn create_chat_room(ctx: Context, name: String) -> Result<()> { diff --git a/tests/idl/programs/relations-derivation/src/lib.rs b/tests/idl/programs/relations-derivation/src/lib.rs index 11e03e885..2dfa753aa 100644 --- a/tests/idl/programs/relations-derivation/src/lib.rs +++ b/tests/idl/programs/relations-derivation/src/lib.rs @@ -8,7 +8,7 @@ pub mod relations_derivation { pub fn init_base(ctx: Context) -> Result<()> { ctx.accounts.account.my_account = ctx.accounts.my_account.key(); - ctx.accounts.account.bump = ctx.bumps["account"]; + ctx.accounts.account.bump = ctx.bumps.account; Ok(()) } diff --git a/tests/ido-pool/programs/ido-pool/src/lib.rs b/tests/ido-pool/programs/ido-pool/src/lib.rs index 53afe43ea..65a44ebd6 100644 --- a/tests/ido-pool/programs/ido-pool/src/lib.rs +++ b/tests/ido-pool/programs/ido-pool/src/lib.rs @@ -33,10 +33,10 @@ pub mod ido_pool { ido_account.ido_name = name_data; ido_account.bumps = PoolBumps { - ido_account: *ctx.bumps.get("ido_account").unwrap(), - redeemable_mint: *ctx.bumps.get("redeemable_mint").unwrap(), - pool_watermelon: *ctx.bumps.get("pool_watermelon").unwrap(), - pool_usdc: *ctx.bumps.get("pool_usdc").unwrap(), + ido_account: ctx.bumps.ido_account, + redeemable_mint: ctx.bumps.redeemable_mint, + pool_watermelon: ctx.bumps.pool_watermelon, + pool_usdc: ctx.bumps.pool_usdc, }; ido_account.ido_authority = ctx.accounts.ido_authority.key(); diff --git a/tests/misc/programs/misc-optional/src/lib.rs b/tests/misc/programs/misc-optional/src/lib.rs index f6ec1dc07..4e447acfd 100644 --- a/tests/misc/programs/misc-optional/src/lib.rs +++ b/tests/misc/programs/misc-optional/src/lib.rs @@ -112,7 +112,7 @@ pub mod misc_optional { pub fn test_pda_init_zero_copy(ctx: Context) -> Result<()> { let mut acc = ctx.accounts.my_pda.as_ref().unwrap().load_init()?; acc.data = 9; - acc.bump = *ctx.bumps.get("my_pda").unwrap(); + acc.bump = ctx.bumps.my_pda; Ok(()) } diff --git a/tests/misc/programs/misc/src/lib.rs b/tests/misc/programs/misc/src/lib.rs index 7935c1450..d0056018f 100644 --- a/tests/misc/programs/misc/src/lib.rs +++ b/tests/misc/programs/misc/src/lib.rs @@ -106,7 +106,7 @@ pub mod misc { pub fn test_pda_init_zero_copy(ctx: Context) -> Result<()> { let mut acc = ctx.accounts.my_pda.load_init()?; acc.data = 9; - acc.bump = *ctx.bumps.get("my_pda").unwrap(); + acc.bump = ctx.bumps.my_pda; Ok(()) } diff --git a/tests/realloc/programs/realloc/src/lib.rs b/tests/realloc/programs/realloc/src/lib.rs index a854e6a0a..3ac5eb5dc 100644 --- a/tests/realloc/programs/realloc/src/lib.rs +++ b/tests/realloc/programs/realloc/src/lib.rs @@ -8,7 +8,7 @@ pub mod realloc { pub fn initialize(ctx: Context) -> Result<()> { ctx.accounts.sample.data = vec![0]; - ctx.accounts.sample.bump = *ctx.bumps.get("sample").unwrap(); + ctx.accounts.sample.bump = ctx.bumps.sample; Ok(()) } diff --git a/tests/relations-derivation/programs/relations-derivation/src/lib.rs b/tests/relations-derivation/programs/relations-derivation/src/lib.rs index d463044a3..c36cabd84 100644 --- a/tests/relations-derivation/programs/relations-derivation/src/lib.rs +++ b/tests/relations-derivation/programs/relations-derivation/src/lib.rs @@ -11,7 +11,7 @@ pub mod relations_derivation { pub fn init_base(ctx: Context) -> Result<()> { ctx.accounts.account.my_account = ctx.accounts.my_account.key(); - ctx.accounts.account.bump = ctx.bumps["account"]; + ctx.accounts.account.bump = ctx.bumps.account; Ok(()) } pub fn test_relation(_ctx: Context) -> Result<()> { @@ -32,7 +32,7 @@ pub struct InitBase<'info> { bump, )] account: Account<'info, MyAccount>, - system_program: Program<'info, System> + system_program: Program<'info, System>, } #[derive(Accounts)] @@ -60,9 +60,8 @@ pub struct TestRelation<'info> { nested: Nested<'info>, } - #[account] pub struct MyAccount { pub my_account: Pubkey, - pub bump: u8 + pub bump: u8, } diff --git a/tests/spl/token-wrapper/programs/token-wrapper/src/lib.rs b/tests/spl/token-wrapper/programs/token-wrapper/src/lib.rs index f0b12551d..58560d86a 100644 --- a/tests/spl/token-wrapper/programs/token-wrapper/src/lib.rs +++ b/tests/spl/token-wrapper/programs/token-wrapper/src/lib.rs @@ -11,9 +11,7 @@ //! 2. Users can call the unwrap function to burn Y and withdraw X unwrapped tokens use anchor_lang::prelude::*; -use anchor_spl::token_interface::{ - self, Mint, TokenAccount, TokenInterface, -}; +use anchor_spl::token_interface::{self, Mint, TokenAccount, TokenInterface}; declare_id!("4ZPcGU8MX8oL2u1EtErHzixAbgNBNeE9yoYq3kKMqnAy"); @@ -24,16 +22,16 @@ pub mod token_wrapper { pub const WRAPPER_AUTH_SEED: &[u8] = b"wrapr"; pub const WRAPPER_VAULT_SEED: &[u8] = b"vault"; - pub fn initialize( - ctx: Context, - initializer_amount: u64, - ) -> Result<()> { + pub fn initialize(ctx: Context, initializer_amount: u64) -> Result<()> { // deposit into vault token_interface::transfer_checked( CpiContext::new( ctx.accounts.deposit_token_program.to_account_info(), token_interface::TransferChecked { - from: ctx.accounts.initializer_deposit_token_account.to_account_info(), + from: ctx + .accounts + .initializer_deposit_token_account + .to_account_info(), mint: ctx.accounts.deposit_mint.to_account_info(), to: ctx.accounts.deposit_token_vault.to_account_info(), authority: ctx.accounts.initializer.to_account_info(), @@ -48,7 +46,7 @@ pub mod token_wrapper { WRAPPER_AUTH_SEED, ctx.accounts.deposit_mint.to_account_info().key.as_ref(), ctx.accounts.wrapped_mint.to_account_info().key.as_ref(), - &[*ctx.bumps.get("wrapper_authority").unwrap()], + &[ctx.bumps.wrapper_authority], ]; let signer_seeds = &[&inner_seeds[..]]; token_interface::mint_to( @@ -56,7 +54,10 @@ pub mod token_wrapper { ctx.accounts.wrapped_token_program.to_account_info(), token_interface::MintTo { mint: ctx.accounts.wrapped_mint.to_account_info(), - to: ctx.accounts.initializer_wrapped_token_account.to_account_info(), + to: ctx + .accounts + .initializer_wrapped_token_account + .to_account_info(), authority: ctx.accounts.wrapper_authority.to_account_info(), }, signer_seeds, @@ -88,7 +89,7 @@ pub mod token_wrapper { WRAPPER_AUTH_SEED, ctx.accounts.deposit_mint.to_account_info().key.as_ref(), ctx.accounts.wrapped_mint.to_account_info().key.as_ref(), - &[*ctx.bumps.get("wrapper_authority").unwrap()], + &[ctx.bumps.wrapper_authority], ]; let signer_seeds = &[&inner_seeds[..]]; token_interface::mint_to( @@ -126,7 +127,7 @@ pub mod token_wrapper { WRAPPER_AUTH_SEED, ctx.accounts.deposit_mint.to_account_info().key.as_ref(), ctx.accounts.wrapped_mint.to_account_info().key.as_ref(), - &[*ctx.bumps.get("wrapper_authority").unwrap()], + &[ctx.bumps.wrapper_authority], ]; let signer_seeds = &[&inner_seeds[..]]; token_interface::transfer_checked( @@ -138,7 +139,7 @@ pub mod token_wrapper { to: ctx.accounts.user_deposit_token_account.to_account_info(), authority: ctx.accounts.wrapper_authority.to_account_info(), }, - signer_seeds + signer_seeds, ), unwrap_amount, ctx.accounts.deposit_mint.decimals,