Remove calculate_fee()'s dependency on ComputeBudget (#32487)

This commit is contained in:
Pankaj Garg 2023-07-14 12:25:04 -07:00 committed by GitHub
parent eb74562124
commit 7177dd9809
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 192 additions and 191 deletions

View File

@ -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,

View File

@ -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)]

View File

@ -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,
);

View File

@ -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,
);

View File

@ -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

View File

@ -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
);

View File

@ -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 {