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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,12 @@ fn cpi_compressed_pda_transfer<'info>(
.clone(),
];
system_accounts.extend_from_slice(ctx.remaining_accounts);
let light_accounts = CpiAccounts::new_with_config(
let light_accounts = CpiAccounts::try_new_with_config(
ctx.accounts.signer.as_ref(),
&system_accounts,
CpiAccountsConfig::new_with_cpi_context(crate::LIGHT_CPI_SIGNER),
);
)
.unwrap();

verify_borsh(light_accounts, &inputs_struct).map_err(ProgramError::from)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,12 @@ fn cpi_compressed_pda_withdrawal<'info>(
.clone(),
];
system_accounts.extend_from_slice(ctx.remaining_accounts);
let light_accounts = CpiAccounts::new_with_config(
let light_accounts = CpiAccounts::try_new_with_config(
ctx.accounts.signer.as_ref(),
&system_accounts,
CpiAccountsConfig::new_with_cpi_context(crate::LIGHT_CPI_SIGNER),
);
)
.unwrap();
verify_borsh(light_accounts, &inputs_struct).unwrap();

Ok(())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use core::ops::{Deref, DerefMut};
use core::{
fmt::Debug,
ops::{Deref, DerefMut},
};

use crate::error::AccountError;

/// Trait to abstract over different AccountInfo implementations (pinocchio vs solana)
pub trait AccountInfoTrait {
type Pubkey: Copy + Clone;
type Pubkey: Copy + Clone + Debug;
type DataRef<'a>: Deref<Target = [u8]>
where
Self: 'a;
Expand Down
9 changes: 6 additions & 3 deletions program-tests/create-address-test-program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use light_compressed_account::instruction_data::{
use light_sdk::{
constants::LIGHT_SYSTEM_PROGRAM_ID,
cpi::{
invoke_light_system_program, to_account_metas, to_account_metas_small, CpiAccountsConfig,
get_account_metas_from_config, invoke_light_system_program, to_account_metas_small,
CpiAccountsConfig, CpiInstructionConfig,
},
};

Expand Down Expand Up @@ -78,14 +79,16 @@ pub mod system_cpi_test {
use light_sdk::cpi::CpiAccounts;
let cpi_accounts =
CpiAccounts::new_with_config(&fee_payer, ctx.remaining_accounts, config);

let account_infos = cpi_accounts
.to_account_infos()
.into_iter()
.cloned()
.collect::<Vec<_>>();

let account_metas =
to_account_metas(cpi_accounts).map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
let config = CpiInstructionConfig::try_from(&cpi_accounts)
.map_err(|_| ErrorCode::AccountNotEnoughKeys)?;
let account_metas = get_account_metas_from_config(config);
(account_infos, account_metas)
};
let instruction = Instruction {
Expand Down
4 changes: 2 additions & 2 deletions program-tests/sdk-pinocchio-test/src/create_pda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ pub fn create_pda<const BATCHED: bool>(
let instruction_data = CreatePdaInstructionData::deserialize(&mut instruction_data)
.map_err(|_| LightSdkError::Borsh)?;
let config = CpiAccountsConfig::new(crate::LIGHT_CPI_SIGNER);
let cpi_accounts = CpiAccounts::new_with_config(
let cpi_accounts = CpiAccounts::try_new_with_config(
&accounts[0],
&accounts[instruction_data.system_accounts_offset as usize..],
config,
);
)?;

let address_tree_info = instruction_data.address_tree_info;
let (address, address_seed) = if BATCHED {
Expand Down
4 changes: 2 additions & 2 deletions program-tests/sdk-pinocchio-test/src/update_pda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ pub fn update_pda<const BATCHED: bool>(

let config = CpiAccountsConfig::new(crate::LIGHT_CPI_SIGNER);
sol_log_compute_units();
let cpi_accounts = CpiAccounts::new_with_config(
let cpi_accounts = CpiAccounts::try_new_with_config(
&accounts[0],
&accounts[instruction_data.system_accounts_offset as usize..],
config,
);
)?;
sol_log_compute_units();
let cpi_inputs = CpiInputs::new(
instruction_data.proof,
Expand Down
5 changes: 3 additions & 2 deletions program-tests/sdk-test/src/create_pda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ pub fn create_pda<const BATCHED: bool>(
let instruction_data = CreatePdaInstructionData::deserialize(&mut instruction_data)
.map_err(|_| LightSdkError::Borsh)?;
let config = CpiAccountsConfig::new(crate::LIGHT_CPI_SIGNER);
let cpi_accounts = CpiAccounts::new_with_config(
let cpi_accounts = CpiAccounts::try_new_with_config(
&accounts[0],
&accounts[instruction_data.system_accounts_offset as usize..],
config,
);
)
.unwrap();

let address_tree_info = instruction_data.address_tree_info;
let (address, address_seed) = if BATCHED {
Expand Down
4 changes: 2 additions & 2 deletions program-tests/sdk-test/src/update_pda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ pub fn update_pda<const BATCHED: bool>(

let config = CpiAccountsConfig::new(crate::LIGHT_CPI_SIGNER);
sol_log_compute_units();
let cpi_accounts = CpiAccounts::new_with_config(
let cpi_accounts = CpiAccounts::try_new_with_config(
&accounts[0],
&accounts[instruction_data.system_accounts_offset as usize..],
config,
);
)?;
sol_log_compute_units();
let cpi_inputs = CpiInputs::new(
instruction_data.proof,
Expand Down
17 changes: 17 additions & 0 deletions sdk-libs/sdk-pinocchio/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use light_account_checks::error::AccountError;
use light_hasher::HasherError;
pub use light_sdk_types::error::LightSdkTypesError;
use light_zero_copy::errors::ZeroCopyError;
Expand Down Expand Up @@ -68,12 +69,20 @@ pub enum LightSdkError {
MetaCloseInputIsNone,
#[error("CPI accounts index out of bounds: {0}")]
CpiAccountsIndexOutOfBounds(usize),
#[error("Invalid CPI context account")]
InvalidCpiContextAccount,
#[error("Invalid sol pool pda account")]
InvalidSolPoolPdaAccount,
#[error("CpiAccounts slice starts with an invalid account. It should start with LightSystemProgram SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7.")]
InvalidCpiAccountsOffset,
#[error(transparent)]
Hasher(#[from] HasherError),
#[error(transparent)]
ZeroCopy(#[from] ZeroCopyError),
#[error("Program error: {0:?}")]
ProgramError(ProgramError),
#[error(transparent)]
AccountError(#[from] AccountError),
}

impl From<ProgramError> for LightSdkError {
Expand Down Expand Up @@ -111,6 +120,10 @@ impl From<LightSdkTypesError> for LightSdkError {
LightSdkTypesError::CpiAccountsIndexOutOfBounds(index) => {
LightSdkError::CpiAccountsIndexOutOfBounds(index)
}
LightSdkTypesError::InvalidCpiContextAccount => LightSdkError::InvalidCpiContextAccount,
LightSdkTypesError::InvalidSolPoolPdaAccount => LightSdkError::InvalidSolPoolPdaAccount,
LightSdkTypesError::AccountError(e) => LightSdkError::AccountError(e),
LightSdkTypesError::InvalidCpiAccountsOffset => LightSdkError::InvalidCpiAccountsOffset,
}
}
}
Expand Down Expand Up @@ -148,9 +161,13 @@ impl From<LightSdkError> for u32 {
LightSdkError::MetaCloseAddressIsNone => 16028,
LightSdkError::MetaCloseInputIsNone => 16029,
LightSdkError::CpiAccountsIndexOutOfBounds(_) => 16031,
LightSdkError::InvalidCpiContextAccount => 16032,
LightSdkError::InvalidSolPoolPdaAccount => 16033,
LightSdkError::InvalidCpiAccountsOffset => 16034,
LightSdkError::Hasher(e) => e.into(),
LightSdkError::ZeroCopy(e) => e.into(),
LightSdkError::ProgramError(e) => u64::from(e) as u32,
LightSdkError::AccountError(e) => e.into(),
}
}
}
1 change: 1 addition & 0 deletions sdk-libs/sdk-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ light-hasher = { workspace = true }
light-compressed-account = { workspace = true }
light-macros = { workspace = true }
light-zero-copy = { workspace = true }
solana-msg = { workspace = true }

# External dependencies
borsh = { workspace = true }
Expand Down
7 changes: 7 additions & 0 deletions sdk-libs/sdk-types/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ pub const LIGHT_SYSTEM_PROGRAM_ID: [u8; 32] =
pubkey_array!("SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7");
pub const REGISTERED_PROGRAM_PDA: [u8; 32] =
pubkey_array!("35hkDgaAKwMCaxRz2ocSZ6NaUrtKkyNqU6c4RV3tYJRh");
pub const ACCOUNT_COMPRESSION_AUTHORITY_PDA: [u8; 32] =
pubkey_array!("HwXnGK3tPkkVY6P439H2p68AxpeuWXd5PcrAxFpbmfbA");

/// ID of the light-compressed-token program.
pub const C_TOKEN_PROGRAM_ID: [u8; 32] =
pubkey_array!("cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m");
Expand All @@ -31,3 +34,7 @@ pub const TOKEN_COMPRESSED_ACCOUNT_DISCRIMINATOR: [u8; 8] = [2, 0, 0, 0, 0, 0, 0

pub const ADDRESS_TREE_V1: [u8; 32] = pubkey_array!("amt1Ayt45jfbdw5YSo7iz6WZxUmnZsQTYXy82hVwyC2");
pub const ADDRESS_QUEUE_V1: [u8; 32] = pubkey_array!("aq1S9z4reTSQAdgWHGD2zDaS39sjGrAxbR31vxJ2F4F");

pub const CPI_CONTEXT_ACCOUNT_DISCRIMINATOR: [u8; 8] = [22, 20, 149, 218, 74, 204, 128, 166];

pub const SOL_POOL_PDA: [u8; 32] = pubkey_array!("CHK57ywWSDncAoRu1F8QgwYJeXuAJyyBYT4LixLXvMZ1");
50 changes: 48 additions & 2 deletions sdk-libs/sdk-types/src/cpi_accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use light_account_checks::AccountInfoTrait;

use crate::{
error::{LightSdkTypesError, Result},
CpiSigner,
CpiSigner, CPI_CONTEXT_ACCOUNT_DISCRIMINATOR, LIGHT_SYSTEM_PROGRAM_ID, SOL_POOL_PDA,
};

#[derive(Debug, Copy, Clone, AnchorSerialize, AnchorDeserialize)]
Expand Down Expand Up @@ -77,6 +77,17 @@ impl<'a, T: AccountInfoTrait> CpiAccounts<'a, T> {
}
}

pub fn try_new(fee_payer: &'a T, accounts: &'a [T], cpi_signer: CpiSigner) -> Result<Self> {
if accounts[0].key() != LIGHT_SYSTEM_PROGRAM_ID {
return Err(LightSdkTypesError::InvalidCpiAccountsOffset);
}
Ok(Self {
fee_payer,
accounts,
config: CpiAccountsConfig::new(cpi_signer),
})
}

pub fn new_with_config(fee_payer: &'a T, accounts: &'a [T], config: CpiAccountsConfig) -> Self {
Self {
fee_payer,
Expand All @@ -85,6 +96,35 @@ impl<'a, T: AccountInfoTrait> CpiAccounts<'a, T> {
}
}

pub fn try_new_with_config(
fee_payer: &'a T,
accounts: &'a [T],
config: CpiAccountsConfig,
) -> Result<Self> {
let res = Self {
fee_payer,
accounts,
config,
};
if accounts[0].key() != LIGHT_SYSTEM_PROGRAM_ID {
return Err(LightSdkTypesError::InvalidCpiAccountsOffset);
}
if res.config().cpi_context {
let cpi_context = res.cpi_context()?;
let discriminator_bytes = &cpi_context.try_borrow_data()?[..8];
if discriminator_bytes != CPI_CONTEXT_ACCOUNT_DISCRIMINATOR.as_slice() {
solana_msg::msg!("Invalid CPI context account: {:?}", cpi_context.pubkey());
return Err(LightSdkTypesError::InvalidCpiContextAccount);
}
}

if res.config().sol_pool_pda && res.sol_pool_pda()?.key() != SOL_POOL_PDA {
return Err(LightSdkTypesError::InvalidSolPoolPdaAccount);
}

Ok(res)
}

pub fn fee_payer(&self) -> &'a T {
self.fee_payer
}
Expand Down Expand Up @@ -160,7 +200,13 @@ impl<'a, T: AccountInfoTrait> CpiAccounts<'a, T> {
}

pub fn cpi_context(&self) -> Result<&'a T> {
let index = CompressionCpiAccountIndex::CpiContext as usize;
let mut index = CompressionCpiAccountIndex::CpiContext as usize;
if !self.config.sol_pool_pda {
index -= 1;
}
if !self.config.sol_compression_recipient {
index -= 1;
}
self.accounts
.get(index)
.ok_or(LightSdkTypesError::CpiAccountsIndexOutOfBounds(index))
Expand Down
13 changes: 13 additions & 0 deletions sdk-libs/sdk-types/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use light_account_checks::error::AccountError;
use light_hasher::HasherError;
use thiserror::Error;

Expand Down Expand Up @@ -27,6 +28,14 @@ pub enum LightSdkTypesError {
FewerAccountsThanSystemAccounts,
#[error("CPI accounts index out of bounds: {0}")]
CpiAccountsIndexOutOfBounds(usize),
#[error("Invalid CPI context account")]
InvalidCpiContextAccount,
#[error("Invalid sol pool pda account")]
InvalidSolPoolPdaAccount,
#[error("CpigAccounts accounts slice starts with an invalid account. It should start with LightSystemProgram SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7.")]
InvalidCpiAccountsOffset,
#[error(transparent)]
AccountError(#[from] AccountError),
#[error(transparent)]
Hasher(#[from] HasherError),
}
Expand All @@ -45,6 +54,10 @@ impl From<LightSdkTypesError> for u32 {
LightSdkTypesError::MetaCloseInputIsNone => 14029,
LightSdkTypesError::FewerAccountsThanSystemAccounts => 14017,
LightSdkTypesError::CpiAccountsIndexOutOfBounds(_) => 14031,
LightSdkTypesError::InvalidCpiContextAccount => 14032,
LightSdkTypesError::InvalidSolPoolPdaAccount => 14033,
LightSdkTypesError::InvalidCpiAccountsOffset => 14034,
LightSdkTypesError::AccountError(e) => e.into(),
LightSdkTypesError::Hasher(e) => e.into(),
}
}
Expand Down
Loading
Loading