Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 1 addition & 37 deletions anchor-programs/system/src/cpi_context_account.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use std::slice;

use aligned_sized::aligned_sized;
use anchor_lang::prelude::*;
use light_compressed_account::instruction_data::{
invoke_cpi::InstructionDataInvokeCpi, zero_copy::ZInstructionDataInvokeCpi,
};
use light_zero_copy::{errors::ZeroCopyError, traits::ZeroCopyAt};
use zerocopy::{little_endian::U32, Ref};
use light_compressed_account::instruction_data::invoke_cpi::InstructionDataInvokeCpi;

/// Collects instruction data without executing a compressed transaction.
/// Signer checks are performed on instruction data.
Expand Down Expand Up @@ -40,33 +34,3 @@ impl CpiContextAccount {
self.context = Vec::new();
}
}

pub struct ZCpiContextAccount2<'a> {
pub fee_payer: Ref<&'a mut [u8], light_compressed_account::pubkey::Pubkey>,
pub associated_merkle_tree: Ref<&'a mut [u8], light_compressed_account::pubkey::Pubkey>,
pub context: Vec<ZInstructionDataInvokeCpi<'a>>,
}

pub fn deserialize_cpi_context_account<'info, 'a>(
account_info: &AccountInfo<'info>,
) -> std::result::Result<ZCpiContextAccount2<'a>, ZeroCopyError> {
let mut account_data = account_info.try_borrow_mut_data().unwrap();
let data = unsafe { slice::from_raw_parts_mut(account_data.as_mut_ptr(), account_data.len()) };
let (fee_payer, data) =
Ref::<&'a mut [u8], light_compressed_account::pubkey::Pubkey>::from_prefix(&mut data[8..])?;
let (associated_merkle_tree, data) =
Ref::<&'a mut [u8], light_compressed_account::pubkey::Pubkey>::from_prefix(data)?;
let (len, data) = Ref::<&'a mut [u8], U32>::from_prefix(data)?;
let mut data = &*data;
let mut context = Vec::new();
for _ in 0..(u64::from(*len)) as usize {
let (context_item, new_data) = ZInstructionDataInvokeCpi::zero_copy_at(data)?;
context.push(context_item);
data = new_data;
}
Ok(ZCpiContextAccount2 {
fee_payer,
associated_merkle_tree,
context,
})
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
use light_compressed_account::instruction_data::zero_copy_set::CompressedCpiContextTrait;
use light_zero_copy::{ZeroCopy, ZeroCopyMut};

use crate::{AnchorDeserialize, AnchorSerialize};
use crate::{AnchorDeserialize, AnchorSerialize, CMINT_ADDRESS_TREE};

#[repr(C)]
#[derive(
Debug, Clone, AnchorSerialize, Default, AnchorDeserialize, ZeroCopy, ZeroCopyMut, PartialEq,
)]
#[derive(Debug, Clone, AnchorSerialize, AnchorDeserialize, ZeroCopy, ZeroCopyMut, PartialEq)]
pub struct CpiContext {
pub set_context: bool,
pub first_set_context: bool,
Expand All @@ -20,6 +18,23 @@ pub struct CpiContext {
/// Placeholder to enable cmints in multiple address trees.
/// Currently set to 0.
pub read_only_address_trees: [u8; 4],
pub address_tree_pubkey: [u8; 32],
}

impl Default for CpiContext {
fn default() -> Self {
Self {
set_context: false,
first_set_context: false,
in_tree_index: 0,
in_queue_index: 0,
out_queue_index: 0,
token_out_queue_index: 0,
assigned_account_index: 0,
read_only_address_trees: [0; 4],
address_tree_pubkey: CMINT_ADDRESS_TREE,
}
}
}

impl CompressedCpiContextTrait for ZCpiContext<'_> {
Expand Down
6 changes: 3 additions & 3 deletions program-tests/compressed-token-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
test-sbf = []
custom-heap = []
default = ["custom-heap"]
default = []

[dependencies]
anchor-lang = { workspace = true }
light-sdk = { workspace = true, features = ["anchor"] }

[dev-dependencies]
anchor-lang = { workspace = true }
light-compressed-token = { workspace = true }
light-system-program-anchor = { workspace = true }
account-compression = { workspace = true }
Expand Down
71 changes: 70 additions & 1 deletion program-tests/compressed-token-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,70 @@
// placeholder
#![allow(clippy::too_many_arguments)]
#![allow(unexpected_cfgs)]
#![allow(deprecated)]

use anchor_lang::{prelude::*, solana_program::instruction::Instruction};

declare_id!("CompressedTokenTestProgram11111111111111111");

#[program]
pub mod compressed_token_test {
use super::*;

/// Wrapper for write_to_cpi_context mode mint_action CPI
/// All accounts are in remaining_accounts (unchecked)
pub fn write_to_cpi_context_mint_action<'info>(
ctx: Context<'_, '_, '_, 'info, MintActionCpiWrapper<'info>>,
inputs: Vec<u8>,
) -> Result<()> {
execute_mint_action_cpi(ctx, inputs)
}

/// Wrapper for execute_cpi_context mode mint_action CPI
/// All accounts are in remaining_accounts (unchecked)
pub fn execute_cpi_context_mint_action<'info>(
ctx: Context<'_, '_, '_, 'info, MintActionCpiWrapper<'info>>,
inputs: Vec<u8>,
) -> Result<()> {
execute_mint_action_cpi(ctx, inputs)
}
}

/// Minimal account structure - only compressed token program ID
/// Everything else goes in remaining_accounts with no validation
#[derive(Accounts)]
pub struct MintActionCpiWrapper<'info> {
/// CHECK: Compressed token program - no validation
pub compressed_token_program: AccountInfo<'info>,
}

/// Shared implementation for both wrapper instructions
/// Passes through raw instruction bytes and accounts without any validation
fn execute_mint_action_cpi<'info>(
ctx: Context<'_, '_, '_, 'info, MintActionCpiWrapper<'info>>,
inputs: Vec<u8>,
) -> Result<()> {
// Build account_metas from remaining_accounts - pass through as-is
let account_metas: Vec<AccountMeta> = ctx
.remaining_accounts
.iter()
.map(|acc| {
if acc.is_writable {
AccountMeta::new(*acc.key, acc.is_signer)
} else {
AccountMeta::new_readonly(*acc.key, acc.is_signer)
}
})
.collect();

// Build instruction with raw bytes (no validation)
let instruction = Instruction {
program_id: *ctx.accounts.compressed_token_program.key,
accounts: account_metas,
data: inputs, // Pass through raw instruction bytes
};

// Simple invoke without any signer seeds
anchor_lang::solana_program::program::invoke(&instruction, ctx.remaining_accounts)?;

Ok(())
}
3 changes: 3 additions & 0 deletions program-tests/compressed-token-test/tests/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// This file serves as the entry point for the mint test module

// Declare submodules from the mint/ directory
#[path = "mint/cpi_context.rs"]
mod cpi_context;

#[path = "mint/edge_cases.rs"]
mod edge_cases;

Expand Down
Loading
Loading