From bfbbc53dac93b3a5c6be9b4b65f679fdb13e41d9 Mon Sep 17 00:00:00 2001 From: Jack May Date: Fri, 22 Oct 2021 14:32:40 -0700 Subject: [PATCH] Divorce the runtime from FeeCalculator (#20737) --- account-decoder/src/parse_sysvar.rs | 10 +- banks-server/src/banks_server.rs | 10 +- cli/src/nonce.rs | 39 +-- core/src/test_validator.rs | 6 + program-test/src/lib.rs | 31 +- programs/bpf/tests/programs.rs | 25 +- rpc/src/rpc.rs | 34 ++- rpc/src/transaction_status_service.rs | 22 +- runtime/src/accounts.rs | 172 ++++++----- runtime/src/bank.rs | 271 ++++++++++-------- runtime/src/bank_client.rs | 34 ++- runtime/src/blockhash_queue.rs | 34 ++- runtime/src/message_processor.rs | 35 ++- runtime/src/snapshot_utils.rs | 2 +- runtime/src/system_instruction_processor.rs | 15 +- sdk/program/src/message/sanitized.rs | 113 -------- sdk/program/src/nonce/state/current.rs | 13 + sdk/program/src/sysvar/recent_blockhashes.rs | 12 +- sdk/src/feature_set.rs | 13 +- sdk/src/nonce_account.rs | 5 +- sdk/src/nonce_keyed_account.rs | 110 +++---- sdk/src/process_instruction.rs | 21 +- sdk/src/recent_blockhashes_account.rs | 16 +- .../src/send_transaction_service.rs | 23 +- 24 files changed, 503 insertions(+), 563 deletions(-) diff --git a/account-decoder/src/parse_sysvar.rs b/account-decoder/src/parse_sysvar.rs index a87f6a7a7..1fae39afc 100644 --- a/account-decoder/src/parse_sysvar.rs +++ b/account-decoder/src/parse_sysvar.rs @@ -254,12 +254,8 @@ mod test { SysvarAccountType::Fees(UiFees::default()), ); - let fee_calculator = FeeCalculator { - lamports_per_signature: 10, - }; - let recent_blockhashes: RecentBlockhashes = vec![IterItem(0, &hash, &fee_calculator)] - .into_iter() - .collect(); + let recent_blockhashes: RecentBlockhashes = + vec![IterItem(0, &hash, 10)].into_iter().collect(); let recent_blockhashes_sysvar = create_account_for_test(&recent_blockhashes); assert_eq!( parse_sysvar( @@ -269,7 +265,7 @@ mod test { .unwrap(), SysvarAccountType::RecentBlockhashes(vec![UiRecentBlockhashesEntry { blockhash: hash.to_string(), - fee_calculator: fee_calculator.into(), + fee_calculator: FeeCalculator::new(10).into(), }]), ); } diff --git a/banks-server/src/banks_server.rs b/banks-server/src/banks_server.rs index 38f046d48..95292f71d 100644 --- a/banks-server/src/banks_server.rs +++ b/banks-server/src/banks_server.rs @@ -185,12 +185,16 @@ impl Banks for BanksServer { commitment: CommitmentLevel, ) -> (FeeCalculator, Hash, u64) { let bank = self.bank(commitment); - #[allow(deprecated)] - let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator(); + let blockhash = bank.last_blockhash(); + let lamports_per_signature = bank.get_lamports_per_signature(); let last_valid_block_height = bank .get_blockhash_last_valid_block_height(&blockhash) .unwrap(); - (fee_calculator, blockhash, last_valid_block_height) + ( + FeeCalculator::new(lamports_per_signature), + blockhash, + last_valid_block_height, + ) } async fn get_transaction_status_with_context( diff --git a/cli/src/nonce.rs b/cli/src/nonce.rs index 0c90ff656..8fa894061 100644 --- a/cli/src/nonce.rs +++ b/cli/src/nonce.rs @@ -653,7 +653,6 @@ mod tests { use solana_sdk::{ account::Account, account_utils::StateMut, - fee_calculator::FeeCalculator, hash::hash, nonce::{self, state::Versions, State}, nonce_account, @@ -916,11 +915,11 @@ mod tests { fn test_check_nonce_account() { let blockhash = Hash::default(); let nonce_pubkey = solana_sdk::pubkey::new_rand(); - let data = Versions::new_current(State::Initialized(nonce::state::Data { - authority: nonce_pubkey, + let data = Versions::new_current(State::Initialized(nonce::state::Data::new( + nonce_pubkey, blockhash, - fee_calculator: FeeCalculator::default(), - })); + 0, + ))); let valid = Account::new_data(1, &data, &system_program::ID); assert!(check_nonce_account(&valid.unwrap(), &nonce_pubkey, &blockhash).is_ok()); @@ -938,11 +937,11 @@ mod tests { assert_eq!(err, Error::InvalidAccountData,); } - let data = Versions::new_current(State::Initialized(nonce::state::Data { - authority: nonce_pubkey, - blockhash: hash(b"invalid"), - fee_calculator: FeeCalculator::default(), - })); + let data = Versions::new_current(State::Initialized(nonce::state::Data::new( + nonce_pubkey, + hash(b"invalid"), + 0, + ))); let invalid_hash = Account::new_data(1, &data, &system_program::ID); if let CliError::InvalidNonce(err) = check_nonce_account(&invalid_hash.unwrap(), &nonce_pubkey, &blockhash).unwrap_err() @@ -950,11 +949,11 @@ mod tests { assert_eq!(err, Error::InvalidHash,); } - let data = Versions::new_current(State::Initialized(nonce::state::Data { - authority: solana_sdk::pubkey::new_rand(), + let data = Versions::new_current(State::Initialized(nonce::state::Data::new( + solana_sdk::pubkey::new_rand(), blockhash, - fee_calculator: FeeCalculator::default(), - })); + 0, + ))); let invalid_authority = Account::new_data(1, &data, &system_program::ID); if let CliError::InvalidNonce(err) = check_nonce_account(&invalid_authority.unwrap(), &nonce_pubkey, &blockhash).unwrap_err() @@ -995,11 +994,7 @@ mod tests { let mut nonce_account = nonce_account::create_account(1).into_inner(); assert_eq!(state_from_account(&nonce_account), Ok(State::Uninitialized)); - let data = nonce::state::Data { - authority: Pubkey::new(&[1u8; 32]), - blockhash: Hash::new(&[42u8; 32]), - fee_calculator: FeeCalculator::new(42), - }; + let data = nonce::state::Data::new(Pubkey::new(&[1u8; 32]), Hash::new(&[42u8; 32]), 42); nonce_account .set_state(&Versions::new_current(State::Initialized(data.clone()))) .unwrap(); @@ -1028,11 +1023,7 @@ mod tests { Err(Error::InvalidStateForOperation) ); - let data = nonce::state::Data { - authority: Pubkey::new(&[1u8; 32]), - blockhash: Hash::new(&[42u8; 32]), - fee_calculator: FeeCalculator::new(42), - }; + let data = nonce::state::Data::new(Pubkey::new(&[1u8; 32]), Hash::new(&[42u8; 32]), 42); nonce_account .set_state(&Versions::new_current(State::Initialized(data.clone()))) .unwrap(); diff --git a/core/src/test_validator.rs b/core/src/test_validator.rs index e54d2da38..df299eb0e 100644 --- a/core/src/test_validator.rs +++ b/core/src/test_validator.rs @@ -636,6 +636,7 @@ impl TestValidator { /// Return an RpcClient for the validator. As a convenience, also return a recent blockhash and /// associated fee calculator + #[deprecated(since = "1.9.0", note = "Please use `get_rpc_client` instead")] pub fn rpc_client(&self) -> (RpcClient, Hash, FeeCalculator) { let rpc_client = RpcClient::new_with_commitment(self.rpc_url.clone(), CommitmentConfig::processed()); @@ -647,6 +648,11 @@ impl TestValidator { (rpc_client, recent_blockhash, fee_calculator) } + /// Return an RpcClient for the validator. + pub fn get_rpc_client(&self) -> RpcClient { + RpcClient::new_with_commitment(self.rpc_url.clone(), CommitmentConfig::processed()) + } + pub fn join(mut self) { if let Some(validator) = self.validator.take() { validator.join(); diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index cbf61db93..ad193f670 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -25,7 +25,7 @@ use { entrypoint::{ProgramResult, SUCCESS}, epoch_schedule::EpochSchedule, feature_set::demote_program_write_locks, - fee_calculator::{FeeCalculator, FeeRateGovernor}, + fee_calculator::FeeRateGovernor, genesis_config::{ClusterType, GenesisConfig}, hash::Hash, instruction::Instruction, @@ -416,9 +416,9 @@ pub fn read_file>(path: P) -> Vec { file_data } -fn setup_fee_calculator(bank: Bank) -> Bank { - // Realistic fee_calculator part 1: Fake a single signature by calling - // `bank.commit_transactions()` so that the fee calculator in the child bank will be +fn setup_fees(bank: Bank) -> Bank { + // Realistic fees part 1: Fake a single signature by calling + // `bank.commit_transactions()` so that the fee in the child bank will be // initialized with a non-zero fee. assert_eq!(bank.signature_count(), 0); bank.commit_transactions( @@ -436,19 +436,15 @@ fn setup_fee_calculator(bank: Bank) -> Bank { let bank = Bank::new_from_parent(&bank, bank.collector_id(), bank.slot() + 1); debug!("Bank slot: {}", bank.slot()); - // Realistic fee_calculator part 2: Tick until a new blockhash is produced to pick up the - // non-zero fee calculator + // Realistic fees part 2: Tick until a new blockhash is produced to pick up the + // non-zero fees let last_blockhash = bank.last_blockhash(); while last_blockhash == bank.last_blockhash() { bank.register_tick(&Hash::new_unique()); } - let last_blockhash = bank.last_blockhash(); - // Make sure the new last_blockhash now requires a fee - #[allow(deprecated)] - let lamports_per_signature = bank - .get_fee_calculator(&last_blockhash) - .expect("fee_calculator") - .lamports_per_signature; + + // Make sure a fee is now required + let lamports_per_signature = bank.get_lamports_per_signature(); assert_ne!(lamports_per_signature, 0); bank @@ -807,7 +803,7 @@ impl ProgramTest { ..ComputeBudget::default() })); } - let bank = setup_fee_calculator(bank); + let bank = setup_fees(bank); let slot = bank.slot(); let last_blockhash = bank.last_blockhash(); let bank_forks = Arc::new(RwLock::new(BankForks::new(bank))); @@ -884,9 +880,10 @@ impl ProgramTest { } } +// TODO need to return lamports_per_signature? #[async_trait] pub trait ProgramTestBanksClientExt { - async fn get_new_blockhash(&mut self, blockhash: &Hash) -> io::Result<(Hash, FeeCalculator)>; + async fn get_new_blockhash(&mut self, blockhash: &Hash) -> io::Result<(Hash, u64)>; } #[async_trait] @@ -894,13 +891,13 @@ impl ProgramTestBanksClientExt for BanksClient { /// Get a new blockhash, similar in spirit to RpcClient::get_new_blockhash() /// /// This probably should eventually be moved into BanksClient proper in some form - async fn get_new_blockhash(&mut self, blockhash: &Hash) -> io::Result<(Hash, FeeCalculator)> { + async fn get_new_blockhash(&mut self, blockhash: &Hash) -> io::Result<(Hash, u64)> { let mut num_retries = 0; let start = Instant::now(); while start.elapsed().as_secs() < 5 { if let Ok((fee_calculator, new_blockhash, _slot)) = self.get_fees().await { if new_blockhash != *blockhash { - return Ok((new_blockhash, fee_calculator)); + return Ok((new_blockhash, fee_calculator.lamports_per_signature)); } } debug!("Got same blockhash ({:?}), will retry...", blockhash); diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index 1c6c2d7e0..5c295a91a 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -23,7 +23,7 @@ use solana_rbpf::{ vm::{Config, Executable, Tracer}, }; use solana_runtime::{ - bank::{Bank, ExecuteTimings, NonceRollbackInfo, TransactionBalancesSet, TransactionResults}, + bank::{Bank, ExecuteTimings, TransactionBalancesSet, TransactionResults}, bank_client::BankClient, genesis_utils::{create_genesis_config, GenesisConfigInfo}, loader_utils::{ @@ -42,7 +42,7 @@ use solana_sdk::{ instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}, keyed_account::KeyedAccount, loader_instruction, - message::Message, + message::{Message, SanitizedMessage}, process_instruction::{InvokeContext, MockInvokeContext}, pubkey::Pubkey, signature::{keypair_from_seed, Keypair, Signer}, @@ -56,8 +56,8 @@ use solana_transaction_status::{ TransactionStatusMeta, TransactionWithStatusMeta, UiTransactionEncoding, }; use std::{ - cell::RefCell, collections::HashMap, convert::TryInto, env, fs::File, io::Read, path::PathBuf, - str::FromStr, sync::Arc, + cell::RefCell, collections::HashMap, convert::TryFrom, convert::TryInto, env, fs::File, + io::Read, path::PathBuf, str::FromStr, sync::Arc, }; /// BPF program file extension @@ -370,13 +370,16 @@ fn execute_transactions(bank: &Bank, txs: Vec) -> Vec, ) -> RpcResponse { let bank = self.bank(commitment); - #[allow(deprecated)] - let (blockhash, fee_calculator) = bank.confirmed_last_blockhash_with_fee_calculator(); + let blockhash = bank.confirmed_last_blockhash(); + let lamports_per_signature = bank + .get_lamports_per_signature_for_blockhash(&blockhash) + .unwrap(); new_response( &bank, RpcBlockhashFeeCalculator { blockhash: blockhash.to_string(), - fee_calculator, + fee_calculator: FeeCalculator::new(lamports_per_signature), }, ) } fn get_fees(&self, commitment: Option) -> RpcResponse { let bank = self.bank(commitment); - #[allow(deprecated)] - let (blockhash, fee_calculator) = bank.confirmed_last_blockhash_with_fee_calculator(); + let blockhash = bank.confirmed_last_blockhash(); + let lamports_per_signature = bank + .get_lamports_per_signature_for_blockhash(&blockhash) + .unwrap(); #[allow(deprecated)] let last_valid_slot = bank .get_blockhash_last_valid_slot(&blockhash) @@ -572,7 +577,7 @@ impl JsonRpcRequestProcessor { &bank, RpcFees { blockhash: blockhash.to_string(), - fee_calculator, + fee_calculator: FeeCalculator::new(lamports_per_signature), last_valid_slot, last_valid_block_height, }, @@ -585,11 +590,12 @@ impl JsonRpcRequestProcessor { commitment: Option, ) -> RpcResponse> { let bank = self.bank(commitment); - #[allow(deprecated)] - let fee_calculator = bank.get_fee_calculator(blockhash); + let lamports_per_signature = bank.get_lamports_per_signature_for_blockhash(blockhash); new_response( &bank, - fee_calculator.map(|fee_calculator| RpcFeeCalculator { fee_calculator }), + lamports_per_signature.map(|lamports_per_signature| RpcFeeCalculator { + fee_calculator: FeeCalculator::new(lamports_per_signature), + }), ) } @@ -1967,7 +1973,7 @@ impl JsonRpcRequestProcessor { ) -> Result>> { let bank = self.bank(commitment); let fee = bank.get_fee_for_message(message); - Ok(new_response(&bank, fee)) + Ok(new_response(&bank, Some(fee))) } } @@ -5890,9 +5896,11 @@ pub mod tests { let bob_pubkey = solana_sdk::pubkey::new_rand(); let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx(&bob_pubkey); - #[allow(deprecated)] - let (blockhash, fee_calculator) = bank.last_blockhash_with_fee_calculator(); - let fee_calculator = RpcFeeCalculator { fee_calculator }; + let blockhash = bank.last_blockhash(); + let lamports_per_signature = bank.get_lamports_per_signature(); + let fee_calculator = RpcFeeCalculator { + fee_calculator: FeeCalculator::new(lamports_per_signature), + }; let req = format!( r#"{{"jsonrpc":"2.0","id":1,"method":"getFeeCalculatorForBlockhash","params":["{:?}"]}}"#, diff --git a/rpc/src/transaction_status_service.rs b/rpc/src/transaction_status_service.rs index bb4cf8564..9a1269023 100644 --- a/rpc/src/transaction_status_service.rs +++ b/rpc/src/transaction_status_service.rs @@ -5,9 +5,7 @@ use { blockstore::Blockstore, blockstore_processor::{TransactionStatusBatch, TransactionStatusMessage}, }, - solana_runtime::bank::{ - Bank, InnerInstructionsList, NonceRollbackInfo, TransactionLogMessages, - }, + solana_runtime::bank::{Bank, InnerInstructionsList, TransactionLogMessages}, solana_transaction_status::{ extract_and_fmt_memos, InnerInstructions, Reward, TransactionStatusMeta, }, @@ -105,16 +103,18 @@ impl TransactionStatusService { rent_debits, ) { if Bank::can_commit(&status) { - let fee_calculator = nonce_rollback - .map(|nonce_rollback| nonce_rollback.fee_calculator()) + let lamports_per_signature = nonce_rollback + .map(|nonce_rollback| nonce_rollback.lamports_per_signature()) .unwrap_or_else(|| { - #[allow(deprecated)] - bank.get_fee_calculator(transaction.message().recent_blockhash()) + bank.get_lamports_per_signature_for_blockhash( + transaction.message().recent_blockhash(), + ) }) - .expect("FeeCalculator must exist"); - let fee = transaction - .message() - .calculate_fee(fee_calculator.lamports_per_signature); + .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(bank.demote_program_write_locks()); diff --git a/runtime/src/accounts.rs b/runtime/src/accounts.rs index b6ba7c726..be6b17a53 100644 --- a/runtime/src/accounts.rs +++ b/runtime/src/accounts.rs @@ -8,7 +8,7 @@ use crate::{ accounts_update_notifier_interface::AccountsUpdateNotifier, ancestors::Ancestors, bank::{ - NonceRollbackFull, NonceRollbackInfo, RentDebits, TransactionCheckResult, + Bank, NonceRollbackFull, NonceRollbackInfo, RentDebits, TransactionCheckResult, TransactionExecutionResult, }, blockhash_queue::BlockhashQueue, @@ -27,7 +27,6 @@ use solana_sdk::{ bpf_loader_upgradeable::{self, UpgradeableLoaderState}, clock::{BankId, Slot, INITIAL_RENT_EPOCH}, feature_set::{self, FeatureSet}, - fee_calculator::FeeCalculator, genesis_config::ClusterType, hash::Hash, message::SanitizedMessage, @@ -475,18 +474,15 @@ impl Accounts { .zip(lock_results) .map(|etx| match etx { (tx, (Ok(()), nonce_rollback)) => { - let fee_calculator = nonce_rollback + let lamports_per_signature = nonce_rollback .as_ref() - .map(|nonce_rollback| nonce_rollback.fee_calculator()) + .map(|nonce_rollback| nonce_rollback.lamports_per_signature()) .unwrap_or_else(|| { #[allow(deprecated)] - hash_queue - .get_fee_calculator(tx.message().recent_blockhash()) - .cloned() + hash_queue.get_lamports_per_signature(tx.message().recent_blockhash()) }); - let fee = if let Some(fee_calculator) = fee_calculator { - tx.message() - .calculate_fee(fee_calculator.lamports_per_signature) + let fee = if let Some(lamports_per_signature) = lamports_per_signature { + Bank::calculate_fee(tx.message(), lamports_per_signature) } else { return (Err(TransactionError::BlockhashNotFound), None); }; @@ -969,7 +965,8 @@ impl Accounts { res: &'a [TransactionExecutionResult], loaded: &'a mut [TransactionLoadResult], rent_collector: &RentCollector, - last_blockhash_with_fee_calculator: &(Hash, FeeCalculator), + blockhash: &Hash, + lamports_per_signature: u64, rent_for_sysvars: bool, merge_nonce_error_into_system_error: bool, demote_program_write_locks: bool, @@ -979,7 +976,8 @@ impl Accounts { res, loaded, rent_collector, - last_blockhash_with_fee_calculator, + blockhash, + lamports_per_signature, rent_for_sysvars, merge_nonce_error_into_system_error, demote_program_write_locks, @@ -999,13 +997,15 @@ impl Accounts { self.accounts_db.add_root(slot) } + #[allow(clippy::too_many_arguments)] fn collect_accounts_to_store<'a>( &self, txs: &'a [SanitizedTransaction], res: &'a [TransactionExecutionResult], loaded: &'a mut [TransactionLoadResult], rent_collector: &RentCollector, - last_blockhash_with_fee_calculator: &(Hash, FeeCalculator), + blockhash: &Hash, + lamports_per_signature: u64, rent_for_sysvars: bool, merge_nonce_error_into_system_error: bool, demote_program_write_locks: bool, @@ -1051,7 +1051,8 @@ impl Accounts { key, res, maybe_nonce_rollback, - last_blockhash_with_fee_calculator, + blockhash, + lamports_per_signature, ); if fee_payer_index.is_none() { fee_payer_index = Some(i); @@ -1103,7 +1104,8 @@ pub fn prepare_if_nonce_account( Option<&AccountSharedData>, bool, )>, - last_blockhash_with_fee_calculator: &(Hash, FeeCalculator), + blockhash: &Hash, + lamports_per_signature: u64, ) -> bool { if let Some((nonce_key, nonce_acc, _maybe_fee_account, advance_blockhash)) = maybe_nonce_rollback @@ -1125,11 +1127,7 @@ pub fn prepare_if_nonce_account( .convert_to_current(); if let nonce::State::Initialized(ref data) = state { let new_data = nonce::state::Versions::new_current(nonce::State::Initialized( - nonce::state::Data { - blockhash: last_blockhash_with_fee_calculator.0, - fee_calculator: last_blockhash_with_fee_calculator.1.clone(), - ..data.clone() - }, + nonce::state::Data::new(data.authority, *blockhash, lamports_per_signature), )); account.set_state(&new_data).unwrap(); } @@ -1172,7 +1170,6 @@ mod tests { use solana_sdk::{ account::{AccountSharedData, WritableAccount}, epoch_schedule::EpochSchedule, - fee_calculator::FeeCalculator, genesis_config::ClusterType, hash::Hash, instruction::{CompiledInstruction, InstructionError}, @@ -1201,12 +1198,12 @@ mod tests { fn load_accounts_with_fee_and_rent( tx: Transaction, ka: &[(Pubkey, AccountSharedData)], - fee_calculator: &FeeCalculator, + lamports_per_signature: u64, rent_collector: &RentCollector, error_counters: &mut ErrorCounters, ) -> Vec { let mut hash_queue = BlockhashQueue::new(100); - hash_queue.register_hash(&tx.message().recent_blockhash, fee_calculator); + hash_queue.register_hash(&tx.message().recent_blockhash, lamports_per_signature); let accounts = Accounts::new_with_config_for_tests( Vec::new(), &ClusterType::Development, @@ -1234,11 +1231,16 @@ mod tests { fn load_accounts_with_fee( tx: Transaction, ka: &[(Pubkey, AccountSharedData)], - fee_calculator: &FeeCalculator, + lamports_per_signature: u64, error_counters: &mut ErrorCounters, ) -> Vec { - let rent_collector = RentCollector::default(); - load_accounts_with_fee_and_rent(tx, ka, fee_calculator, &rent_collector, error_counters) + load_accounts_with_fee_and_rent( + tx, + ka, + lamports_per_signature, + &RentCollector::default(), + error_counters, + ) } fn load_accounts( @@ -1246,8 +1248,7 @@ mod tests { ka: &[(Pubkey, AccountSharedData)], error_counters: &mut ErrorCounters, ) -> Vec { - let fee_calculator = FeeCalculator::default(); - load_accounts_with_fee(tx, ka, &fee_calculator, error_counters) + load_accounts_with_fee(tx, ka, 0, error_counters) } #[test] @@ -1383,13 +1384,13 @@ mod tests { instructions, ); - let fee_calculator = FeeCalculator::new(10); - #[allow(deprecated)] - let fee = fee_calculator.calculate_fee(tx.message()); + let fee = Bank::calculate_fee( + &SanitizedMessage::try_from(tx.message().clone()).unwrap(), + 10, + ); assert_eq!(fee, 10); - let loaded_accounts = - load_accounts_with_fee(tx, &accounts, &fee_calculator, &mut error_counters); + let loaded_accounts = load_accounts_with_fee(tx, &accounts, 10, &mut error_counters); assert_eq!(error_counters.insufficient_funds, 1); assert_eq!(loaded_accounts.len(), 1); @@ -1442,7 +1443,6 @@ mod tests { }, ); let min_balance = rent_collector.rent.minimum_balance(nonce::State::size()); - let fee_calculator = FeeCalculator::new(min_balance); let nonce = Keypair::new(); let mut accounts = vec![( nonce.pubkey(), @@ -1468,7 +1468,7 @@ mod tests { let loaded_accounts = load_accounts_with_fee_and_rent( tx.clone(), &accounts, - &fee_calculator, + min_balance, &rent_collector, &mut error_counters, ); @@ -1482,7 +1482,7 @@ mod tests { let loaded_accounts = load_accounts_with_fee_and_rent( tx.clone(), &accounts, - &fee_calculator, + min_balance, &rent_collector, &mut error_counters, ); @@ -1495,7 +1495,7 @@ mod tests { let loaded_accounts = load_accounts_with_fee_and_rent( tx, &accounts, - &fee_calculator, + min_balance, &rent_collector, &mut error_counters, ); @@ -2403,7 +2403,8 @@ mod tests { &programs, loaded.as_mut_slice(), &rent_collector, - &(Hash::default(), FeeCalculator::default()), + &Hash::default(), + 0, true, true, // merge_nonce_error_into_system_error true, // demote_program_write_locks @@ -2461,9 +2462,8 @@ mod tests { fn load_accounts_no_store(accounts: &Accounts, tx: Transaction) -> Vec { let tx = SanitizedTransaction::try_from(tx).unwrap(); let rent_collector = RentCollector::default(); - let fee_calculator = FeeCalculator::new(10); let mut hash_queue = BlockhashQueue::new(100); - hash_queue.register_hash(tx.message().recent_blockhash(), &fee_calculator); + hash_queue.register_hash(tx.message().recent_blockhash(), 10); let ancestors = vec![(0, 0)].into_iter().collect(); let mut error_counters = ErrorCounters::default(); @@ -2510,7 +2510,7 @@ mod tests { AccountSharedData, AccountSharedData, Hash, - FeeCalculator, + u64, Option, ) { let data = nonce::state::Versions::new_current(nonce::State::Initialized( @@ -2524,9 +2524,7 @@ mod tests { pre_account, account, Hash::new(&[1u8; 32]), - FeeCalculator { - lamports_per_signature: 1234, - }, + 1234, None, ) } @@ -2541,7 +2539,8 @@ mod tests { Option<&AccountSharedData>, bool, )>, - last_blockhash_with_fee_calculator: &(Hash, FeeCalculator), + blockhash: &Hash, + lamports_per_signature: u64, expect_account: &AccountSharedData, ) -> bool { // Verify expect_account's relationship @@ -2564,7 +2563,8 @@ mod tests { account_pubkey, tx_result, maybe_nonce_rollback, - last_blockhash_with_fee_calculator, + blockhash, + lamports_per_signature, ); expect_account == account } @@ -2575,8 +2575,8 @@ mod tests { pre_account_pubkey, pre_account, mut post_account, - last_blockhash, - last_fee_calculator, + blockhash, + lamports_per_signature, maybe_fee_account, ) = create_accounts_prepare_if_nonce_account(); let post_account_pubkey = pre_account_pubkey; @@ -2597,7 +2597,8 @@ mod tests { maybe_fee_account.as_ref(), false, )), - &(last_blockhash, last_fee_calculator), + &blockhash, + lamports_per_signature, &expect_account, )); } @@ -2608,8 +2609,8 @@ mod tests { pre_account_pubkey, _pre_account, _post_account, - last_blockhash, - last_fee_calculator, + blockhash, + lamports_per_signature, _maybe_fee_account, ) = create_accounts_prepare_if_nonce_account(); let post_account_pubkey = pre_account_pubkey; @@ -2621,7 +2622,8 @@ mod tests { &post_account_pubkey, &Ok(()), None, - &(last_blockhash, last_fee_calculator), + &blockhash, + lamports_per_signature, &expect_account, )); } @@ -2632,8 +2634,8 @@ mod tests { pre_account_pubkey, pre_account, mut post_account, - last_blockhash, - last_fee_calculator, + blockhash, + lamports_per_signature, maybe_fee_account, ) = create_accounts_prepare_if_nonce_account(); @@ -2649,7 +2651,8 @@ mod tests { maybe_fee_account.as_ref(), true, )), - &(last_blockhash, last_fee_calculator), + &blockhash, + lamports_per_signature, &expect_account, )); } @@ -2660,8 +2663,8 @@ mod tests { pre_account_pubkey, pre_account, mut post_account, - last_blockhash, - last_fee_calculator, + blockhash, + lamports_per_signature, maybe_fee_account, ) = create_accounts_prepare_if_nonce_account(); let post_account_pubkey = pre_account_pubkey; @@ -2669,11 +2672,11 @@ mod tests { let mut expect_account = pre_account.clone(); expect_account .set_state(&nonce::state::Versions::new_current( - nonce::State::Initialized(nonce::state::Data { - blockhash: last_blockhash, - fee_calculator: last_fee_calculator.clone(), - ..nonce::state::Data::default() - }), + nonce::State::Initialized(nonce::state::Data::new( + Pubkey::default(), + blockhash, + lamports_per_signature, + )), )) .unwrap(); @@ -2690,7 +2693,8 @@ mod tests { maybe_fee_account.as_ref(), true, )), - &(last_blockhash, last_fee_calculator), + &blockhash, + lamports_per_signature, &expect_account, )); } @@ -2704,12 +2708,9 @@ mod tests { let from = keypair_from_seed(&[1; 32]).unwrap(); let from_address = from.pubkey(); let to_address = Pubkey::new_unique(); - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash: Hash::new_unique(), - fee_calculator: FeeCalculator::default(), - })); + let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(nonce_authority.pubkey(), Hash::new_unique(), 0), + )); let nonce_account_post = AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); let from_account_post = AccountSharedData::new(4199, 0, &Pubkey::default()); @@ -2732,12 +2733,9 @@ mod tests { ]; let tx = new_sanitized_tx(&[&nonce_authority, &from], message, blockhash); - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash, - fee_calculator: FeeCalculator::default(), - })); + let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(nonce_authority.pubkey(), Hash::new_unique(), 0), + )); let nonce_account_pre = AccountSharedData::new_data(42, &nonce_state, &system_program::id()).unwrap(); let from_account_pre = AccountSharedData::new(4242, 0, &Pubkey::default()); @@ -2781,7 +2779,8 @@ mod tests { &programs, loaded.as_mut_slice(), &rent_collector, - &(next_blockhash, FeeCalculator::default()), + &next_blockhash, + 0, true, true, // merge_nonce_error_into_system_error true, // demote_program_write_locks @@ -2821,12 +2820,9 @@ mod tests { let from = keypair_from_seed(&[1; 32]).unwrap(); let from_address = from.pubkey(); let to_address = Pubkey::new_unique(); - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash: Hash::new_unique(), - fee_calculator: FeeCalculator::default(), - })); + let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(nonce_authority.pubkey(), Hash::new_unique(), 0), + )); let nonce_account_post = AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); let from_account_post = AccountSharedData::new(4200, 0, &Pubkey::default()); @@ -2849,12 +2845,9 @@ mod tests { ]; let tx = new_sanitized_tx(&[&nonce_authority, &from], message, blockhash); - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: nonce_authority.pubkey(), - blockhash, - fee_calculator: FeeCalculator::default(), - })); + let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(nonce_authority.pubkey(), Hash::new_unique(), 0), + )); let nonce_account_pre = AccountSharedData::new_data(42, &nonce_state, &system_program::id()).unwrap(); @@ -2897,7 +2890,8 @@ mod tests { &programs, loaded.as_mut_slice(), &rent_collector, - &(next_blockhash, FeeCalculator::default()), + &next_blockhash, + 0, true, true, // merge_nonce_error_into_system_error true, // demote_program_write_locks diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 914f4c672..9e6537446 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -86,10 +86,11 @@ use solana_sdk::{ MAX_TRANSACTION_FORWARDING_DELAY, SECONDS_PER_DAY, }, compute_budget::ComputeBudget, + ed25519_program, epoch_info::EpochInfo, epoch_schedule::EpochSchedule, feature, - feature_set::{self, tx_wide_compute_cap, FeatureSet}, + feature_set::{self, disable_fee_calculator, tx_wide_compute_cap, FeatureSet}, fee_calculator::{FeeCalculator, FeeRateGovernor}, genesis_config::{ClusterType, GenesisConfig}, hard_forks::HardForks, @@ -107,6 +108,7 @@ use solana_sdk::{ process_instruction::{ComputeMeter, Executor, ProcessInstructionWithContext}, program_utils::limited_deserialize, pubkey::Pubkey, + secp256k1_program, signature::{Keypair, Signature}, slot_hashes::SlotHashes, slot_history::SlotHistory, @@ -563,7 +565,7 @@ pub struct TransactionLogCollector { pub trait NonceRollbackInfo { fn nonce_address(&self) -> &Pubkey; fn nonce_account(&self) -> &AccountSharedData; - fn fee_calculator(&self) -> Option; + fn lamports_per_signature(&self) -> Option; fn fee_account(&self) -> Option<&AccountSharedData>; } @@ -589,8 +591,8 @@ impl NonceRollbackInfo for NonceRollbackPartial { fn nonce_account(&self) -> &AccountSharedData { &self.nonce_account } - fn fee_calculator(&self) -> Option { - nonce_account::fee_calculator_of(&self.nonce_account) + fn lamports_per_signature(&self) -> Option { + nonce_account::lamports_per_signature_of(&self.nonce_account) } fn fee_account(&self) -> Option<&AccountSharedData> { None @@ -652,6 +654,9 @@ impl NonceRollbackFull { Err(TransactionError::AccountNotFound) } } + pub fn lamports_per_signature(&self) -> Option { + nonce_account::lamports_per_signature_of(&self.nonce_account) + } } impl NonceRollbackInfo for NonceRollbackFull { @@ -661,8 +666,8 @@ impl NonceRollbackInfo for NonceRollbackFull { fn nonce_account(&self) -> &AccountSharedData { &self.nonce_account } - fn fee_calculator(&self) -> Option { - nonce_account::fee_calculator_of(&self.nonce_account) + fn lamports_per_signature(&self) -> Option { + nonce_account::lamports_per_signature_of(&self.nonce_account) } fn fee_account(&self) -> Option<&AccountSharedData> { self.fee_account.as_ref() @@ -929,6 +934,7 @@ pub struct Bank { /// Fees that have been collected collector_fees: AtomicU64, + /// Deprecated, do not use /// Latest transaction fees for transactions processed by this bank fee_calculator: FeeCalculator, @@ -1322,6 +1328,12 @@ impl Bank { let fee_rate_governor = FeeRateGovernor::new_derived(&parent.fee_rate_governor, parent.signature_count()); + let fee_calculator = if parent.feature_set.is_active(&disable_fee_calculator::id()) { + FeeCalculator::default() + } else { + fee_rate_governor.create_fee_calculator() + }; + let bank_id = rc.bank_id_generator.fetch_add(1, Relaxed) + 1; let mut new = Bank { rc, @@ -1343,7 +1355,7 @@ impl Bank { rent_collector: parent.rent_collector.clone_with_epoch(epoch), max_tick_height: (slot + 1) * parent.ticks_per_slot, block_height: parent.block_height + 1, - fee_calculator: fee_rate_governor.create_fee_calculator(), + fee_calculator, fee_rate_governor, capitalization: AtomicU64::new(parent.capitalization()), vote_only_bank, @@ -1612,11 +1624,14 @@ impl Bank { ); assert_eq!(bank.epoch_schedule, genesis_config.epoch_schedule); assert_eq!(bank.epoch, bank.epoch_schedule.get_epoch(bank.slot)); - bank.fee_rate_governor.lamports_per_signature = bank.fee_calculator.lamports_per_signature; - assert_eq!( - bank.fee_rate_governor.create_fee_calculator(), - bank.fee_calculator - ); + if !bank.feature_set.is_active(&disable_fee_calculator::id()) { + bank.fee_rate_governor.lamports_per_signature = + bank.fee_calculator.lamports_per_signature; + assert_eq!( + bank.fee_rate_governor.create_fee_calculator(), + bank.fee_calculator + ); + } bank } @@ -1934,7 +1949,7 @@ impl Bank { { self.update_sysvar_account(&sysvar::fees::id(), |account| { create_account( - &sysvar::fees::Fees::new(&self.fee_calculator), + &sysvar::fees::Fees::new(&self.fee_rate_governor.create_fee_calculator()), self.inherit_specially_retained_account_fields(account), ) }); @@ -2942,10 +2957,10 @@ impl Bank { .highest_staked_node() .unwrap_or_default(); - self.blockhash_queue - .write() - .unwrap() - .genesis_hash(&genesis_config.hash(), &self.fee_calculator); + self.blockhash_queue.write().unwrap().genesis_hash( + &genesis_config.hash(), + self.fee_rate_governor.lamports_per_signature, + ); self.hashes_per_tick = genesis_config.hashes_per_tick(); self.ticks_per_slot = genesis_config.ticks_per_slot(); @@ -3089,28 +3104,13 @@ impl Bank { self.rent_collector.rent.minimum_balance(data_len).max(1) } - #[deprecated( - since = "1.8.0", - note = "Please use `last_blockhash` and `get_fee_for_message` instead" - )] - pub fn last_blockhash_with_fee_calculator(&self) -> (Hash, FeeCalculator) { - let blockhash_queue = self.blockhash_queue.read().unwrap(); - let last_hash = blockhash_queue.last_hash(); - ( - last_hash, - #[allow(deprecated)] - blockhash_queue - .get_fee_calculator(&last_hash) - .unwrap() - .clone(), - ) + pub fn get_lamports_per_signature(&self) -> u64 { + self.fee_rate_governor.lamports_per_signature } - #[deprecated(since = "1.8.0", note = "Please use `get_fee_for_message` instead")] - pub fn get_fee_calculator(&self, hash: &Hash) -> Option { + pub fn get_lamports_per_signature_for_blockhash(&self, hash: &Hash) -> Option { let blockhash_queue = self.blockhash_queue.read().unwrap(); - #[allow(deprecated)] - blockhash_queue.get_fee_calculator(hash).cloned() + blockhash_queue.get_lamports_per_signature(hash) } #[deprecated(since = "1.8.0", note = "Please use `get_fee_for_message` instead")] @@ -3118,8 +3118,15 @@ impl Bank { &self.fee_rate_governor } - pub fn get_fee_for_message(&self, message: &SanitizedMessage) -> Option { - Some(message.calculate_fee(self.fee_rate_governor.lamports_per_signature)) + pub fn get_fee_for_message(&self, message: &SanitizedMessage) -> u64 { + Self::calculate_fee(message, self.fee_rate_governor.lamports_per_signature) + } + + pub fn get_fee_for_message_with_lamports_per_signature( + message: &SanitizedMessage, + lamports_per_signature: u64, + ) -> u64 { + Self::calculate_fee(message, lamports_per_signature) } #[deprecated( @@ -3144,24 +3151,6 @@ impl Bank { .map(|age| self.block_height + blockhash_queue.len() as u64 - age) } - #[deprecated( - since = "1.8.0", - note = "Please use `confirmed_last_blockhash` and `get_fee_for_message` instead" - )] - pub fn confirmed_last_blockhash_with_fee_calculator(&self) -> (Hash, FeeCalculator) { - const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3; - - let parents = self.parents(); - if parents.is_empty() { - #[allow(deprecated)] - self.last_blockhash_with_fee_calculator() - } else { - let index = NUM_BLOCKHASH_CONFIRMATIONS.min(parents.len() - 1); - #[allow(deprecated)] - parents[index].last_blockhash_with_fee_calculator() - } - } - pub fn confirmed_last_blockhash(&self) -> Hash { const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3; @@ -3238,7 +3227,7 @@ impl Bank { inc_new_counter_debug!("bank-register_tick-registered", 1); let mut w_blockhash_queue = self.blockhash_queue.write().unwrap(); if self.is_block_boundary(self.tick_height.load(Relaxed) + 1) { - w_blockhash_queue.register_hash(hash, &self.fee_calculator); + w_blockhash_queue.register_hash(hash, self.fee_rate_governor.lamports_per_signature); self.update_recent_blockhashes_locked(&w_blockhash_queue); } // ReplayStage will start computing the accounts delta hash when it @@ -3847,16 +3836,14 @@ impl Bank { compute_budget.max_units, ))); - let (blockhash, fee_calculator) = { + let (blockhash, lamports_per_signature) = { let blockhash_queue = self.blockhash_queue.read().unwrap(); let blockhash = blockhash_queue.last_hash(); ( blockhash, - #[allow(deprecated)] blockhash_queue - .get_fee_calculator(&blockhash) - .cloned() - .unwrap_or_else(|| self.fee_calculator.clone()), + .get_lamports_per_signature(&blockhash) + .unwrap_or(self.fee_rate_governor.lamports_per_signature), ) }; @@ -3877,7 +3864,7 @@ impl Bank { self.rc.accounts.clone(), &self.ancestors, blockhash, - fee_calculator, + lamports_per_signature, ); } else { // TODO: support versioned messages @@ -4022,6 +4009,20 @@ impl Bank { ) } + /// Calculate fee for `SanitizedMessage` + pub fn calculate_fee(message: &SanitizedMessage, lamports_per_signature: u64) -> u64 { + let mut num_signatures = u64::from(message.header().num_required_signatures); + for (program_id, instruction) in message.program_instructions_iter() { + if secp256k1_program::check_id(program_id) || ed25519_program::check_id(program_id) { + if let Some(num_verifies) = instruction.data.get(0) { + num_signatures = num_signatures.saturating_add(u64::from(*num_verifies)); + } + } + } + + lamports_per_signature.saturating_mul(num_signatures) + } + fn filter_program_errors_and_collect_fee( &self, txs: &[SanitizedTransaction], @@ -4034,24 +4035,20 @@ impl Bank { .iter() .zip(executed) .map(|(tx, (res, nonce_rollback))| { - let (fee_calculator, is_durable_nonce) = nonce_rollback + let (lamports_per_signature, is_durable_nonce) = nonce_rollback .as_ref() - .map(|nonce_rollback| nonce_rollback.fee_calculator()) - .map(|maybe_fee_calculator| (maybe_fee_calculator, true)) + .map(|nonce_rollback| nonce_rollback.lamports_per_signature()) + .map(|maybe_lamports_per_signature| (maybe_lamports_per_signature, true)) .unwrap_or_else(|| { ( - #[allow(deprecated)] - hash_queue - .get_fee_calculator(tx.message().recent_blockhash()) - .cloned(), + hash_queue.get_lamports_per_signature(tx.message().recent_blockhash()), false, ) }); - let fee_calculator = fee_calculator.ok_or(TransactionError::BlockhashNotFound)?; - let fee = tx - .message() - .calculate_fee(fee_calculator.lamports_per_signature); + let lamports_per_signature = + lamports_per_signature.ok_or(TransactionError::BlockhashNotFound)?; + let fee = Self::calculate_fee(tx.message(), lamports_per_signature); match *res { Err(TransactionError::InstructionError(_, _)) => { @@ -4118,14 +4115,14 @@ impl Bank { } let mut write_time = Measure::start("write_time"); - #[allow(deprecated)] self.rc.accounts.store_cached( self.slot(), sanitized_txs, executed, loaded_txs, &self.rent_collector, - &self.last_blockhash_with_fee_calculator(), + &self.last_blockhash(), + self.get_lamports_per_signature(), self.rent_for_sysvars(), self.merge_nonce_error_into_system_error(), self.demote_program_write_locks(), @@ -6376,20 +6373,24 @@ pub(crate) mod tests { fn test_nonce_rollback_info() { let nonce_authority = keypair_from_seed(&[0; 32]).unwrap(); let nonce_address = nonce_authority.pubkey(); - let fee_calculator = FeeCalculator::new(42); - let state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: Pubkey::default(), - blockhash: Hash::new_unique(), - fee_calculator: fee_calculator.clone(), - })); + let lamports_per_signature = 42; + let state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new( + Pubkey::default(), + Hash::new_unique(), + lamports_per_signature, + ), + )); let nonce_account = AccountSharedData::new_data(43, &state, &system_program::id()).unwrap(); // NonceRollbackPartial create + NonceRollbackInfo impl let partial = NonceRollbackPartial::new(nonce_address, nonce_account.clone()); assert_eq!(*partial.nonce_address(), nonce_address); assert_eq!(*partial.nonce_account(), nonce_account); - assert_eq!(partial.fee_calculator(), Some(fee_calculator.clone())); + assert_eq!( + partial.lamports_per_signature(), + Some(lamports_per_signature) + ); assert_eq!(partial.fee_account(), None); let from = keypair_from_seed(&[1; 32]).unwrap(); @@ -6418,7 +6419,7 @@ pub(crate) mod tests { let full = NonceRollbackFull::from_partial(partial.clone(), &message, &accounts).unwrap(); assert_eq!(*full.nonce_address(), nonce_address); assert_eq!(*full.nonce_account(), nonce_account); - assert_eq!(full.fee_calculator(), Some(fee_calculator)); + assert_eq!(full.lamports_per_signature(), Some(lamports_per_signature)); assert_eq!(full.fee_account(), Some(&from_account)); let message = new_sanitized_message(&instructions, Some(&nonce_address)); @@ -8949,19 +8950,15 @@ pub(crate) mod tests { let mut bank = Bank::new_for_tests(&genesis_config); goto_end_of_slot(&mut bank); - #[allow(deprecated)] - let (cheap_blockhash, cheap_fee_calculator) = bank.last_blockhash_with_fee_calculator(); - assert_eq!(cheap_fee_calculator.lamports_per_signature, 0); + let cheap_blockhash = bank.last_blockhash(); + let cheap_lamports_per_signature = bank.get_lamports_per_signature(); + assert_eq!(cheap_lamports_per_signature, 0); let mut bank = Bank::new_from_parent(&Arc::new(bank), &leader, 1); goto_end_of_slot(&mut bank); - #[allow(deprecated)] - let (expensive_blockhash, expensive_fee_calculator) = - bank.last_blockhash_with_fee_calculator(); - assert!( - cheap_fee_calculator.lamports_per_signature - < expensive_fee_calculator.lamports_per_signature - ); + let expensive_blockhash = bank.last_blockhash(); + let expensive_lamports_per_signature = bank.get_lamports_per_signature(); + assert!(cheap_lamports_per_signature < expensive_lamports_per_signature); let bank = Bank::new_from_parent(&Arc::new(bank), &leader, 2); @@ -8973,7 +8970,7 @@ pub(crate) mod tests { assert_eq!(bank.get_balance(&key.pubkey()), 1); assert_eq!( bank.get_balance(&mint_keypair.pubkey()), - initial_mint_balance - 1 - cheap_fee_calculator.lamports_per_signature + initial_mint_balance - 1 - cheap_lamports_per_signature ); // Send a transfer using expensive_blockhash @@ -8984,7 +8981,7 @@ pub(crate) mod tests { assert_eq!(bank.get_balance(&key.pubkey()), 1); assert_eq!( bank.get_balance(&mint_keypair.pubkey()), - initial_mint_balance - 1 - expensive_fee_calculator.lamports_per_signature + initial_mint_balance - 1 - expensive_lamports_per_signature ); } @@ -9028,7 +9025,7 @@ pub(crate) mod tests { initial_balance + bank .fee_rate_governor - .burn(bank.fee_calculator.lamports_per_signature * 2) + .burn(bank.fee_rate_governor.lamports_per_signature * 2) .0 ); assert_eq!(results[0], Ok(())); @@ -9937,7 +9934,7 @@ pub(crate) mod tests { solana_logger::setup(); let (genesis_config, mint_keypair) = create_genesis_config(500); let mut bank = Bank::new_for_tests(&genesis_config); - bank.fee_calculator.lamports_per_signature = 2; + bank.fee_rate_governor.lamports_per_signature = 2; let key = Keypair::new(); let mut transfer_instruction = @@ -10175,7 +10172,7 @@ pub(crate) mod tests { let fees_account = bank.get_account(&sysvar::fees::id()).unwrap(); let fees = from_account::(&fees_account).unwrap(); assert_eq!( - bank.fee_calculator.lamports_per_signature, + bank.fee_rate_governor.lamports_per_signature, fees.fee_calculator.lamports_per_signature ); assert_eq!(fees.fee_calculator.lamports_per_signature, 12345); @@ -10936,10 +10933,8 @@ pub(crate) mod tests { assert_eq!(bank.process_transaction(&durable_tx), Ok(())); /* Check balances */ - let mut expected_balance = 4_650_000 - - bank - .get_fee_for_message(&durable_tx.message.try_into().unwrap()) - .unwrap(); + let mut expected_balance = + 4_650_000 - bank.get_fee_for_message(&durable_tx.message.try_into().unwrap()); assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance); assert_eq!(bank.get_balance(&nonce_pubkey), 250_000); assert_eq!(bank.get_balance(&alice_pubkey), 100_000); @@ -10992,8 +10987,7 @@ pub(crate) mod tests { ); /* Check fee charged and nonce has advanced */ expected_balance -= bank - .get_fee_for_message(&SanitizedMessage::try_from(durable_tx.message.clone()).unwrap()) - .unwrap(); + .get_fee_for_message(&SanitizedMessage::try_from(durable_tx.message.clone()).unwrap()); assert_eq!(bank.get_balance(&custodian_pubkey), expected_balance); assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap()); /* Confirm replaying a TX that failed with InstructionError::* now @@ -11055,9 +11049,7 @@ pub(crate) mod tests { assert_eq!( bank.get_balance(&custodian_pubkey), initial_custodian_balance - - bank - .get_fee_for_message(&durable_tx.message.try_into().unwrap()) - .unwrap() + - bank.get_fee_for_message(&durable_tx.message.try_into().unwrap()) ); assert_eq!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap()); } @@ -11107,9 +11099,7 @@ pub(crate) mod tests { assert_eq!( bank.get_balance(&nonce_pubkey), nonce_starting_balance - - bank - .get_fee_for_message(&durable_tx.message.try_into().unwrap()) - .unwrap() + - bank.get_fee_for_message(&durable_tx.message.try_into().unwrap()) ); assert_ne!(nonce_hash, get_nonce_account(&bank, &nonce_pubkey).unwrap()); } @@ -15017,4 +15007,61 @@ pub(crate) mod tests { // even if the program itself is not called bank.process_transaction(&tx).unwrap(); } + + #[test] + fn test_calculate_fee() { + // Default: no fee. + let message = + SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap(); + assert_eq!(Bank::calculate_fee(&message, 0), 0); + + // One signature, a fee. + assert_eq!(Bank::calculate_fee(&message, 1), 1); + + // Two signatures, double the fee. + let key0 = Pubkey::new_unique(); + let key1 = Pubkey::new_unique(); + let ix0 = system_instruction::transfer(&key0, &key1, 1); + let ix1 = system_instruction::transfer(&key1, &key0, 1); + let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap(); + assert_eq!(Bank::calculate_fee(&message, 2), 4); + } + + #[test] + fn test_calculate_fee_secp256k1() { + let key0 = Pubkey::new_unique(); + let key1 = Pubkey::new_unique(); + let ix0 = system_instruction::transfer(&key0, &key1, 1); + + let mut secp_instruction1 = Instruction { + program_id: secp256k1_program::id(), + accounts: vec![], + data: vec![], + }; + let mut secp_instruction2 = Instruction { + program_id: secp256k1_program::id(), + accounts: vec![], + data: vec![1], + }; + + let message = SanitizedMessage::try_from(Message::new( + &[ + ix0.clone(), + secp_instruction1.clone(), + secp_instruction2.clone(), + ], + Some(&key0), + )) + .unwrap(); + assert_eq!(Bank::calculate_fee(&message, 1), 2); + + secp_instruction1.data = vec![0]; + secp_instruction2.data = vec![10]; + let message = SanitizedMessage::try_from(Message::new( + &[ix0, secp_instruction1, secp_instruction2], + Some(&key0), + )) + .unwrap(); + assert_eq!(Bank::calculate_fee(&message, 1), 11); + } } diff --git a/runtime/src/bank_client.rs b/runtime/src/bank_client.rs index cf5b049e6..a2b356ffb 100644 --- a/runtime/src/bank_client.rs +++ b/runtime/src/bank_client.rs @@ -149,27 +149,34 @@ impl SyncClient for BankClient { } fn get_recent_blockhash(&self) -> Result<(Hash, FeeCalculator)> { - #[allow(deprecated)] - Ok(self.bank.last_blockhash_with_fee_calculator()) + Ok(( + self.bank.last_blockhash(), + FeeCalculator::new(self.bank.get_lamports_per_signature()), + )) } fn get_recent_blockhash_with_commitment( &self, _commitment_config: CommitmentConfig, ) -> Result<(Hash, FeeCalculator, u64)> { - #[allow(deprecated)] - let (blockhash, fee_calculator) = self.bank.last_blockhash_with_fee_calculator(); + let blockhash = self.bank.last_blockhash(); #[allow(deprecated)] let last_valid_slot = self .bank .get_blockhash_last_valid_slot(&blockhash) .expect("bank blockhash queue should contain blockhash"); - Ok((blockhash, fee_calculator, last_valid_slot)) + Ok(( + blockhash, + FeeCalculator::new(self.bank.get_lamports_per_signature()), + last_valid_slot, + )) } fn get_fee_calculator_for_blockhash(&self, blockhash: &Hash) -> Result> { - #[allow(deprecated)] - Ok(self.bank.get_fee_calculator(blockhash)) + Ok(self + .bank + .get_lamports_per_signature_for_blockhash(blockhash) + .map(FeeCalculator::new)) } fn get_fee_rate_governor(&self) -> Result { @@ -263,10 +270,12 @@ impl SyncClient for BankClient { } fn get_new_blockhash(&self, blockhash: &Hash) -> Result<(Hash, FeeCalculator)> { - #[allow(deprecated)] - let (recent_blockhash, fee_calculator) = self.get_recent_blockhash()?; + let recent_blockhash = self.get_latest_blockhash()?; if recent_blockhash != *blockhash { - Ok((recent_blockhash, fee_calculator)) + Ok(( + recent_blockhash, + FeeCalculator::new(self.bank.get_lamports_per_signature()), + )) } else { Err(TransportError::IoError(io::Error::new( io::ErrorKind::Other, @@ -305,9 +314,8 @@ impl SyncClient for BankClient { fn get_fee_for_message(&self, message: &Message) -> Result { SanitizedMessage::try_from(message.clone()) - .ok() - .and_then(|message| self.bank.get_fee_for_message(&message)) - .ok_or_else(|| { + .map(|message| self.bank.get_fee_for_message(&message)) + .map_err(|_| { TransportError::IoError(io::Error::new( io::ErrorKind::Other, "Unable calculate fee", diff --git a/runtime/src/blockhash_queue.rs b/runtime/src/blockhash_queue.rs index 07e5afafd..8f39d7ea3 100644 --- a/runtime/src/blockhash_queue.rs +++ b/runtime/src/blockhash_queue.rs @@ -46,12 +46,10 @@ impl BlockhashQueue { self.last_hash.expect("no hash has been set") } - #[deprecated( - since = "1.8.0", - note = "Please do not use, will no longer be available in the future" - )] - pub fn get_fee_calculator(&self, hash: &Hash) -> Option<&FeeCalculator> { - self.ages.get(hash).map(|hash_age| &hash_age.fee_calculator) + pub fn get_lamports_per_signature(&self, hash: &Hash) -> Option { + self.ages + .get(hash) + .map(|hash_age| hash_age.fee_calculator.lamports_per_signature) } /// Check if the age of the hash is within the max_age @@ -74,11 +72,11 @@ impl BlockhashQueue { self.ages.get(hash).is_some() } - pub fn genesis_hash(&mut self, hash: &Hash, fee_calculator: &FeeCalculator) { + pub fn genesis_hash(&mut self, hash: &Hash, lamports_per_signature: u64) { self.ages.insert( *hash, HashAge { - fee_calculator: fee_calculator.clone(), + fee_calculator: FeeCalculator::new(lamports_per_signature), hash_height: 0, timestamp: timestamp(), }, @@ -91,7 +89,7 @@ impl BlockhashQueue { hash_height - age.hash_height <= max_age as u64 } - pub fn register_hash(&mut self, hash: &Hash, fee_calculator: &FeeCalculator) { + pub fn register_hash(&mut self, hash: &Hash, lamports_per_signature: u64) { self.hash_height += 1; let hash_height = self.hash_height; @@ -105,7 +103,7 @@ impl BlockhashQueue { self.ages.insert( *hash, HashAge { - fee_calculator: fee_calculator.clone(), + fee_calculator: FeeCalculator::new(lamports_per_signature), hash_height, timestamp: timestamp(), }, @@ -130,9 +128,9 @@ impl BlockhashQueue { )] #[allow(deprecated)] pub fn get_recent_blockhashes(&self) -> impl Iterator { - (&self.ages) - .iter() - .map(|(k, v)| recent_blockhashes::IterItem(v.hash_height, k, &v.fee_calculator)) + (&self.ages).iter().map(|(k, v)| { + recent_blockhashes::IterItem(v.hash_height, k, v.fee_calculator.lamports_per_signature) + }) } pub(crate) fn len(&self) -> usize { @@ -152,7 +150,7 @@ mod tests { let last_hash = Hash::default(); let mut hash_queue = BlockhashQueue::new(100); assert!(!hash_queue.check_hash(&last_hash)); - hash_queue.register_hash(&last_hash, &FeeCalculator::default()); + hash_queue.register_hash(&last_hash, 0); assert!(hash_queue.check_hash(&last_hash)); assert_eq!(hash_queue.hash_height(), 1); } @@ -163,7 +161,7 @@ mod tests { let last_hash = hash(&serialize(&0).unwrap()); for i in 0..102 { let last_hash = hash(&serialize(&i).unwrap()); - hash_queue.register_hash(&last_hash, &FeeCalculator::default()); + hash_queue.register_hash(&last_hash, 0); } // Assert we're no longer able to use the oldest hash. assert!(!hash_queue.check_hash(&last_hash)); @@ -180,7 +178,7 @@ mod tests { fn test_queue_init_blockhash() { let last_hash = Hash::default(); let mut hash_queue = BlockhashQueue::new(100); - hash_queue.register_hash(&last_hash, &FeeCalculator::default()); + hash_queue.register_hash(&last_hash, 0); assert_eq!(last_hash, hash_queue.last_hash()); assert_eq!(Some(true), hash_queue.check_hash_age(&last_hash, 0)); } @@ -194,13 +192,13 @@ mod tests { assert_eq!(recent_blockhashes.count(), 0); for i in 0..MAX_RECENT_BLOCKHASHES { let hash = hash(&serialize(&i).unwrap()); - blockhash_queue.register_hash(&hash, &FeeCalculator::default()); + blockhash_queue.register_hash(&hash, 0); } #[allow(deprecated)] let recent_blockhashes = blockhash_queue.get_recent_blockhashes(); // Verify that the returned hashes are most recent #[allow(deprecated)] - for IterItem(_slot, hash, _fee_calc) in recent_blockhashes { + for IterItem(_slot, hash, _lamports_per_signature) in recent_blockhashes { assert_eq!( Some(true), blockhash_queue.check_hash_age(hash, MAX_RECENT_BLOCKHASHES) diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 2385cc6a0..2b4f2169b 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -14,7 +14,6 @@ use solana_sdk::{ prevent_calling_precompiles_as_programs, remove_native_loader, requestable_heap_size, tx_wide_compute_cap, FeatureSet, }, - fee_calculator::FeeCalculator, hash::Hash, ic_logger_msg, instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError}, @@ -93,7 +92,7 @@ pub struct ThisInvokeContext<'a> { #[allow(clippy::type_complexity)] sysvars: RefCell>>)>>, blockhash: Hash, - fee_calculator: FeeCalculator, + lamports_per_signature: u64, return_data: (Pubkey, Vec), } impl<'a> ThisInvokeContext<'a> { @@ -111,7 +110,7 @@ impl<'a> ThisInvokeContext<'a> { account_db: Arc, ancestors: Option<&'a Ancestors>, blockhash: Hash, - fee_calculator: FeeCalculator, + lamports_per_signature: u64, ) -> Self { Self { instruction_index: 0, @@ -131,7 +130,7 @@ impl<'a> ThisInvokeContext<'a> { ancestors, sysvars: RefCell::new(Vec::new()), blockhash, - fee_calculator, + lamports_per_signature, return_data: (Pubkey::default(), Vec::new()), } } @@ -154,7 +153,7 @@ impl<'a> ThisInvokeContext<'a> { Arc::new(Accounts::default_for_tests()), None, Hash::default(), - FeeCalculator::default(), + 0, ) } @@ -488,11 +487,11 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> { fn get_blockhash(&self) -> &Hash { &self.blockhash } - fn set_fee_calculator(&mut self, fee_calculator: FeeCalculator) { - self.fee_calculator = fee_calculator; + fn set_lamports_per_signature(&mut self, lamports_per_signature: u64) { + self.lamports_per_signature = lamports_per_signature; } - fn get_fee_calculator(&self) -> &FeeCalculator { - &self.fee_calculator + fn get_lamports_per_signature(&self) -> u64 { + self.lamports_per_signature } fn set_return_data(&mut self, data: Vec) -> Result<(), InstructionError> { self.return_data = (*self.get_caller()?, data); @@ -622,7 +621,7 @@ impl MessageProcessor { account_db: Arc, ancestors: &Ancestors, blockhash: Hash, - fee_calculator: FeeCalculator, + lamports_per_signature: u64, ) -> Result<(), TransactionError> { let mut invoke_context = ThisInvokeContext::new( rent_collector.rent, @@ -637,7 +636,7 @@ impl MessageProcessor { account_db, Some(ancestors), blockhash, - fee_calculator, + lamports_per_signature, ); let compute_meter = invoke_context.get_compute_meter(); @@ -1011,7 +1010,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!(result, Ok(())); assert_eq!(accounts[0].1.borrow().lamports(), 100); @@ -1042,7 +1041,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!( result, @@ -1077,7 +1076,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!( result, @@ -1222,7 +1221,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!( result, @@ -1257,7 +1256,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!(result, Ok(())); @@ -1290,7 +1289,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &ancestors, Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!(result, Ok(())); assert_eq!(accounts[0].1.borrow().lamports(), 80); @@ -1593,7 +1592,7 @@ mod tests { Arc::new(Accounts::default_for_tests()), &Ancestors::default(), Hash::default(), - FeeCalculator::default(), + 0, ); assert_eq!( result, diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 10e74ffdc..922fece9d 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -3049,7 +3049,7 @@ mod tests { bank2.last_blockhash(), )) .unwrap(); - let fee = bank2.get_fee_for_message(tx.message()).unwrap(); + let fee = bank2.get_fee_for_message(tx.message()); let tx = system_transaction::transfer( &key1, &key2.pubkey(), diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index c9faee22f..e0dd9571a 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -486,7 +486,6 @@ mod tests { use solana_sdk::{ account::{self, Account, AccountSharedData}, client::SyncClient, - fee_calculator::FeeCalculator, genesis_config::create_genesis_config, hash::{hash, Hash}, instruction::{AccountMeta, Instruction, InstructionError}, @@ -536,11 +535,8 @@ mod tests { RefCell::new( #[allow(deprecated)] recent_blockhashes_account::create_account_with_data_for_test( - vec![ - IterItem(0u64, &Hash::default(), &FeeCalculator::default()); - sysvar::recent_blockhashes::MAX_ENTRIES - ] - .into_iter(), + vec![IterItem(0u64, &Hash::default(), 0); sysvar::recent_blockhashes::MAX_ENTRIES] + .into_iter(), ), ) } @@ -1588,11 +1584,8 @@ mod tests { let new_recent_blockhashes_account = RefCell::new( #[allow(deprecated)] solana_sdk::recent_blockhashes_account::create_account_with_data_for_test( - vec![ - IterItem(0u64, blockhash, &FeeCalculator::default()); - sysvar::recent_blockhashes::MAX_ENTRIES - ] - .into_iter(), + vec![IterItem(0u64, blockhash, 0); sysvar::recent_blockhashes::MAX_ENTRIES] + .into_iter(), ), ); let owner = Pubkey::default(); diff --git a/sdk/program/src/message/sanitized.rs b/sdk/program/src/message/sanitized.rs index 89764f00d..ba70b618f 100644 --- a/sdk/program/src/message/sanitized.rs +++ b/sdk/program/src/message/sanitized.rs @@ -5,8 +5,6 @@ use { message::{MappedAddresses, MappedMessage, Message, MessageHeader}, pubkey::Pubkey, sanitize::{Sanitize, SanitizeError}, - secp256k1_program, - ed25519_program, serialize_utils::{append_slice, append_u16, append_u8}, }, bitflags::bitflags, @@ -291,21 +289,6 @@ impl SanitizedMessage { }) } - /// Calculate the total fees for a transaction given a fee calculator - pub fn calculate_fee(&self, lamports_per_signature: u64) -> u64 { - let mut num_signatures = u64::from(self.header().num_required_signatures); - for (program_id, instruction) in self.program_instructions_iter() { - if secp256k1_program::check_id(program_id) || ed25519_program::check_id(program_id) { - if let Some(num_verifies) = instruction.data.get(0) { - num_signatures = - num_signatures.saturating_add(u64::from(*num_verifies)); - } - } - } - - lamports_per_signature.saturating_mul(num_signatures) - } - /// Inspect all message keys for the bpf upgradeable loader pub fn is_upgradeable_loader_present(&self) -> bool { match self { @@ -321,7 +304,6 @@ mod tests { use crate::{ instruction::{AccountMeta, Instruction}, message::v0, - secp256k1_program, system_instruction, }; #[test] @@ -460,25 +442,6 @@ mod tests { } } - #[test] - fn test_calculate_fee() { - // Default: no fee. - let message = - SanitizedMessage::try_from(Message::new(&[], Some(&Pubkey::new_unique()))).unwrap(); - assert_eq!(message.calculate_fee(0), 0); - - // One signature, a fee. - assert_eq!(message.calculate_fee(1), 1); - - // Two signatures, double the fee. - let key0 = Pubkey::new_unique(); - let key1 = Pubkey::new_unique(); - let ix0 = system_instruction::transfer(&key0, &key1, 1); - let ix1 = system_instruction::transfer(&key1, &key0, 1); - let message = SanitizedMessage::try_from(Message::new(&[ix0, ix1], Some(&key0))).unwrap(); - assert_eq!(message.calculate_fee(2), 4); - } - #[test] fn test_try_compile_instruction() { let key0 = Pubkey::new_unique(); @@ -561,80 +524,4 @@ mod tests { .is_none()); } } - - #[test] - fn test_calculate_fee_secp256k1() { - let key0 = Pubkey::new_unique(); - let key1 = Pubkey::new_unique(); - let ix0 = system_instruction::transfer(&key0, &key1, 1); - - let mut secp_instruction1 = Instruction { - program_id: secp256k1_program::id(), - accounts: vec![], - data: vec![], - }; - let mut secp_instruction2 = Instruction { - program_id: secp256k1_program::id(), - accounts: vec![], - data: vec![1], - }; - - let message = SanitizedMessage::try_from(Message::new( - &[ - ix0.clone(), - secp_instruction1.clone(), - secp_instruction2.clone(), - ], - Some(&key0), - )) - .unwrap(); - assert_eq!(message.calculate_fee(1), 2); - - secp_instruction1.data = vec![0]; - secp_instruction2.data = vec![10]; - let message = SanitizedMessage::try_from(Message::new( - &[ix0, secp_instruction1, secp_instruction2], - Some(&key0), - )) - .unwrap(); - assert_eq!(message.calculate_fee(1), 11); - } - - #[test] - fn test_calculate_fee_ed25519() { - let key0 = Pubkey::new_unique(); - let key1 = Pubkey::new_unique(); - let ix0 = system_instruction::transfer(&key0, &key1, 1); - - let mut instruction1 = Instruction { - program_id: ed25519_program::id(), - accounts: vec![], - data: vec![], - }; - let mut instruction2 = Instruction { - program_id: ed25519_program::id(), - accounts: vec![], - data: vec![1], - }; - - let message = SanitizedMessage::try_from(Message::new( - &[ - ix0.clone(), - instruction1.clone(), - instruction2.clone(), - ], - Some(&key0), - )) - .unwrap(); - assert_eq!(message.calculate_fee(1), 2); - - instruction1.data = vec![0]; - instruction2.data = vec![10]; - let message = SanitizedMessage::try_from(Message::new( - &[ix0, instruction1, instruction2], - Some(&key0), - )) - .unwrap(); - assert_eq!(message.calculate_fee(1), 11); - } } diff --git a/sdk/program/src/nonce/state/current.rs b/sdk/program/src/nonce/state/current.rs index 3b3178909..461547624 100644 --- a/sdk/program/src/nonce/state/current.rs +++ b/sdk/program/src/nonce/state/current.rs @@ -9,6 +9,19 @@ pub struct Data { pub fee_calculator: FeeCalculator, } +impl Data { + pub fn new(authority: Pubkey, blockhash: Hash, lamports_per_signature: u64) -> Self { + Data { + authority, + blockhash, + fee_calculator: FeeCalculator::new(lamports_per_signature), + } + } + pub fn get_lamports_per_signature(&self) -> u64 { + self.fee_calculator.lamports_per_signature + } +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Clone)] pub enum State { Uninitialized, diff --git a/sdk/program/src/sysvar/recent_blockhashes.rs b/sdk/program/src/sysvar/recent_blockhashes.rs index d1b196807..b9e553312 100644 --- a/sdk/program/src/sysvar/recent_blockhashes.rs +++ b/sdk/program/src/sysvar/recent_blockhashes.rs @@ -30,10 +30,10 @@ pub struct Entry { pub fee_calculator: FeeCalculator, } impl Entry { - pub fn new(blockhash: &Hash, fee_calculator: &FeeCalculator) -> Self { + pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self { Self { blockhash: *blockhash, - fee_calculator: fee_calculator.clone(), + fee_calculator: FeeCalculator::new(lamports_per_signature), } } } @@ -43,7 +43,7 @@ impl Entry { note = "Please do not use, will no longer be available in the future" )] #[derive(Clone, Debug)] -pub struct IterItem<'a>(pub u64, pub &'a Hash, pub &'a FeeCalculator); +pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64); impl<'a> Eq for IterItem<'a> {} @@ -149,13 +149,13 @@ pub fn create_test_recent_blockhashes(start: usize) -> RecentBlockhashes { ( i as u64, hash(&bincode::serialize(&i).unwrap()), - FeeCalculator::new(i as u64 * 100), + i as u64 * 100, ) }) .collect(); blocks .iter() - .map(|(i, hash, fee_calc)| IterItem(*i, hash, fee_calc)) + .map(|(i, hash, lamports_per_signature)| IterItem(*i, hash, *lamports_per_signature)) .collect() } @@ -173,7 +173,7 @@ mod tests { #[test] fn test_size_of() { - let entry = Entry::new(&Hash::default(), &FeeCalculator::default()); + let entry = Entry::new(&Hash::default(), 0); assert_eq!( bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap() as usize, diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index 563d64f30..f8d348592 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -249,6 +249,10 @@ pub mod requestable_heap_size { solana_sdk::declare_id!("CCu4boMmfLuqcmfTLPHQiUo22ZdUsXjgzPAURYaWt1Bw"); } +pub mod disable_fee_calculator { + solana_sdk::declare_id!("2jXx2yDmGysmBKfKYNgLj2DQyAQv6mMk2BPh4eSbyB4H"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -300,12 +304,13 @@ lazy_static! { (sol_log_data_syscall_enabled::id(), "enable sol_log_data syscall"), (stakes_remove_delegation_if_inactive::id(), "remove delegations from stakes cache when inactive"), (do_support_realloc::id(), "support account data reallocation"), - (prevent_calling_precompiles_as_programs::id(), "Prevent calling precompiles as programs"), - (optimize_epoch_boundary_updates::id(), "Optimize epoch boundary updates"), - (remove_native_loader::id(), "Remove support for the native loader"), - (send_to_tpu_vote_port::id(), "Send votes to the tpu vote port"), + (prevent_calling_precompiles_as_programs::id(), "prevent calling precompiles as programs"), + (optimize_epoch_boundary_updates::id(), "optimize epoch boundary updates"), + (remove_native_loader::id(), "remove support for the native loader"), + (send_to_tpu_vote_port::id(), "send votes to the tpu vote port"), (turbine_peers_shuffle::id(), "turbine peers shuffle patch"), (requestable_heap_size::id(), "Requestable heap frame size"), + (disable_fee_calculator::id(), "deprecate fee calculator"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter() diff --git a/sdk/src/nonce_account.rs b/sdk/src/nonce_account.rs index dcfff92e5..bdca92ed1 100644 --- a/sdk/src/nonce_account.rs +++ b/sdk/src/nonce_account.rs @@ -1,7 +1,6 @@ use crate::{ account::{AccountSharedData, ReadableAccount}, account_utils::StateMut, - fee_calculator::FeeCalculator, hash::Hash, nonce::{state::Versions, State}, }; @@ -29,12 +28,12 @@ pub fn verify_nonce_account(acc: &AccountSharedData, hash: &Hash) -> bool { } } -pub fn fee_calculator_of(account: &AccountSharedData) -> Option { +pub fn lamports_per_signature_of(account: &AccountSharedData) -> Option { let state = StateMut::::state(account) .ok()? .convert_to_current(); match state { - State::Initialized(data) => Some(data.fee_calculator), + State::Initialized(data) => Some(data.fee_calculator.lamports_per_signature), _ => None, } } diff --git a/sdk/src/nonce_keyed_account.rs b/sdk/src/nonce_keyed_account.rs index 64fd61dff..77097fb86 100644 --- a/sdk/src/nonce_keyed_account.rs +++ b/sdk/src/nonce_keyed_account.rs @@ -76,11 +76,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { )); } - let new_data = nonce::state::Data { - blockhash: recent_blockhash, - fee_calculator: invoke_context.get_fee_calculator().clone(), - ..data - }; + let new_data = nonce::state::Data::new( + data.authority, + recent_blockhash, + invoke_context.get_lamports_per_signature(), + ); self.set_state(&Versions::new_current(State::Initialized(new_data))) } _ => { @@ -195,11 +195,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { ); return Err(InstructionError::InsufficientFunds); } - let data = nonce::state::Data { - authority: *nonce_authority, - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - }; + let data = nonce::state::Data::new( + *nonce_authority, + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); self.set_state(&Versions::new_current(State::Initialized(data))) } _ => { @@ -234,10 +234,11 @@ impl<'a> NonceKeyedAccount for KeyedAccount<'a> { ); return Err(InstructionError::MissingRequiredSignature); } - let new_data = nonce::state::Data { - authority: *nonce_authority, - ..data - }; + let new_data = nonce::state::Data::new( + *nonce_authority, + data.blockhash, + data.get_lamports_per_signature(), + ); self.set_state(&Versions::new_current(State::Initialized(new_data))) } _ => { @@ -272,7 +273,6 @@ mod test { use crate::{ account::ReadableAccount, account_utils::State as AccountUtilsState, - fee_calculator::FeeCalculator, keyed_account::KeyedAccount, nonce::{self, State}, nonce_account::verify_nonce_account, @@ -281,18 +281,18 @@ mod test { }; use solana_program::hash::{hash, Hash}; - fn create_test_blockhash(seed: usize) -> (Hash, FeeCalculator) { + fn create_test_blockhash(seed: usize) -> (Hash, u64) { ( hash(&bincode::serialize(&seed).unwrap()), - FeeCalculator::new((seed as u64).saturating_mul(100)), + (seed as u64).saturating_mul(100), ) } fn create_invoke_context_with_blockhash<'a>(seed: usize) -> MockInvokeContext<'a> { let mut invoke_context = MockInvokeContext::new(&Pubkey::default(), vec![]); - let (blockhash, fee_calculator) = create_test_blockhash(seed); + let (blockhash, lamports_per_signature) = create_test_blockhash(seed); invoke_context.blockhash = blockhash; - invoke_context.fee_calculator = fee_calculator; + invoke_context.lamports_per_signature = lamports_per_signature; invoke_context } @@ -328,11 +328,11 @@ mod test { let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - let data = nonce::state::Data { - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - ..data - }; + let data = nonce::state::Data::new( + data.authority, + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); // First nonce instruction drives state from Uninitialized to Initialized assert_eq!(state, State::Initialized(data.clone())); let invoke_context = create_invoke_context_with_blockhash(63); @@ -342,11 +342,11 @@ mod test { let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - let data = nonce::state::Data { - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - ..data - }; + let data = nonce::state::Data::new( + data.authority, + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); // Second nonce instruction consumes and replaces stored nonce assert_eq!(state, State::Initialized(data.clone())); let invoke_context = create_invoke_context_with_blockhash(31); @@ -356,11 +356,11 @@ mod test { let state = AccountUtilsState::::state(keyed_account) .unwrap() .convert_to_current(); - let data = nonce::state::Data { - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - ..data - }; + let data = nonce::state::Data::new( + data.authority, + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); // Third nonce instruction for fun and profit assert_eq!(state, State::Initialized(data)); with_test_keyed_account(42, false, |to_keyed| { @@ -412,11 +412,11 @@ mod test { let state = AccountUtilsState::::state(&nonce_account) .unwrap() .convert_to_current(); - let data = nonce::state::Data { + let data = nonce::state::Data::new( authority, - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - }; + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); assert_eq!(state, State::Initialized(data)); let signers = HashSet::new(); let invoke_context = create_invoke_context_with_blockhash(0); @@ -690,11 +690,11 @@ mod test { let state = AccountUtilsState::::state(nonce_keyed) .unwrap() .convert_to_current(); - let data = nonce::state::Data { + let data = nonce::state::Data::new( authority, - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - }; + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); assert_eq!(state, State::Initialized(data.clone())); with_test_keyed_account(42, false, |to_keyed| { let withdraw_lamports = nonce_keyed.account.borrow().lamports() - min_lamports; @@ -713,11 +713,11 @@ mod test { let state = AccountUtilsState::::state(nonce_keyed) .unwrap() .convert_to_current(); - let data = nonce::state::Data { - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - ..data.clone() - }; + let data = nonce::state::Data::new( + data.authority, + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); assert_eq!(state, State::Initialized(data)); assert_eq!( nonce_keyed.account.borrow().lamports(), @@ -887,11 +887,11 @@ mod test { let invoke_context = create_invoke_context_with_blockhash(0); let authority = *keyed_account.unsigned_key(); let result = keyed_account.initialize_nonce_account(&authority, &rent, &invoke_context); - let data = nonce::state::Data { + let data = nonce::state::Data::new( authority, - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - }; + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); assert_eq!(result, Ok(())); let state = AccountUtilsState::::state(keyed_account) .unwrap() @@ -952,11 +952,11 @@ mod test { .initialize_nonce_account(&authorized, &rent, &invoke_context) .unwrap(); let authority = Pubkey::default(); - let data = nonce::state::Data { + let data = nonce::state::Data::new( authority, - blockhash: *invoke_context.get_blockhash(), - fee_calculator: invoke_context.get_fee_calculator().clone(), - }; + *invoke_context.get_blockhash(), + invoke_context.get_lamports_per_signature(), + ); let result = nonce_account.authorize_nonce_account( &Pubkey::default(), &signers, diff --git a/sdk/src/process_instruction.rs b/sdk/src/process_instruction.rs index 6b657cee5..c8fea8033 100644 --- a/sdk/src/process_instruction.rs +++ b/sdk/src/process_instruction.rs @@ -5,7 +5,6 @@ use solana_sdk::{ account::AccountSharedData, compute_budget::ComputeBudget, feature_set::remove_native_loader, - fee_calculator::FeeCalculator, hash::Hash, instruction::{CompiledInstruction, Instruction, InstructionError}, keyed_account::{create_keyed_accounts_unified, KeyedAccount}, @@ -132,10 +131,10 @@ pub trait InvokeContext { fn set_blockhash(&mut self, hash: Hash); /// Get this invocation's blockhash fn get_blockhash(&self) -> &Hash; - /// Set this invocation's `FeeCalculator` - fn set_fee_calculator(&mut self, fee_calculator: FeeCalculator); - /// Get this invocation's `FeeCalculator` - fn get_fee_calculator(&self) -> &FeeCalculator; + /// Set this invocation's lamports_per_signature value + fn set_lamports_per_signature(&mut self, lamports_per_signature: u64); + /// Get this invocation's lamports_per_signature value + fn get_lamports_per_signature(&self) -> u64; /// Set the return data fn set_return_data(&mut self, data: Vec) -> Result<(), InstructionError>; /// Get the return data @@ -361,7 +360,7 @@ pub struct MockInvokeContext<'a> { pub sysvars: RefCell>>)>>, pub disabled_features: HashSet, pub blockhash: Hash, - pub fee_calculator: FeeCalculator, + pub lamports_per_signature: u64, pub return_data: (Pubkey, Vec), } @@ -380,7 +379,7 @@ impl<'a> MockInvokeContext<'a> { sysvars: RefCell::new(Vec::new()), disabled_features: HashSet::default(), blockhash: Hash::default(), - fee_calculator: FeeCalculator::default(), + lamports_per_signature: 0, return_data: (Pubkey::default(), Vec::new()), }; let number_of_program_accounts = keyed_accounts @@ -510,11 +509,11 @@ impl<'a> InvokeContext for MockInvokeContext<'a> { fn get_blockhash(&self) -> &Hash { &self.blockhash } - fn set_fee_calculator(&mut self, fee_calculator: FeeCalculator) { - self.fee_calculator = fee_calculator; + fn set_lamports_per_signature(&mut self, lamports_per_signature: u64) { + self.lamports_per_signature = lamports_per_signature; } - fn get_fee_calculator(&self) -> &FeeCalculator { - &self.fee_calculator + fn get_lamports_per_signature(&self) -> u64 { + self.lamports_per_signature } fn set_return_data(&mut self, data: Vec) -> Result<(), InstructionError> { self.return_data = (*self.get_caller()?, data); diff --git a/sdk/src/recent_blockhashes_account.rs b/sdk/src/recent_blockhashes_account.rs index 416dd58e3..4f6ca6c65 100644 --- a/sdk/src/recent_blockhashes_account.rs +++ b/sdk/src/recent_blockhashes_account.rs @@ -83,7 +83,6 @@ mod tests { use crate::account::from_account; use rand::{seq::SliceRandom, thread_rng}; use solana_program::{ - fee_calculator::FeeCalculator, hash::{Hash, HASH_BYTES}, sysvar::recent_blockhashes::Entry, }; @@ -98,9 +97,9 @@ mod tests { #[test] fn test_create_account_full() { let def_hash = Hash::default(); - let def_fees = FeeCalculator::default(); + let def_lamports_per_signature = 0; let account = create_account_with_data_for_test( - vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES].into_iter(), + vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES].into_iter(), ); let recent_blockhashes = from_account::(&account).unwrap(); assert_eq!(recent_blockhashes.len(), MAX_ENTRIES); @@ -109,9 +108,10 @@ mod tests { #[test] fn test_create_account_truncate() { let def_hash = Hash::default(); - let def_fees = FeeCalculator::default(); + let def_lamports_per_signature = 0; let account = create_account_with_data_for_test( - vec![IterItem(0u64, &def_hash, &def_fees); MAX_ENTRIES + 1].into_iter(), + vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES + 1] + .into_iter(), ); let recent_blockhashes = from_account::(&account).unwrap(); assert_eq!(recent_blockhashes.len(), MAX_ENTRIES); @@ -119,7 +119,7 @@ mod tests { #[test] fn test_create_account_unsorted() { - let def_fees = FeeCalculator::default(); + let def_lamports_per_signature = 0; let mut unsorted_blocks: Vec<_> = (0..MAX_ENTRIES) .map(|i| { (i as u64, { @@ -135,13 +135,13 @@ mod tests { let account = create_account_with_data_for_test( unsorted_blocks .iter() - .map(|(i, hash)| IterItem(*i, hash, &def_fees)), + .map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature)), ); let recent_blockhashes = from_account::(&account).unwrap(); let mut unsorted_recent_blockhashes: Vec<_> = unsorted_blocks .iter() - .map(|(i, hash)| IterItem(*i, hash, &def_fees)) + .map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature)) .collect(); unsorted_recent_blockhashes.sort(); unsorted_recent_blockhashes.reverse(); diff --git a/send-transaction-service/src/send_transaction_service.rs b/send-transaction-service/src/send_transaction_service.rs index 707d0a576..ae498e8f9 100644 --- a/send-transaction-service/src/send_transaction_service.rs +++ b/send-transaction-service/src/send_transaction_service.rs @@ -328,9 +328,8 @@ mod test { super::*, crate::tpu_info::NullTpuInfo, solana_sdk::{ - account::AccountSharedData, fee_calculator::FeeCalculator, - genesis_config::create_genesis_config, nonce, pubkey::Pubkey, signature::Signer, - system_program, system_transaction, + account::AccountSharedData, genesis_config::create_genesis_config, nonce, + pubkey::Pubkey, signature::Signer, system_program, system_transaction, }, std::sync::mpsc::channel, }; @@ -625,12 +624,9 @@ mod test { let nonce_address = Pubkey::new_unique(); let durable_nonce = Hash::new_unique(); - let nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: Pubkey::default(), - blockhash: durable_nonce, - fee_calculator: FeeCalculator::new(42), - })); + let nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(Pubkey::default(), durable_nonce, 42), + )); let nonce_account = AccountSharedData::new_data(43, &nonce_state, &system_program::id()).unwrap(); root_bank.store_account(&nonce_address, &nonce_account); @@ -857,12 +853,9 @@ mod test { ); // Advance nonce let new_durable_nonce = Hash::new_unique(); - let new_nonce_state = - nonce::state::Versions::new_current(nonce::State::Initialized(nonce::state::Data { - authority: Pubkey::default(), - blockhash: new_durable_nonce, - fee_calculator: FeeCalculator::new(42), - })); + let new_nonce_state = nonce::state::Versions::new_current(nonce::State::Initialized( + nonce::state::Data::new(Pubkey::default(), new_durable_nonce, 42), + )); let nonce_account = AccountSharedData::new_data(43, &new_nonce_state, &system_program::id()).unwrap(); working_bank.store_account(&nonce_address, &nonce_account);