Deserialize only the discriminant in the entrypoint.
It would seem that Borsh, when deserializing an enum will consume a large amount of stack space proportional to the number of discriminants. This causes the entrypoint to trigger stack frame access violations during the initial deserialization. This change uses an enum represented by a u8 instead, and removes the association between the discriminant and the data. Deserializing the associated data is now pushed down to within the entrypoint match arms instead. Change-Id: I2dcb466bf7820b3344e175ad92988bb89f30cb15
This commit is contained in:
parent
1fc6842917
commit
1cc90e54db
|
@ -67,7 +67,7 @@ pub fn initialize(
|
|||
AccountMeta::new_readonly(sysvar::rent::id(), false),
|
||||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
data: crate::instruction::Instruction::Initialize(InitializeData {
|
||||
data: (crate::instruction::Instruction::Initialize, InitializeData {
|
||||
initial_guardians: initial_guardians.to_vec(),
|
||||
fee,
|
||||
fee_persistent,
|
||||
|
@ -122,7 +122,7 @@ pub fn post_message(
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::PostMessage(PostMessageData {
|
||||
data: (crate::instruction::Instruction::PostMessage, PostMessageData {
|
||||
nonce,
|
||||
payload: payload.clone(),
|
||||
persist,
|
||||
|
@ -163,7 +163,7 @@ pub fn verify_signatures(
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::VerifySignatures(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::VerifySignatures, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ pub fn post_vaa(program_id: Pubkey, payer: Pubkey, vaa: PostVAAData) -> Instruct
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::PostVAA(vaa)
|
||||
data: (crate::instruction::Instruction::PostVAA, vaa)
|
||||
.try_to_vec()
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ pub fn upgrade_contract(
|
|||
AccountMeta::new(spill, false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::UpgradeContract(UpgradeContractData {})
|
||||
data: (crate::instruction::Instruction::UpgradeContract, UpgradeContractData {})
|
||||
.try_to_vec()
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ pub fn upgrade_guardian_set(
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::UpgradeGuardianSet(UpgradeGuardianSetData {})
|
||||
data: (crate::instruction::Instruction::UpgradeGuardianSet, UpgradeGuardianSetData {})
|
||||
.try_to_vec()
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -328,7 +328,7 @@ pub fn set_fees(
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::SetFees(SetFeesData {})
|
||||
data: (crate::instruction::Instruction::SetFees, SetFeesData {})
|
||||
.try_to_vec()
|
||||
.unwrap(),
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ pub fn transfer_fees(
|
|||
AccountMeta::new_readonly(solana_program::system_program::id(), false),
|
||||
],
|
||||
|
||||
data: crate::instruction::Instruction::TransferFees(TransferFeesData {})
|
||||
data: (crate::instruction::Instruction::TransferFees, TransferFeesData {})
|
||||
.try_to_vec()
|
||||
.unwrap(),
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ name = "token_bridge"
|
|||
|
||||
[features]
|
||||
no-entrypoint = ["solitaire/no-entrypoint"]
|
||||
trace = ["solitaire/trace"]
|
||||
client = ["solitaire-client", "solitaire/client", "no-entrypoint"]
|
||||
cpi = ["no-entrypoint"]
|
||||
default = []
|
||||
|
|
|
@ -84,7 +84,7 @@ pub fn attest_token(
|
|||
// Populate fields
|
||||
}
|
||||
|
||||
let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
|
||||
let params = (bridge::instruction::Instruction::PostMessage, PostMessageData {
|
||||
nonce: data.nonce,
|
||||
payload: payload.try_to_vec()?,
|
||||
persist: true,
|
||||
|
|
|
@ -148,7 +148,7 @@ pub fn transfer_native(
|
|||
to_chain: data.target_chain,
|
||||
fee: U256::from(data.fee),
|
||||
};
|
||||
let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
|
||||
let params = (bridge::instruction::Instruction::PostMessage, PostMessageData {
|
||||
nonce: data.nonce,
|
||||
payload: payload.try_to_vec()?,
|
||||
persist: true,
|
||||
|
@ -272,7 +272,7 @@ pub fn transfer_wrapped(
|
|||
to_chain: data.target_chain,
|
||||
fee: U256::from(data.fee),
|
||||
};
|
||||
let params = bridge::instruction::Instruction::PostMessage(PostMessageData {
|
||||
let params = (bridge::instruction::Instruction::PostMessage, PostMessageData {
|
||||
nonce: data.nonce,
|
||||
payload: payload.try_to_vec()?,
|
||||
persist: true,
|
||||
|
|
|
@ -43,7 +43,7 @@ pub fn initialize(
|
|||
AccountMeta::new(solana_program::sysvar::rent::id(), false),
|
||||
AccountMeta::new(solana_program::system_program::id(), false),
|
||||
],
|
||||
data: crate::instruction::Instruction::Initialize(bridge).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::Initialize, bridge).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ pub fn complete_native(
|
|||
// Program
|
||||
AccountMeta::new_readonly(bridge_id, false),
|
||||
],
|
||||
data: crate::instruction::Instruction::CompleteNative(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::CompleteNative, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ pub fn complete_wrapped(
|
|||
// Program
|
||||
AccountMeta::new_readonly(bridge_id, false),
|
||||
],
|
||||
data: crate::instruction::Instruction::CompleteWrapped(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::CompleteWrapped, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ pub fn create_wrapped(
|
|||
// Program
|
||||
AccountMeta::new_readonly(bridge_id, false),
|
||||
],
|
||||
data: crate::instruction::Instruction::CreateWrapped(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::CreateWrapped, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -231,7 +231,7 @@ pub fn register_chain(
|
|||
// Program
|
||||
AccountMeta::new_readonly(bridge_id, false),
|
||||
],
|
||||
data: crate::instruction::Instruction::RegisterChain(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::RegisterChain, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ pub fn transfer_native(
|
|||
AccountMeta::new_readonly(bridge_id, false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: crate::instruction::Instruction::TransferNative(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::TransferNative, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -410,7 +410,7 @@ pub fn transfer_wrapped(
|
|||
AccountMeta::new_readonly(bridge_id, false),
|
||||
AccountMeta::new_readonly(spl_token::id(), false),
|
||||
],
|
||||
data: crate::instruction::Instruction::TransferWrapped(data).try_to_vec()?,
|
||||
data: (crate::instruction::Instruction::TransferWrapped, data).try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,7 @@ pub fn attest(
|
|||
// Program
|
||||
AccountMeta::new_readonly(bridge_id, false),
|
||||
],
|
||||
data: crate::instruction::Instruction::AttestToken(AttestTokenData { nonce })
|
||||
data: (crate::instruction::Instruction::AttestToken, AttestTokenData { nonce })
|
||||
.try_to_vec()?,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(const_generics)]
|
||||
#![feature(const_generics_defaults)]
|
||||
#![allow(warnings)]
|
||||
|
||||
// #![cfg(all(target_arch = "bpf", not(feature = "no-entrypoint")))]
|
||||
|
@ -12,7 +11,7 @@ pub mod api;
|
|||
pub mod messages;
|
||||
pub mod types;
|
||||
|
||||
use api::{
|
||||
pub use api::{
|
||||
attest_token, complete_native, complete_wrapped, create_wrapped, initialize, register_chain,
|
||||
transfer_native, transfer_wrapped, AttestToken, AttestTokenData, CompleteNative,
|
||||
CompleteNativeData, CompleteWrapped, CompleteWrappedData, CreateWrapped, CreateWrappedData,
|
||||
|
|
|
@ -47,23 +47,25 @@ macro_rules! solitaire {
|
|||
/// This Instruction contains a 1-1 mapping for each enum variant to function call. The
|
||||
/// function calls can be found below in the `api` module.
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub enum Instruction {
|
||||
$($row($kind),)*
|
||||
$($row,)*
|
||||
}
|
||||
|
||||
/// This entrypoint is generated from the enum above, it deserializes incoming bytes
|
||||
/// and automatically dispatches to the correct method.
|
||||
pub fn dispatch<'a, 'b: 'a, 'c>(p: &Pubkey, a: &'c [AccountInfo<'b>], d: &[u8]) -> Result<()> {
|
||||
match Instruction::try_from_slice(d).map_err(|e| SolitaireError::InstructionDeserializeFailed(e))? {
|
||||
match d[0] {
|
||||
$(
|
||||
Instruction::$row(ix_data) => {
|
||||
n if n == Instruction::$row as u8 => {
|
||||
trace!("Dispatch: {}", stringify!($row));
|
||||
let (mut accounts): ($row) = FromAccounts::from(p, &mut a.iter(), &())?;
|
||||
let ix_data: $kind = BorshDeserialize::try_from_slice(&d[1..]).map_err(|e| SolitaireError::InstructionDeserializeFailed(e))?;
|
||||
let mut accounts: $row = FromAccounts::from(p, &mut a.iter(), &())?;
|
||||
$fn(&ExecutionContext{program_id: p, accounts: a}, &mut accounts, ix_data)?;
|
||||
Persist::persist(&accounts, p)?;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
)*
|
||||
|
||||
_ => {
|
||||
|
|
Loading…
Reference in New Issue