Include the Epoch Accounts Hash in the Bank hash (#27541)
This commit is contained in:
parent
93a4f80a2c
commit
1cf9077d06
|
@ -1191,7 +1191,6 @@ pub struct AccountsDb {
|
||||||
exhaustively_verify_refcounts: bool,
|
exhaustively_verify_refcounts: bool,
|
||||||
|
|
||||||
/// A special accounts hash that occurs once per epoch
|
/// A special accounts hash that occurs once per epoch
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) epoch_accounts_hash: Mutex<Option<EpochAccountsHash>>,
|
pub(crate) epoch_accounts_hash: Mutex<Option<EpochAccountsHash>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ use {
|
||||||
blockhash_queue::BlockhashQueue,
|
blockhash_queue::BlockhashQueue,
|
||||||
builtins::{self, BuiltinAction, BuiltinFeatureTransition, Builtins},
|
builtins::{self, BuiltinAction, BuiltinFeatureTransition, Builtins},
|
||||||
cost_tracker::CostTracker,
|
cost_tracker::CostTracker,
|
||||||
|
epoch_accounts_hash::{self, EpochAccountsHash},
|
||||||
epoch_stakes::{EpochStakes, NodeVoteAccounts},
|
epoch_stakes::{EpochStakes, NodeVoteAccounts},
|
||||||
expected_rent_collection::{ExpectedRentCollection, SlotInfoInEpoch},
|
expected_rent_collection::{ExpectedRentCollection, SlotInfoInEpoch},
|
||||||
inline_spl_associated_token_account, inline_spl_token,
|
inline_spl_associated_token_account, inline_spl_token,
|
||||||
|
@ -6835,6 +6836,21 @@ impl Bank {
|
||||||
self.last_blockhash().as_ref(),
|
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
|
let buf = self
|
||||||
.hard_forks
|
.hard_forks
|
||||||
.read()
|
.read()
|
||||||
|
@ -6853,13 +6869,17 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}",
|
"bank frozen: {} hash: {} accounts_delta: {} signature_count: {} last_blockhash: {} capitalization: {}{}",
|
||||||
self.slot(),
|
self.slot(),
|
||||||
hash,
|
hash,
|
||||||
accounts_delta_hash.hash,
|
accounts_delta_hash.hash,
|
||||||
self.signature_count(),
|
self.signature_count(),
|
||||||
self.last_blockhash(),
|
self.last_blockhash(),
|
||||||
self.capitalization(),
|
self.capitalization(),
|
||||||
|
match epoch_accounts_hash {
|
||||||
|
None => "".to_string(),
|
||||||
|
Some(epoch_accounts_hash) => format!(", epoch_accounts_hash: {}", epoch_accounts_hash.as_ref()),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
|
@ -6870,6 +6890,22 @@ impl Bank {
|
||||||
hash
|
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
|
/// Recalculate the hash_internal_state from the account stores. Would be used to verify a
|
||||||
/// snapshot.
|
/// snapshot.
|
||||||
/// return true if all is good
|
/// return true if all is good
|
||||||
|
@ -7843,6 +7879,17 @@ impl Bank {
|
||||||
|
|
||||||
total_accounts_stats
|
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
|
/// Compute how much an account has changed size. This function is useful when the data size delta
|
||||||
|
|
|
@ -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
|
/// and referred to as the "stop" slot for the EAH calculation. All nodes must complete the EAH
|
||||||
/// calculation before this slot!
|
/// calculation before this slot!
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn calculation_offset_stop(bank: &Bank) -> Slot {
|
pub fn calculation_offset_stop(bank: &Bank) -> Slot {
|
||||||
let slots_per_epoch = bank.epoch_schedule().slots_per_epoch;
|
let slots_per_epoch = bank.epoch_schedule().slots_per_epoch;
|
||||||
slots_per_epoch / 4 * 3
|
slots_per_epoch / 4 * 3
|
||||||
|
|
|
@ -514,6 +514,10 @@ pub mod cap_accounts_data_allocations_per_transaction {
|
||||||
solana_sdk::declare_id!("9gxu85LYRAcZL38We8MYJ4A9AwgBBPtVBAqebMcT1241");
|
solana_sdk::declare_id!("9gxu85LYRAcZL38We8MYJ4A9AwgBBPtVBAqebMcT1241");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod epoch_accounts_hash {
|
||||||
|
solana_sdk::declare_id!("5GpmAKxaGsWWbPp4bNXFLJxZVvG92ctxf7jQnzTQjF3n");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
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"),
|
(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"),
|
(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"),
|
(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 ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Reference in New Issue