Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
Address feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
jstarry committed Jul 18, 2022
1 parent aa175c0 commit 0b82b05
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 26 deletions.
6 changes: 3 additions & 3 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
case TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED: {
sol_log("Test max instruction data len exceeded");
SolAccountMeta arguments[] = {};
uint64_t data_len = 10 * 1024 + 1;
uint64_t data_len = MAX_CPI_INSTRUCTION_DATA_LEN + 1;
uint8_t *data = sol_calloc(data_len, 1);
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
Expand All @@ -498,7 +498,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
}
case TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED: {
sol_log("Test max instruction accounts exceeded");
uint64_t accounts_len = 256;
uint64_t accounts_len = MAX_CPI_INSTRUCTION_ACCOUNTS + 1;
SolAccountMeta *arguments = sol_calloc(accounts_len, sizeof(SolAccountMeta));
sol_assert(0 != arguments);
uint8_t data[] = {};
Expand All @@ -515,7 +515,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
case TEST_MAX_ACCOUNT_INFOS_EXCEEDED: {
sol_log("Test max account infos exceeded");
SolAccountMeta arguments[] = {};
uint64_t account_infos_len = 65;
uint64_t account_infos_len = MAX_CPI_ACCOUNT_INFOS + 1;
SolAccountInfo *account_infos = sol_calloc(account_infos_len, sizeof(SolAccountInfo));
sol_assert(0 != account_infos);
uint8_t data[] = {};
Expand Down
11 changes: 8 additions & 3 deletions programs/bpf/rust/invoke/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ use {
program::{get_return_data, invoke, invoke_signed, set_return_data},
program_error::ProgramError,
pubkey::{Pubkey, PubkeyError},
syscalls::{
MAX_CPI_ACCOUNT_INFOS, MAX_CPI_INSTRUCTION_ACCOUNTS, MAX_CPI_INSTRUCTION_DATA_LEN,
},
system_instruction,
},
};
Expand Down Expand Up @@ -556,23 +559,25 @@ fn process_instruction(
}
TEST_MAX_INSTRUCTION_DATA_LEN_EXCEEDED => {
msg!("Test max instruction data len exceeded");
let data_len = 10usize.saturating_mul(1024).saturating_add(1);
let data_len = MAX_CPI_INSTRUCTION_DATA_LEN.saturating_add(1) as usize;
let instruction =
create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![0; data_len]);
invoke_signed(&instruction, &[], &[])?;
}
TEST_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED => {
msg!("Test max instruction accounts exceeded");
let default_key = Pubkey::default();
let account_metas = vec![(&default_key, false, false); 256];
let account_metas_len = (MAX_CPI_INSTRUCTION_ACCOUNTS as usize).saturating_add(1);
let account_metas = vec![(&default_key, false, false); account_metas_len];
let instruction =
create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &account_metas, vec![]);
invoke_signed(&instruction, &[], &[])?;
}
TEST_MAX_ACCOUNT_INFOS_EXCEEDED => {
msg!("Test max account infos exceeded");
let instruction = create_instruction(*accounts[INVOKED_PROGRAM_INDEX].key, &[], vec![]);
let account_infos = vec![accounts[0].clone(); 65];
let account_infos_len = (MAX_CPI_ACCOUNT_INFOS as usize).saturating_add(1);
let account_infos = vec![accounts[0].clone(); account_infos_len];
invoke_signed(&instruction, &account_infos, &[])?;
}
TEST_RETURN_ERROR => {
Expand Down
27 changes: 9 additions & 18 deletions programs/bpf_loader/src/syscalls/cpi.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use {super::*, crate::declare_syscall};
use {
super::*,
crate::declare_syscall,
solana_sdk::syscalls::{
MAX_CPI_ACCOUNT_INFOS, MAX_CPI_INSTRUCTION_ACCOUNTS, MAX_CPI_INSTRUCTION_DATA_LEN,
},
};

struct CallerAccount<'a> {
lamports: &'a mut u64,
Expand Down Expand Up @@ -737,16 +743,6 @@ where
static_assertions::const_assert_eq!(ACCOUNT_META_SIZE, 34);
const ACCOUNT_META_SIZE: usize = size_of::<AccountMeta>();

/// Maximum CPI instruction data size. 10 KiB was chosen to ensure that CPI
/// instructions are not more limited than transaction instructions if the size
/// of transactions is doubled in the future.
const MAX_CPI_INSTRUCTION_DATA_LEN: u64 = 10 * 1024;

/// Maximum CPI instruction accounts. 255 was chosen to ensure that instruction
/// accounts are always within the maximum instruction account limit for BPF
/// program instructions.
const MAX_CPI_INSTRUCTION_ACCOUNTS: u8 = u8::MAX;

fn check_instruction_size(
num_accounts: usize,
data_len: usize,
Expand Down Expand Up @@ -791,11 +787,6 @@ fn check_instruction_size(
Ok(())
}

/// Maximum number of account info structs that can be used in a single CPI
/// invocation. A limit on account info structs is effectively the same as
/// limiting the number of unique accounts.
const MAX_CPI_ACCOUNT_INFOS: usize = MAX_TX_ACCOUNT_LOCKS;

fn check_account_infos(
num_account_infos: usize,
invoke_context: &mut InvokeContext,
Expand All @@ -804,8 +795,8 @@ fn check_account_infos(
.feature_set
.is_active(&feature_set::loosen_cpi_size_restriction::ID)
{
let num_account_infos = u64::try_from(num_account_infos).unwrap();
let max_account_infos = u64::try_from(MAX_CPI_ACCOUNT_INFOS).unwrap();
let num_account_infos = num_account_infos as u64;
let max_account_infos = MAX_CPI_ACCOUNT_INFOS as u64;
if num_account_infos > max_account_infos {
return Err(SyscallError::MaxInstructionAccountInfosExceeded {
num_account_infos,
Expand Down
1 change: 0 additions & 1 deletion programs/bpf_loader/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ use {
Secp256k1RecoverError, SECP256K1_PUBLIC_KEY_LENGTH, SECP256K1_SIGNATURE_LENGTH,
},
sysvar::{Sysvar, SysvarId},
transaction::MAX_TX_ACCOUNT_LOCKS,
transaction_context::InstructionAccount,
},
std::{
Expand Down
22 changes: 22 additions & 0 deletions sdk/bpf/c/inc/sol/cpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@
extern "C" {
#endif

/**
* Maximum CPI instruction data size. 10 KiB was chosen to ensure that CPI
* instructions are not more limited than transaction instructions if the size
* of transactions is doubled in the future.
*/
static const uint64_t MAX_CPI_INSTRUCTION_DATA_LEN = 10240;

/**
* Maximum CPI instruction accounts. 255 was chosen to ensure that instruction
* accounts are always within the maximum instruction account limit for BPF
* program instructions.
*/
static const uint8_t MAX_CPI_INSTRUCTION_ACCOUNTS = 255;

/**
* Maximum number of account info structs that can be used in a single CPI
* invocation. A limit on account info structs is effectively the same as
* limiting the number of unique accounts. 64 was chosen to match the max
* number of locked accounts per transaction (MAX_TX_ACCOUNT_LOCKS).
*/
static const uint8_t MAX_CPI_ACCOUNT_INFOS = 64;

/**
* Account Meta
*/
Expand Down
1 change: 0 additions & 1 deletion sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,6 @@ pub mod slot_hashes;
pub mod slot_history;
pub mod stake;
pub mod stake_history;
#[cfg(target_os = "solana")]
pub mod syscalls;
pub mod system_instruction;
pub mod system_program;
Expand Down
File renamed without changes.
21 changes: 21 additions & 0 deletions sdk/program/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#[cfg(target_os = "solana")]
mod definitions;

#[cfg(target_os = "solana")]
pub use definitions::*;

/// Maximum CPI instruction data size. 10 KiB was chosen to ensure that CPI
/// instructions are not more limited than transaction instructions if the size
/// of transactions is doubled in the future.
pub const MAX_CPI_INSTRUCTION_DATA_LEN: u64 = 10 * 1024;

/// Maximum CPI instruction accounts. 255 was chosen to ensure that instruction
/// accounts are always within the maximum instruction account limit for BPF
/// program instructions.
pub const MAX_CPI_INSTRUCTION_ACCOUNTS: u8 = u8::MAX;

/// Maximum number of account info structs that can be used in a single CPI
/// invocation. A limit on account info structs is effectively the same as
/// limiting the number of unique accounts. 64 was chosen to match the max
/// number of locked accounts per transaction (MAX_TX_ACCOUNT_LOCKS).
pub const MAX_CPI_ACCOUNT_INFOS: usize = 64;

0 comments on commit 0b82b05

Please sign in to comment.