Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
23f8d97
SIMD 0339 functionality + integration tests
nbelenkov Oct 16, 2025
1c9619b
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 16, 2025
2f3446d
refactor feature gate to be in ComputeBudget
nbelenkov Oct 16, 2025
12b7a09
Merge branch 'increase_cpi_info_account_limit' of github.com:nbelenko…
nbelenkov Oct 16, 2025
8a65c68
adding types for byte calculation and updated the comment
nbelenkov Oct 17, 2025
0d31630
fix missed invocation with new function signature
nbelenkov Oct 17, 2025
620ff0e
changed feature name to increase_cpi_account_info_limit
nbelenkov Oct 17, 2025
917abad
test renaming for new normal prospective + whitespace format
nbelenkov Oct 20, 2025
b0407e6
changing missed hardcoded value to type size on c account translation
nbelenkov Oct 20, 2025
01466de
fixing CI issue with whitespaces in C program
nbelenkov Oct 21, 2025
df4d61d
adding execution cost initialization to bank creation
nbelenkov Oct 21, 2025
8e3e3d1
adding CU tests
nbelenkov Oct 22, 2025
3c81a81
cargo fmt didn't work on some files
nbelenkov Oct 22, 2025
4629daa
c file whitespace
nbelenkov Oct 22, 2025
abc7e34
using test-v3 for CU estimations
nbelenkov Oct 22, 2025
c51ec8c
upper bound of CU test due to different sbpf versions
nbelenkov Oct 23, 2025
9071ea7
panic error fix
nbelenkov Oct 23, 2025
004ac03
constant for AccountInfo type size + account info charging relocation
nbelenkov Oct 23, 2025
c4b8563
merge CU consuming calls into 1
nbelenkov Oct 24, 2025
9076cff
cargo fmt
nbelenkov Oct 24, 2025
4db843a
mergin master into this PR
nbelenkov Oct 24, 2025
ac84ebd
cargo fmt the merge
nbelenkov Oct 24, 2025
3f722bd
renamed tests + cargo.lock update
nbelenkov Oct 24, 2025
bcf5f2b
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 25, 2025
634f923
updated keypair for feature gate + refactored total_cu_translation_co…
nbelenkov Oct 27, 2025
f44b4c8
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 27, 2025
c9e055d
fmt after upstream sync
nbelenkov Oct 27, 2025
171f59b
var renaming
nbelenkov Oct 27, 2025
3e71a15
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 27, 2025
4f474f5
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 28, 2025
7fa3a0d
Merge branch 'master' into increase_cpi_info_account_limit
nbelenkov Oct 28, 2025
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
4 changes: 2 additions & 2 deletions compute-budget/src/compute_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ impl Default for ComputeBudget {
}

