From f9f54bcba0b75b7566a948c3441bc5e1d03152fc Mon Sep 17 00:00:00 2001 From: Brooks Date: Thu, 21 Nov 2024 12:03:36 -0500 Subject: [PATCH] Adds --accounts-db-verify-experimental-accumulator-hash (#3728) --- accounts-db/src/accounts_db.rs | 9 +++++++++ ledger-tool/src/args.rs | 6 ++++++ runtime/src/bank.rs | 28 ++++++++++++++++++++++++++++ validator/src/cli.rs | 6 ++++++ validator/src/main.rs | 2 ++ 5 files changed, 51 insertions(+) diff --git a/accounts-db/src/accounts_db.rs b/accounts-db/src/accounts_db.rs index 6fcba71e0728eb..80e6120fa689b6 100644 --- a/accounts-db/src/accounts_db.rs +++ b/accounts-db/src/accounts_db.rs @@ -511,6 +511,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_TESTING: AccountsDbConfig = AccountsDbConfig { storage_access: StorageAccess::Mmap, scan_filter_for_shrinking: ScanFilter::OnlyAbnormalWithVerify, enable_experimental_accumulator_hash: false, + verify_experimental_accumulator_hash: false, num_clean_threads: None, num_foreground_threads: None, num_hash_threads: None, @@ -536,6 +537,7 @@ pub const ACCOUNTS_DB_CONFIG_FOR_BENCHMARKS: AccountsDbConfig = AccountsDbConfig storage_access: StorageAccess::Mmap, scan_filter_for_shrinking: ScanFilter::OnlyAbnormalWithVerify, enable_experimental_accumulator_hash: false, + verify_experimental_accumulator_hash: false, num_clean_threads: None, num_foreground_threads: None, num_hash_threads: None, @@ -663,6 +665,7 @@ pub struct AccountsDbConfig { pub storage_access: StorageAccess, pub scan_filter_for_shrinking: ScanFilter, pub enable_experimental_accumulator_hash: bool, + pub verify_experimental_accumulator_hash: bool, /// Number of threads for background cleaning operations (`thread_pool_clean') pub num_clean_threads: Option, /// Number of threads for foreground operations (`thread_pool`) @@ -1621,6 +1624,10 @@ pub struct AccountsDb { /// (For R&D only; a feature-gate also exists to turn this on and make it a part of consensus.) pub is_experimental_accumulator_hash_enabled: AtomicBool, + /// Flag to indicate if the experimental accounts lattice hash should be verified. + /// (For R&D only) + pub verify_experimental_accumulator_hash: bool, + /// These are the ancient storages that could be valuable to /// shrink, sorted by amount of dead bytes. The elements /// are sorted from the largest dead bytes to the smallest. @@ -2040,6 +2047,8 @@ impl AccountsDb { is_experimental_accumulator_hash_enabled: accounts_db_config .enable_experimental_accumulator_hash .into(), + verify_experimental_accumulator_hash: accounts_db_config + .verify_experimental_accumulator_hash, bank_hash_stats, thread_pool, thread_pool_clean, diff --git a/ledger-tool/src/args.rs b/ledger-tool/src/args.rs index be03ea145bd410..bc80abcfa7b113 100644 --- a/ledger-tool/src/args.rs +++ b/ledger-tool/src/args.rs @@ -131,6 +131,10 @@ pub fn accounts_db_args<'a, 'b>() -> Box<[Arg<'a, 'b>]> { .long("accounts-db-experimental-accumulator-hash") .help("Enables the experimental accumulator hash") .hidden(hidden_unless_forced()), + Arg::with_name("accounts_db_verify_experimental_accumulator_hash") + .long("accounts-db-verify-experimental-accumulator-hash") + .help("Verifies the experimental accumulator hash") + .hidden(hidden_unless_forced()), Arg::with_name("accounts_db_hash_threads") .long("accounts-db-hash-threads") .value_name("NUM_THREADS") @@ -392,6 +396,8 @@ pub fn get_accounts_db_config( scan_filter_for_shrinking, enable_experimental_accumulator_hash: arg_matches .is_present("accounts_db_experimental_accumulator_hash"), + verify_experimental_accumulator_hash: arg_matches + .is_present("accounts_db_verify_experimental_accumulator_hash"), num_hash_threads, ..AccountsDbConfig::default() } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 5d82043d1f19fa..ba80fbd5d26210 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -3028,6 +3028,34 @@ impl Bank { // updating the accounts lt hash must happen *outside* of hash_internal_state() so // that rehash() can be called and *not* modify self.accounts_lt_hash. self.update_accounts_lt_hash(); + + // For lattice-hash R&D, we have a CLI arg to do extra verfication. If set, we'll + // re-calculate the accounts lt hash every slot and compare it against the value + // already stored in the bank. + if self + .rc + .accounts + .accounts_db + .verify_experimental_accumulator_hash + { + let slot = self.slot(); + info!("Verifying the accounts lt hash for slot {slot}..."); + let (calculated_accounts_lt_hash, duration) = meas_dur!({ + self.rc + .accounts + .accounts_db + .calculate_accounts_lt_hash_at_startup_from_index(&self.ancestors, slot) + }); + let actual_accounts_lt_hash = self.accounts_lt_hash.lock().unwrap(); + assert_eq!( + calculated_accounts_lt_hash, + *actual_accounts_lt_hash, + "Verifying the accounts lt hash for slot {slot} failed! calculated checksum: {}, actual checksum: {}", + calculated_accounts_lt_hash.0.checksum(), + actual_accounts_lt_hash.0.checksum(), + ); + info!("Verifying the accounts lt hash for slot {slot}... Done successfully in {duration:?}"); + } } *hash = self.hash_internal_state(); self.rc.accounts.accounts_db.mark_slot_frozen(self.slot()); diff --git a/validator/src/cli.rs b/validator/src/cli.rs index ff048a98a88a01..19a2b7f77e7b0a 100644 --- a/validator/src/cli.rs +++ b/validator/src/cli.rs @@ -1420,6 +1420,12 @@ pub fn app<'a>(version: &'a str, default_args: &'a DefaultArgs) -> App<'a, 'a> { .help("Enables the experimental accumulator hash") .hidden(hidden_unless_forced()), ) + .arg( + Arg::with_name("accounts_db_verify_experimental_accumulator_hash") + .long("accounts-db-verify-experimental-accumulator-hash") + .help("Verifies the experimental accumulator hash") + .hidden(hidden_unless_forced()), + ) .arg( Arg::with_name("accounts_index_scan_results_limit_mb") .long("accounts-index-scan-results-limit-mb") diff --git a/validator/src/main.rs b/validator/src/main.rs index 922d676d750238..a6f98646555c7a 100644 --- a/validator/src/main.rs +++ b/validator/src/main.rs @@ -1364,6 +1364,8 @@ pub fn main() { scan_filter_for_shrinking, enable_experimental_accumulator_hash: matches .is_present("accounts_db_experimental_accumulator_hash"), + verify_experimental_accumulator_hash: matches + .is_present("accounts_db_verify_experimental_accumulator_hash"), num_clean_threads: Some(accounts_db_clean_threads), num_foreground_threads: Some(accounts_db_foreground_threads), num_hash_threads: Some(accounts_db_hash_threads),