Remove calculate_fee()'s dependency on ComputeBudget (#32487)
This commit is contained in:
parent
eb74562124
commit
7177dd9809
|
@ -17,6 +17,7 @@ use {
|
|||
include_loaded_accounts_data_size_in_fee_calculation,
|
||||
remove_deprecated_request_unit_ix, FeatureSet,
|
||||
},
|
||||
fee::FeeStructure,
|
||||
instruction::CompiledInstruction,
|
||||
program_utils::limited_deserialize,
|
||||
pubkey::Pubkey,
|
||||
|
@ -26,8 +27,6 @@ use {
|
|||
},
|
||||
};
|
||||
|
||||
const ACCOUNT_DATA_COST_PAGE_SIZE: u64 = 32_u64.saturating_mul(1024);
|
||||
|
||||
pub struct CostModel;
|
||||
|
||||
impl CostModel {
|
||||
|
@ -57,10 +56,10 @@ impl CostModel {
|
|||
// limit of 64MB; which will convert to (64M/32K)*8CU = 16_000 CUs
|
||||
//
|
||||
pub fn calculate_loaded_accounts_data_size_cost(compute_budget: &ComputeBudget) -> u64 {
|
||||
(compute_budget.loaded_accounts_data_size_limit as u64)
|
||||
.saturating_add(ACCOUNT_DATA_COST_PAGE_SIZE.saturating_sub(1))
|
||||
.saturating_div(ACCOUNT_DATA_COST_PAGE_SIZE)
|
||||
.saturating_mul(compute_budget.heap_cost)
|
||||
FeeStructure::calculate_memory_usage_cost(
|
||||
compute_budget.loaded_accounts_data_size_limit,
|
||||
compute_budget.heap_cost,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_signature_cost(transaction: &SanitizedTransaction) -> u64 {
|
||||
|
@ -209,6 +208,7 @@ mod tests {
|
|||
super::*,
|
||||
solana_sdk::{
|
||||
compute_budget::{self, ComputeBudgetInstruction},
|
||||
fee::ACCOUNT_DATA_COST_PAGE_SIZE,
|
||||
hash::Hash,
|
||||
instruction::CompiledInstruction,
|
||||
message::Message,
|
||||
|
|
|
@ -4,6 +4,12 @@ use {
|
|||
borsh::try_from_slice_unchecked,
|
||||
compute_budget::{self, ComputeBudgetInstruction},
|
||||
entrypoint::HEAP_LENGTH as MIN_HEAP_FRAME_BYTES,
|
||||
feature_set::{
|
||||
add_set_tx_loaded_accounts_data_size_instruction, enable_request_heap_frame_ix,
|
||||
remove_deprecated_request_unit_ix, use_default_units_in_fee_calculation, FeatureSet,
|
||||
},
|
||||
fee::FeeBudgetLimits,
|
||||
genesis_config::ClusterType,
|
||||
instruction::{CompiledInstruction, InstructionError},
|
||||
pubkey::Pubkey,
|
||||
transaction::TransactionError,
|
||||
|
@ -276,6 +282,39 @@ impl ComputeBudget {
|
|||
.map(|fee_type| PrioritizationFeeDetails::new(fee_type, self.compute_unit_limit))
|
||||
.unwrap_or_default())
|
||||
}
|
||||
|
||||
pub fn fee_budget_limits<'a>(
|
||||
instructions: impl Iterator<Item = (&'a Pubkey, &'a CompiledInstruction)>,
|
||||
feature_set: &FeatureSet,
|
||||
maybe_cluster_type: Option<ClusterType>,
|
||||
) -> FeeBudgetLimits {
|
||||
let mut compute_budget = Self::default();
|
||||
|
||||
// A cluster specific feature gate, when not activated it keeps v1.13 behavior in mainnet-beta;
|
||||
// once activated for v1.14+, it allows compute_budget::request_heap_frame and
|
||||
// compute_budget::set_compute_unit_price co-exist in same transaction.
|
||||
let enable_request_heap_frame_ix = feature_set
|
||||
.is_active(&enable_request_heap_frame_ix::id())
|
||||
|| maybe_cluster_type
|
||||
.and_then(|cluster_type| (cluster_type != ClusterType::MainnetBeta).then_some(0))
|
||||
.is_some();
|
||||
let prioritization_fee_details = compute_budget
|
||||
.process_instructions(
|
||||
instructions,
|
||||
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
||||
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||
enable_request_heap_frame_ix,
|
||||
feature_set.is_active(&add_set_tx_loaded_accounts_data_size_instruction::id()),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
FeeBudgetLimits {
|
||||
loaded_accounts_data_size_limit: compute_budget.loaded_accounts_data_size_limit,
|
||||
heap_cost: compute_budget.heap_cost,
|
||||
compute_unit_limit: compute_budget.compute_unit_limit,
|
||||
prioritization_fee: prioritization_fee_details.get_fee(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -40,7 +40,7 @@ use {
|
|||
clock::MAX_PROCESSING_AGE,
|
||||
compute_budget::ComputeBudgetInstruction,
|
||||
entrypoint::MAX_PERMITTED_DATA_INCREASE,
|
||||
feature_set::{self, FeatureSet},
|
||||
feature_set::{self, remove_deprecated_request_unit_ix, FeatureSet},
|
||||
fee::FeeStructure,
|
||||
loader_instruction,
|
||||
message::{v0::LoadedAddresses, SanitizedMessage},
|
||||
|
@ -3824,15 +3824,19 @@ fn test_program_fees() {
|
|||
Some(&mint_keypair.pubkey()),
|
||||
);
|
||||
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&remove_deprecated_request_unit_ix::id());
|
||||
|
||||
let sanitized_message = SanitizedMessage::try_from(message.clone()).unwrap();
|
||||
let expected_normal_fee = Bank::calculate_fee(
|
||||
&sanitized_message,
|
||||
congestion_multiplier,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
&ComputeBudget::fee_budget_limits(
|
||||
sanitized_message.program_instructions_iter(),
|
||||
&feature_set,
|
||||
None,
|
||||
),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
@ -3851,14 +3855,17 @@ fn test_program_fees() {
|
|||
Some(&mint_keypair.pubkey()),
|
||||
);
|
||||
let sanitized_message = SanitizedMessage::try_from(message.clone()).unwrap();
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&remove_deprecated_request_unit_ix::id());
|
||||
let expected_prioritized_fee = Bank::calculate_fee(
|
||||
&sanitized_message,
|
||||
congestion_multiplier,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
&ComputeBudget::fee_budget_limits(
|
||||
sanitized_message.program_instructions_iter(),
|
||||
&feature_set,
|
||||
None,
|
||||
),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
|
|
@ -36,11 +36,10 @@ use {
|
|||
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
|
||||
clock::{BankId, Slot},
|
||||
feature_set::{
|
||||
self, add_set_tx_loaded_accounts_data_size_instruction, enable_request_heap_frame_ix,
|
||||
self, add_set_tx_loaded_accounts_data_size_instruction,
|
||||
include_loaded_accounts_data_size_in_fee_calculation,
|
||||
remove_congestion_multiplier_from_fee_calculation, remove_deprecated_request_unit_ix,
|
||||
simplify_writable_program_account_check, use_default_units_in_fee_calculation,
|
||||
FeatureSet,
|
||||
simplify_writable_program_account_check, FeatureSet,
|
||||
},
|
||||
fee::FeeStructure,
|
||||
genesis_config::ClusterType,
|
||||
|
@ -727,11 +726,8 @@ impl Accounts {
|
|||
tx.message(),
|
||||
lamports_per_signature,
|
||||
fee_structure,
|
||||
feature_set.is_active(&use_default_units_in_fee_calculation::id()),
|
||||
!feature_set.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||
&ComputeBudget::fee_budget_limits(tx.message().program_instructions_iter(), feature_set, Some(self.accounts_db.expected_cluster_type())),
|
||||
feature_set.is_active(&remove_congestion_multiplier_from_fee_calculation::id()),
|
||||
feature_set.is_active(&enable_request_heap_frame_ix::id()) || self.accounts_db.expected_cluster_type() != ClusterType::MainnetBeta,
|
||||
feature_set.is_active(&add_set_tx_loaded_accounts_data_size_instruction::id()),
|
||||
feature_set.is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()),
|
||||
)
|
||||
} else {
|
||||
|
@ -1761,14 +1757,19 @@ mod tests {
|
|||
instructions,
|
||||
);
|
||||
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&remove_deprecated_request_unit_ix::id());
|
||||
|
||||
let message = SanitizedMessage::try_from(tx.message().clone()).unwrap();
|
||||
let fee = Bank::calculate_fee(
|
||||
&SanitizedMessage::try_from(tx.message().clone()).unwrap(),
|
||||
&message,
|
||||
lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
&ComputeBudget::fee_budget_limits(
|
||||
message.program_instructions_iter(),
|
||||
&feature_set,
|
||||
None,
|
||||
),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
@ -4324,14 +4325,19 @@ mod tests {
|
|||
Hash::default(),
|
||||
);
|
||||
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&remove_deprecated_request_unit_ix::id());
|
||||
|
||||
let message = SanitizedMessage::try_from(tx.message().clone()).unwrap();
|
||||
let fee = Bank::calculate_fee(
|
||||
&SanitizedMessage::try_from(tx.message().clone()).unwrap(),
|
||||
&message,
|
||||
lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
&ComputeBudget::fee_budget_limits(
|
||||
message.program_instructions_iter(),
|
||||
&feature_set,
|
||||
None,
|
||||
),
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
|
|
@ -96,7 +96,7 @@ use {
|
|||
ThreadPool, ThreadPoolBuilder,
|
||||
},
|
||||
solana_bpf_loader_program::syscalls::create_program_runtime_environment,
|
||||
solana_cost_model::{cost_model::CostModel, cost_tracker::CostTracker},
|
||||
solana_cost_model::cost_tracker::CostTracker,
|
||||
solana_measure::{measure, measure::Measure, measure_us},
|
||||
solana_perf::perf_libs,
|
||||
solana_program_runtime::{
|
||||
|
@ -131,10 +131,10 @@ use {
|
|||
feature,
|
||||
feature_set::{
|
||||
self, add_set_tx_loaded_accounts_data_size_instruction,
|
||||
enable_early_verification_of_account_modifications, enable_request_heap_frame_ix,
|
||||
enable_early_verification_of_account_modifications,
|
||||
include_loaded_accounts_data_size_in_fee_calculation,
|
||||
remove_congestion_multiplier_from_fee_calculation, remove_deprecated_request_unit_ix,
|
||||
use_default_units_in_fee_calculation, FeatureSet,
|
||||
FeatureSet,
|
||||
},
|
||||
fee::FeeStructure,
|
||||
fee_calculator::{FeeCalculator, FeeRateGovernor},
|
||||
|
@ -267,6 +267,7 @@ pub struct BankRc {
|
|||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
use solana_frozen_abi::abi_example::AbiExample;
|
||||
use solana_sdk::fee::FeeBudgetLimits;
|
||||
|
||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||
impl AbiExample for BankRc {
|
||||
|
@ -4226,23 +4227,7 @@ impl Bank {
|
|||
NoncePartial::new(address, account).lamports_per_signature()
|
||||
})
|
||||
})?;
|
||||
Some(Self::calculate_fee(
|
||||
message,
|
||||
lamports_per_signature,
|
||||
&self.fee_structure,
|
||||
self.feature_set
|
||||
.is_active(&use_default_units_in_fee_calculation::id()),
|
||||
!self
|
||||
.feature_set
|
||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||
self.feature_set
|
||||
.is_active(&remove_congestion_multiplier_from_fee_calculation::id()),
|
||||
self.enable_request_heap_frame_ix(),
|
||||
self.feature_set
|
||||
.is_active(&add_set_tx_loaded_accounts_data_size_instruction::id()),
|
||||
self.feature_set
|
||||
.is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()),
|
||||
))
|
||||
Some(self.get_fee_for_message_with_lamports_per_signature(message, lamports_per_signature))
|
||||
}
|
||||
|
||||
pub fn get_startup_verification_complete(&self) -> &Arc<AtomicBool> {
|
||||
|
@ -4281,16 +4266,13 @@ impl Bank {
|
|||
message,
|
||||
lamports_per_signature,
|
||||
&self.fee_structure,
|
||||
self.feature_set
|
||||
.is_active(&use_default_units_in_fee_calculation::id()),
|
||||
!self
|
||||
.feature_set
|
||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||
&ComputeBudget::fee_budget_limits(
|
||||
message.program_instructions_iter(),
|
||||
&self.feature_set,
|
||||
Some(self.cluster_type()),
|
||||
),
|
||||
self.feature_set
|
||||
.is_active(&remove_congestion_multiplier_from_fee_calculation::id()),
|
||||
self.enable_request_heap_frame_ix(),
|
||||
self.feature_set
|
||||
.is_active(&add_set_tx_loaded_accounts_data_size_instruction::id()),
|
||||
self.feature_set
|
||||
.is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()),
|
||||
)
|
||||
|
@ -5083,15 +5065,6 @@ impl Bank {
|
|||
}
|
||||
}
|
||||
|
||||
// A cluster specific feature gate, when not activated it keeps v1.13 behavior in mainnet-beta;
|
||||
// once activated for v1.14+, it allows compute_budget::request_heap_frame and
|
||||
// compute_budget::set_compute_unit_price co-exist in same transaction.
|
||||
fn enable_request_heap_frame_ix(&self) -> bool {
|
||||
self.feature_set
|
||||
.is_active(&enable_request_heap_frame_ix::id())
|
||||
|| self.cluster_type() != ClusterType::MainnetBeta
|
||||
}
|
||||
|
||||
fn replenish_program_cache(
|
||||
&self,
|
||||
program_accounts_map: &HashMap<Pubkey, (&Pubkey, u64)>,
|
||||
|
@ -5556,11 +5529,8 @@ impl Bank {
|
|||
message: &SanitizedMessage,
|
||||
lamports_per_signature: u64,
|
||||
fee_structure: &FeeStructure,
|
||||
use_default_units_per_instruction: bool,
|
||||
support_request_units_deprecated: bool,
|
||||
budget_limits: &FeeBudgetLimits,
|
||||
remove_congestion_multiplier: bool,
|
||||
enable_request_heap_frame_ix: bool,
|
||||
support_set_accounts_data_size_limit_ix: bool,
|
||||
include_loaded_account_data_size_in_fee: bool,
|
||||
) -> u64 {
|
||||
// Fee based on compute units and signatures
|
||||
|
@ -5574,17 +5544,6 @@ impl Bank {
|
|||
BASE_CONGESTION / current_congestion
|
||||
};
|
||||
|
||||
let mut compute_budget = ComputeBudget::default();
|
||||
let prioritization_fee_details = compute_budget
|
||||
.process_instructions(
|
||||
message.program_instructions_iter(),
|
||||
use_default_units_per_instruction,
|
||||
support_request_units_deprecated,
|
||||
enable_request_heap_frame_ix,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
)
|
||||
.unwrap_or_default();
|
||||
let prioritization_fee = prioritization_fee_details.get_fee();
|
||||
let signature_fee = message
|
||||
.num_signatures()
|
||||
.saturating_mul(fee_structure.lamports_per_signature);
|
||||
|
@ -5595,12 +5554,15 @@ impl Bank {
|
|||
// `compute_fee` covers costs for both requested_compute_units and
|
||||
// requested_loaded_account_data_size
|
||||
let loaded_accounts_data_size_cost = if include_loaded_account_data_size_in_fee {
|
||||
CostModel::calculate_loaded_accounts_data_size_cost(&compute_budget)
|
||||
FeeStructure::calculate_memory_usage_cost(
|
||||
budget_limits.loaded_accounts_data_size_limit,
|
||||
budget_limits.heap_cost,
|
||||
)
|
||||
} else {
|
||||
0_u64
|
||||
};
|
||||
let total_compute_units =
|
||||
loaded_accounts_data_size_cost.saturating_add(compute_budget.compute_unit_limit);
|
||||
loaded_accounts_data_size_cost.saturating_add(budget_limits.compute_unit_limit);
|
||||
let compute_fee = fee_structure
|
||||
.compute_fee_bins
|
||||
.iter()
|
||||
|
@ -5614,7 +5576,8 @@ impl Bank {
|
|||
.unwrap_or_default()
|
||||
});
|
||||
|
||||
((prioritization_fee
|
||||
((budget_limits
|
||||
.prioritization_fee
|
||||
.saturating_add(signature_fee)
|
||||
.saturating_add(write_lock_fee)
|
||||
.saturating_add(compute_fee) as f64)
|
||||
|
@ -5653,22 +5616,9 @@ impl Bank {
|
|||
|
||||
let lamports_per_signature =
|
||||
lamports_per_signature.ok_or(TransactionError::BlockhashNotFound)?;
|
||||
let fee = Self::calculate_fee(
|
||||
let fee = self.get_fee_for_message_with_lamports_per_signature(
|
||||
tx.message(),
|
||||
lamports_per_signature,
|
||||
&self.fee_structure,
|
||||
self.feature_set
|
||||
.is_active(&use_default_units_in_fee_calculation::id()),
|
||||
!self
|
||||
.feature_set
|
||||
.is_active(&remove_deprecated_request_unit_ix::id()),
|
||||
self.feature_set
|
||||
.is_active(&remove_congestion_multiplier_from_fee_calculation::id()),
|
||||
self.enable_request_heap_frame_ix(),
|
||||
self.feature_set
|
||||
.is_active(&add_set_tx_loaded_accounts_data_size_instruction::id()),
|
||||
self.feature_set
|
||||
.is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()),
|
||||
);
|
||||
|
||||
// In case of instruction error, even though no accounts
|
||||
|
|
|
@ -60,7 +60,7 @@ use {
|
|||
entrypoint::MAX_PERMITTED_DATA_INCREASE,
|
||||
epoch_schedule::{EpochSchedule, MINIMUM_SLOTS_PER_EPOCH},
|
||||
feature::{self, Feature},
|
||||
feature_set::{self, FeatureSet},
|
||||
feature_set::{self, enable_request_heap_frame_ix, FeatureSet},
|
||||
fee::FeeStructure,
|
||||
fee_calculator::FeeRateGovernor,
|
||||
genesis_config::{create_genesis_config, ClusterType, GenesisConfig},
|
||||
|
@ -2870,19 +2870,16 @@ fn test_bank_tx_compute_unit_fee() {
|
|||
} = create_genesis_config_with_leader(mint, &leader, 3);
|
||||
genesis_config.fee_rate_governor = FeeRateGovernor::new(4, 0); // something divisible by 2
|
||||
|
||||
let expected_fee_paid = Bank::calculate_fee(
|
||||
let expected_fee_paid = calculate_test_fee(
|
||||
&SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap(),
|
||||
genesis_config
|
||||
.fee_rate_governor
|
||||
.create_fee_calculator()
|
||||
.lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
||||
let (expected_fee_collected, expected_fee_burned) =
|
||||
|
@ -3058,16 +3055,13 @@ fn test_bank_blockhash_compute_unit_fee_structure() {
|
|||
let tx = system_transaction::transfer(&mint_keypair, &key, 1, cheap_blockhash);
|
||||
assert_eq!(bank.process_transaction(&tx), Ok(()));
|
||||
assert_eq!(bank.get_balance(&key), 1);
|
||||
let cheap_fee = Bank::calculate_fee(
|
||||
let cheap_fee = calculate_test_fee(
|
||||
&SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap(),
|
||||
cheap_lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
assert_eq!(
|
||||
bank.get_balance(&mint_keypair.pubkey()),
|
||||
|
@ -3080,16 +3074,13 @@ fn test_bank_blockhash_compute_unit_fee_structure() {
|
|||
let tx = system_transaction::transfer(&mint_keypair, &key, 1, expensive_blockhash);
|
||||
assert_eq!(bank.process_transaction(&tx), Ok(()));
|
||||
assert_eq!(bank.get_balance(&key), 1);
|
||||
let expensive_fee = Bank::calculate_fee(
|
||||
let expensive_fee = calculate_test_fee(
|
||||
&SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap(),
|
||||
expensive_lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
);
|
||||
assert_eq!(
|
||||
bank.get_balance(&mint_keypair.pubkey()),
|
||||
|
@ -3193,7 +3184,7 @@ fn test_filter_program_errors_and_collect_compute_unit_fee() {
|
|||
+ bank
|
||||
.fee_rate_governor
|
||||
.burn(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique())))
|
||||
.unwrap(),
|
||||
genesis_config
|
||||
|
@ -3201,12 +3192,9 @@ fn test_filter_program_errors_and_collect_compute_unit_fee() {
|
|||
.create_fee_calculator()
|
||||
.lamports_per_signature,
|
||||
&FeeStructure::default(),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
) * 2
|
||||
)
|
||||
.0
|
||||
|
@ -10122,6 +10110,37 @@ fn test_call_precomiled_program() {
|
|||
bank.process_transaction(&tx).unwrap();
|
||||
}
|
||||
|
||||
fn calculate_test_fee(
|
||||
message: &SanitizedMessage,
|
||||
lamports_per_signature: u64,
|
||||
fee_structure: &FeeStructure,
|
||||
support_set_accounts_data_size_limit_ix: bool,
|
||||
enable_request_heap_frame_ix: bool,
|
||||
remove_congestion_multiplier: bool,
|
||||
) -> u64 {
|
||||
let mut feature_set = FeatureSet::all_enabled();
|
||||
feature_set.deactivate(&remove_deprecated_request_unit_ix::id());
|
||||
|
||||
if !support_set_accounts_data_size_limit_ix {
|
||||
feature_set.deactivate(&include_loaded_accounts_data_size_in_fee_calculation::id());
|
||||
}
|
||||
|
||||
if !enable_request_heap_frame_ix {
|
||||
feature_set.deactivate(&enable_request_heap_frame_ix::id());
|
||||
}
|
||||
|
||||
let budget_limits =
|
||||
ComputeBudget::fee_budget_limits(message.program_instructions_iter(), &feature_set, None);
|
||||
Bank::calculate_fee(
|
||||
message,
|
||||
lamports_per_signature,
|
||||
fee_structure,
|
||||
&budget_limits,
|
||||
remove_congestion_multiplier,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_calculate_fee() {
|
||||
// Default: no fee.
|
||||
|
@ -10129,19 +10148,16 @@ fn test_calculate_fee() {
|
|||
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
0,
|
||||
&FeeStructure {
|
||||
lamports_per_signature: 0,
|
||||
..FeeStructure::default()
|
||||
},
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
0
|
||||
);
|
||||
|
@ -10150,19 +10166,16 @@ fn test_calculate_fee() {
|
|||
// One signature, a fee.
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&FeeStructure {
|
||||
lamports_per_signature: 1,
|
||||
..FeeStructure::default()
|
||||
},
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
1
|
||||
);
|
||||
|
@ -10176,19 +10189,16 @@ fn test_calculate_fee() {
|
|||
let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
2,
|
||||
&FeeStructure {
|
||||
lamports_per_signature: 2,
|
||||
..FeeStructure::default()
|
||||
},
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
4
|
||||
);
|
||||
|
@ -10210,16 +10220,13 @@ fn test_calculate_fee_compute_units() {
|
|||
SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
max_fee + lamports_per_signature
|
||||
);
|
||||
|
@ -10233,16 +10240,13 @@ fn test_calculate_fee_compute_units() {
|
|||
SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&Pubkey::new_unique()))).unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
max_fee + 3 * lamports_per_signature
|
||||
);
|
||||
|
@ -10278,16 +10282,13 @@ fn test_calculate_fee_compute_units() {
|
|||
))
|
||||
.unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
let fee = Bank::calculate_fee(
|
||||
let fee = calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
assert_eq!(
|
||||
fee,
|
||||
|
@ -10321,16 +10322,13 @@ fn test_calculate_prioritization_fee() {
|
|||
))
|
||||
.unwrap();
|
||||
|
||||
let fee = Bank::calculate_fee(
|
||||
let fee = calculate_test_fee(
|
||||
&message,
|
||||
fee_structure.lamports_per_signature,
|
||||
&fee_structure,
|
||||
true, // use_default_units_per_instruction
|
||||
false, // not support_request_units_deprecated
|
||||
true, // remove_congestion_multiplier
|
||||
true, // enable_request_heap_frame_ix
|
||||
true, // support_set_accounts_data_size_limit_ix,
|
||||
false, // include_loaded_account_data_size_in_fee
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
assert_eq!(
|
||||
fee,
|
||||
|
@ -10370,16 +10368,13 @@ fn test_calculate_fee_secp256k1() {
|
|||
.unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
2
|
||||
);
|
||||
|
@ -10394,16 +10389,13 @@ fn test_calculate_fee_secp256k1() {
|
|||
.unwrap();
|
||||
for support_set_accounts_data_size_limit_ix in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
1,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
support_set_accounts_data_size_limit_ix,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
),
|
||||
11
|
||||
);
|
||||
|
@ -12051,16 +12043,13 @@ fn test_calculate_fee_with_congestion_multiplier() {
|
|||
// congestion_multiplier has no effect on fee.
|
||||
for remove_congestion_multiplier in [true, false] {
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
cheap_lamports_per_signature,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
remove_congestion_multiplier,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
signature_fee * signature_count
|
||||
);
|
||||
|
@ -12076,16 +12065,13 @@ fn test_calculate_fee_with_congestion_multiplier() {
|
|||
};
|
||||
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
expensive_lamports_per_signature,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
remove_congestion_multiplier,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
signature_fee * signature_count / denominator
|
||||
);
|
||||
|
@ -12119,16 +12105,13 @@ fn test_calculate_fee_with_request_heap_frame_flag() {
|
|||
// into transaction fee
|
||||
let mut enable_request_heap_frame_ix = true;
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
lamports_per_signature,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
enable_request_heap_frame_ix,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
signature_fee + request_cu * lamports_per_cu
|
||||
);
|
||||
|
@ -12137,16 +12120,13 @@ fn test_calculate_fee_with_request_heap_frame_flag() {
|
|||
// into transaction fee
|
||||
enable_request_heap_frame_ix = false;
|
||||
assert_eq!(
|
||||
Bank::calculate_fee(
|
||||
calculate_test_fee(
|
||||
&message,
|
||||
lamports_per_signature,
|
||||
&fee_structure,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
enable_request_heap_frame_ix,
|
||||
true,
|
||||
false,
|
||||
),
|
||||
signature_fee
|
||||
);
|
||||
|
|
|
@ -11,6 +11,13 @@ pub struct FeeBin {
|
|||
pub fee: u64,
|
||||
}
|
||||
|
||||
pub struct FeeBudgetLimits {
|
||||
pub loaded_accounts_data_size_limit: usize,
|
||||
pub heap_cost: u64,
|
||||
pub compute_unit_limit: u64,
|
||||
pub prioritization_fee: u64,
|
||||
}
|
||||
|
||||
/// Information used to calculate fees
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct FeeStructure {
|
||||
|
@ -22,6 +29,8 @@ pub struct FeeStructure {
|
|||
pub compute_fee_bins: Vec<FeeBin>,
|
||||
}
|
||||
|
||||
pub const ACCOUNT_DATA_COST_PAGE_SIZE: u64 = 32_u64.saturating_mul(1024);
|
||||
|
||||
impl FeeStructure {
|
||||
pub fn new(
|
||||
sol_per_signature: f64,
|
||||
|
@ -53,6 +62,16 @@ impl FeeStructure {
|
|||
.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn calculate_memory_usage_cost(
|
||||
loaded_accounts_data_size_limit: usize,
|
||||
heap_cost: u64,
|
||||
) -> u64 {
|
||||
(loaded_accounts_data_size_limit as u64)
|
||||
.saturating_add(ACCOUNT_DATA_COST_PAGE_SIZE.saturating_sub(1))
|
||||
.saturating_div(ACCOUNT_DATA_COST_PAGE_SIZE)
|
||||
.saturating_mul(heap_cost)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FeeStructure {
|
||||
|
|
Loading…
Reference in New Issue