add fee burning (#4818)

This commit is contained in:
Rob Walker
2019-06-26 10:13:21 -07:00
committed by GitHub
parent eb47538a82
commit 8a64e1ddc3
7 changed files with 164 additions and 57 deletions

View File

@ -487,8 +487,10 @@ impl Bank {
let mut hash = self.hash.write().unwrap();
if *hash == Hash::default() {
let collector_fees = self.collector_fees.load(Ordering::Relaxed) as u64;
if collector_fees != 0 {
self.deposit(&self.collector_id, collector_fees);
// burn a portion of fees
self.deposit(&self.collector_id, self.fee_calculator.burn(collector_fees));
}
// freeze is a one-way trip, idempotent
*hash = self.hash_internal_state();
@ -1723,28 +1725,44 @@ mod tests {
#[test]
fn test_bank_tx_fee() {
let arbitrary_transfer_amount = 42;
let mint = arbitrary_transfer_amount * 100;
let leader = Pubkey::new_rand();
let GenesisBlockInfo {
mut genesis_block,
mint_keypair,
..
} = create_genesis_block_with_leader(100, &leader, 3);
genesis_block.fee_calculator.lamports_per_signature = 3;
} = create_genesis_block_with_leader(mint, &leader, 3);
genesis_block.fee_calculator.lamports_per_signature = 4; // something divisible by 2
let expected_fee_paid = genesis_block.fee_calculator.lamports_per_signature;
let expected_fee_collected = genesis_block.fee_calculator.burn(expected_fee_paid);
let mut bank = Bank::new(&genesis_block);
let key = Keypair::new();
let tx =
system_transaction::transfer(&mint_keypair, &key.pubkey(), 2, bank.last_blockhash());
let tx = system_transaction::transfer(
&mint_keypair,
&key.pubkey(),
arbitrary_transfer_amount,
bank.last_blockhash(),
);
let initial_balance = bank.get_balance(&leader);
assert_eq!(bank.process_transaction(&tx), Ok(()));
assert_eq!(bank.get_balance(&key.pubkey()), 2);
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5);
assert_eq!(bank.get_balance(&key.pubkey()), arbitrary_transfer_amount);
assert_eq!(
bank.get_balance(&mint_keypair.pubkey()),
mint - arbitrary_transfer_amount - expected_fee_paid
);
assert_eq!(bank.get_balance(&leader), initial_balance);
goto_end_of_slot(&mut bank);
assert_eq!(bank.signature_count(), 1);
assert_eq!(bank.get_balance(&leader), initial_balance + 3); // Leader collects fee after the bank is frozen
assert_eq!(
bank.get_balance(&leader),
initial_balance + expected_fee_collected
); // Leader collects fee after the bank is frozen
// Verify that an InstructionError collects fees, too
let mut bank = Bank::new_from_parent(&Arc::new(bank), &leader, 1);
@ -1755,13 +1773,19 @@ mod tests {
bank.process_transaction(&tx)
.expect_err("instruction error");
assert_eq!(bank.get_balance(&key.pubkey()), 2); // no change
assert_eq!(bank.get_balance(&mint_keypair.pubkey()), 100 - 5 - 3); // mint_keypair still pays a fee
assert_eq!(bank.get_balance(&key.pubkey()), arbitrary_transfer_amount); // no change
assert_eq!(
bank.get_balance(&mint_keypair.pubkey()),
mint - arbitrary_transfer_amount - 2 * expected_fee_paid
); // mint_keypair still pays a fee
goto_end_of_slot(&mut bank);
assert_eq!(bank.signature_count(), 1);
// Profit! 2 transaction signatures processed at 3 lamports each
assert_eq!(bank.get_balance(&leader), initial_balance + 6);
assert_eq!(
bank.get_balance(&leader),
initial_balance + 2 * expected_fee_collected
);
}
#[test]
@ -1840,11 +1864,17 @@ mod tests {
InstructionError::new_result_with_negative_lamports(),
)),
];
let initial_balance = bank.get_balance(&leader);
let results = bank.filter_program_errors_and_collect_fee(&vec![tx1, tx2], &results);
bank.freeze();
assert_eq!(bank.get_balance(&leader), initial_balance + 2 + 2);
assert_eq!(
bank.get_balance(&leader),
initial_balance
+ bank
.fee_calculator
.burn(bank.fee_calculator.lamports_per_signature * 2)
);
assert_eq!(results[0], Ok(()));
assert_eq!(results[1], Ok(()));
}
@ -2436,11 +2466,11 @@ mod tests {
fn test_bank_inherit_fee_calculator() {
let (mut genesis_block, _mint_keypair) = create_genesis_block(500);
genesis_block.fee_calculator.target_lamports_per_signature = 123;
assert_eq!(genesis_block.fee_calculator.target_signatures_per_slot, 0);
let bank0 = Arc::new(Bank::new(&genesis_block));
let bank1 = Arc::new(new_from_parent(&bank0));
assert_eq!(
bank0.fee_calculator.target_lamports_per_signature,
bank0.fee_calculator.target_lamports_per_signature / 2,
bank1.fee_calculator.lamports_per_signature
);
}

View File

@ -1,8 +1,11 @@
use solana_sdk::account::Account;
use solana_sdk::genesis_block::{Builder, GenesisBlock};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, KeypairUtil};
use solana_sdk::system_program;
use solana_sdk::{
account::Account,
fee_calculator::FeeCalculator,
genesis_block::{Builder, GenesisBlock},
pubkey::Pubkey,
signature::{Keypair, KeypairUtil},
system_program,
};
use solana_stake_api;
use solana_vote_api::vote_state;
@ -67,7 +70,8 @@ pub fn create_genesis_block_with_leader(
solana_bpf_loader_program!(),
solana_vote_program!(),
solana_stake_program!(),
]);
])
.fee_calculator(FeeCalculator::new(0)); // most tests don't want fees
builder = solana_stake_api::rewards_pools::genesis(builder);
builder = solana_storage_api::rewards_pools::genesis(builder);