lang: Update `dispatch` function to support dynamic discriminators (#3104)

This commit is contained in:
acheron 2024-07-23 14:09:44 +02:00 committed by GitHub
parent 4e4c04c6e0
commit ccac42dfcf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 226 additions and 235 deletions

View File

@ -21,6 +21,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- lang: Get discriminator length dynamically ([#3101](https://github.com/coral-xyz/anchor/pull/3101)).
- lang: Add non-8-byte discriminator support in `declare_program!` ([#3103](https://github.com/coral-xyz/anchor/pull/3103)).
- client: Make `ThreadSafeSigner` trait public ([#3107](https://github.com/coral-xyz/anchor/pull/3107)).
- lang: Update `dispatch` function to support dynamic discriminators ([#3104](https://github.com/coral-xyz/anchor/pull/3104)).
### Fixes

View File

@ -16,9 +16,9 @@ The programs and their tests are located in [/tests/bench](https://github.com/co
Solana version: 1.18.17
| Program | Binary Size | - |
| ------- | ----------- | --- |
| bench | 791,008 | - |
| Program | Binary Size | - |
| ------- | ----------- | ------------------- |
| bench | 790,256 | 🟢 **-752 (0.10%)** |
### Notable changes

View File

@ -16,98 +16,100 @@ The programs and their tests are located in [/tests/bench](https://github.com/co
Solana version: 1.18.17
| Instruction | Compute Units | - |
| --------------------------- | ------------- | --- |
| accountInfo1 | 601 | - |
| accountInfo2 | 923 | - |
| accountInfo4 | 1,583 | - |
| accountInfo8 | 2,975 | - |
| accountEmptyInit1 | 5,034 | - |
| accountEmpty1 | 652 | - |
| accountEmptyInit2 | 9,687 | - |
| accountEmpty2 | 1,016 | - |
| accountEmptyInit4 | 18,501 | - |
| accountEmpty4 | 1,737 | - |
| accountEmptyInit8 | 36,169 | - |
| accountEmpty8 | 3,186 | - |
| accountSizedInit1 | 5,106 | - |
| accountSized1 | 668 | - |
| accountSizedInit2 | 9,828 | - |
| accountSized2 | 1,046 | - |
| accountSizedInit4 | 18,837 | - |
| accountSized4 | 1,807 | - |
| accountSizedInit8 | 36,761 | - |
| accountSized8 | 3,326 | - |
| accountUnsizedInit1 | 5,199 | - |
| accountUnsized1 | 702 | - |
| accountUnsizedInit2 | 10,078 | - |
| accountUnsized2 | 1,116 | - |
| accountUnsizedInit4 | 19,259 | - |
| accountUnsized4 | 1,953 | - |
| accountUnsizedInit8 | 37,331 | - |
| accountUnsized8 | 3,626 | - |
| boxedAccountEmptyInit1 | 5,064 | - |
| boxedAccountEmpty1 | 671 | - |
| boxedAccountEmptyInit2 | 9,721 | - |
| boxedAccountEmpty2 | 1,052 | - |
| boxedAccountEmptyInit4 | 18,582 | - |
| boxedAccountEmpty4 | 1,811 | - |
| boxedAccountEmptyInit8 | 36,329 | - |
| boxedAccountEmpty8 | 3,357 | - |
| boxedAccountSizedInit1 | 5,119 | - |
| boxedAccountSized1 | 686 | - |
| boxedAccountSizedInit2 | 9,845 | - |
| boxedAccountSized2 | 1,085 | - |
| boxedAccountSizedInit4 | 18,825 | - |
| boxedAccountSized4 | 1,874 | - |
| boxedAccountSizedInit8 | 36,824 | - |
| boxedAccountSized8 | 3,490 | - |
| boxedAccountUnsizedInit1 | 5,207 | - |
| boxedAccountUnsized1 | 721 | - |
| boxedAccountUnsizedInit2 | 10,015 | - |
| boxedAccountUnsized2 | 1,157 | - |
| boxedAccountUnsizedInit4 | 19,160 | - |
| boxedAccountUnsized4 | 2,019 | - |
| boxedAccountUnsizedInit8 | 37,496 | - |
| boxedAccountUnsized8 | 3,776 | - |
| boxedInterfaceAccountMint1 | 1,372 | - |
| boxedInterfaceAccountMint2 | 2,293 | - |
| boxedInterfaceAccountMint4 | 4,121 | - |
| boxedInterfaceAccountMint8 | 7,811 | - |
| boxedInterfaceAccountToken1 | 2,056 | - |
| boxedInterfaceAccountToken2 | 3,660 | - |
| boxedInterfaceAccountToken4 | 6,858 | - |
| boxedInterfaceAccountToken8 | 13,284 | - |
| interfaceAccountMint1 | 1,472 | - |
| interfaceAccountMint2 | 2,631 | - |
| interfaceAccountMint4 | 4,951 | - |
| interfaceAccountMint8 | 9,588 | - |
| interfaceAccountToken1 | 2,130 | - |
| interfaceAccountToken2 | 3,928 | - |
| interfaceAccountToken4 | 7,521 | - |
| interface1 | 600 | - |
| interface2 | 745 | - |
| interface4 | 1,033 | - |
| interface8 | 1,616 | - |
| program1 | 596 | - |
| program2 | 737 | - |
| program4 | 1,019 | - |
| program8 | 1,584 | - |
| signer1 | 580 | - |
| signer2 | 872 | - |
| signer4 | 1,454 | - |
| signer8 | 2,618 | - |
| systemAccount1 | 592 | - |
| systemAccount2 | 894 | - |
| systemAccount4 | 1,497 | - |
| systemAccount8 | 2,707 | - |
| uncheckedAccount1 | 563 | - |
| uncheckedAccount2 | 836 | - |
| uncheckedAccount4 | 1,378 | - |
| uncheckedAccount8 | 2,468 | - |
| Instruction | Compute Units | - |
| --------------------------- | ------------- | -------------------- |
| accountInfo1 | 574 | 🟢 **-27 (4.49%)** |
| accountInfo2 | 900 | 🟢 **-23 (2.49%)** |
| accountInfo4 | 1,562 | 🟢 **-21 (1.33%)** |
| accountInfo8 | 2,958 | 🟢 **-17 (0.57%)** |
| accountEmptyInit1 | 5,019 | 🟢 **-15 (0.30%)** |
| accountEmpty1 | 650 | 🟢 **-2 (0.31%)** |
| accountEmptyInit2 | 9,675 | 🟢 **-12 (0.12%)** |
| accountEmpty2 | 1,016 | - |
| accountEmptyInit4 | 18,492 | 🟢 **-9 (0.05%)** |
| accountEmpty4 | 1,741 | 🔴 **+4 (0.23%)** |
| accountEmptyInit8 | 36,164 | 🟢 **-5 (0.01%)** |
| accountEmpty8 | 3,194 | 🔴 **+8 (0.25%)** |
| accountSizedInit1 | 5,115 | 🔴 **+9 (0.18%)** |
| accountSized1 | 691 | 🔴 **+23 (3.44%)** |
| accountSizedInit2 | 9,839 | 🔴 **+11 (0.11%)** |
| accountSized2 | 1,070 | 🔴 **+24 (2.29%)** |
| accountSizedInit4 | 18,854 | 🔴 **+17 (0.09%)** |
| accountSized4 | 1,835 | 🔴 **+28 (1.55%)** |
| accountSizedInit8 | 36,779 | 🔴 **+18 (0.05%)** |
| accountSized8 | 3,358 | 🔴 **+32 (0.96%)** |
| accountUnsizedInit1 | 5,232 | 🔴 **+33 (0.63%)** |
| accountUnsized1 | 748 | 🔴 **+46 (6.55%)** |
| accountUnsizedInit2 | 10,116 | 🔴 **+38 (0.38%)** |
| accountUnsized2 | 1,166 | 🔴 **+50 (4.48%)** |
| accountUnsizedInit4 | 19,299 | 🔴 **+40 (0.21%)** |
| accountUnsized4 | 2,005 | 🔴 **+52 (2.66%)** |
| accountUnsizedInit8 | 37,375 | 🔴 **+44 (0.12%)** |
| accountUnsized8 | 3,680 | 🔴 **+54 (1.49%)** |
| boxedAccountEmptyInit1 | 5,121 | 🔴 **+57 (1.13%)** |
| boxedAccountEmpty1 | 741 | 🔴 **+70 (10.43%)** |
| boxedAccountEmptyInit2 | 9,782 | 🔴 **+61 (0.63%)** |
| boxedAccountEmpty2 | 1,126 | 🔴 **+74 (7.03%)** |
| boxedAccountEmptyInit4 | 18,646 | 🔴 **+64 (0.34%)** |
| boxedAccountEmpty4 | 1,887 | 🔴 **+76 (4.20%)** |
| boxedAccountEmptyInit8 | 36,396 | 🔴 **+67 (0.18%)** |
| boxedAccountEmpty8 | 3,436 | 🔴 **+79 (2.35%)** |
| boxedAccountSizedInit1 | 5,202 | 🔴 **+83 (1.62%)** |
| boxedAccountSized1 | 781 | 🔴 **+95 (13.85%)** |
| boxedAccountSizedInit2 | 9,931 | 🔴 **+86 (0.87%)** |
| boxedAccountSized2 | 1,181 | 🔴 **+96 (8.85%)** |
| boxedAccountSizedInit4 | 18,913 | 🔴 **+88 (0.47%)** |
| boxedAccountSized4 | 1,975 | 🔴 **+101 (5.39%)** |
| boxedAccountSizedInit8 | 36,916 | 🔴 **+92 (0.25%)** |
| boxedAccountSized8 | 3,594 | 🔴 **+104 (2.98%)** |
| boxedAccountUnsizedInit1 | 5,313 | 🔴 **+106 (2.04%)** |
| boxedAccountUnsized1 | 840 | 🔴 **+119 (16.50%)** |
| boxedAccountUnsizedInit2 | 10,123 | 🔴 **+108 (1.08%)** |
| boxedAccountUnsized2 | 1,278 | 🔴 **+121 (10.46%)** |
| boxedAccountUnsizedInit4 | 19,273 | 🔴 **+113 (0.59%)** |
| boxedAccountUnsized4 | 2,143 | 🔴 **+124 (6.14%)** |
| boxedAccountUnsizedInit8 | 37,612 | 🔴 **+116 (0.31%)** |
| boxedAccountUnsized8 | 3,904 | 🔴 **+128 (3.39%)** |
| boxedInterfaceAccountMint1 | 1,503 | 🔴 **+131 (9.55%)** |
| boxedInterfaceAccountMint2 | 2,424 | 🔴 **+131 (5.71%)** |
| boxedInterfaceAccountMint4 | 4,257 | 🔴 **+136 (3.30%)** |
| boxedInterfaceAccountMint8 | 7,951 | 🔴 **+140 (1.79%)** |
| boxedInterfaceAccountToken1 | 2,199 | 🔴 **+143 (6.96%)** |
| boxedInterfaceAccountToken2 | 3,804 | 🔴 **+144 (3.93%)** |
| boxedInterfaceAccountToken4 | 7,005 | 🔴 **+147 (2.14%)** |
| boxedInterfaceAccountToken8 | 13,435 | 🔴 **+151 (1.14%)** |
| interfaceAccountMint1 | 1,627 | 🔴 **+155 (10.53%)** |
| interfaceAccountMint2 | 2,789 | 🔴 **+158 (6.01%)** |
| interfaceAccountMint4 | 5,111 | 🔴 **+160 (3.23%)** |
| interfaceAccountMint8 | 9,750 | 🔴 **+162 (1.69%)** |
| interfaceAccountToken1 | 2,297 | 🔴 **+167 (7.84%)** |
| interfaceAccountToken2 | 4,097 | 🔴 **+169 (4.30%)** |
| interfaceAccountToken4 | 7,693 | 🔴 **+172 (2.29%)** |
| interface1 | 775 | 🔴 **+175 (29.17%)** |
| interface2 | 924 | 🔴 **+179 (24.03%)** |
| interface4 | 1,215 | 🔴 **+182 (17.62%)** |
| interface8 | 1,800 | 🔴 **+184 (11.39%)** |
| program1 | 783 | 🔴 **+187 (31.38%)** |
| program2 | 928 | 🔴 **+191 (25.92%)** |
| program4 | 1,211 | 🔴 **+192 (18.84%)** |
| program8 | 1,780 | 🔴 **+196 (12.37%)** |
| signer1 | 780 | 🔴 **+200 (34.48%)** |
| signer2 | 1,075 | 🔴 **+203 (23.28%)** |
| signer4 | 1,658 | 🔴 **+204 (14.03%)** |
| signer8 | 2,827 | 🔴 **+209 (7.98%)** |
| systemAccount1 | 803 | 🔴 **+211 (35.64%)** |
| systemAccount2 | 1,109 | 🔴 **+215 (24.05%)** |
| systemAccount4 | 1,714 | 🔴 **+217 (14.50%)** |
| systemAccount8 | 2,927 | 🔴 **+220 (8.13%)** |
| uncheckedAccount1 | 786 | 🔴 **+223 (39.61%)** |
| uncheckedAccount2 | 1,062 | 🔴 **+226 (27.03%)** |
| uncheckedAccount4 | 1,605 | 🔴 **+227 (16.47%)** |
| uncheckedAccount8 | 2,700 | 🔴 **+232 (9.40%)** |
### Notable changes
- lang: Update `dispatch` function to support dynamic discriminators ([#3104](https://github.com/coral-xyz/anchor/pull/3104)).
---
## [0.30.1]

View File

@ -4,28 +4,25 @@ use quote::quote;
pub fn generate(program: &Program) -> proc_macro2::TokenStream {
// Dispatch all global instructions.
let global_dispatch_arms: Vec<proc_macro2::TokenStream> = program
.ixs
.iter()
.map(|ix| {
let ix_method_name = &ix.raw_method.sig.ident;
let ix_name_camel: proc_macro2::TokenStream = ix_method_name
.to_string()
.to_camel_case()
.parse()
.expect("Failed to parse ix method name in camel as `TokenStream`");
let global_ixs = program.ixs.iter().map(|ix| {
let ix_method_name = &ix.raw_method.sig.ident;
let ix_name_camel: proc_macro2::TokenStream = ix_method_name
.to_string()
.to_camel_case()
.parse()
.expect("Failed to parse ix method name in camel as `TokenStream`");
let discriminator = quote! { instruction::#ix_name_camel::DISCRIMINATOR };
quote! {
instruction::#ix_name_camel::DISCRIMINATOR => {
__private::__global::#ix_method_name(
program_id,
accounts,
ix_data,
)
}
quote! {
if data.starts_with(#discriminator) {
return __private::__global::#ix_method_name(
program_id,
accounts,
&data[#discriminator.len()..],
)
}
})
.collect();
}
});
let fallback_fn = gen_fallback(program).unwrap_or(quote! {
Err(anchor_lang::error::ErrorCode::InstructionFallbackNotFound.into())
@ -54,42 +51,29 @@ pub fn generate(program: &Program) -> proc_macro2::TokenStream {
accounts: &'info [AccountInfo<'info>],
data: &[u8],
) -> anchor_lang::Result<()> {
// Split the instruction data into the first 8 byte method
// identifier (sighash) and the serialized instruction data.
let mut ix_data: &[u8] = data;
let sighash: [u8; 8] = {
let mut sighash: [u8; 8] = [0; 8];
sighash.copy_from_slice(&ix_data[..8]);
ix_data = &ix_data[8..];
sighash
};
#(#global_ixs)*
match sighash.as_slice() {
#(#global_dispatch_arms)*
anchor_lang::idl::IDL_IX_TAG_LE => {
// If the method identifier is the IDL tag, then execute an IDL
// instruction, injected into all Anchor programs unless they have
// no-idl enabled
#[cfg(not(feature = "no-idl"))]
{
__private::__idl::__idl_dispatch(
program_id,
accounts,
&ix_data,
)
}
#[cfg(feature = "no-idl")]
{
Err(anchor_lang::error::ErrorCode::IdlInstructionStub.into())
}
}
anchor_lang::event::EVENT_IX_TAG_LE => {
#event_cpi_handler
}
_ => {
#fallback_fn
}
// Dispatch IDL instructions
if data.starts_with(anchor_lang::idl::IDL_IX_TAG_LE) {
// If the method identifier is the IDL tag, then execute an IDL
// instruction, injected into all Anchor programs unless they have
// `no-idl` feature enabled
#[cfg(not(feature = "no-idl"))]
return __private::__idl::__idl_dispatch(
program_id,
accounts,
&data[anchor_lang::idl::IDL_IX_TAG_LE.len()..],
);
#[cfg(feature = "no-idl")]
return Err(anchor_lang::error::ErrorCode::IdlInstructionStub.into());
}
// Dispatch Event CPI instruction
if data.starts_with(anchor_lang::event::EVENT_IX_TAG_LE) {
return #event_cpi_handler;
}
#fallback_fn
}
}
}
@ -110,7 +94,11 @@ pub fn generate_event_cpi_handler() -> proc_macro2::TokenStream {
#[cfg(feature = "event-cpi")]
quote! {
// `event-cpi` feature is enabled, dispatch self-cpi instruction
__private::__events::__event_dispatch(program_id, accounts, &ix_data)
__private::__events::__event_dispatch(
program_id,
accounts,
&data[anchor_lang::event::EVENT_IX_TAG_LE.len()..]
)
}
#[cfg(not(feature = "event-cpi"))]
quote! {

View File

@ -933,96 +933,96 @@
"solanaVersion": "1.18.17",
"result": {
"binarySize": {
"bench": 791008
"bench": 790256
},
"computeUnits": {
"accountInfo1": 601,
"accountInfo2": 923,
"accountInfo4": 1583,
"accountInfo8": 2975,
"accountEmptyInit1": 5034,
"accountEmpty1": 652,
"accountEmptyInit2": 9687,
"accountInfo1": 574,
"accountInfo2": 900,
"accountInfo4": 1562,
"accountInfo8": 2958,
"accountEmptyInit1": 5019,
"accountEmpty1": 650,
"accountEmptyInit2": 9675,
"accountEmpty2": 1016,
"accountEmptyInit4": 18501,
"accountEmpty4": 1737,
"accountEmptyInit8": 36169,
"accountEmpty8": 3186,
"accountSizedInit1": 5106,
"accountSized1": 668,
"accountSizedInit2": 9828,
"accountSized2": 1046,
"accountSizedInit4": 18837,
"accountSized4": 1807,
"accountSizedInit8": 36761,
"accountSized8": 3326,
"accountUnsizedInit1": 5199,
"accountUnsized1": 702,
"accountUnsizedInit2": 10078,
"accountUnsized2": 1116,
"accountUnsizedInit4": 19259,
"accountUnsized4": 1953,
"accountUnsizedInit8": 37331,
"accountUnsized8": 3626,
"boxedAccountEmptyInit1": 5064,
"boxedAccountEmpty1": 671,
"boxedAccountEmptyInit2": 9721,
"boxedAccountEmpty2": 1052,
"boxedAccountEmptyInit4": 18582,
"boxedAccountEmpty4": 1811,
"boxedAccountEmptyInit8": 36329,
"boxedAccountEmpty8": 3357,
"boxedAccountSizedInit1": 5119,
"boxedAccountSized1": 686,
"boxedAccountSizedInit2": 9845,
"boxedAccountSized2": 1085,
"boxedAccountSizedInit4": 18825,
"boxedAccountSized4": 1874,
"boxedAccountSizedInit8": 36824,
"boxedAccountSized8": 3490,
"boxedAccountUnsizedInit1": 5207,
"boxedAccountUnsized1": 721,
"boxedAccountUnsizedInit2": 10015,
"boxedAccountUnsized2": 1157,
"boxedAccountUnsizedInit4": 19160,
"boxedAccountUnsized4": 2019,
"boxedAccountUnsizedInit8": 37496,
"boxedAccountUnsized8": 3776,
"boxedInterfaceAccountMint1": 1372,
"boxedInterfaceAccountMint2": 2293,
"boxedInterfaceAccountMint4": 4121,
"boxedInterfaceAccountMint8": 7811,
"boxedInterfaceAccountToken1": 2056,
"boxedInterfaceAccountToken2": 3660,
"boxedInterfaceAccountToken4": 6858,
"boxedInterfaceAccountToken8": 13284,
"interfaceAccountMint1": 1472,
"interfaceAccountMint2": 2631,
"interfaceAccountMint4": 4951,
"interfaceAccountMint8": 9588,
"interfaceAccountToken1": 2130,
"interfaceAccountToken2": 3928,
"interfaceAccountToken4": 7521,
"interface1": 600,
"interface2": 745,
"interface4": 1033,
"interface8": 1616,
"program1": 596,
"program2": 737,
"program4": 1019,
"program8": 1584,
"signer1": 580,
"signer2": 872,
"signer4": 1454,
"signer8": 2618,
"systemAccount1": 592,
"systemAccount2": 894,
"systemAccount4": 1497,
"systemAccount8": 2707,
"uncheckedAccount1": 563,
"uncheckedAccount2": 836,
"uncheckedAccount4": 1378,
"uncheckedAccount8": 2468
"accountEmptyInit4": 18492,
"accountEmpty4": 1741,
"accountEmptyInit8": 36164,
"accountEmpty8": 3194,
"accountSizedInit1": 5115,
"accountSized1": 691,
"accountSizedInit2": 9839,
"accountSized2": 1070,
"accountSizedInit4": 18854,
"accountSized4": 1835,
"accountSizedInit8": 36779,
"accountSized8": 3358,
"accountUnsizedInit1": 5232,
"accountUnsized1": 748,
"accountUnsizedInit2": 10116,
"accountUnsized2": 1166,
"accountUnsizedInit4": 19299,
"accountUnsized4": 2005,
"accountUnsizedInit8": 37375,
"accountUnsized8": 3680,
"boxedAccountEmptyInit1": 5121,
"boxedAccountEmpty1": 741,
"boxedAccountEmptyInit2": 9782,
"boxedAccountEmpty2": 1126,
"boxedAccountEmptyInit4": 18646,
"boxedAccountEmpty4": 1887,
"boxedAccountEmptyInit8": 36396,
"boxedAccountEmpty8": 3436,
"boxedAccountSizedInit1": 5202,
"boxedAccountSized1": 781,
"boxedAccountSizedInit2": 9931,
"boxedAccountSized2": 1181,
"boxedAccountSizedInit4": 18913,
"boxedAccountSized4": 1975,
"boxedAccountSizedInit8": 36916,
"boxedAccountSized8": 3594,
"boxedAccountUnsizedInit1": 5313,
"boxedAccountUnsized1": 840,
"boxedAccountUnsizedInit2": 10123,
"boxedAccountUnsized2": 1278,
"boxedAccountUnsizedInit4": 19273,
"boxedAccountUnsized4": 2143,
"boxedAccountUnsizedInit8": 37612,
"boxedAccountUnsized8": 3904,
"boxedInterfaceAccountMint1": 1503,
"boxedInterfaceAccountMint2": 2424,
"boxedInterfaceAccountMint4": 4257,
"boxedInterfaceAccountMint8": 7951,
"boxedInterfaceAccountToken1": 2199,
"boxedInterfaceAccountToken2": 3804,
"boxedInterfaceAccountToken4": 7005,
"boxedInterfaceAccountToken8": 13435,
"interfaceAccountMint1": 1627,
"interfaceAccountMint2": 2789,
"interfaceAccountMint4": 5111,
"interfaceAccountMint8": 9750,
"interfaceAccountToken1": 2297,
"interfaceAccountToken2": 4097,
"interfaceAccountToken4": 7693,
"interface1": 775,
"interface2": 924,
"interface4": 1215,
"interface8": 1800,
"program1": 783,
"program2": 928,
"program4": 1211,
"program8": 1780,
"signer1": 780,
"signer2": 1075,
"signer4": 1658,
"signer8": 2827,
"systemAccount1": 803,
"systemAccount2": 1109,
"systemAccount4": 1714,
"systemAccount8": 2927,
"uncheckedAccount1": 786,
"uncheckedAccount2": 1062,
"uncheckedAccount4": 1605,
"uncheckedAccount8": 2700
},
"stackMemory": {
"account_info1": 144,
@ -1115,4 +1115,4 @@
}
}
}
}
}