|
@@ -76,7 +76,7 @@ use {
|
|
|
accounts::{AccountAddressFilter, Accounts, PubkeyAccountSlot},
|
|
accounts::{AccountAddressFilter, Accounts, PubkeyAccountSlot},
|
|
|
accounts_db::{
|
|
accounts_db::{
|
|
|
AccountStorageEntry, AccountsDb, AccountsDbConfig, CalcAccountsHashDataSource,
|
|
AccountStorageEntry, AccountsDb, AccountsDbConfig, CalcAccountsHashDataSource,
|
|
|
- DuplicatesLtHash, PubkeyHashAccount, VerifyAccountsHashAndLamportsConfig,
|
|
|
|
|
|
|
+ DuplicatesLtHash, PubkeyHashAccount,
|
|
|
},
|
|
},
|
|
|
accounts_hash::{
|
|
accounts_hash::{
|
|
|
AccountsHash, AccountsLtHash, CalcAccountsHashConfig, HashStats,
|
|
AccountsHash, AccountsLtHash, CalcAccountsHashConfig, HashStats,
|
|
@@ -198,10 +198,8 @@ pub use {partitioned_epoch_rewards::KeyedRewardsAndNumPartitions, solana_reward_
|
|
|
|
|
|
|
|
/// params to `verify_accounts_hash`
|
|
/// params to `verify_accounts_hash`
|
|
|
struct VerifyAccountsHashConfig {
|
|
struct VerifyAccountsHashConfig {
|
|
|
- ignore_mismatch: bool,
|
|
|
|
|
require_rooted_bank: bool,
|
|
require_rooted_bank: bool,
|
|
|
run_in_background: bool,
|
|
run_in_background: bool,
|
|
|
- store_hash_raw_data_for_debug: bool,
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
mod accounts_lt_hash;
|
|
mod accounts_lt_hash;
|
|
@@ -4580,16 +4578,16 @@ impl Bank {
|
|
|
|
|
|
|
|
/// Used by ledger tool to run a final hash calculation once all ledger replay has completed.
|
|
/// Used by ledger tool to run a final hash calculation once all ledger replay has completed.
|
|
|
/// This should not be called by validator code.
|
|
/// This should not be called by validator code.
|
|
|
- pub fn run_final_hash_calc(&self, on_halt_store_hash_raw_data_for_debug: bool) {
|
|
|
|
|
|
|
+ pub fn run_final_hash_calc(
|
|
|
|
|
+ &self,
|
|
|
|
|
+ _on_halt_store_hash_raw_data_for_debug: bool, // will be removed next
|
|
|
|
|
+ ) {
|
|
|
self.force_flush_accounts_cache();
|
|
self.force_flush_accounts_cache();
|
|
|
// note that this slot may not be a root
|
|
// note that this slot may not be a root
|
|
|
_ = self.verify_accounts_hash(
|
|
_ = self.verify_accounts_hash(
|
|
|
- None,
|
|
|
|
|
VerifyAccountsHashConfig {
|
|
VerifyAccountsHashConfig {
|
|
|
- ignore_mismatch: true,
|
|
|
|
|
require_rooted_bank: false,
|
|
require_rooted_bank: false,
|
|
|
run_in_background: false,
|
|
run_in_background: false,
|
|
|
- store_hash_raw_data_for_debug: on_halt_store_hash_raw_data_for_debug,
|
|
|
|
|
},
|
|
},
|
|
|
None,
|
|
None,
|
|
|
);
|
|
);
|
|
@@ -4601,17 +4599,9 @@ impl Bank {
|
|
|
#[must_use]
|
|
#[must_use]
|
|
|
fn verify_accounts_hash(
|
|
fn verify_accounts_hash(
|
|
|
&self,
|
|
&self,
|
|
|
- base: Option<(Slot, /*capitalization*/ u64)>,
|
|
|
|
|
mut config: VerifyAccountsHashConfig,
|
|
mut config: VerifyAccountsHashConfig,
|
|
|
duplicates_lt_hash: Option<Box<DuplicatesLtHash>>,
|
|
duplicates_lt_hash: Option<Box<DuplicatesLtHash>>,
|
|
|
) -> bool {
|
|
) -> bool {
|
|
|
- #[derive(Debug, Eq, PartialEq)]
|
|
|
|
|
- enum VerifyKind {
|
|
|
|
|
- #[allow(dead_code)] // will be removed next
|
|
|
|
|
- Merkle,
|
|
|
|
|
- Lattice,
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
let accounts = &self.rc.accounts;
|
|
let accounts = &self.rc.accounts;
|
|
|
// Wait until initial hash calc is complete before starting a new hash calc.
|
|
// Wait until initial hash calc is complete before starting a new hash calc.
|
|
|
// This should only occur when we halt at a slot in ledger-tool.
|
|
// This should only occur when we halt at a slot in ledger-tool.
|
|
@@ -4622,7 +4612,6 @@ impl Bank {
|
|
|
|
|
|
|
|
let slot = self.slot();
|
|
let slot = self.slot();
|
|
|
|
|
|
|
|
- let verify_kind = VerifyKind::Lattice;
|
|
|
|
|
if duplicates_lt_hash.is_none() {
|
|
if duplicates_lt_hash.is_none() {
|
|
|
// Calculating the accounts lt hash from storages *requires* a duplicates_lt_hash.
|
|
// Calculating the accounts lt hash from storages *requires* a duplicates_lt_hash.
|
|
|
// If it is None here, then we must use the index instead, which also means we
|
|
// If it is None here, then we must use the index instead, which also means we
|
|
@@ -4636,13 +4625,11 @@ impl Bank {
|
|
|
"slot {slot} is not a root, so verify accounts hash on parent bank at slot {}",
|
|
"slot {slot} is not a root, so verify accounts hash on parent bank at slot {}",
|
|
|
parent.slot(),
|
|
parent.slot(),
|
|
|
);
|
|
);
|
|
|
- if verify_kind == VerifyKind::Lattice {
|
|
|
|
|
- // The duplicates_lt_hash is only valid for the current slot, so we must fall
|
|
|
|
|
- // back to verifying the accounts lt hash with the index (which also means we
|
|
|
|
|
- // cannot run in the background).
|
|
|
|
|
- config.run_in_background = false;
|
|
|
|
|
- }
|
|
|
|
|
- return parent.verify_accounts_hash(base, config, None);
|
|
|
|
|
|
|
+ // The duplicates_lt_hash is only valid for the current slot, so we must fall
|
|
|
|
|
+ // back to verifying the accounts lt hash with the index (which also means we
|
|
|
|
|
+ // cannot run in the background).
|
|
|
|
|
+ config.run_in_background = false;
|
|
|
|
|
+ return parent.verify_accounts_hash(config, None);
|
|
|
} else {
|
|
} else {
|
|
|
// this will result in mismatch errors
|
|
// this will result in mismatch errors
|
|
|
// accounts hash calc doesn't include unrooted slots
|
|
// accounts hash calc doesn't include unrooted slots
|
|
@@ -4654,25 +4641,14 @@ impl Bank {
|
|
|
// Otherwise, it is possible that a delayed call to `get_snapshot_storages()` will *not*
|
|
// Otherwise, it is possible that a delayed call to `get_snapshot_storages()` will *not*
|
|
|
// get the correct storages required to calculate and verify the accounts hashes.
|
|
// get the correct storages required to calculate and verify the accounts hashes.
|
|
|
let snapshot_storages = self.rc.accounts.accounts_db.get_storages(RangeFull);
|
|
let snapshot_storages = self.rc.accounts.accounts_db.get_storages(RangeFull);
|
|
|
- let capitalization = self.capitalization();
|
|
|
|
|
- let verify_config = VerifyAccountsHashAndLamportsConfig {
|
|
|
|
|
- ancestors: &self.ancestors,
|
|
|
|
|
- epoch_schedule: self.epoch_schedule(),
|
|
|
|
|
- epoch: self.epoch(),
|
|
|
|
|
- ignore_mismatch: config.ignore_mismatch,
|
|
|
|
|
- store_detailed_debug_info: config.store_hash_raw_data_for_debug,
|
|
|
|
|
- use_bg_thread_pool: config.run_in_background,
|
|
|
|
|
- };
|
|
|
|
|
|
|
|
|
|
info!(
|
|
info!(
|
|
|
- "Verifying accounts, in background? {}, verify kind: {verify_kind:?}",
|
|
|
|
|
|
|
+ "Verifying accounts, in background? {}",
|
|
|
config.run_in_background,
|
|
config.run_in_background,
|
|
|
);
|
|
);
|
|
|
if config.run_in_background {
|
|
if config.run_in_background {
|
|
|
let accounts = Arc::clone(accounts);
|
|
let accounts = Arc::clone(accounts);
|
|
|
let accounts_ = Arc::clone(&accounts);
|
|
let accounts_ = Arc::clone(&accounts);
|
|
|
- let ancestors = self.ancestors.clone();
|
|
|
|
|
- let epoch_schedule = self.epoch_schedule().clone();
|
|
|
|
|
let expected_accounts_lt_hash = self.accounts_lt_hash.lock().unwrap().clone();
|
|
let expected_accounts_lt_hash = self.accounts_lt_hash.lock().unwrap().clone();
|
|
|
accounts.accounts_db.verify_accounts_hash_in_bg.start(|| {
|
|
accounts.accounts_db.verify_accounts_hash_in_bg.start(|| {
|
|
|
Builder::new()
|
|
Builder::new()
|
|
@@ -4680,71 +4656,32 @@ impl Bank {
|
|
|
.spawn(move || {
|
|
.spawn(move || {
|
|
|
info!("Initial background accounts hash verification has started");
|
|
info!("Initial background accounts hash verification has started");
|
|
|
let start = Instant::now();
|
|
let start = Instant::now();
|
|
|
- let mut lattice_verify_time = None;
|
|
|
|
|
- let mut merkle_verify_time = None;
|
|
|
|
|
- let is_ok = match verify_kind {
|
|
|
|
|
- VerifyKind::Lattice => {
|
|
|
|
|
- // accounts lt hash is *enabled* so use lattice-based verification
|
|
|
|
|
- let accounts_db = &accounts_.accounts_db;
|
|
|
|
|
- let (calculated_accounts_lt_hash, duration) =
|
|
|
|
|
- meas_dur!(accounts_db.thread_pool_hash.install(|| {
|
|
|
|
|
- accounts_db
|
|
|
|
|
- .calculate_accounts_lt_hash_at_startup_from_storages(
|
|
|
|
|
- snapshot_storages.0.as_slice(),
|
|
|
|
|
- &duplicates_lt_hash.unwrap(),
|
|
|
|
|
- )
|
|
|
|
|
- }));
|
|
|
|
|
- let is_ok =
|
|
|
|
|
- calculated_accounts_lt_hash == expected_accounts_lt_hash;
|
|
|
|
|
- if !is_ok {
|
|
|
|
|
- let expected = expected_accounts_lt_hash.0.checksum();
|
|
|
|
|
- let calculated = calculated_accounts_lt_hash.0.checksum();
|
|
|
|
|
- error!(
|
|
|
|
|
- "Verifying accounts failed: accounts lattice hashes do not \
|
|
|
|
|
- match, expected: {expected}, calculated: {calculated}",
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- lattice_verify_time = Some(duration);
|
|
|
|
|
- is_ok
|
|
|
|
|
- }
|
|
|
|
|
- VerifyKind::Merkle => {
|
|
|
|
|
- // accounts lt hash is *disabled* so use merkle-based verification
|
|
|
|
|
- let snapshot_storages_and_slots = (
|
|
|
|
|
|
|
+ let accounts_db = &accounts_.accounts_db;
|
|
|
|
|
+ let (calculated_accounts_lt_hash, lattice_verify_time) =
|
|
|
|
|
+ meas_dur!(accounts_db.thread_pool_hash.install(|| {
|
|
|
|
|
+ accounts_db.calculate_accounts_lt_hash_at_startup_from_storages(
|
|
|
snapshot_storages.0.as_slice(),
|
|
snapshot_storages.0.as_slice(),
|
|
|
- snapshot_storages.1.as_slice(),
|
|
|
|
|
- );
|
|
|
|
|
- let (is_ok, duration) = meas_dur!(accounts_
|
|
|
|
|
- .verify_accounts_hash_and_lamports(
|
|
|
|
|
- snapshot_storages_and_slots,
|
|
|
|
|
- slot,
|
|
|
|
|
- capitalization,
|
|
|
|
|
- base,
|
|
|
|
|
- VerifyAccountsHashAndLamportsConfig {
|
|
|
|
|
- ancestors: &ancestors,
|
|
|
|
|
- epoch_schedule: &epoch_schedule,
|
|
|
|
|
- ..verify_config
|
|
|
|
|
- },
|
|
|
|
|
- ));
|
|
|
|
|
- merkle_verify_time = Some(duration);
|
|
|
|
|
- is_ok
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
- accounts_
|
|
|
|
|
- .accounts_db
|
|
|
|
|
- .verify_accounts_hash_in_bg
|
|
|
|
|
- .background_finished();
|
|
|
|
|
|
|
+ &duplicates_lt_hash.unwrap(),
|
|
|
|
|
+ )
|
|
|
|
|
+ }));
|
|
|
|
|
+ let is_ok = calculated_accounts_lt_hash == expected_accounts_lt_hash;
|
|
|
|
|
+ if !is_ok {
|
|
|
|
|
+ let expected = expected_accounts_lt_hash.0.checksum();
|
|
|
|
|
+ let calculated = calculated_accounts_lt_hash.0.checksum();
|
|
|
|
|
+ error!(
|
|
|
|
|
+ "Verifying accounts failed: accounts lattice hashes do not \
|
|
|
|
|
+ match, expected: {expected}, calculated: {calculated}",
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ accounts_db.verify_accounts_hash_in_bg.background_finished();
|
|
|
let total_time = start.elapsed();
|
|
let total_time = start.elapsed();
|
|
|
datapoint_info!(
|
|
datapoint_info!(
|
|
|
"startup_verify_accounts",
|
|
"startup_verify_accounts",
|
|
|
("total_us", total_time.as_micros(), i64),
|
|
("total_us", total_time.as_micros(), i64),
|
|
|
(
|
|
(
|
|
|
"verify_accounts_lt_hash_us",
|
|
"verify_accounts_lt_hash_us",
|
|
|
- lattice_verify_time.as_ref().map(Duration::as_micros),
|
|
|
|
|
- Option<i64>
|
|
|
|
|
- ),
|
|
|
|
|
- ("verify_accounts_hash_us",
|
|
|
|
|
- merkle_verify_time.as_ref().map(Duration::as_micros),
|
|
|
|
|
- Option<i64>
|
|
|
|
|
|
|
+ lattice_verify_time.as_micros(),
|
|
|
|
|
+ i64
|
|
|
),
|
|
),
|
|
|
);
|
|
);
|
|
|
info!("Initial background accounts hash verification has stopped");
|
|
info!("Initial background accounts hash verification has stopped");
|
|
@@ -4754,51 +4691,30 @@ impl Bank {
|
|
|
});
|
|
});
|
|
|
true // initial result is true. We haven't failed yet. If verification fails, we'll panic from bg thread.
|
|
true // initial result is true. We haven't failed yet. If verification fails, we'll panic from bg thread.
|
|
|
} else {
|
|
} else {
|
|
|
- match verify_kind {
|
|
|
|
|
- VerifyKind::Lattice => {
|
|
|
|
|
- let expected_accounts_lt_hash = self.accounts_lt_hash.lock().unwrap().clone();
|
|
|
|
|
- let calculated_accounts_lt_hash = if let Some(duplicates_lt_hash) =
|
|
|
|
|
- duplicates_lt_hash
|
|
|
|
|
- {
|
|
|
|
|
- accounts
|
|
|
|
|
- .accounts_db
|
|
|
|
|
- .calculate_accounts_lt_hash_at_startup_from_storages(
|
|
|
|
|
- snapshot_storages.0.as_slice(),
|
|
|
|
|
- &duplicates_lt_hash,
|
|
|
|
|
- )
|
|
|
|
|
- } else {
|
|
|
|
|
- accounts
|
|
|
|
|
- .accounts_db
|
|
|
|
|
- .calculate_accounts_lt_hash_at_startup_from_index(&self.ancestors, slot)
|
|
|
|
|
- };
|
|
|
|
|
- let is_ok = calculated_accounts_lt_hash == expected_accounts_lt_hash;
|
|
|
|
|
- if !is_ok {
|
|
|
|
|
- let expected = expected_accounts_lt_hash.0.checksum();
|
|
|
|
|
- let calculated = calculated_accounts_lt_hash.0.checksum();
|
|
|
|
|
- error!(
|
|
|
|
|
- "Verifying accounts failed: accounts lattice hashes do not \
|
|
|
|
|
- match, expected: {expected}, calculated: {calculated}",
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- self.set_initial_accounts_hash_verification_completed();
|
|
|
|
|
- is_ok
|
|
|
|
|
- }
|
|
|
|
|
- VerifyKind::Merkle => {
|
|
|
|
|
- let snapshot_storages_and_slots = (
|
|
|
|
|
|
|
+ let expected_accounts_lt_hash = self.accounts_lt_hash.lock().unwrap().clone();
|
|
|
|
|
+ let calculated_accounts_lt_hash = if let Some(duplicates_lt_hash) = duplicates_lt_hash {
|
|
|
|
|
+ accounts
|
|
|
|
|
+ .accounts_db
|
|
|
|
|
+ .calculate_accounts_lt_hash_at_startup_from_storages(
|
|
|
snapshot_storages.0.as_slice(),
|
|
snapshot_storages.0.as_slice(),
|
|
|
- snapshot_storages.1.as_slice(),
|
|
|
|
|
- );
|
|
|
|
|
- let is_ok = accounts.verify_accounts_hash_and_lamports(
|
|
|
|
|
- snapshot_storages_and_slots,
|
|
|
|
|
- slot,
|
|
|
|
|
- capitalization,
|
|
|
|
|
- base,
|
|
|
|
|
- verify_config,
|
|
|
|
|
- );
|
|
|
|
|
- self.set_initial_accounts_hash_verification_completed();
|
|
|
|
|
- is_ok
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ &duplicates_lt_hash,
|
|
|
|
|
+ )
|
|
|
|
|
+ } else {
|
|
|
|
|
+ accounts
|
|
|
|
|
+ .accounts_db
|
|
|
|
|
+ .calculate_accounts_lt_hash_at_startup_from_index(&self.ancestors, slot)
|
|
|
|
|
+ };
|
|
|
|
|
+ let is_ok = calculated_accounts_lt_hash == expected_accounts_lt_hash;
|
|
|
|
|
+ if !is_ok {
|
|
|
|
|
+ let expected = expected_accounts_lt_hash.0.checksum();
|
|
|
|
|
+ let calculated = calculated_accounts_lt_hash.0.checksum();
|
|
|
|
|
+ error!(
|
|
|
|
|
+ "Verifying accounts failed: accounts lattice hashes do not \
|
|
|
|
|
+ match, expected: {expected}, calculated: {calculated}",
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
|
|
+ self.set_initial_accounts_hash_verification_completed();
|
|
|
|
|
+ is_ok
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -5102,7 +5018,7 @@ impl Bank {
|
|
|
skip_shrink: bool,
|
|
skip_shrink: bool,
|
|
|
force_clean: bool,
|
|
force_clean: bool,
|
|
|
latest_full_snapshot_slot: Slot,
|
|
latest_full_snapshot_slot: Slot,
|
|
|
- base: Option<(Slot, /*capitalization*/ u64)>,
|
|
|
|
|
|
|
+ _base: Option<(Slot, /*capitalization*/ u64)>, // will be removed next
|
|
|
duplicates_lt_hash: Option<Box<DuplicatesLtHash>>,
|
|
duplicates_lt_hash: Option<Box<DuplicatesLtHash>>,
|
|
|
) -> bool {
|
|
) -> bool {
|
|
|
// If we verify the accounts using the lattice-based hash *and* with storages (as opposed
|
|
// If we verify the accounts using the lattice-based hash *and* with storages (as opposed
|
|
@@ -5117,12 +5033,9 @@ impl Bank {
|
|
|
if should_verify_accounts {
|
|
if should_verify_accounts {
|
|
|
info!("Verifying accounts...");
|
|
info!("Verifying accounts...");
|
|
|
let verified = self.verify_accounts_hash(
|
|
let verified = self.verify_accounts_hash(
|
|
|
- base,
|
|
|
|
|
VerifyAccountsHashConfig {
|
|
VerifyAccountsHashConfig {
|
|
|
- ignore_mismatch: false,
|
|
|
|
|
require_rooted_bank: false,
|
|
require_rooted_bank: false,
|
|
|
run_in_background: true,
|
|
run_in_background: true,
|
|
|
- store_hash_raw_data_for_debug: false,
|
|
|
|
|
},
|
|
},
|
|
|
duplicates_lt_hash,
|
|
duplicates_lt_hash,
|
|
|
);
|
|
);
|