diff --git a/accounts-db/src/accounts.rs b/accounts-db/src/accounts.rs index e0ed2639bf53b6..49dbeca3437f61 100644 --- a/accounts-db/src/accounts.rs +++ b/accounts-db/src/accounts.rs @@ -838,6 +838,7 @@ mod tests { solana_sdk::{ account::{AccountSharedData, WritableAccount}, address_lookup_table::state::LookupTableMeta, + fee::FeeDetails, hash::Hash, instruction::{CompiledInstruction, InstructionError}, message::{Message, MessageHeader}, @@ -848,8 +849,7 @@ mod tests { transaction::{Transaction, MAX_TX_ACCOUNT_LOCKS}, }, solana_svm::{ - account_loader::LoadedTransaction, - transaction_results::{DurableNonceFee, TransactionExecutionDetails}, + account_loader::LoadedTransaction, transaction_results::TransactionExecutionDetails, }, std::{ borrow::Cow, @@ -880,7 +880,8 @@ mod tests { status, log_messages: None, inner_instructions: None, - durable_nonce_fee: nonce.map(DurableNonceFee::from), + fee_details: FeeDetails::default(), + is_nonce: nonce.is_some(), return_data: None, executed_units: 0, accounts_data_len_delta: 0, @@ -1578,6 +1579,7 @@ mod tests { accounts: transaction_accounts0, program_indices: vec![], nonce: None, + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }); @@ -1586,6 +1588,7 @@ mod tests { accounts: transaction_accounts1, program_indices: vec![], nonce: None, + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }); @@ -1962,6 +1965,7 @@ mod tests { accounts: transaction_accounts, program_indices: vec![], nonce: nonce.clone(), + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }); @@ -2066,6 +2070,7 @@ mod tests { accounts: transaction_accounts, program_indices: vec![], nonce: nonce.clone(), + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }); diff --git a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs index b6385d3917b27f..2d3879843e38e9 100644 --- a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs +++ b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs @@ -653,9 +653,9 @@ mod tests { solana_poh::poh_recorder::{PohRecorder, Record, WorkingBankEntry}, solana_runtime::bank::Bank, solana_sdk::{ - compute_budget::ComputeBudgetInstruction, hash::Hash, message::Message, - poh_config::PohConfig, pubkey::Pubkey, signature::Keypair, signer::Signer, - system_instruction, system_transaction, transaction::Transaction, + compute_budget::ComputeBudgetInstruction, fee_calculator::FeeRateGovernor, hash::Hash, + message::Message, poh_config::PohConfig, pubkey::Pubkey, signature::Keypair, + signer::Signer, system_instruction, system_transaction, transaction::Transaction, }, std::sync::{atomic::AtomicBool, Arc, RwLock}, tempfile::TempDir, @@ -682,10 +682,11 @@ mod tests { fn create_test_frame(num_threads: usize) -> (TestFrame, SchedulerController) { let GenesisConfigInfo { - genesis_config, + mut genesis_config, mint_keypair, .. } = create_slow_genesis_config(u64::MAX); + genesis_config.fee_rate_governor = FeeRateGovernor::new(5000, 0); let (bank, bank_forks) = Bank::new_no_wallclock_throttle_for_tests(&genesis_config); let ledger_path = get_tmp_ledger_path_auto_delete!(); diff --git a/programs/sbf/tests/programs.rs b/programs/sbf/tests/programs.rs index 19533d73eb3724..a1a4515f82cea3 100644 --- a/programs/sbf/tests/programs.rs +++ b/programs/sbf/tests/programs.rs @@ -50,7 +50,7 @@ use { }, solana_svm::transaction_processor::ExecutionRecordingConfig, solana_svm::transaction_results::{ - DurableNonceFee, InnerInstruction, TransactionExecutionDetails, TransactionExecutionResult, + InnerInstruction, TransactionExecutionDetails, TransactionExecutionResult, TransactionResults, }, solana_transaction_status::{ @@ -185,38 +185,19 @@ fn execute_transactions( status, log_messages, inner_instructions, - durable_nonce_fee, + fee_details, return_data, executed_units, .. } = details; - let lamports_per_signature = match durable_nonce_fee { - Some(DurableNonceFee::Valid(lamports_per_signature)) => { - Some(lamports_per_signature) - } - Some(DurableNonceFee::Invalid) => None, - None => bank.get_lamports_per_signature_for_blockhash( - &tx.message().recent_blockhash, - ), - } - .expect("lamports_per_signature must be available"); - let fee = bank.get_fee_for_message_with_lamports_per_signature( - &SanitizedMessage::try_from_legacy_message( - tx.message().clone(), - &ReservedAccountKeys::empty_key_set(), - ) - .unwrap(), - lamports_per_signature, - ); - let inner_instructions = inner_instructions.map(|inner_instructions| { map_inner_instructions(inner_instructions).collect() }); let tx_status_meta = TransactionStatusMeta { status, - fee, + fee: fee_details.total_fee(), pre_balances, post_balances, pre_token_balances: Some(pre_token_balances), diff --git a/rpc/src/transaction_status_service.rs b/rpc/src/transaction_status_service.rs index 38ea3f1f5d1d84..c244827e3dd980 100644 --- a/rpc/src/transaction_status_service.rs +++ b/rpc/src/transaction_status_service.rs @@ -6,7 +6,7 @@ use { blockstore::Blockstore, blockstore_processor::{TransactionStatusBatch, TransactionStatusMessage}, }, - solana_svm::transaction_results::{DurableNonceFee, TransactionExecutionDetails}, + solana_svm::transaction_results::TransactionExecutionDetails, solana_transaction_status::{ extract_and_fmt_memos, map_inner_instructions, Reward, TransactionStatusMeta, }, @@ -99,27 +99,14 @@ impl TransactionStatusService { status, log_messages, inner_instructions, - durable_nonce_fee, return_data, executed_units, + fee_details, .. } = details; - let lamports_per_signature = match durable_nonce_fee { - Some(DurableNonceFee::Valid(lamports_per_signature)) => { - Some(lamports_per_signature) - } - Some(DurableNonceFee::Invalid) => None, - None => bank.get_lamports_per_signature_for_blockhash( - transaction.message().recent_blockhash(), - ), - } - .expect("lamports_per_signature must be available"); - let fee = bank.get_fee_for_message_with_lamports_per_signature( - transaction.message(), - lamports_per_signature, - ); let tx_account_locks = transaction.get_account_locks_unchecked(); + let fee = fee_details.total_fee(); let inner_instructions = inner_instructions.map(|inner_instructions| { map_inner_instructions(inner_instructions).collect() }); @@ -217,6 +204,7 @@ pub(crate) mod tests { solana_sdk::{ account_utils::StateMut, clock::Slot, + fee::FeeDetails, hash::Hash, nonce::{self, state::DurableNonce}, nonce_account, @@ -230,7 +218,6 @@ pub(crate) mod tests { VersionedTransaction, }, }, - solana_svm::nonce_info::{NonceFull, NoncePartial}, solana_transaction_status::{ token_balances::TransactionTokenBalancesSet, TransactionStatusMeta, TransactionTokenBalance, @@ -333,23 +320,15 @@ pub(crate) mod tests { ))) .unwrap(); - let rollback_partial = NoncePartial::new(pubkey, nonce_account.clone()); - let mut rent_debits = RentDebits::default(); rent_debits.insert(&pubkey, 123, 456); - let fee_payer_address = &pubkey; - let fee_payer_account = nonce_account; let transaction_result = Some(TransactionExecutionDetails { status: Ok(()), log_messages: None, inner_instructions: None, - durable_nonce_fee: Some(DurableNonceFee::from(&NonceFull::from_partial( - &rollback_partial, - fee_payer_address, - fee_payer_account, - &rent_debits, - ))), + fee_details: FeeDetails::default(), + is_nonce: true, return_data: None, executed_units: 0, accounts_data_len_delta: 0, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 95e10d6eb14053..6cacf085f72b1d 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -3889,7 +3889,6 @@ impl Bank { txs: &[SanitizedTransaction], execution_results: &[TransactionExecutionResult], ) -> Vec> { - let hash_queue = self.blockhash_queue.read().unwrap(); let mut fees = 0; let results = txs @@ -3897,21 +3896,16 @@ impl Bank { .zip(execution_results) .map(|(tx, execution_result)| { let message = tx.message(); - let (execution_status, is_nonce, lamports_per_signature) = - Self::get_details_from_execution_result( - &hash_queue, - execution_result, - message.recent_blockhash(), - )?; - let fee = self.get_fee_for_message_with_lamports_per_signature( - message, - lamports_per_signature, - ); + let details = match &execution_result { + TransactionExecutionResult::Executed { details, .. } => details, + TransactionExecutionResult::NotExecuted(err) => return Err(err.clone()), + }; + let fee = details.fee_details.total_fee(); self.check_execution_status_and_charge_fee( message, - execution_status, - is_nonce, + &details.status, + details.is_nonce, fee, )?; @@ -3930,7 +3924,6 @@ impl Bank { txs: &[SanitizedTransaction], execution_results: &[TransactionExecutionResult], ) -> Vec> { - let hash_queue = self.blockhash_queue.read().unwrap(); let mut accumulated_fee_details = FeeDetails::default(); let results = txs @@ -3938,34 +3931,20 @@ impl Bank { .zip(execution_results) .map(|(tx, execution_result)| { let message = tx.message(); - let (execution_status, is_nonce, lamports_per_signature) = - Self::get_details_from_execution_result( - &hash_queue, - execution_result, - message.recent_blockhash(), - )?; - - if !FeeStructure::to_clear_transaction_fee(lamports_per_signature) { - let fee_details = self.fee_structure().calculate_fee_details( - message, - &process_compute_budget_instructions(message.program_instructions_iter()) - .unwrap_or_default() - .into(), - self.feature_set - .is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()), - self.feature_set - .is_active(&remove_rounding_in_fee_calculation::id()), - ); + let details = match &execution_result { + TransactionExecutionResult::Executed { details, .. } => details, + TransactionExecutionResult::NotExecuted(err) => return Err(err.clone()), + }; - self.check_execution_status_and_charge_fee( - message, - execution_status, - is_nonce, - fee_details.total_fee(), - )?; + self.check_execution_status_and_charge_fee( + message, + &details.status, + details.is_nonce, + details.fee_details.total_fee(), + )?; + + accumulated_fee_details.accumulate(&details.fee_details); - accumulated_fee_details.accumulate(&fee_details); - } Ok(()) }) .collect(); @@ -3977,33 +3956,6 @@ impl Bank { results } - fn get_details_from_execution_result<'a>( - hash_queue_readonly: &RwLockReadGuard<'a, BlockhashQueue>, - execution_result: &'a TransactionExecutionResult, - transaction_blockhash: &Hash, - ) -> Result<(&'a transaction::Result<()>, bool, u64)> { - let (execution_status, durable_nonce_fee) = match &execution_result { - TransactionExecutionResult::Executed { details, .. } => { - Ok((&details.status, details.durable_nonce_fee.as_ref())) - } - TransactionExecutionResult::NotExecuted(err) => Err(err.clone()), - }?; - - let (lamports_per_signature, is_nonce) = durable_nonce_fee - .map(|durable_nonce_fee| durable_nonce_fee.lamports_per_signature()) - .map(|maybe_lamports_per_signature| (maybe_lamports_per_signature, true)) - .unwrap_or_else(|| { - ( - hash_queue_readonly.get_lamports_per_signature(transaction_blockhash), - false, - ) - }); - - let lamports_per_signature = - lamports_per_signature.ok_or(TransactionError::BlockhashNotFound)?; - Ok((execution_status, is_nonce, lamports_per_signature)) - } - fn check_execution_status_and_charge_fee( &self, message: &SanitizedMessage, diff --git a/runtime/src/bank/fee_distribution.rs b/runtime/src/bank/fee_distribution.rs index 89cfc23056d7f2..b9c4d29a700cae 100644 --- a/runtime/src/bank/fee_distribution.rs +++ b/runtime/src/bank/fee_distribution.rs @@ -87,6 +87,7 @@ impl Bank { ) -> u64 { let fee_details = self.fee_structure().calculate_fee_details( transaction.message(), + self.get_lamports_per_signature(), fee_budget_limits, self.feature_set .is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()), diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index c674c58f7f2ece..eb57e1c6b43078 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -101,7 +101,7 @@ use { transaction_context::TransactionAccount, }, solana_stake_program::stake_state::{self, StakeStateV2}, - solana_svm::{nonce_info::NonceFull, transaction_results::DurableNonceFee}, + solana_svm::nonce_info::NonceFull, solana_vote_program::{ vote_instruction, vote_state::{ @@ -231,13 +231,15 @@ fn test_race_register_tick_freeze() { fn new_execution_result( status: Result<()>, nonce: Option<&NonceFull>, + fee_details: FeeDetails, ) -> TransactionExecutionResult { TransactionExecutionResult::Executed { details: TransactionExecutionDetails { status, log_messages: None, inner_instructions: None, - durable_nonce_fee: nonce.map(DurableNonceFee::from), + fee_details, + is_nonce: nonce.is_some(), return_data: None, executed_units: 0, accounts_data_len_delta: 0, @@ -2863,11 +2865,10 @@ fn test_bank_blockhash_compute_unit_fee_structure() { fn test_filter_program_errors_and_collect_fee() { let leader = solana_sdk::pubkey::new_rand(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(100_000, &leader, 3); - genesis_config.fee_rate_governor = FeeRateGovernor::new(5000, 0); let mut bank = Bank::new_for_tests(&genesis_config); // this test is only for when `feature_set::reward_full_priority_fee` inactivated bank.deactivate_feature(&feature_set::reward_full_priority_fee::id()); @@ -2886,14 +2887,17 @@ fn test_filter_program_errors_and_collect_fee() { genesis_config.hash(), )); + let tx_fee = 42; + let fee_details = FeeDetails::new_for_tests(tx_fee, 0, false); let results = vec![ - new_execution_result(Ok(()), None), + new_execution_result(Ok(()), None, fee_details), new_execution_result( Err(TransactionError::InstructionError( 1, SystemError::ResultWithNegativeLamports.into(), )), None, + fee_details, ), ]; let initial_balance = bank.get_balance(&leader); @@ -2902,25 +2906,20 @@ fn test_filter_program_errors_and_collect_fee() { bank.freeze(); assert_eq!( bank.get_balance(&leader), - initial_balance - + bank - .fee_rate_governor - .burn(bank.fee_rate_governor.lamports_per_signature * 2) - .0 + initial_balance + bank.fee_rate_governor.burn(tx_fee * 2).0 ); assert_eq!(results[0], Ok(())); assert_eq!(results[1], Ok(())); } #[test] -fn test_filter_program_errors_and_collect_compute_unit_fee() { +fn test_filter_program_errors_and_collect_priority_fee() { let leader = solana_sdk::pubkey::new_rand(); let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(1000000, &leader, 3); - genesis_config.fee_rate_governor = FeeRateGovernor::new(2, 0); let mut bank = Bank::new_for_tests(&genesis_config); // this test is only for when `feature_set::reward_full_priority_fee` inactivated bank.deactivate_feature(&feature_set::reward_full_priority_fee::id()); @@ -2939,14 +2938,17 @@ fn test_filter_program_errors_and_collect_compute_unit_fee() { genesis_config.hash(), )); + let priority_fee = 42; + let fee_details: FeeDetails = FeeDetails::new_for_tests(0, priority_fee, false); let results = vec![ - new_execution_result(Ok(()), None), + new_execution_result(Ok(()), None, fee_details), new_execution_result( Err(TransactionError::InstructionError( 1, SystemError::ResultWithNegativeLamports.into(), )), None, + fee_details, ), ]; let initial_balance = bank.get_balance(&leader); @@ -2955,20 +2957,7 @@ fn test_filter_program_errors_and_collect_compute_unit_fee() { bank.freeze(); assert_eq!( bank.get_balance(&leader), - initial_balance - + bank - .fee_rate_governor - .burn( - calculate_test_fee( - &new_sanitized_message(Message::new(&[], Some(&Pubkey::new_unique()))), - genesis_config - .fee_rate_governor - .create_fee_calculator() - .lamports_per_signature, - bank.fee_structure(), - ) * 2 - ) - .0 + initial_balance + bank.fee_rate_governor.burn(priority_fee * 2).0 ); assert_eq!(results[0], Ok(())); assert_eq!(results[1], Ok(())); @@ -12886,21 +12875,13 @@ fn test_filter_program_errors_and_collect_fee_details() { // let initial_payer_balance = 7_000; let additional_payer_withdraw = 6_000; + let tx_fee = 5000; + let priority_fee = 1000; + let tx_fee_details = FeeDetails::new_for_tests(tx_fee, priority_fee, false); let expected_collected_fee_details = CollectorFeeDetails { - transaction_fee: 15_000, - priority_fee: 3_000, + transaction_fee: 3 * tx_fee, + priority_fee: 3 * priority_fee, }; - let lamports_per_signature = 9; - let nonce_account = AccountSharedData::new_data( - 99, - &nonce::state::Versions::new(nonce::State::Initialized(nonce::state::Data::new( - Pubkey::default(), - DurableNonce::from_blockhash(&Hash::new_unique()), - lamports_per_signature, - ))), - &system_program::id(), - ) - .unwrap(); let expected_collect_results = vec![ Err(TransactionError::AccountNotFound), @@ -12911,19 +12892,18 @@ fn test_filter_program_errors_and_collect_fee_details() { ]; let GenesisConfigInfo { - mut genesis_config, + genesis_config, mint_keypair, .. } = create_genesis_config_with_leader(initial_payer_balance, &Pubkey::new_unique(), 3); - genesis_config.fee_rate_governor = FeeRateGovernor::new(lamports_per_signature, 0); let bank = Bank::new_for_tests(&genesis_config); let tx = SanitizedTransaction::from_transaction_for_tests(Transaction::new_signed_with_payer( - &[ - system_instruction::transfer(&mint_keypair.pubkey(), &Pubkey::new_unique(), 2), - ComputeBudgetInstruction::set_compute_unit_limit(1_000), - ComputeBudgetInstruction::set_compute_unit_price(1_000_000), - ], + &[system_instruction::transfer( + &mint_keypair.pubkey(), + &Pubkey::new_unique(), + 2, + )], Some(&mint_keypair.pubkey()), &[&mint_keypair], genesis_config.hash(), @@ -12932,22 +12912,28 @@ fn test_filter_program_errors_and_collect_fee_details() { let results = vec![ TransactionExecutionResult::NotExecuted(TransactionError::AccountNotFound), - new_execution_result(Ok(()), None), + new_execution_result(Ok(()), None, tx_fee_details), new_execution_result( Err(TransactionError::InstructionError( - 1, + 0, SystemError::ResultWithNegativeLamports.into(), )), - Some(&NonceFull::new(Pubkey::new_unique(), nonce_account, None)), + Some(&NonceFull::new( + Pubkey::new_unique(), + AccountSharedData::default(), + None, + )), + tx_fee_details, ), new_execution_result( Err(TransactionError::InstructionError( - 1, + 0, SystemError::ResultWithNegativeLamports.into(), )), None, + tx_fee_details, ), - new_execution_result(Err(TransactionError::AccountNotFound), None), + new_execution_result(Err(TransactionError::AccountNotFound), None, tx_fee_details), ]; let results = bank.filter_program_errors_and_collect_fee_details(&txs, &results); diff --git a/sdk/src/fee.rs b/sdk/src/fee.rs index 6c5ca9ddeda1c3..5edba38ee4f60f 100644 --- a/sdk/src/fee.rs +++ b/sdk/src/fee.rs @@ -39,6 +39,19 @@ pub struct FeeDetails { } impl FeeDetails { + #[cfg(feature = "dev-context-only-utils")] + pub fn new_for_tests( + transaction_fee: u64, + prioritization_fee: u64, + remove_rounding_in_fee_calculation: bool, + ) -> Self { + Self { + transaction_fee, + prioritization_fee, + remove_rounding_in_fee_calculation, + } + } + pub fn total_fee(&self) -> u64 { let total_fee = self.transaction_fee.saturating_add(self.prioritization_fee); if self.remove_rounding_in_fee_calculation { @@ -111,12 +124,6 @@ impl FeeStructure { .saturating_mul(heap_cost) } - /// Backward compatibility - lamports_per_signature == 0 means to clear - /// transaction fee to zero - pub fn to_clear_transaction_fee(lamports_per_signature: u64) -> bool { - lamports_per_signature == 0 - } - /// Calculate fee for `SanitizedMessage` #[cfg(not(target_os = "solana"))] pub fn calculate_fee( @@ -127,17 +134,14 @@ impl FeeStructure { include_loaded_account_data_size_in_fee: bool, remove_rounding_in_fee_calculation: bool, ) -> u64 { - if Self::to_clear_transaction_fee(lamports_per_signature) { - 0 - } else { - self.calculate_fee_details( - message, - budget_limits, - include_loaded_account_data_size_in_fee, - remove_rounding_in_fee_calculation, - ) - .total_fee() - } + self.calculate_fee_details( + message, + lamports_per_signature, + budget_limits, + include_loaded_account_data_size_in_fee, + remove_rounding_in_fee_calculation, + ) + .total_fee() } /// Calculate fee details for `SanitizedMessage` @@ -145,10 +149,17 @@ impl FeeStructure { pub fn calculate_fee_details( &self, message: &SanitizedMessage, + lamports_per_signature: u64, budget_limits: &FeeBudgetLimits, include_loaded_account_data_size_in_fee: bool, remove_rounding_in_fee_calculation: bool, ) -> FeeDetails { + // Backward compatibility - lamports_per_signature == 0 means to clear + // transaction fee to zero + if lamports_per_signature == 0 { + return FeeDetails::default(); + } + let signature_fee = message .num_signatures() .saturating_mul(self.lamports_per_signature); diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index 412526eee656f2..4e4f76146e3869 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -17,7 +17,7 @@ use { self, include_loaded_accounts_data_size_in_fee_calculation, remove_rounding_in_fee_calculation, }, - fee::FeeStructure, + fee::{FeeDetails, FeeStructure}, message::SanitizedMessage, native_loader, nonce::State as NonceState, @@ -51,6 +51,7 @@ pub struct LoadedTransaction { pub accounts: Vec, pub program_indices: TransactionProgramIndices, pub nonce: Option, + pub fee_details: FeeDetails, pub rent: TransactionRent, pub rent_debits: RentDebits, } @@ -141,7 +142,7 @@ pub(crate) fn load_accounts( }), ) => { let message = tx.message(); - let fee = fee_structure.calculate_fee( + let fee_details = fee_structure.calculate_fee_details( message, *lamports_per_signature, &process_compute_budget_instructions(message.program_instructions_iter()) @@ -157,7 +158,7 @@ pub(crate) fn load_accounts( callbacks, message, nonce.as_ref(), - fee, + fee_details, error_counters, account_overrides, loaded_programs, @@ -172,7 +173,7 @@ fn load_transaction_accounts( callbacks: &CB, message: &SanitizedMessage, nonce: Option<&NoncePartial>, - fee: u64, + fee_details: FeeDetails, error_counters: &mut TransactionErrorMetrics, account_overrides: Option<&AccountOverrides>, loaded_programs: &ProgramCacheForTxBatch, @@ -283,7 +284,7 @@ fn load_transaction_accounts( i as IndexOfAccount, error_counters, rent_collector, - fee, + fee_details.total_fee(), )?; validated_fee_payer = true; @@ -386,6 +387,7 @@ fn load_transaction_accounts( accounts, program_indices, nonce, + fee_details, rent: tx_rent, rent_debits, }) @@ -1448,7 +1450,7 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, @@ -1488,11 +1490,12 @@ mod tests { vec![Signature::new_unique()], false, ); + let fee_details = FeeDetails::new_for_tests(32, 0, false); let result = load_transaction_accounts( &mock_bank, sanitized_transaction.message(), None, - 32, + fee_details, &mut error_counter, None, &loaded_programs, @@ -1518,6 +1521,7 @@ mod tests { ], program_indices: vec![vec![]], nonce: None, + fee_details, rent: 0, rent_debits: RentDebits::default() } @@ -1559,7 +1563,7 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, @@ -1602,7 +1606,7 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, @@ -1645,7 +1649,7 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, @@ -1691,11 +1695,12 @@ mod tests { vec![Signature::new_unique()], false, ); + let fee_details = FeeDetails::new_for_tests(32, 0, false); let result = load_transaction_accounts( &mock_bank, sanitized_transaction.message(), None, - 32, + fee_details, &mut error_counter, None, &loaded_programs, @@ -1720,6 +1725,7 @@ mod tests { ), ], nonce: None, + fee_details, program_indices: vec![vec![1]], rent: 0, rent_debits: RentDebits::default() @@ -1764,16 +1770,11 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, ); - mock_bank - .accounts_map - .get_mut(&key2.pubkey()) - .unwrap() - .set_lamports(200 - 32); assert_eq!(result.err(), Some(TransactionError::ProgramAccountNotFound)); } @@ -1821,16 +1822,11 @@ mod tests { &mock_bank, sanitized_transaction.message(), None, - 32, + FeeDetails::default(), &mut error_counter, None, &loaded_programs, ); - mock_bank - .accounts_map - .get_mut(&key2.pubkey()) - .unwrap() - .set_lamports(200 - 32); assert_eq!( result.err(), @@ -1879,11 +1875,12 @@ mod tests { vec![Signature::new_unique()], false, ); + let fee_details = FeeDetails::new_for_tests(32, 0, false); let result = load_transaction_accounts( &mock_bank, sanitized_transaction.message(), None, - 32, + fee_details, &mut error_counter, None, &loaded_programs, @@ -1913,6 +1910,7 @@ mod tests { ], program_indices: vec![vec![2, 1]], nonce: None, + fee_details, rent: 0, rent_debits: RentDebits::default() } @@ -1968,11 +1966,12 @@ mod tests { vec![Signature::new_unique()], false, ); + let fee_details = FeeDetails::new_for_tests(32, 0, false); let result = load_transaction_accounts( &mock_bank, sanitized_transaction.message(), None, - 32, + fee_details, &mut error_counter, None, &loaded_programs, @@ -2005,6 +2004,7 @@ mod tests { ], program_indices: vec![vec![3, 1], vec![3, 1]], nonce: None, + fee_details, rent: 0, rent_debits: RentDebits::default() } @@ -2167,6 +2167,7 @@ mod tests { AccountSharedData::default(), Some(mock_bank.accounts_map[&key2.pubkey()].clone()) )), + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default() } diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index a8ec91ff6b7e9d..c2c93aac85826b 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -10,9 +10,7 @@ use { transaction_account_state_info::TransactionAccountStateInfo, transaction_error_metrics::TransactionErrorMetrics, transaction_processing_callback::TransactionProcessingCallback, - transaction_results::{ - DurableNonceFee, TransactionExecutionDetails, TransactionExecutionResult, - }, + transaction_results::{TransactionExecutionDetails, TransactionExecutionResult}, }, log::debug, percentage::Percentage, @@ -727,7 +725,8 @@ impl TransactionBatchProcessor { status, log_messages, inner_instructions, - durable_nonce_fee: loaded_transaction.nonce.as_ref().map(DurableNonceFee::from), + fee_details: loaded_transaction.fee_details, + is_nonce: loaded_transaction.nonce.is_some(), return_data, executed_units, accounts_data_len_delta, @@ -838,6 +837,7 @@ mod tests { account::{create_account_shared_data_for_test, WritableAccount}, bpf_loader, feature_set::FeatureSet, + fee::FeeDetails, fee_calculator::FeeCalculator, hash::Hash, message::{LegacyMessage, Message, MessageHeader}, @@ -990,6 +990,7 @@ mod tests { accounts: vec![(Pubkey::new_unique(), AccountSharedData::default())], program_indices: vec![vec![0]], nonce: None, + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }; @@ -1114,6 +1115,7 @@ mod tests { ], program_indices: vec![vec![0]], nonce: None, + fee_details: FeeDetails::default(), rent: 0, rent_debits: RentDebits::default(), }; diff --git a/svm/src/transaction_results.rs b/svm/src/transaction_results.rs index d6f0c8a304433c..f82fc47d04649c 100644 --- a/svm/src/transaction_results.rs +++ b/svm/src/transaction_results.rs @@ -5,9 +5,9 @@ )] pub use solana_sdk::inner_instruction::{InnerInstruction, InnerInstructionsList}; use { - crate::nonce_info::{NonceFull, NonceInfo}, solana_program_runtime::loaded_programs::ProgramCacheForTxBatch, solana_sdk::{ + fee::FeeDetails, rent_debits::RentDebits, transaction::{self, TransactionError}, transaction_context::TransactionReturnData, @@ -74,34 +74,11 @@ pub struct TransactionExecutionDetails { pub status: transaction::Result<()>, pub log_messages: Option>, pub inner_instructions: Option, - pub durable_nonce_fee: Option, + pub fee_details: FeeDetails, + pub is_nonce: bool, pub return_data: Option, pub executed_units: u64, /// The change in accounts data len for this transaction. /// NOTE: This value is valid IFF `status` is `Ok`. pub accounts_data_len_delta: i64, } - -#[derive(Debug, Clone)] -pub enum DurableNonceFee { - Valid(u64), - Invalid, -} - -impl From<&NonceFull> for DurableNonceFee { - fn from(nonce: &NonceFull) -> Self { - match nonce.lamports_per_signature() { - Some(lamports_per_signature) => Self::Valid(lamports_per_signature), - None => Self::Invalid, - } - } -} - -impl DurableNonceFee { - pub fn lamports_per_signature(&self) -> Option { - match self { - Self::Valid(lamports_per_signature) => Some(*lamports_per_signature), - Self::Invalid => None, - } - } -}