impl ComputeBudget {
pub fn new_with_defaults(simd_0268_active: bool) -> Self {
pub fn new_with_defaults(simd_0268_active: bool, simd_0339_active: bool) -> Self {
Self::from_budget_and_cost(
&SVMTransactionExecutionBudget::new_with_defaults(simd_0268_active),
&SVMTransactionExecutionCost::default(),
&SVMTransactionExecutionCost::new_with_defaults(simd_0339_active),
)
}

Expand Down
10 changes: 9 additions & 1 deletion feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ impl FeatureSet {
raise_cpi_nesting_limit_to_8: self.is_active(&raise_cpi_nesting_limit_to_8::id()),
provide_instruction_data_offset_in_vm_r2: self
.is_active(&provide_instruction_data_offset_in_vm_r2::id()),
increase_cpi_account_info_limit: self.is_active(&increase_cpi_account_info_limit::id()),
vote_state_v4: self.is_active(&vote_state_v4::id()),
}
}
Expand Down Expand Up @@ -1154,7 +1155,6 @@ pub mod static_instruction_limit {
pub mod discard_unexpected_data_complete_shreds {
solana_pubkey::declare_id!("8MhfKhoZEoiySpVe248bDkisyEcBA7JQLyUS94xoTSqN");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is very nit picky but this doesn't look intentional, can you undo this?

pub mod vote_state_v4 {
solana_pubkey::declare_id!("Gx4XFcrVMt4HUvPzTpTSVkdDVgcDSjKhDN1RqRS6KDuZ");

Expand All @@ -1167,6 +1167,10 @@ pub mod switch_to_chacha8_turbine {
solana_pubkey::declare_id!("CHaChatUnR3s6cPyPMMGNJa3VdQQ8PNH2JqdD4LpCKnB");
}

pub mod increase_cpi_account_info_limit {
solana_pubkey::declare_id!("7wM2pdjwmSXviEdsorpcBY3T4YWUPQXDMepZudub7nGQ"); // Placeholder ID HAVE TO CHANGE BEFORE USE

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update this with a real key?

}

pub mod deprecate_rent_exemption_threshold {
solana_pubkey::declare_id!("rent6iVy6PDoViPBeJ6k5EJQrkj62h7DPyLbWGHwjrC");
}
Expand Down Expand Up @@ -2102,6 +2106,10 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
switch_to_chacha8_turbine::id(),
"SIMD-0332: Reduce ChaCha rounds for Turbine from 20 to 8",
),
(
increase_cpi_account_info_limit::id(),
"SIMD-0339: increase CPI info account limit",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This title doesn't match the SIMD

),
(
deprecate_rent_exemption_threshold::id(),
"SIMD-0194: Deprecate rent exemption threshold",
Expand Down
68 changes: 60 additions & 8 deletions program-runtime/src/cpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ type Error = Box<dyn std::error::Error>;
const SUCCESS: u64 = 0;
/// Maximum signers
const MAX_SIGNERS: usize = 16;
///SIMD-0339 based calculation of AccountInfo translation byte size. Fixed size of **80 bytes** for each AccountInfo broken down as:
/// - 32 bytes for account address
/// - 32 bytes for owner address
/// - 8 bytes for lamport balance
/// - 8 bytes for data length
const ACCOUNT_INFO_BYTE_SIZE: usize = 80;

/// Rust representation of C's SolInstruction
#[derive(Debug)]
Expand Down Expand Up @@ -114,6 +120,8 @@ struct SolSignerSeedsC {

/// Maximum number of account info structs that can be used in a single CPI invocation
const MAX_CPI_ACCOUNT_INFOS: usize = 128;
/// Maximum number of account info structs that can be used in a single CPI invocation with SIMD-0339 active
const MAX_CPI_ACCOUNT_INFOS_SIMD_0339: usize = 255;

/// Check that an account info pointer field points to the expected address
fn check_account_info_pointer(
Expand Down Expand Up @@ -158,6 +166,11 @@ fn check_account_infos(
invoke_context: &mut InvokeContext,
) -> Result<(), Error> {
let max_cpi_account_infos = if invoke_context
.get_feature_set()
.increase_cpi_account_info_limit
{
MAX_CPI_ACCOUNT_INFOS_SIMD_0339
} else if invoke_context
.get_feature_set()
.increase_tx_account_lock_limit
{
Expand Down Expand Up @@ -531,14 +544,24 @@ pub fn translate_instruction_rust(
ix.data.as_vaddr(),
ix.data.len(),
check_aligned,
)?
.to_vec();
)?;

check_instruction_size(account_metas.len(), data.len())?;

let mut total_cu_translation_cost = data.len() as u64;

if invoke_context
.get_feature_set()
.increase_cpi_account_info_limit
{
// Each account meta is 34 bytes (32 for pubkey, 1 for is_signer, 1 for is_writable)
total_cu_translation_cost = total_cu_translation_cost
.saturating_add(account_metas.len().saturating_mul(size_of::<AccountMeta>()) as u64);
}

consume_compute_meter(
invoke_context,
(data.len() as u64)
(total_cu_translation_cost)
.checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
.unwrap_or(u64::MAX),
)?;
Expand All @@ -559,7 +582,7 @@ pub fn translate_instruction_rust(

Ok(Instruction {
accounts,
data,
data: data.to_vec(),
program_id: ix.program_id,
})
}
Expand Down Expand Up @@ -650,14 +673,28 @@ pub fn translate_instruction_c(
ix_c.accounts_len,
check_aligned,
)?;
let data = translate_slice::<u8>(memory_mapping, ix_c.data_addr, ix_c.data_len, check_aligned)?
.to_vec();
let data = translate_slice::<u8>(memory_mapping, ix_c.data_addr, ix_c.data_len, check_aligned)?;

check_instruction_size(ix_c.accounts_len as usize, data.len())?;

let mut total_cu_translation_cost = data.len() as u64;

if invoke_context
.get_feature_set()
.increase_cpi_account_info_limit
{
// Each account meta is 34 bytes (32 for pubkey, 1 for is_signer, 1 for is_writable)
total_cu_translation_cost =
total_cu_translation_cost.saturating_add(ix_c.accounts_len.saturating_mul(size_of::<
AccountMeta,
>(
)
as u64));
}

consume_compute_meter(
invoke_context,
(data.len() as u64)
(total_cu_translation_cost)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summing the total data size (ix data + account meta's) before dividing by "cpi bytes per unit" could reduce the impact of rounding error.. and that behavior doesn't match the SIMD. Combining the total cost is fine, just make sure you do the division first before summing the ix_data_cost with the ix_account_meta_cost

.checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
.unwrap_or(u64::MAX),
)?;
Expand All @@ -684,7 +721,7 @@ pub fn translate_instruction_c(

Ok(Instruction {
accounts,
data,
data: data.to_vec(),
program_id: *program_id,
})
}
Expand Down Expand Up @@ -926,6 +963,21 @@ where
check_aligned,
)?;
check_account_infos(account_infos.len(), invoke_context)?;

if invoke_context
.get_feature_set()
.increase_cpi_account_info_limit
{
let account_infos_bytes = account_infos.len().saturating_mul(ACCOUNT_INFO_BYTE_SIZE);

consume_compute_meter(
invoke_context,
(account_infos_bytes as u64)
.checked_div(invoke_context.get_execution_cost().cpi_bytes_per_unit)
.unwrap_or(u64::MAX),
)?;
}

let mut account_info_keys = Vec::with_capacity(account_infos_len as usize);
#[allow(clippy::needless_range_loop)]
for account_index in 0..account_infos_len as usize {
Expand Down
25 changes: 21 additions & 4 deletions program-runtime/src/execution_budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@ fn get_max_instruction_stack_depth(simd_0268_active: bool) -> usize {
}
}

//Default CPI invocation cost
pub const DEFAULT_INVOCATION_COST: u64 = 1000;
//CPI Invocation cost with SIMD-0339 active
pub const INVOKE_UNITS_COST_SIMD_0339: u64 = 946;

fn get_invoke_unit_cost(simd_0339_active: bool) -> u64 {
if simd_0339_active {
INVOKE_UNITS_COST_SIMD_0339
} else {
DEFAULT_INVOCATION_COST
}
}

/// Max call depth. This is the maximum nesting of SBF to SBF call that can happen within a program.
pub const MAX_CALL_DEPTH: usize = 64;

Expand Down Expand Up @@ -176,10 +189,16 @@ pub struct SVMTransactionExecutionCost {

impl Default for SVMTransactionExecutionCost {
fn default() -> Self {
Self {
Self::new_with_defaults(/* simd_0339_active */ false)
}
}

impl SVMTransactionExecutionCost {
pub fn new_with_defaults(simd_0339_active: bool) -> Self {
SVMTransactionExecutionCost {
log_64_units: 100,
create_program_address_units: 1500,
invoke_units: 1000,
invoke_units: get_invoke_unit_cost(simd_0339_active),
sha256_base_cost: 85,
sha256_byte_cost: 1,
log_pubkey_units: 100,
Expand Down Expand Up @@ -216,9 +235,7 @@ impl Default for SVMTransactionExecutionCost {
alt_bn128_g2_decompress: 13610,
}
}
}

impl SVMTransactionExecutionCost {
/// Returns cost of the Poseidon hash function for the given number of
/// inputs is determined by the following quadratic function:
///
Expand Down
4 changes: 3 additions & 1 deletion program-runtime/src/invoke_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,9 @@ macro_rules! with_mock_invoke_context_with_feature_set {
environment_config,
Some(LogCollector::new_ref()),
compute_budget,
SVMTransactionExecutionCost::default(),
SVMTransactionExecutionCost::new_with_defaults(
$feature_set.increase_cpi_account_info_limit,
),
);
};
}
Expand Down
7 changes: 6 additions & 1 deletion program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
// Export tokio for test clients
pub use tokio;
use {
agave_feature_set::{raise_cpi_nesting_limit_to_8, FEATURE_NAMES},
agave_feature_set::{
increase_cpi_account_info_limit, raise_cpi_nesting_limit_to_8, FEATURE_NAMES,
},
async_trait::async_trait,
base64::{prelude::BASE64_STANDARD, Engine},
chrono_humanize::{Accuracy, HumanTime, Tense},
Expand Down Expand Up @@ -859,6 +861,9 @@ impl ProgramTest {
genesis_config
.accounts
.contains_key(&raise_cpi_nesting_limit_to_8::id()),
genesis_config
.accounts
.contains_key(&increase_cpi_account_info_limit::id()),
)
}),
transaction_account_lock_limit: self.transaction_account_lock_limit,
Expand Down
Loading
Loading