Include the Epoch Accounts Hash in the Bank hash (#27541)

This commit is contained in:
Brooks Prumo 2022-09-07 10:10:49 -04:00 committed by GitHub
parent 93a4f80a2c
commit 1cf9077d06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 3 deletions

View File

@ -1191,7 +1191,6 @@ pub struct AccountsDb {
exhaustively_verify_refcounts: bool,
/// A special accounts hash that occurs once per epoch
#[allow(dead_code)]
pub(crate) epoch_accounts_hash: Mutex<Option<EpochAccountsHash>>,
}

View File

@ -53,6 +53,7 @@ use {
blockhash_queue::BlockhashQueue,
builtins::{self, BuiltinAction, BuiltinFeatureTransition, Builtins},
cost_tracker::CostTracker,
epoch_accounts_hash::{self, EpochAccountsHash},
epoch_stakes::{EpochStakes, NodeVoteAccounts},
expected_rent_collection::{ExpectedRentCollection, SlotInfoInEpoch},
inline_spl_associated_token_account, inline_spl_token,
@ -6835,6 +6836,21 @@ impl Bank {
self.last_blockhash().as_ref(),
]);
let epoch_accounts_hash = self.epoch_accounts_hash();
if self.should_include_epoch_accounts_hash() {
// Nothing is writing a value into the epoch accounts hash yet—this is not a problem
// for normal clusters, as the feature gating this `if` block is always false.
// However, some tests enable all features, so this `if` block can be true.
//
// For now, check to see if the epoch accounts hash is `Some` before hashing. Once the
// writer-side is implemented, change this to be an `.expect()` or `.unwrap()`, as it
// will be required for the epoch accounts hash calculation to have compleleted and
// for this value to be `Some`.
if let Some(epoch_accounts_hash) = epoch_accounts_hash {
hash = hashv(&[hash.as_ref(), epoch_accounts_hash.as_ref().as_ref()]);
}
}
let buf = self
.hard_forks
.read()
@ -6853,13 +6869,17 @@ impl Bank {
}
info!(
"bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}",
"bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}{}",
self.slot(),
hash,
accounts_delta_hash.hash,
self.signature_count(),
self.last_blockhash(),
self.capitalization(),
match epoch_accounts_hash {
None => "".to_string(),
Some(epoch_accounts_hash) => format!(", epoch_accounts_hash: {}", epoch_accounts_hash.as_ref()),
},
);
info!(
@ -6870,6 +6890,22 @@ impl Bank {
hash
}
/// The epoch accounts hash is hashed into the bank's hash once per epoch at a predefined slot.
/// Should it be included in *this* bank?
fn should_include_epoch_accounts_hash(&self) -> bool {
if !self
.feature_set
.is_active(&feature_set::epoch_accounts_hash::id())
{
return false;
}
let first_slot_in_epoch = self.epoch_schedule().get_first_slot_in_epoch(self.epoch);
let stop_offset = epoch_accounts_hash::calculation_offset_stop(self);
let stop_slot = first_slot_in_epoch + stop_offset;
self.parent_slot() < stop_slot && self.slot() >= stop_slot
}
/// Recalculate the hash_internal_state from the account stores. Would be used to verify a
/// snapshot.
/// return true if all is good
@ -7843,6 +7879,17 @@ impl Bank {
total_accounts_stats
}
/// Convenience fn to get the Epoch Accounts Hash
fn epoch_accounts_hash(&self) -> Option<EpochAccountsHash> {
*self
.rc
.accounts
.accounts_db
.epoch_accounts_hash
.lock()
.unwrap()
}
}
/// Compute how much an account has changed size. This function is useful when the data size delta

View File

@ -38,7 +38,6 @@ pub fn calculation_offset_start(bank: &Bank) -> Slot {
/// and referred to as the "stop" slot for the EAH calculation. All nodes must complete the EAH
/// calculation before this slot!
#[must_use]
#[allow(dead_code)]
pub fn calculation_offset_stop(bank: &Bank) -> Slot {
let slots_per_epoch = bank.epoch_schedule().slots_per_epoch;
slots_per_epoch / 4 * 3

View File

@ -514,6 +514,10 @@ pub mod cap_accounts_data_allocations_per_transaction {
solana_sdk::declare_id!("9gxu85LYRAcZL38We8MYJ4A9AwgBBPtVBAqebMcT1241");
}
pub mod epoch_accounts_hash {
solana_sdk::declare_id!("5GpmAKxaGsWWbPp4bNXFLJxZVvG92ctxf7jQnzTQjF3n");
}
lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
@ -637,6 +641,7 @@ lazy_static! {
(stop_sibling_instruction_search_at_parent::id(), "stop the search in get_processed_sibling_instruction when the parent instruction is reached #27289"),
(vote_state_update_root_fix::id(), "fix root in vote state updates #27361"),
(cap_accounts_data_allocations_per_transaction::id(), "cap accounts data allocations per transaction #27375"),
(epoch_accounts_hash::id(), "enable epoch accounts hash calculation #27539"),
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()