Split signature throughput tracking out of FeeCalculator (#8447)

* SDK: Split new `FeeRateGovernor` out of `FeeCalculator`

Leaving `FeeCalculator` to *only* calculate transaction fees

* Replace `FeeCalculator` with `FeeRateGovernor` as appropriate

* Expose recent `FeeRateGovernor` to clients

* Move `burn()` back into `FeeCalculator`

Appease BPF tests

* Revert "Move `burn()` back into `FeeCalculator`"

This reverts commit f3035624307196722b62ff8b74c12cfcc13b1941.

* Adjust BPF `Fee` sysvar test to reflect removal of `burn()` from `FeeCalculator`

* Make `FeeRateGovernor`'s `lamports_per_signature` private

* rebase artifacts

* fmt

* Drop 'Recent'

* Drop _with_commitment variant

* Use a more portable integer for `target_signatures_per_slot`

* Add docs for `getReeRateCalculator` JSON RPC method

* Don't return `lamports_per_signature` in `getFeeRateGovernor` JSONRPC reply
This commit is contained in:
Trent Nelson
2020-02-28 13:27:01 -07:00
committed by GitHub
parent 7d27be2a73
commit 90bedd7e06
22 changed files with 298 additions and 118 deletions

View File

@ -853,7 +853,7 @@ mod tests {
instructions,
);
let fee_calculator = FeeCalculator::new(10, 0);
let fee_calculator = FeeCalculator::new(10);
assert_eq!(fee_calculator.calculate_fee(tx.message()), 10);
let loaded_accounts =
@ -918,7 +918,7 @@ mod tests {
let min_balance = rent_collector
.rent
.minimum_balance(nonce_state::NonceState::size());
let fee_calculator = FeeCalculator::new(min_balance, 0);
let fee_calculator = FeeCalculator::new(min_balance);
let nonce = Keypair::new();
let mut accounts = vec![(
nonce.pubkey(),

View File

@ -35,7 +35,7 @@ use solana_sdk::{
account::Account,
clock::{get_segment_from_slot, Epoch, Slot, UnixTimestamp, MAX_RECENT_BLOCKHASHES},
epoch_schedule::EpochSchedule,
fee_calculator::FeeCalculator,
fee_calculator::{FeeCalculator, FeeRateGovernor},
genesis_config::GenesisConfig,
hard_forks::HardForks,
hash::{extend_and_hash, hashv, Hash},
@ -302,6 +302,9 @@ pub struct Bank {
/// Latest transaction fees for transactions processed by this bank
fee_calculator: FeeCalculator,
/// Track cluster signature throughput and adjust fee rate
fee_rate_governor: FeeRateGovernor,
/// Rent that have been collected
#[serde(serialize_with = "serialize_atomicu64")]
#[serde(deserialize_with = "deserialize_atomicu64")]
@ -401,6 +404,9 @@ impl Bank {
let epoch_schedule = parent.epoch_schedule;
let epoch = epoch_schedule.get_epoch(slot);
let fee_rate_governor =
FeeRateGovernor::new_derived(&parent.fee_rate_governor, parent.signature_count());
let mut new = Bank {
rc,
src,
@ -420,10 +426,8 @@ 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: FeeCalculator::new_derived(
&parent.fee_calculator,
parent.signature_count() as usize,
),
fee_calculator: fee_rate_governor.create_fee_calculator(),
fee_rate_governor,
capitalization: AtomicU64::new(parent.capitalization()),
inflation: parent.inflation.clone(),
transaction_count: AtomicU64::new(parent.transaction_count()),
@ -745,7 +749,7 @@ impl Bank {
let collector_fees = self.collector_fees.load(Ordering::Relaxed) as u64;
if collector_fees != 0 {
let (unburned, burned) = self.fee_calculator.burn(collector_fees);
let (unburned, burned) = self.fee_rate_governor.burn(collector_fees);
// burn a portion of fees
self.deposit(&self.collector_id, unburned);
self.capitalization.fetch_sub(burned, Ordering::Relaxed);
@ -811,7 +815,8 @@ impl Bank {
fn process_genesis_config(&mut self, genesis_config: &GenesisConfig) {
// Bootstrap validator collects fees until `new_from_parent` is called.
self.fee_calculator = genesis_config.fee_calculator.clone();
self.fee_rate_governor = genesis_config.fee_rate_governor.clone();
self.fee_calculator = self.fee_rate_governor.create_fee_calculator();
self.update_fees();
for (pubkey, account) in genesis_config.accounts.iter() {
@ -905,6 +910,10 @@ impl Bank {
blockhash_queue.get_fee_calculator(hash).cloned()
}
pub fn get_fee_rate_governor(&self) -> &FeeRateGovernor {
&self.fee_rate_governor
}
pub fn confirmed_last_blockhash(&self) -> (Hash, FeeCalculator) {
const NUM_BLOCKHASH_CONFIRMATIONS: usize = 3;
@ -3290,7 +3299,7 @@ mod tests {
#[test]
fn test_detect_failed_duplicate_transactions() {
let (mut genesis_config, mint_keypair) = create_genesis_config(2);
genesis_config.fee_calculator.lamports_per_signature = 1;
genesis_config.fee_rate_governor = FeeRateGovernor::new(1, 0);
let bank = Bank::new(&genesis_config);
let dest = Keypair::new();
@ -3450,11 +3459,14 @@ mod tests {
mint_keypair,
..
} = create_genesis_config_with_leader(mint, &leader, 3);
genesis_config.fee_calculator.lamports_per_signature = 4; // something divisible by 2
genesis_config.fee_rate_governor = FeeRateGovernor::new(4, 0); // something divisible by 2
let expected_fee_paid = genesis_config.fee_calculator.lamports_per_signature;
let expected_fee_paid = genesis_config
.fee_rate_governor
.create_fee_calculator()
.lamports_per_signature;
let (expected_fee_collected, expected_fee_burned) =
genesis_config.fee_calculator.burn(expected_fee_paid);
genesis_config.fee_rate_governor.burn(expected_fee_paid);
let mut bank = Bank::new(&genesis_config);
@ -3521,8 +3533,10 @@ mod tests {
mint_keypair,
..
} = create_genesis_config_with_leader(1_000_000, &leader, 3);
genesis_config.fee_calculator.target_lamports_per_signature = 1000;
genesis_config.fee_calculator.target_signatures_per_slot = 1;
genesis_config
.fee_rate_governor
.target_lamports_per_signature = 1000;
genesis_config.fee_rate_governor.target_signatures_per_slot = 1;
let mut bank = Bank::new(&genesis_config);
goto_end_of_slot(&mut bank);
@ -3571,7 +3585,7 @@ mod tests {
mint_keypair,
..
} = create_genesis_config_with_leader(100, &leader, 3);
genesis_config.fee_calculator.lamports_per_signature = 2;
genesis_config.fee_rate_governor = FeeRateGovernor::new(2, 0);
let bank = Bank::new(&genesis_config);
let key = Keypair::new();
@ -3598,7 +3612,7 @@ mod tests {
bank.get_balance(&leader),
initial_balance
+ bank
.fee_calculator
.fee_rate_governor
.burn(bank.fee_calculator.lamports_per_signature * 2)
.0
);
@ -4548,15 +4562,20 @@ mod tests {
}
#[test]
fn test_bank_inherit_fee_calculator() {
fn test_bank_inherit_fee_rate_governor() {
let (mut genesis_config, _mint_keypair) = create_genesis_config(500);
genesis_config.fee_calculator.target_lamports_per_signature = 123;
genesis_config
.fee_rate_governor
.target_lamports_per_signature = 123;
let bank0 = Arc::new(Bank::new(&genesis_config));
let bank1 = Arc::new(new_from_parent(&bank0));
assert_eq!(
bank0.fee_calculator.target_lamports_per_signature / 2,
bank1.fee_calculator.lamports_per_signature
bank0.fee_rate_governor.target_lamports_per_signature / 2,
bank1
.fee_rate_governor
.create_fee_calculator()
.lamports_per_signature
);
}
@ -4659,7 +4678,7 @@ mod tests {
#[test]
fn test_bank_fees_account() {
let (mut genesis_config, _) = create_genesis_config(500);
genesis_config.fee_calculator.lamports_per_signature = 12345;
genesis_config.fee_rate_governor = FeeRateGovernor::new(12345, 0);
let bank = Arc::new(Bank::new(&genesis_config));
let fees_account = bank.get_account(&sysvar::fees::id()).unwrap();
@ -5443,8 +5462,8 @@ mod tests {
#[test]
fn test_pre_post_transaction_balances() {
let (mut genesis_config, _mint_keypair) = create_genesis_config(500);
let fee_calculator = FeeCalculator::new(1, 0);
genesis_config.fee_calculator = fee_calculator;
let fee_rate_governor = FeeRateGovernor::new(1, 0);
genesis_config.fee_rate_governor = fee_rate_governor;
let parent = Arc::new(Bank::new(&genesis_config));
let bank0 = Arc::new(new_from_parent(&parent));

View File

@ -3,7 +3,7 @@ use solana_sdk::{
account::Account,
client::{AsyncClient, Client, SyncClient},
commitment_config::CommitmentConfig,
fee_calculator::FeeCalculator,
fee_calculator::{FeeCalculator, FeeRateGovernor},
hash::Hash,
instruction::Instruction,
message::Message,
@ -137,6 +137,10 @@ impl SyncClient for BankClient {
Ok(self.bank.last_blockhash_with_fee_calculator())
}
fn get_fee_rate_governor(&self) -> Result<FeeRateGovernor> {
Ok(self.bank.get_fee_rate_governor().clone())
}
fn get_signature_status(
&self,
signature: &Signature,

View File

@ -1,6 +1,6 @@
use solana_sdk::{
account::Account,
fee_calculator::FeeCalculator,
fee_calculator::FeeRateGovernor,
genesis_config::GenesisConfig,
pubkey::Pubkey,
rent::Rent,
@ -140,11 +140,11 @@ pub fn create_genesis_config_with_leader_ex(
solana_stake_program!(),
];
let fee_calculator = FeeCalculator::new(0, 0); // most tests can't handle transaction fees
let fee_rate_governor = FeeRateGovernor::new(0, 0); // most tests can't handle transaction fees
let mut genesis_config = GenesisConfig {
accounts,
native_instruction_processors,
fee_calculator,
fee_rate_governor,
rent,
..GenesisConfig::default()
};