diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 2147af06e07ff4..76a1193828ae07 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -1288,7 +1288,7 @@ fn test_program_bpf_invoke_sanity() { format!("Program log: invoke {program_lang} program"), "Program log: Test max account infos exceeded".into(), "skip".into(), // don't compare compute consumption logs - "Program failed to complete: Invoked an instruction with too many account info's (65 > 64)".into(), + "Program failed to complete: Invoked an instruction with too many account info's (129 > 128)".into(), format!("Program {invoke_program_id} failed: Program failed to complete"), ]), ); diff --git a/programs/bpf_loader/src/syscalls/cpi.rs b/programs/bpf_loader/src/syscalls/cpi.rs index 7ab7654314d4d8..f11c7981571d7e 100644 --- a/programs/bpf_loader/src/syscalls/cpi.rs +++ b/programs/bpf_loader/src/syscalls/cpi.rs @@ -799,8 +799,16 @@ fn check_account_infos( .feature_set .is_active(&feature_set::loosen_cpi_size_restriction::id()) { + let max_cpi_account_infos = if invoke_context + .feature_set + .is_active(&feature_set::increase_tx_account_lock_limit::id()) + { + MAX_CPI_ACCOUNT_INFOS + } else { + 64 + }; let num_account_infos = num_account_infos as u64; - let max_account_infos = MAX_CPI_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, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index a25ade41f0599a..d7f3ec2417847c 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -3913,8 +3913,13 @@ impl Bank { self.runtime_config.transaction_account_lock_limit { transaction_account_lock_limit - } else { + } else if self + .feature_set + .is_active(&feature_set::increase_tx_account_lock_limit::id()) + { MAX_TX_ACCOUNT_LOCKS + } else { + 64 } } @@ -8135,7 +8140,6 @@ pub(crate) mod tests { }, system_program, timing::duration_as_s, - transaction::MAX_TX_ACCOUNT_LOCKS, transaction_context::IndexOfAccount, }, solana_vote_program::{ @@ -14361,7 +14365,8 @@ pub(crate) mod tests { bank.last_blockhash(), ); - while tx.message.account_keys.len() <= MAX_TX_ACCOUNT_LOCKS { + let transaction_account_lock_limit = bank.get_transaction_account_lock_limit(); + while tx.message.account_keys.len() <= transaction_account_lock_limit { tx.message.account_keys.push(solana_sdk::pubkey::new_rand()); } diff --git a/sdk/bpf/c/inc/sol/cpi.h b/sdk/bpf/c/inc/sol/cpi.h index a1c4c21de5e7f7..b3748cff2240f9 100644 --- a/sdk/bpf/c/inc/sol/cpi.h +++ b/sdk/bpf/c/inc/sol/cpi.h @@ -28,10 +28,10 @@ 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 + * limiting the number of unique accounts. 128 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; +static const uint16_t MAX_CPI_ACCOUNT_INFOS = 128; /** * Account Meta diff --git a/sdk/bpf/c/inc/sol/inc/cpi.inc b/sdk/bpf/c/inc/sol/inc/cpi.inc index ce615e90b84f4d..41ce4fb01a691b 100644 --- a/sdk/bpf/c/inc/sol/inc/cpi.inc +++ b/sdk/bpf/c/inc/sol/inc/cpi.inc @@ -28,10 +28,10 @@ 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 + * limiting the number of unique accounts. 128 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; +static const uint16_t MAX_CPI_ACCOUNT_INFOS = 128; /** * Account Meta diff --git a/sdk/program/src/syscalls/mod.rs b/sdk/program/src/syscalls/mod.rs index aa0a85c23f4590..d66c9361e95792 100644 --- a/sdk/program/src/syscalls/mod.rs +++ b/sdk/program/src/syscalls/mod.rs @@ -16,6 +16,6 @@ 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 +/// limiting the number of unique accounts. 128 was chosen to match the max /// number of locked accounts per transaction (MAX_TX_ACCOUNT_LOCKS). -pub const MAX_CPI_ACCOUNT_INFOS: usize = 64; +pub const MAX_CPI_ACCOUNT_INFOS: usize = 128; diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index 1c6ca47ff5bf53..f2f3be0332c729 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -526,6 +526,10 @@ pub mod remove_deprecated_request_unit_ix { solana_sdk::declare_id!("EfhYd3SafzGT472tYQDUc4dPd2xdEfKs5fwkowUgVt4W"); } +pub mod increase_tx_account_lock_limit { + solana_sdk::declare_id!("9LZdXeKGeBV6hRLdxS1rHbHoEUsKqesCC2ZAPTPKJAbK"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -652,6 +656,7 @@ lazy_static! { (return_none_for_zero_lamport_accounts::id(), "return none for zero lamport accounts #27800"), (epoch_accounts_hash::id(), "enable epoch accounts hash calculation #27539"), (remove_deprecated_request_unit_ix::id(), "remove support for RequestUnitsDeprecated instruction #27500"), + (increase_tx_account_lock_limit::id(), "increase tx account lock limit to 128 #27241"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter() diff --git a/sdk/src/transaction/sanitized.rs b/sdk/src/transaction/sanitized.rs index 7d1b34a4ab41e6..7c5a9df4d662c7 100644 --- a/sdk/src/transaction/sanitized.rs +++ b/sdk/src/transaction/sanitized.rs @@ -21,9 +21,9 @@ use { }; /// Maximum number of accounts that a transaction may lock. -/// 64 was chosen because it is roughly twice the previous -/// number of account keys that could fit in a legacy tx. -pub const MAX_TX_ACCOUNT_LOCKS: usize = 64; +/// 128 was chosen because it is the minimum number of accounts +/// needed for the Neon EVM implementation. +pub const MAX_TX_ACCOUNT_LOCKS: usize = 128; /// Sanitized transaction and the hash of its message #[derive(Debug, Clone)]