Output more inflation calc details in ledger-tool (#13345)

* Output more inflation calc details in ledger-tool

* Fix broken ci...

* Rename confusing variables

* Fix panic by wrapping PointValue with Opiton...

* Minor modifications

* Remove explict needless flush; Drop already does

* Yet another csv field adjustments

* Add data_size and rename epochs to earned_epochs

* Introduce null_tracer

* Unwrap Option in new_from_parent_with_tracer

* Don't shorten identifiers

* Allow irrefutable_let_patterns temporalily

* More null_tracer

* More field adjustments
This commit is contained in:
Ryo Onodera
2020-11-08 16:43:50 +09:00
committed by GitHub
parent 549492954e
commit a81e7e7749
5 changed files with 386 additions and 60 deletions

View File

@ -67,7 +67,9 @@ use solana_sdk::{
timing::years_as_slots,
transaction::{self, Result, Transaction, TransactionError},
};
use solana_stake_program::stake_state::{self, Delegation, PointValue};
use solana_stake_program::stake_state::{
self, Delegation, InflationPointCalculationEvent, PointValue,
};
use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::VoteState};
use std::{
cell::RefCell,
@ -543,6 +545,15 @@ pub enum RewardType {
Voting,
}
#[derive(Debug)]
pub enum RewardCalculationEvent<'a, 'b> {
Staking(&'a Pubkey, &'b InflationPointCalculationEvent),
}
fn null_tracer() -> Option<impl FnMut(&RewardCalculationEvent)> {
None::<fn(&RewardCalculationEvent)>
}
impl fmt::Display for RewardType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
@ -752,6 +763,24 @@ impl Bank {
/// Create a new bank that points to an immutable checkpoint of another bank.
pub fn new_from_parent(parent: &Arc<Bank>, collector_id: &Pubkey, slot: Slot) -> Self {
Self::_new_from_parent(parent, collector_id, slot, &mut null_tracer())
}
pub fn new_from_parent_with_tracer(
parent: &Arc<Bank>,
collector_id: &Pubkey,
slot: Slot,
reward_calc_tracer: impl FnMut(&RewardCalculationEvent),
) -> Self {
Self::_new_from_parent(parent, collector_id, slot, &mut Some(reward_calc_tracer))
}
fn _new_from_parent(
parent: &Arc<Bank>,
collector_id: &Pubkey,
slot: Slot,
reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
) -> Self {
parent.freeze();
assert_ne!(slot, parent.slot());
@ -844,7 +873,7 @@ impl Bank {
}
new.update_slot_hashes();
new.update_rewards(parent.epoch());
new.update_rewards(parent.epoch(), reward_calc_tracer);
new.update_stake_history(Some(parent.epoch()));
new.update_clock(Some(parent.epoch()));
new.update_fees();
@ -1256,7 +1285,11 @@ impl Bank {
}
// update rewards based on the previous epoch
fn update_rewards(&mut self, prev_epoch: Epoch) {
fn update_rewards(
&mut self,
prev_epoch: Epoch,
reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
) {
if prev_epoch == self.epoch() {
return;
}
@ -1282,7 +1315,8 @@ impl Bank {
let old_vote_balance_and_staked = self.stakes.read().unwrap().vote_balance_and_staked();
let validator_point_value = self.pay_validator_rewards(validator_rewards);
let validator_point_value =
self.pay_validator_rewards(validator_rewards, reward_calc_tracer);
if !self
.feature_set
@ -1354,7 +1388,10 @@ impl Bank {
/// returns a map (has to be copied) of loaded
/// ( Vec<(staker info)> (voter account) ) keyed by voter pubkey
///
fn stake_delegation_accounts(&self) -> HashMap<Pubkey, (Vec<(Pubkey, Account)>, Account)> {
fn stake_delegation_accounts(
&self,
reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
) -> HashMap<Pubkey, (Vec<(Pubkey, Account)>, Account)> {
let mut accounts = HashMap::new();
self.stakes
@ -1371,6 +1408,12 @@ impl Bank {
let entry = accounts
.entry(delegation.voter_pubkey)
.or_insert((Vec::new(), vote_account));
if let Some(reward_calc_tracer) = reward_calc_tracer {
reward_calc_tracer(&RewardCalculationEvent::Staking(
stake_pubkey,
&InflationPointCalculationEvent::Delegation(*delegation),
));
}
entry.0.push((*stake_pubkey, stake_account));
}
(_, _) => {}
@ -1382,10 +1425,14 @@ impl Bank {
/// iterate over all stakes, redeem vote credits for each stake we can
/// successfully load and parse, return the lamport value of one point
fn pay_validator_rewards(&mut self, rewards: u64) -> f64 {
fn pay_validator_rewards(
&mut self,
rewards: u64,
reward_calc_tracer: &mut Option<impl FnMut(&RewardCalculationEvent)>,
) -> f64 {
let stake_history = self.stakes.read().unwrap().history().clone();
let mut stake_delegation_accounts = self.stake_delegation_accounts();
let mut stake_delegation_accounts = self.stake_delegation_accounts(reward_calc_tracer);
let points: u128 = stake_delegation_accounts
.iter()
@ -1413,11 +1460,20 @@ impl Bank {
let voters_account_pre_balance = vote_account.lamports;
for (stake_pubkey, stake_account) in stake_group.iter_mut() {
// curry closure to add the contextual stake_pubkey
let mut reward_calc_tracer = reward_calc_tracer.as_mut().map(|outer| {
let stake_pubkey = *stake_pubkey;
// inner
move |inner_event: &_| {
outer(&RewardCalculationEvent::Staking(&stake_pubkey, inner_event))
}
});
let redeemed = stake_state::redeem_rewards(
stake_account,
vote_account,
&point_value,
Some(&stake_history),
&mut reward_calc_tracer.as_mut(),
);
if let Ok((stakers_reward, _voters_reward)) = redeemed {
self.store_account(&stake_pubkey, &stake_account);
@ -5968,7 +6024,7 @@ mod tests {
bank.add_account_and_update_capitalization(&vote_id, &vote_account);
let validator_points: u128 = bank
.stake_delegation_accounts()
.stake_delegation_accounts(&mut null_tracer())
.iter()
.flat_map(|(_vote_pubkey, (stake_group, vote_account))| {
stake_group