Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactors accounts lt hash startup verification #3397

Merged
merged 1 commit into from
Oct 31, 2024

Conversation

brooksprumo
Copy link

Problem

Startup verification was a bit clumsy due to the separate handling of the accounts lt hash via the cli arg and via the snapshot. These can (should) be unified, and also remove unnecessary memory allocations when the accounts lt hash is not in use.

Summary of Changes

Refactors accounts lt hash startup verification. Now, if the cli arg is set, or if the snapshot contains an accounts lt hash, then startup accounts verification will use lattice-based verification.

@brooksprumo brooksprumo self-assigned this Oct 30, 2024
Copy link
Author

@brooksprumo brooksprumo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully helpful comments to aid reviewers. This comments are in "chronological" order (iow, the order the functions are called/executed in).

Comment on lines +1237 to +1241
// When generating the index, we want to calculate the duplicates lt hash value (needed to do
// the lattice-based verification of the accounts in the background) optimistically.
// This means, either when the cli arg is set, or when the snapshot has an accounts lt hash.
let is_accounts_lt_hash_enabled =
accounts_db.is_experimental_accumulator_hash_enabled() || has_accounts_lt_hash;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the main change that the rest of the PR falls out from: When loading from a snapshot, here is where we generate the index. And generate_index() needs to know if it should calculate the duplicates lt hash value.

Before snapshot support was added for accounts lt hash, the only thing we needed to check was the CLI arg. Now we need to check the CLI arg and the snapshot. Inside generate_index() we don't have a way to know if the accounts lt hash was in the snapshot, so we pass in a new parameter here.

(More info: And since we don't have a Bank instance here yet, we don't know which feature gates are enabled. In typical snapshot style, we use the presence of the accounts lt hash in the snapshot as a proxy for if the feature is enabled or not.)

@@ -8597,6 +8597,7 @@ impl AccountsDb {
limit_load_slot_count_from_snapshot: Option<usize>,
verify: bool,
genesis_config: &GenesisConfig,
should_calculate_duplicates_lt_hash: bool,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next, here's the new parameter for generate_index(). We use this parameter to determine whether or not to calculate the duplicates lt hash value, and not checking the cli arg.

A nice fallout is that now we only conditionally malloc the LtHash when handling the duplicates (below). No more perf hit when not using accounts lt hash.

Comment on lines +9080 to +9081
let mut duplicates_lt_hash =
should_calculate_duplicates_lt_hash.then(|| Box::new(DuplicatesLtHash::default()));
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's where we conditionally malloc the LtHash. And the other change in this function can now switch based on if this is Some/None.

Comment on lines +8875 to +8897
match (
self.duplicates_lt_hash.is_some(),
other.duplicates_lt_hash.is_some(),
) {
(true, true) => {
// SAFETY: We just checked that both values are Some
self.duplicates_lt_hash
.as_mut()
.unwrap()
.0
.mix_in(&other.duplicates_lt_hash.as_ref().unwrap().0);
}
(true, false) => {
// nothing to do; `other` doesn't have a duplicates lt hash
}
(false, true) => {
// `self` doesn't have a duplicates lt hash, so pilfer from `other`
self.duplicates_lt_hash = other.duplicates_lt_hash;
}
(false, false) => {
// nothing to do; no duplicates lt hash at all
}
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that handling the duplicates can return the LtHash as an Option, we need to update how we handle merging. It's actually quite nice, as now intermediate threads that spin up to just do the merge-reduce don't need to malloc an LtHash either (they can use the allocation from the merged-from side).

Comment on lines +5625 to +5641
let verify_kind = match (
duplicates_lt_hash.is_some(),
self.rc
.accounts
.accounts_db
.is_experimental_accumulator_hash_enabled(),
) {
(true, _) => VerifyKind::Lattice,
(false, false) => VerifyKind::Merkle,
(false, true) => {
// 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
// cannot run in the background.
config.run_in_background = false;
VerifyKind::Lattice
}
}
};
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And finally we get to startup verification! We can now primarily use the Option-ness of the passed-in duplicates_lt_hash to decide which kind of accounts verification to do. We still support using the CLI arg as a way to force using the lattice-based verification too (which is useful in tests, and also experimenting on running validators before the feature gate is enabled).

@brooksprumo brooksprumo marked this pull request as ready for review October 31, 2024 12:59
Copy link

@jeffwashington jeffwashington left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@brooksprumo brooksprumo requested a review from HaoranYi October 31, 2024 14:31
Copy link

@HaoranYi HaoranYi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@brooksprumo brooksprumo merged commit 8d68125 into anza-xyz:master Oct 31, 2024
40 checks passed
@brooksprumo brooksprumo deleted the lthash/startup branch October 31, 2024 14:40
ray-kast pushed a commit to abklabs/agave that referenced this pull request Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants