Skip to content

Commit

Permalink
Divorce the runtime from FeeCalculator (solana-labs#20737)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackcmay authored Oct 22, 2021
1 parent 613c7b8 commit bfbbc53
Show file tree
Hide file tree
Showing 24 changed files with 503 additions and 563 deletions.
10 changes: 3 additions & 7 deletions account-decoder/src/parse_sysvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(),
}]),
);
}
Expand Down
10 changes: 7 additions & 3 deletions banks-server/src/banks_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
39 changes: 15 additions & 24 deletions cli/src/nonce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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());

Expand All @@ -938,23 +937,23 @@ 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()
{
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()
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions core/src/test_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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();
Expand Down
31 changes: 14 additions & 17 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -416,9 +416,9 @@ pub fn read_file<P: AsRef<Path>>(path: P) -> Vec<u8> {
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(
Expand All @@ -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
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -884,23 +880,24 @@ 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]
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);
Expand Down
25 changes: 14 additions & 11 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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},
Expand All @@ -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
Expand Down Expand Up @@ -370,13 +370,16 @@ fn execute_transactions(bank: &Bank, txs: Vec<Transaction>) -> Vec<ConfirmedTran
post_token_balances,
log_messages,
)| {
#[allow(deprecated)]
let fee_calculator = nonce_rollback
.map(|nonce_rollback| nonce_rollback.fee_calculator())
.unwrap_or_else(|| bank.get_fee_calculator(&tx.message().recent_blockhash))
.expect("FeeCalculator must exist");
#[allow(deprecated)]
let fee = fee_calculator.calculate_fee(tx.message());
let lamports_per_signature = nonce_rollback
.map(|nonce_rollback| nonce_rollback.lamports_per_signature())
.unwrap_or_else(|| {
bank.get_lamports_per_signature_for_blockhash(&tx.message().recent_blockhash)
})
.expect("lamports_per_signature must exist");
let fee = Bank::get_fee_for_message_with_lamports_per_signature(
&SanitizedMessage::try_from(tx.message().clone()).unwrap(),
lamports_per_signature,
);

let inner_instructions = inner_instructions.map(|inner_instructions| {
inner_instructions
Expand Down
34 changes: 21 additions & 13 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use {
epoch_schedule::EpochSchedule,
exit::Exit,
feature_set,
fee_calculator::FeeCalculator,
hash::Hash,
message::{Message, SanitizedMessage},
pubkey::Pubkey,
Expand Down Expand Up @@ -546,21 +547,25 @@ impl JsonRpcRequestProcessor {
commitment: Option<CommitmentConfig>,
) -> RpcResponse<RpcBlockhashFeeCalculator> {
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<CommitmentConfig>) -> RpcResponse<RpcFees> {
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)
Expand All @@ -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,
},
Expand All @@ -585,11 +590,12 @@ impl JsonRpcRequestProcessor {
commitment: Option<CommitmentConfig>,
) -> RpcResponse<Option<RpcFeeCalculator>> {
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),
}),
)
}

Expand Down Expand Up @@ -1967,7 +1973,7 @@ impl JsonRpcRequestProcessor {
) -> Result<RpcResponse<Option<u64>>> {
let bank = self.bank(commitment);
let fee = bank.get_fee_for_message(message);
Ok(new_response(&bank, fee))
Ok(new_response(&bank, Some(fee)))
}
}

Expand Down Expand Up @@ -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":["{:?}"]}}"#,
Expand Down
Loading

0 comments on commit bfbbc53

Please sign in to comment.