Browse Source

lang: Type safe bumps (#2542)

Jean Marchand (Exotic Markets) 2 years ago
parent
commit
243ab75738
37 changed files with 524 additions and 398 deletions
  1. 1 0
      CHANGELOG.md
  2. 3 3
      bench/BINARY_SIZE.md
  3. 53 53
      bench/COMPUTE_UNITS.md
  4. 89 89
      bench/STACK_MEMORY.md
  5. 2 2
      docs/src/pages/docs/pdas.md
  6. 1 3
      examples/tutorial/basic-4/programs/basic-4/src/lib.rs
  7. 1 2
      lang/attribute/event/src/lib.rs
  8. 3 3
      lang/src/accounts/account.rs
  9. 3 3
      lang/src/accounts/account_info.rs
  10. 3 3
      lang/src/accounts/account_loader.rs
  11. 3 3
      lang/src/accounts/boxed.rs
  12. 3 3
      lang/src/accounts/interface.rs
  13. 3 3
      lang/src/accounts/interface_account.rs
  14. 3 3
      lang/src/accounts/option.rs
  15. 3 3
      lang/src/accounts/program.rs
  16. 3 3
      lang/src/accounts/signer.rs
  17. 3 3
      lang/src/accounts/system_account.rs
  18. 3 3
      lang/src/accounts/sysvar.rs
  19. 3 3
      lang/src/accounts/unchecked_account.rs
  20. 13 7
      lang/src/context.rs
  21. 32 4
      lang/src/lib.rs
  22. 5 5
      lang/src/vec.rs
  23. 89 0
      lang/syn/src/codegen/accounts/bumps.rs
  24. 2 2
      lang/syn/src/codegen/accounts/constraints.rs
  25. 3 0
      lang/syn/src/codegen/accounts/mod.rs
  26. 5 4
      lang/syn/src/codegen/accounts/try_accounts.rs
  27. 8 8
      lang/syn/src/codegen/program/handlers.rs
  28. 14 13
      tests/auction-house/programs/auction-house/src/lib.rs
  29. 141 141
      tests/bench/bench.json
  30. 1 1
      tests/chat/programs/chat/src/lib.rs
  31. 1 1
      tests/idl/programs/relations-derivation/src/lib.rs
  32. 4 4
      tests/ido-pool/programs/ido-pool/src/lib.rs
  33. 1 1
      tests/misc/programs/misc-optional/src/lib.rs
  34. 1 1
      tests/misc/programs/misc/src/lib.rs
  35. 1 1
      tests/realloc/programs/realloc/src/lib.rs
  36. 3 4
      tests/relations-derivation/programs/relations-derivation/src/lib.rs
  37. 14 13
      tests/spl/token-wrapper/programs/token-wrapper/src/lib.rs

+ 1 - 0
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<Idl>` instead of `Result<Option<Idl>>` ([#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)).

+ 3 - 3
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
 

+ 53 - 53
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
 

+ 89 - 89
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
 

+ 2 - 2
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)`):

+ 1 - 3
examples/tutorial/basic-4/programs/basic-4/src/lib.rs

@@ -9,7 +9,7 @@ pub mod basic_4 {
 
     pub fn initialize(ctx: Context<Initialize>) -> 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,
 }

