Revert "Cap accounts data a transaction can load by its requested limit" (#29373)
Revert "Cap accounts data a transaction can load by its requested limit (#27840)"
This reverts commit 81dc2e56ac
.
This commit is contained in:
parent
c5380d4699
commit
1d88654116
|
@ -60,9 +60,8 @@ to.
|
||||||
As the transaction is processed compute units are consumed by its
|
As the transaction is processed compute units are consumed by its
|
||||||
instruction's programs performing operations such as executing SBF instructions,
|
instruction's programs performing operations such as executing SBF instructions,
|
||||||
calling syscalls, etc... When the transaction consumes its entire budget, or
|
calling syscalls, etc... When the transaction consumes its entire budget, or
|
||||||
exceeds a bound such as attempting a call stack that is too deep, or loaded
|
exceeds a bound such as attempting a call stack that is too deep, the runtime
|
||||||
account data exceeds limit, the runtime halts the transaction processing and
|
halts the transaction processing and returns an error.
|
||||||
returns an error.
|
|
||||||
|
|
||||||
The following operations incur a compute cost:
|
The following operations incur a compute cost:
|
||||||
|
|
||||||
|
@ -151,21 +150,6 @@ let instruction = ComputeBudgetInstruction::set_compute_unit_limit(300_000);
|
||||||
let instruction = ComputeBudgetInstruction::set_compute_unit_price(1);
|
let instruction = ComputeBudgetInstruction::set_compute_unit_price(1);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Accounts data size limit
|
|
||||||
|
|
||||||
A transaction should request the maximum bytes of accounts data it is
|
|
||||||
allowed to load by including a `SetAccountsDataSizeLimit` instruction, requested
|
|
||||||
limit is capped by `get_max_loaded_accounts_data_limit()`. If no
|
|
||||||
`SetAccountsDataSizeLimit` is provided, the transaction is defaulted to
|
|
||||||
have limit of `get_default_loaded_accounts_data_limit()`.
|
|
||||||
|
|
||||||
The `ComputeBudgetInstruction::set_accounts_data_size_limit` function can be used
|
|
||||||
to create this instruction:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
let instruction = ComputeBudgetInstruction::set_accounts_data_size_limit(100_000);
|
|
||||||
```
|
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
|
|
||||||
As Solana evolves, new features or patches may be introduced that changes the
|
As Solana evolves, new features or patches may be introduced that changes the
|
||||||
|
|
|
@ -14,33 +14,6 @@ pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000;
|
||||||
pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
|
pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
|
||||||
const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
|
const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
|
||||||
|
|
||||||
/// To change `default` and/or `max` values for `accounts_data_size_limit` in the future,
|
|
||||||
/// add new enum type here, link to feature gate, and implement the enum in
|
|
||||||
/// `get_default_loaded_accounts_data_limit()` and/or `get_max_loaded_accounts_data_limit()`.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum LoadedAccountsDataLimitType {
|
|
||||||
V0,
|
|
||||||
// add future versions here
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get default value of `ComputeBudget::accounts_data_size_limit` if not set specifically. It
|
|
||||||
/// sets to 10MB initially, may be changed with feature gate.
|
|
||||||
const DEFAULT_LOADED_ACCOUNTS_DATA_LIMIT: u32 = 10 * 1024 * 1024;
|
|
||||||
pub fn get_default_loaded_accounts_data_limit(limit_type: &LoadedAccountsDataLimitType) -> u32 {
|
|
||||||
match limit_type {
|
|
||||||
LoadedAccountsDataLimitType::V0 => DEFAULT_LOADED_ACCOUNTS_DATA_LIMIT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Get max value of `ComputeBudget::accounts_data_size_limit`, it caps value user
|
|
||||||
/// sets via `ComputeBudgetInstruction::set_compute_unit_limit`. It is set to 100MB
|
|
||||||
/// initially, can be changed with feature gate.
|
|
||||||
const MAX_LOADED_ACCOUNTS_DATA_LIMIT: u32 = 100 * 1024 * 1024;
|
|
||||||
pub fn get_max_loaded_accounts_data_limit(limit_type: &LoadedAccountsDataLimitType) -> u32 {
|
|
||||||
match limit_type {
|
|
||||||
LoadedAccountsDataLimitType::V0 => MAX_LOADED_ACCOUNTS_DATA_LIMIT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget {
|
impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget {
|
||||||
fn example() -> Self {
|
fn example() -> Self {
|
||||||
|
@ -55,8 +28,6 @@ pub struct ComputeBudget {
|
||||||
/// allowed to consume. Compute units are consumed by program execution,
|
/// allowed to consume. Compute units are consumed by program execution,
|
||||||
/// resources they use, etc...
|
/// resources they use, etc...
|
||||||
pub compute_unit_limit: u64,
|
pub compute_unit_limit: u64,
|
||||||
/// Maximum accounts data size, in bytes, that a transaction is allowed to load
|
|
||||||
pub accounts_data_size_limit: u64,
|
|
||||||
/// Number of compute units consumed by a log_u64 call
|
/// Number of compute units consumed by a log_u64 call
|
||||||
pub log_64_units: u64,
|
pub log_64_units: u64,
|
||||||
/// Number of compute units consumed by a create_program_address call
|
/// Number of compute units consumed by a create_program_address call
|
||||||
|
@ -148,7 +119,6 @@ impl ComputeBudget {
|
||||||
pub fn new(compute_unit_limit: u64) -> Self {
|
pub fn new(compute_unit_limit: u64) -> Self {
|
||||||
ComputeBudget {
|
ComputeBudget {
|
||||||
compute_unit_limit,
|
compute_unit_limit,
|
||||||
accounts_data_size_limit: DEFAULT_LOADED_ACCOUNTS_DATA_LIMIT as u64,
|
|
||||||
log_64_units: 100,
|
log_64_units: 100,
|
||||||
create_program_address_units: 1500,
|
create_program_address_units: 1500,
|
||||||
invoke_units: 1000,
|
invoke_units: 1000,
|
||||||
|
@ -192,14 +162,11 @@ impl ComputeBudget {
|
||||||
instructions: impl Iterator<Item = (&'a Pubkey, &'a CompiledInstruction)>,
|
instructions: impl Iterator<Item = (&'a Pubkey, &'a CompiledInstruction)>,
|
||||||
default_units_per_instruction: bool,
|
default_units_per_instruction: bool,
|
||||||
support_request_units_deprecated: bool,
|
support_request_units_deprecated: bool,
|
||||||
cap_transaction_accounts_data_size: bool,
|
|
||||||
loaded_accounts_data_limit_type: LoadedAccountsDataLimitType,
|
|
||||||
) -> Result<PrioritizationFeeDetails, TransactionError> {
|
) -> Result<PrioritizationFeeDetails, TransactionError> {
|
||||||
let mut num_non_compute_budget_instructions: usize = 0;
|
let mut num_non_compute_budget_instructions: usize = 0;
|
||||||
let mut updated_compute_unit_limit = None;
|
let mut updated_compute_unit_limit = None;
|
||||||
let mut requested_heap_size = None;
|
let mut requested_heap_size = None;
|
||||||
let mut prioritization_fee = None;
|
let mut prioritization_fee = None;
|
||||||
let mut updated_accounts_data_size_limit = None;
|
|
||||||
|
|
||||||
for (i, (program_id, instruction)) in instructions.enumerate() {
|
for (i, (program_id, instruction)) in instructions.enumerate() {
|
||||||
if compute_budget::check_id(program_id) {
|
if compute_budget::check_id(program_id) {
|
||||||
|
@ -243,14 +210,6 @@ impl ComputeBudget {
|
||||||
prioritization_fee =
|
prioritization_fee =
|
||||||
Some(PrioritizationFeeType::ComputeUnitPrice(micro_lamports));
|
Some(PrioritizationFeeType::ComputeUnitPrice(micro_lamports));
|
||||||
}
|
}
|
||||||
Ok(ComputeBudgetInstruction::SetAccountsDataSizeLimit(bytes))
|
|
||||||
if cap_transaction_accounts_data_size =>
|
|
||||||
{
|
|
||||||
if updated_accounts_data_size_limit.is_some() {
|
|
||||||
return Err(duplicate_instruction_error);
|
|
||||||
}
|
|
||||||
updated_accounts_data_size_limit = Some(bytes);
|
|
||||||
}
|
|
||||||
_ => return Err(invalid_instruction_data_error),
|
_ => return Err(invalid_instruction_data_error),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -286,14 +245,6 @@ impl ComputeBudget {
|
||||||
.unwrap_or(MAX_COMPUTE_UNIT_LIMIT)
|
.unwrap_or(MAX_COMPUTE_UNIT_LIMIT)
|
||||||
.min(MAX_COMPUTE_UNIT_LIMIT) as u64;
|
.min(MAX_COMPUTE_UNIT_LIMIT) as u64;
|
||||||
|
|
||||||
self.accounts_data_size_limit = updated_accounts_data_size_limit
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
get_default_loaded_accounts_data_limit(&loaded_accounts_data_limit_type)
|
|
||||||
})
|
|
||||||
.min(get_max_loaded_accounts_data_limit(
|
|
||||||
&loaded_accounts_data_limit_type,
|
|
||||||
)) as u64;
|
|
||||||
|
|
||||||
Ok(prioritization_fee
|
Ok(prioritization_fee
|
||||||
.map(|fee_type| PrioritizationFeeDetails::new(fee_type, self.compute_unit_limit))
|
.map(|fee_type| PrioritizationFeeDetails::new(fee_type, self.compute_unit_limit))
|
||||||
.unwrap_or_default())
|
.unwrap_or_default())
|
||||||
|
@ -328,8 +279,6 @@ mod tests {
|
||||||
tx.message().program_instructions_iter(),
|
tx.message().program_instructions_iter(),
|
||||||
true,
|
true,
|
||||||
false, /*not support request_units_deprecated*/
|
false, /*not support request_units_deprecated*/
|
||||||
true, /*supports cap transaction accounts data size feature*/
|
|
||||||
LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
assert_eq!($expected_result, result);
|
assert_eq!($expected_result, result);
|
||||||
assert_eq!(compute_budget, $expected_budget);
|
assert_eq!(compute_budget, $expected_budget);
|
||||||
|
@ -595,84 +544,4 @@ mod tests {
|
||||||
ComputeBudget::default()
|
ComputeBudget::default()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_process_accounts_data_size_limit_instruction() {
|
|
||||||
test!(
|
|
||||||
&[],
|
|
||||||
Ok(PrioritizationFeeDetails::default()),
|
|
||||||
ComputeBudget {
|
|
||||||
compute_unit_limit: 0,
|
|
||||||
..ComputeBudget::default()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
test!(
|
|
||||||
&[
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(1),
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
],
|
|
||||||
Ok(PrioritizationFeeDetails::default()),
|
|
||||||
ComputeBudget {
|
|
||||||
compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64,
|
|
||||||
accounts_data_size_limit: 1,
|
|
||||||
..ComputeBudget::default()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
test!(
|
|
||||||
&[
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(
|
|
||||||
get_max_loaded_accounts_data_limit(&LoadedAccountsDataLimitType::V0) + 1
|
|
||||||
),
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
],
|
|
||||||
Ok(PrioritizationFeeDetails::default()),
|
|
||||||
ComputeBudget {
|
|
||||||
compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64,
|
|
||||||
accounts_data_size_limit: get_max_loaded_accounts_data_limit(
|
|
||||||
&LoadedAccountsDataLimitType::V0
|
|
||||||
) as u64,
|
|
||||||
..ComputeBudget::default()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
test!(
|
|
||||||
&[
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(
|
|
||||||
get_max_loaded_accounts_data_limit(&LoadedAccountsDataLimitType::V0)
|
|
||||||
),
|
|
||||||
],
|
|
||||||
Ok(PrioritizationFeeDetails::default()),
|
|
||||||
ComputeBudget {
|
|
||||||
compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64,
|
|
||||||
accounts_data_size_limit: get_max_loaded_accounts_data_limit(
|
|
||||||
&LoadedAccountsDataLimitType::V0
|
|
||||||
) as u64,
|
|
||||||
..ComputeBudget::default()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
test!(
|
|
||||||
&[
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(1),
|
|
||||||
],
|
|
||||||
Ok(PrioritizationFeeDetails::default()),
|
|
||||||
ComputeBudget {
|
|
||||||
compute_unit_limit: 3 * DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64,
|
|
||||||
accounts_data_size_limit: 1,
|
|
||||||
..ComputeBudget::default()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
test!(
|
|
||||||
&[
|
|
||||||
Instruction::new_with_bincode(Pubkey::new_unique(), &0_u8, vec![]),
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(1),
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(1),
|
|
||||||
],
|
|
||||||
Err(TransactionError::DuplicateInstruction(2)),
|
|
||||||
ComputeBudget::default()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub async fn setup_test_context() -> ProgramTestContext {
|
||||||
|
|
||||||
pub async fn assert_ix_error(
|
pub async fn assert_ix_error(
|
||||||
context: &mut ProgramTestContext,
|
context: &mut ProgramTestContext,
|
||||||
ixs: &[Instruction],
|
ix: Instruction,
|
||||||
additional_payer_keypair: Option<&Keypair>,
|
additional_payer_keypair: Option<&Keypair>,
|
||||||
expected_err: InstructionError,
|
expected_err: InstructionError,
|
||||||
assertion_failed_msg: &str,
|
assertion_failed_msg: &str,
|
||||||
|
@ -36,7 +36,7 @@ pub async fn assert_ix_error(
|
||||||
}
|
}
|
||||||
|
|
||||||
let transaction = Transaction::new_signed_with_payer(
|
let transaction = Transaction::new_signed_with_payer(
|
||||||
ixs,
|
&[ix],
|
||||||
Some(&fee_payer.pubkey()),
|
Some(&fee_payer.pubkey()),
|
||||||
&signers,
|
&signers,
|
||||||
recent_blockhash,
|
recent_blockhash,
|
||||||
|
|
|
@ -5,7 +5,6 @@ use {
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
account::{AccountSharedData, ReadableAccount, WritableAccount},
|
||||||
bpf_loader_upgradeable::{extend_program, id, UpgradeableLoaderState},
|
bpf_loader_upgradeable::{extend_program, id, UpgradeableLoaderState},
|
||||||
compute_budget::ComputeBudgetInstruction,
|
|
||||||
instruction::InstructionError,
|
instruction::InstructionError,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
signature::{Keypair, Signer},
|
signature::{Keypair, Signer},
|
||||||
|
@ -104,7 +103,7 @@ async fn test_extend_program_not_upgradeable() {
|
||||||
let payer_address = context.payer.pubkey();
|
let payer_address = context.payer.pubkey();
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 42)],
|
extend_program(&program_address, Some(&payer_address), 42),
|
||||||
None,
|
None,
|
||||||
InstructionError::Immutable,
|
InstructionError::Immutable,
|
||||||
"should fail because the program data account isn't upgradeable",
|
"should fail because the program data account isn't upgradeable",
|
||||||
|
@ -143,7 +142,7 @@ async fn test_extend_program_by_zero_bytes() {
|
||||||
let payer_address = context.payer.pubkey();
|
let payer_address = context.payer.pubkey();
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 0)],
|
extend_program(&program_address, Some(&payer_address), 0),
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidInstructionData,
|
InstructionError::InvalidInstructionData,
|
||||||
"should fail because the program data account must be extended by more than 0 bytes",
|
"should fail because the program data account must be extended by more than 0 bytes",
|
||||||
|
@ -182,12 +181,7 @@ async fn test_extend_program_past_max_size() {
|
||||||
let payer_address = context.payer.pubkey();
|
let payer_address = context.payer.pubkey();
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[
|
|
||||||
extend_program(&program_address, Some(&payer_address), 1),
|
extend_program(&program_address, Some(&payer_address), 1),
|
||||||
// To request large transaction accounts data size to allow max sized test
|
|
||||||
// instruction being loaded and processed.
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidRealloc,
|
InstructionError::InvalidRealloc,
|
||||||
"should fail because the program data account cannot be extended past the max data size",
|
"should fail because the program data account cannot be extended past the max data size",
|
||||||
|
@ -244,11 +238,11 @@ async fn test_extend_program_with_invalid_payer() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(
|
extend_program(
|
||||||
&program_address,
|
&program_address,
|
||||||
Some(&payer_with_insufficient_funds.pubkey()),
|
Some(&payer_with_insufficient_funds.pubkey()),
|
||||||
1024,
|
1024,
|
||||||
)],
|
),
|
||||||
Some(&payer_with_insufficient_funds),
|
Some(&payer_with_insufficient_funds),
|
||||||
InstructionError::from(SystemError::ResultWithNegativeLamports),
|
InstructionError::from(SystemError::ResultWithNegativeLamports),
|
||||||
"should fail because the payer has insufficient funds to cover program data account rent",
|
"should fail because the payer has insufficient funds to cover program data account rent",
|
||||||
|
@ -257,11 +251,11 @@ async fn test_extend_program_with_invalid_payer() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(
|
extend_program(
|
||||||
&program_address,
|
&program_address,
|
||||||
Some(&payer_with_invalid_owner.pubkey()),
|
Some(&payer_with_invalid_owner.pubkey()),
|
||||||
1,
|
1,
|
||||||
)],
|
),
|
||||||
Some(&payer_with_invalid_owner),
|
Some(&payer_with_invalid_owner),
|
||||||
InstructionError::ExternalAccountLamportSpend,
|
InstructionError::ExternalAccountLamportSpend,
|
||||||
"should fail because the payer is not a system account",
|
"should fail because the payer is not a system account",
|
||||||
|
@ -286,7 +280,7 @@ async fn test_extend_program_with_invalid_payer() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[ix],
|
ix,
|
||||||
None,
|
None,
|
||||||
InstructionError::PrivilegeEscalation,
|
InstructionError::PrivilegeEscalation,
|
||||||
"should fail because the payer did not sign",
|
"should fail because the payer did not sign",
|
||||||
|
@ -326,7 +320,7 @@ async fn test_extend_program_without_payer() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, None, 1024)],
|
extend_program(&program_address, None, 1024),
|
||||||
None,
|
None,
|
||||||
InstructionError::NotEnoughAccountKeys,
|
InstructionError::NotEnoughAccountKeys,
|
||||||
"should fail because program data has insufficient funds to cover rent",
|
"should fail because program data has insufficient funds to cover rent",
|
||||||
|
@ -412,7 +406,7 @@ async fn test_extend_program_with_invalid_system_program() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[ix],
|
ix,
|
||||||
None,
|
None,
|
||||||
InstructionError::MissingAccount,
|
InstructionError::MissingAccount,
|
||||||
"should fail because the system program is missing",
|
"should fail because the system program is missing",
|
||||||
|
@ -465,7 +459,7 @@ async fn test_extend_program_with_mismatch_program_data() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[ix],
|
ix,
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidArgument,
|
InstructionError::InvalidArgument,
|
||||||
"should fail because the program data account doesn't match the program",
|
"should fail because the program data account doesn't match the program",
|
||||||
|
@ -516,7 +510,7 @@ async fn test_extend_program_with_readonly_program_data() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[ix],
|
ix,
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidArgument,
|
InstructionError::InvalidArgument,
|
||||||
"should fail because the program data account is not writable",
|
"should fail because the program data account is not writable",
|
||||||
|
@ -554,7 +548,7 @@ async fn test_extend_program_with_invalid_program_data_state() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 1024)],
|
extend_program(&program_address, Some(&payer_address), 1024),
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidAccountData,
|
InstructionError::InvalidAccountData,
|
||||||
"should fail because the program data account state isn't valid",
|
"should fail because the program data account state isn't valid",
|
||||||
|
@ -595,7 +589,7 @@ async fn test_extend_program_with_invalid_program_data_owner() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 1024)],
|
extend_program(&program_address, Some(&payer_address), 1024),
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidAccountOwner,
|
InstructionError::InvalidAccountOwner,
|
||||||
"should fail because the program data account owner isn't valid",
|
"should fail because the program data account owner isn't valid",
|
||||||
|
@ -646,7 +640,7 @@ async fn test_extend_program_with_readonly_program() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[ix],
|
ix,
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidArgument,
|
InstructionError::InvalidArgument,
|
||||||
"should fail because the program account is not writable",
|
"should fail because the program account is not writable",
|
||||||
|
@ -686,7 +680,7 @@ async fn test_extend_program_with_invalid_program_owner() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 1024)],
|
extend_program(&program_address, Some(&payer_address), 1024),
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidAccountOwner,
|
InstructionError::InvalidAccountOwner,
|
||||||
"should fail because the program account owner isn't valid",
|
"should fail because the program account owner isn't valid",
|
||||||
|
@ -726,7 +720,7 @@ async fn test_extend_program_with_invalid_program_state() {
|
||||||
|
|
||||||
assert_ix_error(
|
assert_ix_error(
|
||||||
&mut context,
|
&mut context,
|
||||||
&[extend_program(&program_address, Some(&payer_address), 1024)],
|
extend_program(&program_address, Some(&payer_address), 1024),
|
||||||
None,
|
None,
|
||||||
InstructionError::InvalidAccountData,
|
InstructionError::InvalidAccountData,
|
||||||
"should fail because the program account state isn't valid",
|
"should fail because the program account state isn't valid",
|
||||||
|
|
|
@ -11,9 +11,7 @@ use {
|
||||||
},
|
},
|
||||||
solana_ledger::token_balances::collect_token_balances,
|
solana_ledger::token_balances::collect_token_balances,
|
||||||
solana_program_runtime::{
|
solana_program_runtime::{
|
||||||
compute_budget::{self, ComputeBudget},
|
compute_budget::ComputeBudget, invoke_context::InvokeContext, timings::ExecuteTimings,
|
||||||
invoke_context::InvokeContext,
|
|
||||||
timings::ExecuteTimings,
|
|
||||||
},
|
},
|
||||||
solana_runtime::{
|
solana_runtime::{
|
||||||
bank::{
|
bank::{
|
||||||
|
@ -2775,17 +2773,13 @@ fn test_program_sbf_realloc() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[realloc_extend_and_fill(
|
||||||
realloc_extend_and_fill(
|
|
||||||
&program_id,
|
&program_id,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
MAX_PERMITTED_DATA_INCREASE,
|
MAX_PERMITTED_DATA_INCREASE,
|
||||||
1,
|
1,
|
||||||
&mut bump,
|
&mut bump,
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -2803,16 +2797,12 @@ fn test_program_sbf_realloc() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[realloc_extend(
|
||||||
realloc_extend(
|
|
||||||
&program_id,
|
&program_id,
|
||||||
&pubkey,
|
&pubkey,
|
||||||
MAX_PERMITTED_DATA_INCREASE,
|
MAX_PERMITTED_DATA_INCREASE,
|
||||||
&mut bump
|
&mut bump
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -2826,10 +2816,7 @@ fn test_program_sbf_realloc() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[realloc(&program_id, &pubkey, 0, &mut bump)],
|
||||||
realloc(&program_id, &pubkey, 0, &mut bump),
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -3033,18 +3020,14 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_REALLOC_MAX_PLUS_ONE],
|
&[INVOKE_REALLOC_MAX_PLUS_ONE],
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new(pubkey, false),
|
AccountMeta::new(pubkey, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -3059,18 +3042,14 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_REALLOC_MAX_TWICE],
|
&[INVOKE_REALLOC_MAX_TWICE],
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new(pubkey, false),
|
AccountMeta::new(pubkey, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -3293,18 +3272,14 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_REALLOC_MAX_INVOKE_MAX],
|
&[INVOKE_REALLOC_MAX_INVOKE_MAX],
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new(invoke_pubkey, false),
|
AccountMeta::new(invoke_pubkey, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -3366,8 +3341,7 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_INVOKE_MAX_TWICE],
|
&[INVOKE_INVOKE_MAX_TWICE],
|
||||||
vec![
|
vec![
|
||||||
|
@ -3375,10 +3349,7 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
AccountMeta::new_readonly(realloc_invoke_program_id, false),
|
AccountMeta::new_readonly(realloc_invoke_program_id, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -3406,18 +3377,14 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_REALLOC_EXTEND_MAX, 1, i as u8, (i / 255) as u8],
|
&[INVOKE_REALLOC_EXTEND_MAX, 1, i as u8, (i / 255) as u8],
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new(pubkey, false),
|
AccountMeta::new(pubkey, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -3435,18 +3402,14 @@ fn test_program_sbf_realloc_invoke() {
|
||||||
.send_and_confirm_message(
|
.send_and_confirm_message(
|
||||||
signer,
|
signer,
|
||||||
Message::new(
|
Message::new(
|
||||||
&[
|
&[Instruction::new_with_bytes(
|
||||||
Instruction::new_with_bytes(
|
|
||||||
realloc_invoke_program_id,
|
realloc_invoke_program_id,
|
||||||
&[INVOKE_REALLOC_EXTEND_MAX, 2, 1, 1],
|
&[INVOKE_REALLOC_EXTEND_MAX, 2, 1, 1],
|
||||||
vec![
|
vec![
|
||||||
AccountMeta::new(pubkey, false),
|
AccountMeta::new(pubkey, false),
|
||||||
AccountMeta::new_readonly(realloc_program_id, false),
|
AccountMeta::new_readonly(realloc_program_id, false),
|
||||||
],
|
],
|
||||||
),
|
)],
|
||||||
// Request max transaction accounts data size to allow large instruction
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&mint_pubkey),
|
Some(&mint_pubkey),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -3611,8 +3574,6 @@ fn test_program_fees() {
|
||||||
&fee_structure,
|
&fee_structure,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
bank_client
|
bank_client
|
||||||
.send_and_confirm_message(&[&mint_keypair], message)
|
.send_and_confirm_message(&[&mint_keypair], message)
|
||||||
|
@ -3635,8 +3596,6 @@ fn test_program_fees() {
|
||||||
&fee_structure,
|
&fee_structure,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
assert!(expected_normal_fee < expected_prioritized_fee);
|
assert!(expected_normal_fee < expected_prioritized_fee);
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,14 @@ use {
|
||||||
dashmap::DashMap,
|
dashmap::DashMap,
|
||||||
log::*,
|
log::*,
|
||||||
solana_address_lookup_table_program::{error::AddressLookupError, state::AddressLookupTable},
|
solana_address_lookup_table_program::{error::AddressLookupError, state::AddressLookupTable},
|
||||||
solana_program_runtime::compute_budget::ComputeBudget,
|
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
|
account::{Account, AccountSharedData, ReadableAccount, WritableAccount},
|
||||||
account_utils::StateMut,
|
account_utils::StateMut,
|
||||||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||||
clock::{BankId, Slot},
|
clock::{BankId, Slot},
|
||||||
feature_set::{
|
feature_set::{
|
||||||
self, cap_transaction_accounts_data_size, remove_deprecated_request_unit_ix,
|
self, remove_deprecated_request_unit_ix, use_default_units_in_fee_calculation,
|
||||||
use_default_units_in_fee_calculation, FeatureSet,
|
FeatureSet,
|
||||||
},
|
},
|
||||||
fee::FeeStructure,
|
fee::FeeStructure,
|
||||||
genesis_config::ClusterType,
|
genesis_config::ClusterType,
|
||||||
|
@ -57,7 +56,6 @@ use {
|
||||||
std::{
|
std::{
|
||||||
cmp::Reverse,
|
cmp::Reverse,
|
||||||
collections::{hash_map, BinaryHeap, HashMap, HashSet},
|
collections::{hash_map, BinaryHeap, HashMap, HashSet},
|
||||||
num::NonZeroUsize,
|
|
||||||
ops::RangeBounds,
|
ops::RangeBounds,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{
|
sync::{
|
||||||
|
@ -262,15 +260,6 @@ impl Accounts {
|
||||||
let account_keys = message.account_keys();
|
let account_keys = message.account_keys();
|
||||||
let mut account_deps = Vec::with_capacity(account_keys.len());
|
let mut account_deps = Vec::with_capacity(account_keys.len());
|
||||||
let mut rent_debits = RentDebits::default();
|
let mut rent_debits = RentDebits::default();
|
||||||
let requested_loaded_accounts_data_size_limit =
|
|
||||||
if feature_set.is_active(&feature_set::cap_transaction_accounts_data_size::id()) {
|
|
||||||
let requested_loaded_accounts_data_size =
|
|
||||||
Self::get_requested_loaded_accounts_data_size_limit(tx, feature_set)?;
|
|
||||||
Some(requested_loaded_accounts_data_size)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let mut accumulated_accounts_data_size: usize = 0;
|
|
||||||
|
|
||||||
let set_exempt_rent_epoch_max =
|
let set_exempt_rent_epoch_max =
|
||||||
feature_set.is_active(&solana_sdk::feature_set::set_exempt_rent_epoch_max::id());
|
feature_set.is_active(&solana_sdk::feature_set::set_exempt_rent_epoch_max::id());
|
||||||
|
@ -278,20 +267,16 @@ impl Accounts {
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, key)| {
|
.map(|(i, key)| {
|
||||||
let (account, loaded_programdata_account_size) = if !message.is_non_loader_key(i) {
|
let account = if !message.is_non_loader_key(i) {
|
||||||
// Fill in an empty account for the program slots.
|
// Fill in an empty account for the program slots.
|
||||||
(AccountSharedData::default(), 0)
|
AccountSharedData::default()
|
||||||
} else {
|
} else {
|
||||||
#[allow(clippy::collapsible_else_if)]
|
#[allow(clippy::collapsible_else_if)]
|
||||||
if solana_sdk::sysvar::instructions::check_id(key) {
|
if solana_sdk::sysvar::instructions::check_id(key) {
|
||||||
(
|
|
||||||
Self::construct_instructions_account(
|
Self::construct_instructions_account(
|
||||||
message,
|
message,
|
||||||
feature_set.is_active(
|
feature_set
|
||||||
&feature_set::instructions_sysvar_owned_by_sysvar::id(),
|
.is_active(&feature_set::instructions_sysvar_owned_by_sysvar::id()),
|
||||||
),
|
|
||||||
),
|
|
||||||
0,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let (mut account, rent) = if let Some(account_override) =
|
let (mut account, rent) = if let Some(account_override) =
|
||||||
|
@ -346,7 +331,6 @@ impl Accounts {
|
||||||
validated_fee_payer = true;
|
validated_fee_payer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut loaded_programdata_account_size: usize = 0;
|
|
||||||
if bpf_loader_upgradeable::check_id(account.owner()) {
|
if bpf_loader_upgradeable::check_id(account.owner()) {
|
||||||
if message.is_writable(i) && !message.is_upgradeable_loader_present() {
|
if message.is_writable(i) && !message.is_upgradeable_loader_present() {
|
||||||
error_counters.invalid_writable_account += 1;
|
error_counters.invalid_writable_account += 1;
|
||||||
|
@ -363,8 +347,6 @@ impl Accounts {
|
||||||
.accounts_db
|
.accounts_db
|
||||||
.load_with_fixed_root(ancestors, &programdata_address)
|
.load_with_fixed_root(ancestors, &programdata_address)
|
||||||
{
|
{
|
||||||
loaded_programdata_account_size =
|
|
||||||
programdata_account.data().len();
|
|
||||||
account_deps
|
account_deps
|
||||||
.push((programdata_address, programdata_account));
|
.push((programdata_address, programdata_account));
|
||||||
} else {
|
} else {
|
||||||
|
@ -384,18 +366,9 @@ impl Accounts {
|
||||||
tx_rent += rent;
|
tx_rent += rent;
|
||||||
rent_debits.insert(key, rent, account.lamports());
|
rent_debits.insert(key, rent, account.lamports());
|
||||||
|
|
||||||
(account, loaded_programdata_account_size)
|
account
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Self::accumulate_and_check_loaded_account_data_size(
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
account
|
|
||||||
.data()
|
|
||||||
.len()
|
|
||||||
.saturating_add(loaded_programdata_account_size),
|
|
||||||
requested_loaded_accounts_data_size_limit,
|
|
||||||
error_counters,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok((*key, account))
|
Ok((*key, account))
|
||||||
})
|
})
|
||||||
|
@ -418,8 +391,6 @@ impl Accounts {
|
||||||
&mut accounts,
|
&mut accounts,
|
||||||
instruction.program_id_index as IndexOfAccount,
|
instruction.program_id_index as IndexOfAccount,
|
||||||
error_counters,
|
error_counters,
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
requested_loaded_accounts_data_size_limit,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<Vec<IndexOfAccount>>>>()?;
|
.collect::<Result<Vec<Vec<IndexOfAccount>>>>()?;
|
||||||
|
@ -436,22 +407,6 @@ impl Accounts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_requested_loaded_accounts_data_size_limit(
|
|
||||||
tx: &SanitizedTransaction,
|
|
||||||
feature_set: &FeatureSet,
|
|
||||||
) -> Result<NonZeroUsize> {
|
|
||||||
let mut compute_budget = ComputeBudget::default();
|
|
||||||
let _prioritization_fee_details = compute_budget.process_instructions(
|
|
||||||
tx.message().program_instructions_iter(),
|
|
||||||
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
|
||||||
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
|
||||||
feature_set.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Bank::get_loaded_accounts_data_limit_type(feature_set),
|
|
||||||
)?;
|
|
||||||
NonZeroUsize::new(compute_budget.accounts_data_size_limit as usize)
|
|
||||||
.ok_or(TransactionError::InvalidLoadedAccountsDataSizeLimit)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_fee_payer(
|
fn validate_fee_payer(
|
||||||
payer_address: &Pubkey,
|
payer_address: &Pubkey,
|
||||||
payer_account: &mut AccountSharedData,
|
payer_account: &mut AccountSharedData,
|
||||||
|
@ -504,17 +459,10 @@ impl Accounts {
|
||||||
accounts: &mut Vec<TransactionAccount>,
|
accounts: &mut Vec<TransactionAccount>,
|
||||||
mut program_account_index: IndexOfAccount,
|
mut program_account_index: IndexOfAccount,
|
||||||
error_counters: &mut TransactionErrorMetrics,
|
error_counters: &mut TransactionErrorMetrics,
|
||||||
accumulated_accounts_data_size: &mut usize,
|
|
||||||
requested_loaded_accounts_data_size_limit: Option<NonZeroUsize>,
|
|
||||||
) -> Result<Vec<IndexOfAccount>> {
|
) -> Result<Vec<IndexOfAccount>> {
|
||||||
let mut account_indices = Vec::new();
|
let mut account_indices = Vec::new();
|
||||||
let (mut program_id, already_loaded_as_non_loader) =
|
let mut program_id = match accounts.get(program_account_index as usize) {
|
||||||
match accounts.get(program_account_index as usize) {
|
Some(program_account) => program_account.0,
|
||||||
Some(program_account) => (
|
|
||||||
program_account.0,
|
|
||||||
// program account is already loaded if it's not empty in `accounts`
|
|
||||||
program_account.1 != AccountSharedData::default(),
|
|
||||||
),
|
|
||||||
None => {
|
None => {
|
||||||
error_counters.account_not_found += 1;
|
error_counters.account_not_found += 1;
|
||||||
return Err(TransactionError::ProgramAccountNotFound);
|
return Err(TransactionError::ProgramAccountNotFound);
|
||||||
|
@ -527,7 +475,6 @@ impl Accounts {
|
||||||
return Err(TransactionError::CallChainTooDeep);
|
return Err(TransactionError::CallChainTooDeep);
|
||||||
}
|
}
|
||||||
depth += 1;
|
depth += 1;
|
||||||
let mut loaded_account_total_size: usize = 0;
|
|
||||||
|
|
||||||
program_account_index = match self
|
program_account_index = match self
|
||||||
.accounts_db
|
.accounts_db
|
||||||
|
@ -535,13 +482,6 @@ impl Accounts {
|
||||||
{
|
{
|
||||||
Some((program_account, _)) => {
|
Some((program_account, _)) => {
|
||||||
let account_index = accounts.len() as IndexOfAccount;
|
let account_index = accounts.len() as IndexOfAccount;
|
||||||
// do not double count account size for program account on top of call chain
|
|
||||||
// that has already been loaded during load_transaction as non-loader account.
|
|
||||||
// Other accounts data size in the call chain are counted.
|
|
||||||
if !(depth == 1 && already_loaded_as_non_loader) {
|
|
||||||
loaded_account_total_size =
|
|
||||||
loaded_account_total_size.saturating_add(program_account.data().len());
|
|
||||||
}
|
|
||||||
accounts.push((program_id, program_account));
|
accounts.push((program_id, program_account));
|
||||||
account_index
|
account_index
|
||||||
}
|
}
|
||||||
|
@ -559,7 +499,6 @@ impl Accounts {
|
||||||
// Add loader to chain
|
// Add loader to chain
|
||||||
let program_owner = *program.owner();
|
let program_owner = *program.owner();
|
||||||
account_indices.insert(0, program_account_index);
|
account_indices.insert(0, program_account_index);
|
||||||
|
|
||||||
if bpf_loader_upgradeable::check_id(&program_owner) {
|
if bpf_loader_upgradeable::check_id(&program_owner) {
|
||||||
// The upgradeable loader requires the derived ProgramData account
|
// The upgradeable loader requires the derived ProgramData account
|
||||||
if let Ok(UpgradeableLoaderState::Program {
|
if let Ok(UpgradeableLoaderState::Program {
|
||||||
|
@ -572,10 +511,6 @@ impl Accounts {
|
||||||
{
|
{
|
||||||
Some((programdata_account, _)) => {
|
Some((programdata_account, _)) => {
|
||||||
let account_index = accounts.len() as IndexOfAccount;
|
let account_index = accounts.len() as IndexOfAccount;
|
||||||
if !(depth == 1 && already_loaded_as_non_loader) {
|
|
||||||
loaded_account_total_size = loaded_account_total_size
|
|
||||||
.saturating_add(programdata_account.data().len());
|
|
||||||
}
|
|
||||||
accounts.push((programdata_address, programdata_account));
|
accounts.push((programdata_address, programdata_account));
|
||||||
account_index
|
account_index
|
||||||
}
|
}
|
||||||
|
@ -590,43 +525,12 @@ impl Accounts {
|
||||||
return Err(TransactionError::InvalidProgramForExecution);
|
return Err(TransactionError::InvalidProgramForExecution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::accumulate_and_check_loaded_account_data_size(
|
|
||||||
accumulated_accounts_data_size,
|
|
||||||
loaded_account_total_size,
|
|
||||||
requested_loaded_accounts_data_size_limit,
|
|
||||||
error_counters,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
program_id = program_owner;
|
program_id = program_owner;
|
||||||
}
|
}
|
||||||
Ok(account_indices)
|
Ok(account_indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accumulate loaded account data size into `accumulated_accounts_data_size`.
|
|
||||||
/// Returns TransactionErr::MaxLoadedAccountsDataSizeExceeded if
|
|
||||||
/// `requested_loaded_accounts_data_size_limit` is specified and
|
|
||||||
/// `accumulated_accounts_data_size` exceeds it.
|
|
||||||
fn accumulate_and_check_loaded_account_data_size(
|
|
||||||
accumulated_loaded_accounts_data_size: &mut usize,
|
|
||||||
account_data_size: usize,
|
|
||||||
requested_loaded_accounts_data_size_limit: Option<NonZeroUsize>,
|
|
||||||
error_counters: &mut TransactionErrorMetrics,
|
|
||||||
) -> Result<()> {
|
|
||||||
if let Some(requested_loaded_accounts_data_size) = requested_loaded_accounts_data_size_limit
|
|
||||||
{
|
|
||||||
*accumulated_loaded_accounts_data_size =
|
|
||||||
accumulated_loaded_accounts_data_size.saturating_add(account_data_size);
|
|
||||||
if *accumulated_loaded_accounts_data_size > requested_loaded_accounts_data_size.get() {
|
|
||||||
error_counters.max_loaded_accounts_data_size_exceeded += 1;
|
|
||||||
Err(TransactionError::MaxLoadedAccountsDataSizeExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn load_accounts(
|
pub fn load_accounts(
|
||||||
&self,
|
&self,
|
||||||
|
@ -657,8 +561,6 @@ impl Accounts {
|
||||||
fee_structure,
|
fee_structure,
|
||||||
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
||||||
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
feature_set.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Bank::get_loaded_accounts_data_limit_type(feature_set),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return (Err(TransactionError::BlockhashNotFound), None);
|
return (Err(TransactionError::BlockhashNotFound), None);
|
||||||
|
@ -1461,7 +1363,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
assert_matches::assert_matches,
|
assert_matches::assert_matches,
|
||||||
solana_address_lookup_table_program::state::LookupTableMeta,
|
solana_address_lookup_table_program::state::LookupTableMeta,
|
||||||
solana_program_runtime::{compute_budget, executor_cache::TransactionExecutorCache},
|
solana_program_runtime::executor_cache::TransactionExecutorCache,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
account::{AccountSharedData, WritableAccount},
|
account::{AccountSharedData, WritableAccount},
|
||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
|
@ -1737,8 +1639,6 @@ mod tests {
|
||||||
&FeeStructure::default(),
|
&FeeStructure::default(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
assert_eq!(fee, lamports_per_signature);
|
assert_eq!(fee, lamports_per_signature);
|
||||||
|
|
||||||
|
@ -2564,8 +2464,6 @@ mod tests {
|
||||||
&mut vec![(keypair.pubkey(), account)],
|
&mut vec![(keypair.pubkey(), account)],
|
||||||
0,
|
0,
|
||||||
&mut error_counters,
|
&mut error_counters,
|
||||||
&mut 0,
|
|
||||||
None,
|
|
||||||
),
|
),
|
||||||
Err(TransactionError::ProgramAccountNotFound)
|
Err(TransactionError::ProgramAccountNotFound)
|
||||||
);
|
);
|
||||||
|
@ -3995,228 +3893,4 @@ mod tests {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_accumulate_and_check_loaded_account_data_size() {
|
|
||||||
let mut error_counter = TransactionErrorMetrics::default();
|
|
||||||
|
|
||||||
// assert check is OK if data limit is not enabled
|
|
||||||
{
|
|
||||||
let mut accumulated_data_size: usize = 0;
|
|
||||||
let data_size = usize::MAX;
|
|
||||||
let requested_data_size_limit = None;
|
|
||||||
|
|
||||||
assert!(Accounts::accumulate_and_check_loaded_account_data_size(
|
|
||||||
&mut accumulated_data_size,
|
|
||||||
data_size,
|
|
||||||
requested_data_size_limit,
|
|
||||||
&mut error_counter
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert accounts are accumulated and check properly
|
|
||||||
{
|
|
||||||
let mut accumulated_data_size: usize = 0;
|
|
||||||
let data_size: usize = 123;
|
|
||||||
let requested_data_size_limit = NonZeroUsize::new(data_size);
|
|
||||||
|
|
||||||
// OK
|
|
||||||
assert!(Accounts::accumulate_and_check_loaded_account_data_size(
|
|
||||||
&mut accumulated_data_size,
|
|
||||||
data_size,
|
|
||||||
requested_data_size_limit,
|
|
||||||
&mut error_counter
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert_eq!(data_size, accumulated_data_size);
|
|
||||||
|
|
||||||
// exceeds
|
|
||||||
let another_byte: usize = 1;
|
|
||||||
assert_eq!(
|
|
||||||
Accounts::accumulate_and_check_loaded_account_data_size(
|
|
||||||
&mut accumulated_data_size,
|
|
||||||
another_byte,
|
|
||||||
requested_data_size_limit,
|
|
||||||
&mut error_counter
|
|
||||||
),
|
|
||||||
Err(TransactionError::MaxLoadedAccountsDataSizeExceeded)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_load_executable_accounts() {
|
|
||||||
solana_logger::setup();
|
|
||||||
let accounts = Accounts::new_with_config_for_tests(
|
|
||||||
Vec::new(),
|
|
||||||
&ClusterType::Development,
|
|
||||||
AccountSecondaryIndexes::default(),
|
|
||||||
AccountShrinkThreshold::default(),
|
|
||||||
);
|
|
||||||
let mut error_counters = TransactionErrorMetrics::default();
|
|
||||||
let ancestors = vec![(0, 0)].into_iter().collect();
|
|
||||||
|
|
||||||
let space: usize = 9;
|
|
||||||
let keypair = Keypair::new();
|
|
||||||
let mut account = AccountSharedData::new(1, space, &native_loader::id());
|
|
||||||
account.set_executable(true);
|
|
||||||
accounts.store_for_tests(0, &keypair.pubkey(), &account);
|
|
||||||
|
|
||||||
let mut accumulated_accounts_data_size: usize = 0;
|
|
||||||
let mut expect_accumulated_accounts_data_size: usize;
|
|
||||||
|
|
||||||
// test: program account has been loaded as non-loader, load_executable_accounts
|
|
||||||
// will not double count its data size
|
|
||||||
{
|
|
||||||
let mut loaded_accounts = vec![(keypair.pubkey(), account)];
|
|
||||||
accumulated_accounts_data_size += space;
|
|
||||||
expect_accumulated_accounts_data_size = accumulated_accounts_data_size;
|
|
||||||
assert!(accounts
|
|
||||||
.load_executable_accounts(
|
|
||||||
&ancestors,
|
|
||||||
&mut loaded_accounts,
|
|
||||||
0,
|
|
||||||
&mut error_counters,
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
NonZeroUsize::new(expect_accumulated_accounts_data_size),
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
expect_accumulated_accounts_data_size,
|
|
||||||
accumulated_accounts_data_size
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test: program account has not been loaded cause it's loader, load_executable_accounts
|
|
||||||
// will accumulate its data size
|
|
||||||
{
|
|
||||||
let mut loaded_accounts = vec![(keypair.pubkey(), AccountSharedData::default())];
|
|
||||||
expect_accumulated_accounts_data_size = accumulated_accounts_data_size + space;
|
|
||||||
assert!(accounts
|
|
||||||
.load_executable_accounts(
|
|
||||||
&ancestors,
|
|
||||||
&mut loaded_accounts,
|
|
||||||
0,
|
|
||||||
&mut error_counters,
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
NonZeroUsize::new(expect_accumulated_accounts_data_size),
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
expect_accumulated_accounts_data_size,
|
|
||||||
accumulated_accounts_data_size
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test: try to load one more account will accumulate additional `space` bytes, therefore
|
|
||||||
// exceed limit of `expect_accumulated_accounts_data_size` set above.
|
|
||||||
{
|
|
||||||
let mut loaded_accounts = vec![(keypair.pubkey(), AccountSharedData::default())];
|
|
||||||
assert_eq!(
|
|
||||||
accounts.load_executable_accounts(
|
|
||||||
&ancestors,
|
|
||||||
&mut loaded_accounts,
|
|
||||||
0,
|
|
||||||
&mut error_counters,
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
NonZeroUsize::new(expect_accumulated_accounts_data_size),
|
|
||||||
),
|
|
||||||
Err(TransactionError::MaxLoadedAccountsDataSizeExceeded)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_load_executable_accounts_with_upgradeable_program() {
|
|
||||||
solana_logger::setup();
|
|
||||||
let accounts = Accounts::new_with_config_for_tests(
|
|
||||||
Vec::new(),
|
|
||||||
&ClusterType::Development,
|
|
||||||
AccountSecondaryIndexes::default(),
|
|
||||||
AccountShrinkThreshold::default(),
|
|
||||||
);
|
|
||||||
let mut error_counters = TransactionErrorMetrics::default();
|
|
||||||
let ancestors = vec![(0, 0)].into_iter().collect();
|
|
||||||
|
|
||||||
// call chain: native_loader -> key0 -> upgradeable bpf loader -> program_key (that has programdata_key)
|
|
||||||
let programdata_key = Pubkey::new(&[3u8; 32]);
|
|
||||||
let program_data = UpgradeableLoaderState::ProgramData {
|
|
||||||
slot: 0,
|
|
||||||
upgrade_authority_address: None,
|
|
||||||
};
|
|
||||||
let mut program_data_account =
|
|
||||||
AccountSharedData::new_data(1, &program_data, &Pubkey::default()).unwrap();
|
|
||||||
let program_data_account_size = program_data_account.data().len();
|
|
||||||
program_data_account.set_executable(true);
|
|
||||||
program_data_account.set_rent_epoch(0);
|
|
||||||
accounts.store_for_tests(0, &programdata_key, &program_data_account);
|
|
||||||
|
|
||||||
let program_key = Pubkey::new(&[2u8; 32]);
|
|
||||||
let program = UpgradeableLoaderState::Program {
|
|
||||||
programdata_address: programdata_key,
|
|
||||||
};
|
|
||||||
let mut program_account =
|
|
||||||
AccountSharedData::new_data(1, &program, &bpf_loader_upgradeable::id()).unwrap();
|
|
||||||
let program_account_size = program_account.data().len();
|
|
||||||
program_account.set_executable(true);
|
|
||||||
program_account.set_rent_epoch(0);
|
|
||||||
accounts.store_for_tests(0, &program_key, &program_account);
|
|
||||||
|
|
||||||
let key0 = Pubkey::new(&[1u8; 32]);
|
|
||||||
let mut bpf_loader_account = AccountSharedData::new(1, 0, &key0);
|
|
||||||
bpf_loader_account.set_executable(true);
|
|
||||||
accounts.store_for_tests(0, &bpf_loader_upgradeable::id(), &bpf_loader_account);
|
|
||||||
|
|
||||||
let space: usize = 9;
|
|
||||||
let mut account = AccountSharedData::new(1, space, &native_loader::id());
|
|
||||||
account.set_executable(true);
|
|
||||||
accounts.store_for_tests(0, &key0, &account);
|
|
||||||
|
|
||||||
// test: program_key account has been loaded as non-loader, load_executable_accounts
|
|
||||||
// will not double count its data size, but still accumulate data size from
|
|
||||||
// callchain
|
|
||||||
{
|
|
||||||
let expect_accumulated_accounts_data_size: usize = space;
|
|
||||||
let mut accumulated_accounts_data_size: usize = 0;
|
|
||||||
let mut loaded_accounts = vec![(program_key, program_account)];
|
|
||||||
assert!(accounts
|
|
||||||
.load_executable_accounts(
|
|
||||||
&ancestors,
|
|
||||||
&mut loaded_accounts,
|
|
||||||
0,
|
|
||||||
&mut error_counters,
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
NonZeroUsize::new(expect_accumulated_accounts_data_size),
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
expect_accumulated_accounts_data_size,
|
|
||||||
accumulated_accounts_data_size
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test: program account has not been loaded cause it's loader, load_executable_accounts
|
|
||||||
// will accumulate entire callchain data size.
|
|
||||||
{
|
|
||||||
let mut loaded_accounts = vec![(program_key, AccountSharedData::default())];
|
|
||||||
let mut accumulated_accounts_data_size: usize = 0;
|
|
||||||
let expect_accumulated_accounts_data_size =
|
|
||||||
program_account_size + program_data_account_size + space;
|
|
||||||
assert!(accounts
|
|
||||||
.load_executable_accounts(
|
|
||||||
&ancestors,
|
|
||||||
&mut loaded_accounts,
|
|
||||||
0,
|
|
||||||
&mut error_counters,
|
|
||||||
&mut accumulated_accounts_data_size,
|
|
||||||
NonZeroUsize::new(expect_accumulated_accounts_data_size),
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert_eq!(
|
|
||||||
expect_accumulated_accounts_data_size,
|
|
||||||
accumulated_accounts_data_size
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,9 +119,8 @@ use {
|
||||||
epoch_schedule::EpochSchedule,
|
epoch_schedule::EpochSchedule,
|
||||||
feature,
|
feature,
|
||||||
feature_set::{
|
feature_set::{
|
||||||
self, cap_transaction_accounts_data_size, disable_fee_calculator,
|
self, disable_fee_calculator, enable_early_verification_of_account_modifications,
|
||||||
enable_early_verification_of_account_modifications, remove_deprecated_request_unit_ix,
|
remove_deprecated_request_unit_ix, use_default_units_in_fee_calculation, FeatureSet,
|
||||||
use_default_units_in_fee_calculation, FeatureSet,
|
|
||||||
},
|
},
|
||||||
fee::FeeStructure,
|
fee::FeeStructure,
|
||||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||||
|
@ -279,7 +278,7 @@ impl RentDebits {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type BankStatusCache = StatusCache<Result<()>>;
|
pub type BankStatusCache = StatusCache<Result<()>>;
|
||||||
#[frozen_abi(digest = "3qia1Zm8X66bzFaBuC8ahz3hADRRATyUPRV36ZzrSois")]
|
#[frozen_abi(digest = "A7T7XohiSoo8FGoCPTsaXAYYugXTkoYnBjQAdBgYHH85")]
|
||||||
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
pub type BankSlotDelta = SlotDelta<Result<()>>;
|
||||||
|
|
||||||
// Eager rent collection repeats in cyclic manner.
|
// Eager rent collection repeats in cyclic manner.
|
||||||
|
@ -3439,9 +3438,6 @@ impl Bank {
|
||||||
!self
|
!self
|
||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
self.feature_set
|
|
||||||
.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Self::get_loaded_accounts_data_limit_type(&self.feature_set),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3486,9 +3482,6 @@ impl Bank {
|
||||||
!self
|
!self
|
||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
self.feature_set
|
|
||||||
.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Self::get_loaded_accounts_data_limit_type(&self.feature_set),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4395,9 +4388,6 @@ impl Bank {
|
||||||
!self
|
!self
|
||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
self.feature_set
|
|
||||||
.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Self::get_loaded_accounts_data_limit_type(&self.feature_set),
|
|
||||||
);
|
);
|
||||||
compute_budget_process_transaction_time.stop();
|
compute_budget_process_transaction_time.stop();
|
||||||
saturating_add_assign!(
|
saturating_add_assign!(
|
||||||
|
@ -4690,8 +4680,6 @@ impl Bank {
|
||||||
fee_structure: &FeeStructure,
|
fee_structure: &FeeStructure,
|
||||||
use_default_units_per_instruction: bool,
|
use_default_units_per_instruction: bool,
|
||||||
support_request_units_deprecated: bool,
|
support_request_units_deprecated: bool,
|
||||||
cap_transaction_accounts_data_size: bool,
|
|
||||||
loaded_accounts_data_limit_type: compute_budget::LoadedAccountsDataLimitType,
|
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
// Fee based on compute units and signatures
|
// Fee based on compute units and signatures
|
||||||
const BASE_CONGESTION: f64 = 5_000.0;
|
const BASE_CONGESTION: f64 = 5_000.0;
|
||||||
|
@ -4708,8 +4696,6 @@ impl Bank {
|
||||||
message.program_instructions_iter(),
|
message.program_instructions_iter(),
|
||||||
use_default_units_per_instruction,
|
use_default_units_per_instruction,
|
||||||
support_request_units_deprecated,
|
support_request_units_deprecated,
|
||||||
cap_transaction_accounts_data_size,
|
|
||||||
loaded_accounts_data_limit_type,
|
|
||||||
)
|
)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let prioritization_fee = prioritization_fee_details.get_fee();
|
let prioritization_fee = prioritization_fee_details.get_fee();
|
||||||
|
@ -4778,9 +4764,6 @@ impl Bank {
|
||||||
!self
|
!self
|
||||||
.feature_set
|
.feature_set
|
||||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
self.feature_set
|
|
||||||
.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Self::get_loaded_accounts_data_limit_type(&self.feature_set),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// In case of instruction error, even though no accounts
|
// In case of instruction error, even though no accounts
|
||||||
|
@ -7756,17 +7739,6 @@ impl Bank {
|
||||||
&mut error_counters,
|
&mut error_counters,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// if the `default` and/or `max` value for ComputeBudget:::Accounts_data_size_limit changes,
|
|
||||||
/// the change needs to be gated by feature gate with corresponding new enum value.
|
|
||||||
/// should use this function to get correct loaded_accounts_data_limit_type based on
|
|
||||||
/// feature_set.
|
|
||||||
pub fn get_loaded_accounts_data_limit_type(
|
|
||||||
_feature_set: &FeatureSet,
|
|
||||||
) -> compute_budget::LoadedAccountsDataLimitType {
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0
|
|
||||||
// In the future, use feature_set to determine correct LoadedAccountsDataLimitType here.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute how much an account has changed size. This function is useful when the data size delta
|
/// Compute how much an account has changed size. This function is useful when the data size delta
|
||||||
|
@ -10956,8 +10928,6 @@ pub(crate) mod tests {
|
||||||
&FeeStructure::default(),
|
&FeeStructure::default(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (expected_fee_collected, expected_fee_burned) =
|
let (expected_fee_collected, expected_fee_burned) =
|
||||||
|
@ -11139,8 +11109,6 @@ pub(crate) mod tests {
|
||||||
&FeeStructure::default(),
|
&FeeStructure::default(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_balance(&mint_keypair.pubkey()),
|
bank.get_balance(&mint_keypair.pubkey()),
|
||||||
|
@ -11159,8 +11127,6 @@ pub(crate) mod tests {
|
||||||
&FeeStructure::default(),
|
&FeeStructure::default(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bank.get_balance(&mint_keypair.pubkey()),
|
bank.get_balance(&mint_keypair.pubkey()),
|
||||||
|
@ -11277,8 +11243,6 @@ pub(crate) mod tests {
|
||||||
&FeeStructure::default(),
|
&FeeStructure::default(),
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
) * 2
|
) * 2
|
||||||
)
|
)
|
||||||
.0
|
.0
|
||||||
|
@ -18454,7 +18418,6 @@ pub(crate) mod tests {
|
||||||
// Default: no fee.
|
// Default: no fee.
|
||||||
let message =
|
let message =
|
||||||
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(
|
||||||
&message,
|
&message,
|
||||||
|
@ -18465,15 +18428,11 @@ pub(crate) mod tests {
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
),
|
),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// One signature, a fee.
|
// One signature, a fee.
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(
|
||||||
&message,
|
&message,
|
||||||
|
@ -18484,12 +18443,9 @@ pub(crate) mod tests {
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
),
|
),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Two signatures, double the fee.
|
// Two signatures, double the fee.
|
||||||
let key0 = Pubkey::new_unique();
|
let key0 = Pubkey::new_unique();
|
||||||
|
@ -18497,7 +18453,6 @@ pub(crate) mod tests {
|
||||||
let ix0 = system_instruction::transfer(&key0, &key1, 1);
|
let ix0 = system_instruction::transfer(&key0, &key1, 1);
|
||||||
let ix1 = system_instruction::transfer(&key1, &key0, 1);
|
let ix1 = system_instruction::transfer(&key1, &key0, 1);
|
||||||
let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap();
|
let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(
|
||||||
&message,
|
&message,
|
||||||
|
@ -18508,13 +18463,10 @@ pub(crate) mod tests {
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
),
|
),
|
||||||
4
|
4
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_fee_compute_units() {
|
fn test_calculate_fee_compute_units() {
|
||||||
|
@ -18529,20 +18481,10 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
let message =
|
let message =
|
||||||
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(&message, 1, &fee_structure, true, false),
|
||||||
&message,
|
|
||||||
1,
|
|
||||||
&fee_structure,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0
|
|
||||||
),
|
|
||||||
max_fee + lamports_per_signature
|
max_fee + lamports_per_signature
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Three signatures, two instructions, no unit request
|
// Three signatures, two instructions, no unit request
|
||||||
|
|
||||||
|
@ -18551,20 +18493,10 @@ pub(crate) mod tests {
|
||||||
let message =
|
let message =
|
||||||
SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&Pubkey::new_unique())))
|
SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&Pubkey::new_unique())))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(&message, 1, &fee_structure, true, false),
|
||||||
&message,
|
|
||||||
1,
|
|
||||||
&fee_structure,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0
|
|
||||||
),
|
|
||||||
max_fee + 3 * lamports_per_signature
|
max_fee + 3 * lamports_per_signature
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Explicit fee schedule
|
// Explicit fee schedule
|
||||||
|
|
||||||
|
@ -18595,23 +18527,13 @@ pub(crate) mod tests {
|
||||||
Some(&Pubkey::new_unique()),
|
Some(&Pubkey::new_unique()),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
let fee = Bank::calculate_fee(&message, 1, &fee_structure, true, false);
|
||||||
let fee = Bank::calculate_fee(
|
|
||||||
&message,
|
|
||||||
1,
|
|
||||||
&fee_structure,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0,
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
fee,
|
fee,
|
||||||
lamports_per_signature + prioritization_fee_details.get_fee()
|
lamports_per_signature + prioritization_fee_details.get_fee()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_calculate_fee_secp256k1() {
|
fn test_calculate_fee_secp256k1() {
|
||||||
|
@ -18643,20 +18565,10 @@ pub(crate) mod tests {
|
||||||
Some(&key0),
|
Some(&key0),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(&message, 1, &fee_structure, true, false),
|
||||||
&message,
|
|
||||||
1,
|
|
||||||
&fee_structure,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0
|
|
||||||
),
|
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
secp_instruction1.data = vec![0];
|
secp_instruction1.data = vec![0];
|
||||||
secp_instruction2.data = vec![10];
|
secp_instruction2.data = vec![10];
|
||||||
|
@ -18665,21 +18577,11 @@ pub(crate) mod tests {
|
||||||
Some(&key0),
|
Some(&key0),
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for cap_transaction_accounts_data_size in &[true, false] {
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Bank::calculate_fee(
|
Bank::calculate_fee(&message, 1, &fee_structure, true, false),
|
||||||
&message,
|
|
||||||
1,
|
|
||||||
&fee_structure,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
*cap_transaction_accounts_data_size,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0
|
|
||||||
),
|
|
||||||
11
|
11
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_an_empty_instruction_without_program() {
|
fn test_an_empty_instruction_without_program() {
|
||||||
|
@ -19670,10 +19572,7 @@ pub(crate) mod tests {
|
||||||
account_metas,
|
account_metas,
|
||||||
);
|
);
|
||||||
Transaction::new_signed_with_payer(
|
Transaction::new_signed_with_payer(
|
||||||
&[
|
&[instruction],
|
||||||
instruction,
|
|
||||||
ComputeBudgetInstruction::set_accounts_data_size_limit(u32::MAX),
|
|
||||||
],
|
|
||||||
Some(&payer.pubkey()),
|
Some(&payer.pubkey()),
|
||||||
&[payer],
|
&[payer],
|
||||||
recent_blockhash,
|
recent_blockhash,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{bank::Bank, block_cost_limits::*},
|
crate::block_cost_limits::*,
|
||||||
log::*,
|
log::*,
|
||||||
solana_program_runtime::compute_budget::{
|
solana_program_runtime::compute_budget::{
|
||||||
ComputeBudget, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
|
ComputeBudget, DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT,
|
||||||
|
@ -14,8 +14,7 @@ use {
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
compute_budget,
|
compute_budget,
|
||||||
feature_set::{
|
feature_set::{
|
||||||
cap_transaction_accounts_data_size, remove_deprecated_request_unit_ix,
|
remove_deprecated_request_unit_ix, use_default_units_in_fee_calculation, FeatureSet,
|
||||||
use_default_units_in_fee_calculation, FeatureSet,
|
|
||||||
},
|
},
|
||||||
instruction::CompiledInstruction,
|
instruction::CompiledInstruction,
|
||||||
program_utils::limited_deserialize,
|
program_utils::limited_deserialize,
|
||||||
|
@ -152,8 +151,6 @@ impl CostModel {
|
||||||
transaction.message().program_instructions_iter(),
|
transaction.message().program_instructions_iter(),
|
||||||
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
||||||
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||||
feature_set.is_active(&cap_transaction_accounts_data_size::id()),
|
|
||||||
Bank::get_loaded_accounts_data_limit_type(feature_set),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// if tx contained user-space instructions and a more accurate estimate available correct it
|
// if tx contained user-space instructions and a more accurate estimate available correct it
|
||||||
|
|
|
@ -23,8 +23,6 @@ pub struct TransactionErrorMetrics {
|
||||||
pub would_exceed_max_account_cost_limit: usize,
|
pub would_exceed_max_account_cost_limit: usize,
|
||||||
pub would_exceed_max_vote_cost_limit: usize,
|
pub would_exceed_max_vote_cost_limit: usize,
|
||||||
pub would_exceed_account_data_block_limit: usize,
|
pub would_exceed_account_data_block_limit: usize,
|
||||||
pub max_loaded_accounts_data_size_exceeded: usize,
|
|
||||||
pub invalid_loaded_accounts_data_size_limit: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionErrorMetrics {
|
impl TransactionErrorMetrics {
|
||||||
|
@ -78,14 +76,6 @@ impl TransactionErrorMetrics {
|
||||||
self.would_exceed_account_data_block_limit,
|
self.would_exceed_account_data_block_limit,
|
||||||
other.would_exceed_account_data_block_limit
|
other.would_exceed_account_data_block_limit
|
||||||
);
|
);
|
||||||
saturating_add_assign!(
|
|
||||||
self.max_loaded_accounts_data_size_exceeded,
|
|
||||||
other.max_loaded_accounts_data_size_exceeded
|
|
||||||
);
|
|
||||||
saturating_add_assign!(
|
|
||||||
self.invalid_loaded_accounts_data_size_limit,
|
|
||||||
other.invalid_loaded_accounts_data_size_limit
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report(&self, id: u32, slot: Slot) {
|
pub fn report(&self, id: u32, slot: Slot) {
|
||||||
|
@ -162,16 +152,6 @@ impl TransactionErrorMetrics {
|
||||||
self.would_exceed_account_data_block_limit as i64,
|
self.would_exceed_account_data_block_limit as i64,
|
||||||
i64
|
i64
|
||||||
),
|
),
|
||||||
(
|
|
||||||
"max_loaded_accounts_data_size_exceeded",
|
|
||||||
self.max_loaded_accounts_data_size_exceeded as i64,
|
|
||||||
i64
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"invalid_loaded_accounts_data_size_limit",
|
|
||||||
self.invalid_loaded_accounts_data_size_limit as i64,
|
|
||||||
i64
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use {
|
use {
|
||||||
solana_program_runtime::compute_budget::{self, ComputeBudget},
|
solana_program_runtime::compute_budget::ComputeBudget,
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
instruction::CompiledInstruction,
|
instruction::CompiledInstruction,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
@ -25,9 +25,6 @@ pub trait GetTransactionPriorityDetails {
|
||||||
instructions,
|
instructions,
|
||||||
true, // use default units per instruction
|
true, // use default units per instruction
|
||||||
false, // stop supporting prioritization by request_units_deprecated instruction
|
false, // stop supporting prioritization by request_units_deprecated instruction
|
||||||
false, //transaction priority doesn't care about accounts data size limit,
|
|
||||||
compute_budget::LoadedAccountsDataLimitType::V0, // transaction priority doesn't
|
|
||||||
// care about accounts data size limit.
|
|
||||||
)
|
)
|
||||||
.ok()?;
|
.ok()?;
|
||||||
Some(TransactionPriorityDetails {
|
Some(TransactionPriorityDetails {
|
||||||
|
|
|
@ -41,8 +41,6 @@ pub enum ComputeBudgetInstruction {
|
||||||
/// Set a compute unit price in "micro-lamports" to pay a higher transaction
|
/// Set a compute unit price in "micro-lamports" to pay a higher transaction
|
||||||
/// fee for higher transaction prioritization.
|
/// fee for higher transaction prioritization.
|
||||||
SetComputeUnitPrice(u64),
|
SetComputeUnitPrice(u64),
|
||||||
/// Set a specific transaction-wide account data size limit, in bytes, is allowed to allocate.
|
|
||||||
SetAccountsDataSizeLimit(u32),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComputeBudgetInstruction {
|
impl ComputeBudgetInstruction {
|
||||||
|
@ -61,11 +59,6 @@ impl ComputeBudgetInstruction {
|
||||||
Instruction::new_with_borsh(id(), &Self::SetComputeUnitPrice(micro_lamports), vec![])
|
Instruction::new_with_borsh(id(), &Self::SetComputeUnitPrice(micro_lamports), vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a `ComputeBudgetInstruction::SetAccountsDataSizeLimit` `Instruction`
|
|
||||||
pub fn set_accounts_data_size_limit(bytes: u32) -> Instruction {
|
|
||||||
Instruction::new_with_borsh(id(), &Self::SetAccountsDataSizeLimit(bytes), vec![])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Serialize Instruction using borsh, this is only used in runtime::cost_model::tests but compilation
|
/// Serialize Instruction using borsh, this is only used in runtime::cost_model::tests but compilation
|
||||||
/// can't be restricted as it's used across packages
|
/// can't be restricted as it's used across packages
|
||||||
// #[cfg(test)]
|
// #[cfg(test)]
|
||||||
|
|
|
@ -550,10 +550,6 @@ pub mod enable_bpf_loader_set_authority_checked_ix {
|
||||||
solana_sdk::declare_id!("5x3825XS7M2A3Ekbn5VGGkvFoAg5qrRWkTrY4bARP1GL");
|
solana_sdk::declare_id!("5x3825XS7M2A3Ekbn5VGGkvFoAg5qrRWkTrY4bARP1GL");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod cap_transaction_accounts_data_size {
|
|
||||||
solana_sdk::declare_id!("DdLwVYuvDz26JohmgSbA7mjpJFgX5zP2dkp8qsF2C33V");
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod enable_alt_bn128_syscall {
|
pub mod enable_alt_bn128_syscall {
|
||||||
solana_sdk::declare_id!("A16q37opZdQMCbe5qJ6xpBB9usykfv8jZaMkxvZQi4GJ");
|
solana_sdk::declare_id!("A16q37opZdQMCbe5qJ6xpBB9usykfv8jZaMkxvZQi4GJ");
|
||||||
}
|
}
|
||||||
|
@ -722,7 +718,6 @@ lazy_static! {
|
||||||
(limit_max_instruction_trace_length::id(), "limit max instruction trace length #27939"),
|
(limit_max_instruction_trace_length::id(), "limit max instruction trace length #27939"),
|
||||||
(check_syscall_outputs_do_not_overlap::id(), "check syscall outputs do_not overlap #28600"),
|
(check_syscall_outputs_do_not_overlap::id(), "check syscall outputs do_not overlap #28600"),
|
||||||
(enable_bpf_loader_set_authority_checked_ix::id(), "enable bpf upgradeable loader SetAuthorityChecked instruction #28424"),
|
(enable_bpf_loader_set_authority_checked_ix::id(), "enable bpf upgradeable loader SetAuthorityChecked instruction #28424"),
|
||||||
(cap_transaction_accounts_data_size::id(), "cap transaction accounts data size up to its compute unit limits #27839"),
|
|
||||||
(enable_alt_bn128_syscall::id(), "add alt_bn128 syscalls #27961"),
|
(enable_alt_bn128_syscall::id(), "add alt_bn128 syscalls #27961"),
|
||||||
(enable_program_redeployment_cooldown::id(), "enable program redeployment cooldown #29135"),
|
(enable_program_redeployment_cooldown::id(), "enable program redeployment cooldown #29135"),
|
||||||
(commission_updates_only_allowed_in_first_half_of_epoch::id(), "validator commission updates are only allowed in the first half of an epoch #29362"),
|
(commission_updates_only_allowed_in_first_half_of_epoch::id(), "validator commission updates are only allowed in the first half of an epoch #29362"),
|
||||||
|
|
|
@ -149,16 +149,6 @@ pub enum TransactionError {
|
||||||
"Transaction results in an account ({account_index}) with insufficient funds for rent"
|
"Transaction results in an account ({account_index}) with insufficient funds for rent"
|
||||||
)]
|
)]
|
||||||
InsufficientFundsForRent { account_index: u8 },
|
InsufficientFundsForRent { account_index: u8 },
|
||||||
|
|
||||||
/// Transaction exceeded max loaded accounts data size capped by requested compute units
|
|
||||||
#[error(
|
|
||||||
"Transaction exceeded max loaded accounts data size capped by requested compute units"
|
|
||||||
)]
|
|
||||||
MaxLoadedAccountsDataSizeExceeded,
|
|
||||||
|
|
||||||
/// LoadedAccountsDataSizeLimit set for transaction must be greater than 0.
|
|
||||||
#[error("LoadedAccountsDataSizeLimit set for transaction must be greater than 0.")]
|
|
||||||
InvalidLoadedAccountsDataSizeLimit,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SanitizeError> for TransactionError {
|
impl From<SanitizeError> for TransactionError {
|
||||||
|
|
|
@ -57,8 +57,6 @@ enum TransactionErrorType {
|
||||||
WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT = 29;
|
WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT = 29;
|
||||||
DUPLICATE_INSTRUCTION = 30;
|
DUPLICATE_INSTRUCTION = 30;
|
||||||
INSUFFICIENT_FUNDS_FOR_RENT = 31;
|
INSUFFICIENT_FUNDS_FOR_RENT = 31;
|
||||||
MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED = 32;
|
|
||||||
INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT = 33;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message InstructionError {
|
message InstructionError {
|
||||||
|
|
|
@ -793,8 +793,6 @@ impl TryFrom<tx_by_addr::TransactionError> for TransactionError {
|
||||||
27 => TransactionError::InvalidRentPayingAccount,
|
27 => TransactionError::InvalidRentPayingAccount,
|
||||||
28 => TransactionError::WouldExceedMaxVoteCostLimit,
|
28 => TransactionError::WouldExceedMaxVoteCostLimit,
|
||||||
29 => TransactionError::WouldExceedAccountDataTotalLimit,
|
29 => TransactionError::WouldExceedAccountDataTotalLimit,
|
||||||
32 => TransactionError::MaxLoadedAccountsDataSizeExceeded,
|
|
||||||
33 => TransactionError::InvalidLoadedAccountsDataSizeLimit,
|
|
||||||
_ => return Err("Invalid TransactionError"),
|
_ => return Err("Invalid TransactionError"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -898,12 +896,6 @@ impl From<TransactionError> for tx_by_addr::TransactionError {
|
||||||
TransactionError::InsufficientFundsForRent { .. } => {
|
TransactionError::InsufficientFundsForRent { .. } => {
|
||||||
tx_by_addr::TransactionErrorType::InsufficientFundsForRent
|
tx_by_addr::TransactionErrorType::InsufficientFundsForRent
|
||||||
}
|
}
|
||||||
TransactionError::MaxLoadedAccountsDataSizeExceeded => {
|
|
||||||
tx_by_addr::TransactionErrorType::MaxLoadedAccountsDataSizeExceeded
|
|
||||||
}
|
|
||||||
TransactionError::InvalidLoadedAccountsDataSizeLimit => {
|
|
||||||
tx_by_addr::TransactionErrorType::InvalidLoadedAccountsDataSizeLimit
|
|
||||||
}
|
|
||||||
} as i32,
|
} as i32,
|
||||||
instruction_error: match transaction_error {
|
instruction_error: match transaction_error {
|
||||||
TransactionError::InstructionError(index, ref instruction_error) => {
|
TransactionError::InstructionError(index, ref instruction_error) => {
|
||||||
|
|
Loading…
Reference in New Issue