Skip to content

Commit 5d8b609

Browse files
committed
refactor: transfer2 add hotpath spl -> ctoken transfer
1 parent df7e5f1 commit 5d8b609

File tree

16 files changed

+205
-153
lines changed

16 files changed

+205
-153
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

program-libs/ctoken-types/src/state/solana_ctoken.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,17 @@ impl CompressedToken {
4545
/// CompressedToken layout: mint (32 bytes) + owner (32 bytes) + amount (8 bytes)
4646
pub fn amount_from_slice(data: &[u8]) -> Result<u64, ZeroCopyError> {
4747
const AMOUNT_OFFSET: usize = 64; // 32 (mint) + 32 (owner)
48-
48+
4949
if data.len() < AMOUNT_OFFSET + 8 {
5050
return Err(ZeroCopyError::Size);
5151
}
52-
52+
5353
let amount_bytes = &data[AMOUNT_OFFSET..AMOUNT_OFFSET + 8];
54-
let amount = u64::from_le_bytes(
55-
amount_bytes
56-
.try_into()
57-
.map_err(|_| ZeroCopyError::Size)?
58-
);
59-
54+
let amount = u64::from_le_bytes(amount_bytes.try_into().map_err(|_| ZeroCopyError::Size)?);
55+
6056
Ok(amount)
6157
}
62-
58+
6359
/// Extract amount from an AccountInfo
6460
#[cfg(feature = "solana")]
6561
pub fn amount_from_account_info(
@@ -200,6 +196,8 @@ impl<'a> ZeroCopyAt<'a> for CompressedTokenMeta {
200196
impl<'a> ZeroCopyAtMut<'a> for CompressedTokenMeta {
201197
type ZeroCopyAtMut = ZCompressedTokenMetaMut<'a>;
202198

199+
#[profile]
200+
#[inline(always)]
203201
fn zero_copy_at_mut(
204202
bytes: &'a mut [u8],
205203
) -> Result<(Self::ZeroCopyAtMut, &'a mut [u8]), ZeroCopyError> {
@@ -481,6 +479,8 @@ impl<'a> ZeroCopyAt<'a> for CompressedToken {
481479
impl<'a> ZeroCopyAtMut<'a> for CompressedToken {
482480
type ZeroCopyAtMut = ZCompressedTokenMut<'a>;
483481

482+
#[profile]
483+
#[inline(always)]
484484
fn zero_copy_at_mut(
485485
bytes: &'a mut [u8],
486486
) -> Result<(Self::ZeroCopyAtMut, &'a mut [u8]), ZeroCopyError> {

programs/compressed-token/anchor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ spl-token-2022 = { workspace = true }
3737
light-zero-copy = { workspace = true }
3838
zerocopy = { workspace = true }
3939
light-ctoken-types = { workspace = true, features = ["anchor"] }
40+
pinocchio-pubkey = { workspace = true }
4041

4142
[target.'cfg(not(target_os = "solana"))'.dependencies]
4243
solana-sdk = { workspace = true }

programs/compressed-token/anchor/src/spl_compression.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub fn check_spl_token_pool_derivation_with_index(
3232
}
3333
}
3434

35+
#[inline(always)]
3536
pub fn is_valid_token_pool_pda(
3637
mint_bytes: &[u8],
3738
token_pool_pubkey: &Pubkey,
@@ -40,9 +41,8 @@ pub fn is_valid_token_pool_pda(
4041
) -> Result<bool> {
4142
let pool_index = if pool_index[0] == 0 { &[] } else { pool_index };
4243
let pda = if let Some(bump) = bump {
43-
let seeds = [POOL_SEED, mint_bytes, pool_index, &[bump]];
44-
Pubkey::create_program_address(&seeds[..], &crate::ID)
45-
.map_err(|_| crate::ErrorCode::NoMatchingBumpFound)?
44+
let seeds = [POOL_SEED, mint_bytes, pool_index];
45+
pinocchio_pubkey::derive_address(&seeds, Some(bump), &crate::ID.to_bytes()).into()
4646
} else {
4747
let seeds = [POOL_SEED, mint_bytes, pool_index];
4848
Pubkey::find_program_address(&seeds[..], &crate::ID).0

programs/compressed-token/program/src/close_token_account/processor.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ use anchor_compressed_token::ErrorCode;
22
use anchor_lang::prelude::ProgramError;
33
use light_account_checks::AccountInfoTrait;
44
use light_ctoken_types::state::{CompressedToken, ZCompressedTokenMut, ZExtensionStructMut};
5+
use light_profiler::profile;
56
use light_zero_copy::traits::ZeroCopyAtMut;
67
use pinocchio::account_info::AccountInfo;
78
use spl_token_2022::state::AccountState;
89

910
use super::accounts::CloseTokenAccountAccounts;
1011

1112
/// Process the close token account instruction
13+
#[profile]
1214
pub fn process_close_token_account(
1315
account_infos: &[AccountInfo],
1416
_instruction_data: &[u8],
@@ -27,6 +29,7 @@ pub fn process_close_token_account(
2729
Ok(())
2830
}
2931

32+
#[profile]
3033
pub fn validate_token_account(
3134
accounts: &CloseTokenAccountAccounts,
3235
compressed_token: &ZCompressedTokenMut<'_>,

programs/compressed-token/program/src/mint_action/actions/mint_to_decompressed.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub fn process_mint_to_decompressed_action(
5555
None, // No authority needed for decompression
5656
None,
5757
amount,
58-
mint.into(),
58+
&mint.into(),
5959
token_account_info,
6060
None,
6161
&ZCompressionMode::Decompress,

programs/compressed-token/program/src/shared/owner_validation.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use anchor_lang::solana_program::program_error::ProgramError;
22
use light_account_checks::checks::check_signer;
33
use light_ctoken_types::state::ZCompressedTokenMut;
4+
use light_profiler::profile;
45
use pinocchio::account_info::AccountInfo;
56

67
/// Verify owner or delegate signer authorization for token operations
78
/// Returns the delegate account info if delegate is used, None otherwise
9+
#[profile]
810
pub fn verify_owner_or_delegate_signer<'a>(
911
owner_account: &'a AccountInfo,
1012
delegate_account: Option<&'a AccountInfo>,
@@ -48,6 +50,7 @@ pub fn verify_owner_or_delegate_signer<'a>(
4850
}
4951

5052
/// Verify and update token account authority using zero-copy compressed token format
53+
#[profile]
5154
pub fn verify_and_update_token_account_authority_with_compressed_token(
5255
compressed_token: &mut ZCompressedTokenMut,
5356
authority_account: &AccountInfo,

programs/compressed-token/program/src/transfer2/accounts.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use anchor_compressed_token::ErrorCode;
22
use anchor_lang::solana_program::program_error::ProgramError;
33
use light_account_checks::packed_accounts::ProgramPackedAccounts;
4+
use light_profiler::profile;
45
use light_sdk_types::ACCOUNT_COMPRESSION_PROGRAM_ID;
56
use pinocchio::{account_info::AccountInfo, pubkey::Pubkey};
67
use spl_pod::solana_msg::msg;
@@ -25,6 +26,8 @@ pub struct Transfer2Accounts<'info> {
2526

2627
impl<'info> Transfer2Accounts<'info> {
2728
/// Validate and parse accounts from the instruction accounts slice
29+
#[profile]
30+
#[inline(always)]
2831
pub fn validate_and_parse(
2932
accounts: &'info [AccountInfo],
3033
config: &Transfer2Config,
@@ -67,6 +70,7 @@ impl<'info> Transfer2Accounts<'info> {
6770

6871
/// Calculate static accounts count after skipping index 0 (system accounts only)
6972
/// Returns the count of fixed accounts based on optional features
73+
#[profile]
7074
#[inline(always)]
7175
pub fn static_accounts_count(&self) -> Result<usize, ProgramError> {
7276
let system = self
@@ -86,6 +90,7 @@ impl<'info> Transfer2Accounts<'info> {
8690
/// Extract CPI accounts slice for light-system-program invocation
8791
/// Includes static accounts + tree accounts based on highest tree index
8892
/// Returns (cpi_accounts_slice, tree_accounts)
93+
#[profile]
8994
#[inline(always)]
9095
pub fn cpi_accounts(
9196
&self,
@@ -116,6 +121,8 @@ impl<'info> Transfer2Accounts<'info> {
116121

117122
// TODO: unit test.
118123
/// Extract tree accounts by finding the highest tree index and using it as closing offset
124+
#[profile]
125+
#[inline(always)]
119126
pub fn extract_tree_accounts<'info>(
120127
packed_accounts: &'info ProgramPackedAccounts<'info, AccountInfo>,
121128
) -> Vec<&'info Pubkey> {

programs/compressed-token/program/src/transfer2/cpi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use arrayvec::ArrayVec;
22
use light_compressed_account::instruction_data::with_readonly::InstructionDataInvokeCpiWithReadOnlyConfig;
33
use light_ctoken_types::instructions::transfer2::ZCompressedTokenInstructionDataTransfer2;
4+
use light_profiler::profile;
45

56
use crate::shared::cpi_bytes_size::{
67
allocate_invoke_with_read_only_cpi_bytes, cpi_bytes_config, CpiConfigInput,
78
};
89

910
/// Build CPI configuration from instruction data
11+
#[profile]
12+
#[inline(always)]
1013
pub fn allocate_cpi_bytes(
1114
inputs: &ZCompressedTokenInstructionDataTransfer2,
1215
) -> (Vec<u8>, InstructionDataInvokeCpiWithReadOnlyConfig) {

programs/compressed-token/program/src/transfer2/native_compression/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use light_compressed_account::pubkey::AsPubkey;
44
use light_ctoken_types::instructions::transfer2::{
55
ZCompressedTokenInstructionDataTransfer2, ZCompression, ZCompressionMode,
66
};
7+
use light_profiler::profile;
78
use pinocchio::account_info::AccountInfo;
89
use spl_pod::solana_msg::msg;
910

@@ -19,6 +20,7 @@ const SPL_TOKEN_2022_ID: &[u8; 32] = &spl_token_2022::ID.to_bytes();
1920
const ID: &[u8; 32] = &LIGHT_CPI_SIGNER.program_id;
2021

2122
/// Process native compressions/decompressions with token accounts
23+
#[profile]
2224
pub fn process_token_compression(
2325
inputs: &ZCompressedTokenInstructionDataTransfer2,
2426
packed_accounts: &ProgramPackedAccounts<'_, AccountInfo>,
@@ -75,6 +77,8 @@ pub fn process_token_compression(
7577
}
7678

7779
/// Validate compression fields based on compression mode
80+
#[profile]
81+
#[inline(always)]
7882
pub(crate) fn validate_compression_mode_fields(
7983
compression: &ZCompression,
8084
) -> Result<(), ProgramError> {

0 commit comments

Comments
 (0)