From 82a93dc3765f704da93d13afba7e8ccebe5be2c7 Mon Sep 17 00:00:00 2001 From: amilz <85324096+amilz@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:02:52 -0700 Subject: [PATCH 1/2] update impl for writealloc size limits I'm not certain, but my hunch is that we need to add some margin to data_len to account for the AccountMeta we're passing into the instruction. We have 3 of them at 34 bytes ea (Pubkey + 2 bool) = 102 bytes above our limit. edit pretty sure this is the case. check out: https://github.com/solana-labs/solana/blob/15d18a03e5203aec6452605cf6381afca46983fa/programs/bpf_loader/src/syscalls.rs#L2750-L2763 (34 * ix.accounts.len() + ix.data.len() <= 1280) --- clients/rust/asset/src/impls.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clients/rust/asset/src/impls.rs b/clients/rust/asset/src/impls.rs index 07e5659..e4717f2 100644 --- a/clients/rust/asset/src/impls.rs +++ b/clients/rust/asset/src/impls.rs @@ -159,6 +159,8 @@ macro_rules! allocate_update_data_length { macro_rules! allocate_and_write { ( $program:expr, $asset:expr, $payer:expr, $system_program:expr, $extension_type:expr, $data:expr, $signers_seeds:expr ) => {{ const CPI_LIMIT: usize = 1280; + const ACCOUNT_META_SIZE: usize = 34; // 32 bytes for pubkey + 1 byte for is_signer + 1 byte for is_writable + let total_data_len = $data.len(); // (1) discriminator // (1) extension type @@ -167,13 +169,16 @@ macro_rules! allocate_and_write { // (4) data length // total = 11 const ALLOCATE_HEADER: usize = 11; - let data_len = std::cmp::min(total_data_len, CPI_LIMIT - ALLOCATE_HEADER); let accounts = vec![ solana_program::instruction::AccountMeta::new(*$asset.key, true), solana_program::instruction::AccountMeta::new(*$payer.key, true), solana_program::instruction::AccountMeta::new_readonly(*$system_program.key, false), ]; + let account_metas_size = accounts.len() * ACCOUNT_META_SIZE; + + let data_len = std::cmp::min(total_data_len, CPI_LIMIT - ALLOCATE_HEADER - account_metas_size); + let account_infos = vec![ $program.clone(), @@ -207,7 +212,7 @@ macro_rules! allocate_and_write { // (1) overwrite // total = 2 const WRITE_HEADER: usize = 2; - let data_len = std::cmp::min(total_data_len - offset, CPI_LIMIT - WRITE_HEADER); + let data_len = std::cmp::min(total_data_len - offset, CPI_LIMIT - WRITE_HEADER - account_metas_size); instruction.data.push(12); // write discriminator instruction.data.push(0); // overwrite (false) From 7a62531a6102d2d02ee7ee27d843abd0724a4c6b Mon Sep 17 00:00:00 2001 From: amilz <85324096+amilz@users.noreply.github.com> Date: Fri, 29 Mar 2024 09:49:26 -0700 Subject: [PATCH 2/2] chore: hardcode const --- clients/rust/asset/src/impls.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/clients/rust/asset/src/impls.rs b/clients/rust/asset/src/impls.rs index e4717f2..fbf953c 100644 --- a/clients/rust/asset/src/impls.rs +++ b/clients/rust/asset/src/impls.rs @@ -159,8 +159,7 @@ macro_rules! allocate_update_data_length { macro_rules! allocate_and_write { ( $program:expr, $asset:expr, $payer:expr, $system_program:expr, $extension_type:expr, $data:expr, $signers_seeds:expr ) => {{ const CPI_LIMIT: usize = 1280; - const ACCOUNT_META_SIZE: usize = 34; // 32 bytes for pubkey + 1 byte for is_signer + 1 byte for is_writable - + const ACCOUNT_METAS_SIZE: usize = 102; // 3 X (32 bytes for pubkey + 1 byte for is_signer + 1 byte for is_writable) let total_data_len = $data.len(); // (1) discriminator // (1) extension type @@ -169,16 +168,13 @@ macro_rules! allocate_and_write { // (4) data length // total = 11 const ALLOCATE_HEADER: usize = 11; + let data_len = std::cmp::min(total_data_len, CPI_LIMIT - ALLOCATE_HEADER - ACCOUNT_METAS_SIZE); let accounts = vec![ solana_program::instruction::AccountMeta::new(*$asset.key, true), solana_program::instruction::AccountMeta::new(*$payer.key, true), solana_program::instruction::AccountMeta::new_readonly(*$system_program.key, false), ]; - let account_metas_size = accounts.len() * ACCOUNT_META_SIZE; - - let data_len = std::cmp::min(total_data_len, CPI_LIMIT - ALLOCATE_HEADER - account_metas_size); - let account_infos = vec![ $program.clone(), @@ -212,7 +208,7 @@ macro_rules! allocate_and_write { // (1) overwrite // total = 2 const WRITE_HEADER: usize = 2; - let data_len = std::cmp::min(total_data_len - offset, CPI_LIMIT - WRITE_HEADER - account_metas_size); + let data_len = std::cmp::min(total_data_len - offset, CPI_LIMIT - WRITE_HEADER - ACCOUNT_METAS_SIZE); instruction.data.push(12); // write discriminator instruction.data.push(0); // overwrite (false)