+ 1 - 2
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);

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<T> {
+impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Box<T> {
     fn try_accounts(
         program_id: &Pubkey,
         accounts: &mut &[AccountInfo<'info>],
         ix_data: &[u8],
-        bumps: &mut BTreeMap<String, u8>,
+        bumps: &mut B,
         reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         T::try_accounts(program_id, accounts, ix_data, bumps, reallocs).map(Box::new)

+ 3 - 3
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<AccountInfo<'info>> 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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<T> {
+impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Option<T> {
     fn try_accounts(
         program_id: &Pubkey,
         accounts: &mut &[AccountInfo<'info>],
         ix_data: &[u8],
-        bumps: &mut BTreeMap<String, u8>,
+        bumps: &mut B,
         reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 3 - 3
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<String, u8>,
+        _bumps: &mut B,
         _reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         if accounts.is_empty() {

+ 13 - 7
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<String, u8>,
+    /// 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<String, u8>,
+        bumps: T::Bumps,
     ) -> Self {
         Self {
             program_id,

+ 32 - 4
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<T> = std::result::Result<T, error::Error>;
 /// 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<String, u8>,
+        bumps: &mut B,
         reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self>;
 }
 
+/// 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> {

+ 5 - 5
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<T> {
     fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
@@ -20,12 +20,12 @@ impl<T: ToAccountMetas> ToAccountMetas for Vec<T> {
     }
 }
 
-impl<'info, T: Accounts<'info>> Accounts<'info> for Vec<T> {
+impl<'info, B, T: Accounts<'info, B>> Accounts<'info, B> for Vec<T> {
     fn try_accounts(
         program_id: &Pubkey,
         accounts: &mut &[AccountInfo<'info>],
         ix_data: &[u8],
-        bumps: &mut BTreeMap<String, u8>,
+        bumps: &mut B,
         reallocs: &mut BTreeSet<Pubkey>,
     ) -> Result<Self> {
         let mut vec: Vec<T> = 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::<Test>::try_accounts(&program_id, &mut accounts, &[], &mut bumps, &mut reallocs)

+ 89 - 0
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<T: Display>(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<proc_macro2::TokenStream>,
+        Vec<proc_macro2::TokenStream>,
+    ) = 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;
+        }
+    }
+}

+ 2 - 2
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! {

+ 3 - 0
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

+ 5 - 4
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<String, u8>,
+                __bumps: &mut #bumps_struct_name,
                 __reallocs: &mut std::collections::BTreeSet<anchor_lang::solana_program::pubkey::Pubkey>,
             ) -> anchor_lang::Result<Self> {
                 // Deserialize instruction, if declared.

+ 8 - 8
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 = <IdlCreateAccounts as anchor_lang::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 = <IdlResizeAccount as anchor_lang::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 = <IdlCloseAccount as anchor_lang::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 = <IdlCreateBuffer as anchor_lang::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 = <IdlAccounts as anchor_lang::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 = <IdlAccounts as anchor_lang::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 = <IdlSetBuffer as anchor_lang::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();
 

+ 14 - 13
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<'info, Mint>>,
     #[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,

+ 141 - 141
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
       }
     }
   }

+ 1 - 1
tests/chat/programs/chat/src/lib.rs

@@ -11,7 +11,7 @@ pub mod chat {
     pub fn create_user(ctx: Context<CreateUser>, 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<CreateChatRoom>, name: String) -> Result<()> {

+ 1 - 1
tests/idl/programs/relations-derivation/src/lib.rs

@@ -8,7 +8,7 @@ pub mod relations_derivation {
 
     pub fn init_base(ctx: Context<InitBase>) -> 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(())
     }
 

+ 4 - 4
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();
 

+ 1 - 1
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<TestPdaInitZeroCopy>) -> 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(())
     }
 

+ 1 - 1
tests/misc/programs/misc/src/lib.rs

@@ -106,7 +106,7 @@ pub mod misc {
     pub fn test_pda_init_zero_copy(ctx: Context<TestPdaInitZeroCopy>) -> 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(())
     }
 

+ 1 - 1
tests/realloc/programs/realloc/src/lib.rs

@@ -8,7 +8,7 @@ pub mod realloc {
 
     pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
         ctx.accounts.sample.data = vec![0];
-        ctx.accounts.sample.bump = *ctx.bumps.get("sample").unwrap();
+        ctx.accounts.sample.bump = ctx.bumps.sample;
         Ok(())
     }
 

+ 3 - 4
tests/relations-derivation/programs/relations-derivation/src/lib.rs

@@ -11,7 +11,7 @@ pub mod relations_derivation {
 
     pub fn init_base(ctx: Context<InitBase>) -> 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<TestRelation>) -> 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,
 }

+ 14 - 13
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<Initialize>,
-        initializer_amount: u64,
-    ) -> Result<()> {
+    pub fn initialize(ctx: Context<Initialize>, 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,