Skip to content

Commit

Permalink
Purge storage rewards from accounts db for testnet (#11996) (#12011)
Browse files Browse the repository at this point in the history
* Purge storage rewards from accounts db for testnet

* Fix test failing only on stable

(cherry picked from commit fb71ee6)

Co-authored-by: Ryo Onodera <ryoqun@gmail.com>
  • Loading branch information
mergify[bot] and ryoqun authored Sep 3, 2020
1 parent 3e78850 commit 8f02fdc
Showing 1 changed file with 88 additions and 4 deletions.
92 changes: 88 additions & 4 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,9 @@ pub struct Bank {
pub operating_mode: Option<OperatingMode>,

pub lazy_rent_collection: AtomicBool,

// this is temporary field only to remove rewards_pool entirely
pub rewards_pool_pubkeys: Arc<HashSet<Pubkey>>,
}

impl Default for BlockhashQueue {
Expand All @@ -479,7 +482,7 @@ impl Bank {

bank.rc.accounts = Arc::new(Accounts::new(paths, &genesis_config.operating_mode));
bank.process_genesis_config(genesis_config);
bank.finish_init();
bank.finish_init(genesis_config);

// Freeze accounts after process_genesis_config creates the initial append vecs
Arc::get_mut(&mut Arc::get_mut(&mut bank.rc.accounts).unwrap().accounts_db)
Expand Down Expand Up @@ -573,6 +576,7 @@ impl Bank {
lazy_rent_collection: AtomicBool::new(
parent.lazy_rent_collection.load(Ordering::Relaxed),
),
rewards_pool_pubkeys: parent.rewards_pool_pubkeys.clone(),
};

datapoint_info!(
Expand Down Expand Up @@ -674,8 +678,9 @@ impl Bank {
skip_drop: new(),
operating_mode: Some(genesis_config.operating_mode),
lazy_rent_collection: new(),
rewards_pool_pubkeys: new(),
};
bank.finish_init();
bank.finish_init(genesis_config);

// Sanity assertions between bank snapshot and genesis config
// Consider removing from serializable bank state
Expand Down Expand Up @@ -2649,7 +2654,9 @@ impl Bank {
self.src = status_cache_rc;
}

pub fn finish_init(&mut self) {
pub fn finish_init(&mut self, genesis_config: &GenesisConfig) {
self.rewards_pool_pubkeys =
Arc::new(genesis_config.rewards_pools.keys().cloned().collect());
self.apply_feature_activations(true, false);
}

Expand Down Expand Up @@ -3235,6 +3242,7 @@ impl Bank {
self.recheck_cross_program_support();
self.recheck_compute_budget();
self.reconfigure_token2_native_mint();
self.ensure_no_storage_rewards_pool();
}

fn ensure_builtins(&mut self, init_or_warp: bool) {
Expand Down Expand Up @@ -3327,6 +3335,35 @@ impl Bank {
}
}

fn ensure_no_storage_rewards_pool(&mut self) {
let purge_window_epoch = match self.operating_mode() {
// never do this for testnet; we're pristine here. :)
OperatingMode::Development => false,
// schedule to remove at testnet/tds
OperatingMode::Preview => self.epoch() == 93,
// never do this for stable; we're pristine here. :)
OperatingMode::Stable => false,
};

if purge_window_epoch {
for reward_pubkey in self.rewards_pool_pubkeys.iter() {
if let Some(mut reward_account) = self.get_account(&reward_pubkey) {
if reward_account.lamports == u64::MAX {
reward_account.lamports = 0;
self.store_account(&reward_pubkey, &reward_account);
// Adjust capitalization.... it has been wrapping, reducing the real capitalization by 1-lamport
self.capitalization.fetch_add(1, Ordering::Relaxed);
info!(
"purged rewards pool accont: {}, new capitalization: {}",
reward_pubkey,
self.capitalization()
);
}
};
}
}
}

fn fix_recent_blockhashes_sysvar_delay(&self) -> bool {
let activation_slot = match self.operating_mode() {
OperatingMode::Development => 0,
Expand Down Expand Up @@ -8304,7 +8341,7 @@ mod tests {
bank.message_processor.set_cross_program_support(false);

// simulate bank is just after deserialized from snapshot
bank.finish_init();
bank.finish_init(&genesis_config);

assert_eq!(bank.message_processor.get_cross_program_support(), true);
}
Expand Down Expand Up @@ -8502,4 +8539,51 @@ mod tests {
);
assert_eq!(native_mint_account.owner, inline_spl_token_v2_0::id());
}

#[test]
fn test_ensure_no_storage_rewards_pool() {
solana_logger::setup();

let mut genesis_config =
create_genesis_config_with_leader(5, &Pubkey::new_rand(), 0).genesis_config;

// OperatingMode::Preview - Storage rewards pool is purged at epoch 93
// Also this is with bad capitalization
genesis_config.operating_mode = OperatingMode::Preview;
genesis_config.inflation = Inflation::default();
let reward_pubkey = Pubkey::new_rand();
genesis_config.rewards_pools.insert(
reward_pubkey,
Account::new(u64::MAX, 0, &Pubkey::new_rand()),
);
let bank0 = Bank::new(&genesis_config);
// because capitalization has been reset with bogus capitalization calculation allowing overflows,
// deliberately substract 1 lamport to simulate it
bank0.capitalization.fetch_sub(1, Ordering::Relaxed);
let bank0 = Arc::new(bank0);
assert_eq!(bank0.get_balance(&reward_pubkey), u64::MAX,);

let bank1 = Bank::new_from_parent(
&bank0,
&Pubkey::default(),
genesis_config.epoch_schedule.get_first_slot_in_epoch(93),
);

// assert that everything gets in order....
assert!(bank1.get_account(&reward_pubkey).is_none());
assert_eq!(bank0.capitalization() + 1, bank1.capitalization());
assert_eq!(bank1.capitalization(), bank1.calculate_capitalization());

// Depending on RUSTFLAGS, this test exposes rust's checked math behavior or not...
// So do some convolted setup; anyway this test itself will just be temporary
let bank0 = std::panic::AssertUnwindSafe(bank0);
let overflowing_capitalization =
std::panic::catch_unwind(|| bank0.calculate_capitalization());
if let Ok(overflowing_capitalization) = overflowing_capitalization {
info!("asserting overflowing capitalization for bank0");
assert_eq!(overflowing_capitalization, bank0.capitalization());
} else {
info!("NOT-asserting overflowing capitalization for bank0");
}
}
}

0 comments on commit 8f02fdc

Please sign in to comment.