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

feat: resharding proof #12418

Merged
merged 2 commits into from
Nov 14, 2024
Merged

feat: resharding proof #12418

merged 2 commits into from
Nov 14, 2024

Conversation

Longarithm
Copy link
Member

@Longarithm Longarithm commented Nov 8, 2024

Generate proof for resharding (retain_multi_range) and check that it is valid against existing retain tests, already including memtrie and disktrie.

Surprisingly, #12390 allows to make the change almost invisible. The actual work here is to move &mut TrieRecorder inside TrieChangesTracker which is inside MemTrieUpdate.

Reasoning: when we work with MemTrieUpdate, it is in fact unique owner of the logic to record proof (what I called "2nd stage" in the previous PR, after "1st stage" of trie lookups). And now, if we are sure that proof doesn't need values, MemTrieUpdate can fully hold the &mut, because memtrie has all the necessary information, and we can record nodes directly on node access instead of doing it retroactively (which was really bad).

TrieRecorder now is passed as a separate mode to process memtrie updates. We indeed need three modes - on loading we don't record anything, for non-validators we save trie changes, for validators we also save proofs. And after that, all we need to do for retain_split_shard is to create TrieRecorder and in the end get recorded storage from it.

Next step will be to validate this proof in the actual state witness processing...

@Longarithm Longarithm changed the title draft: resharding proof feat: resharding proof Nov 8, 2024
@Longarithm Longarithm linked an issue Nov 8, 2024 that may be closed by this pull request
@Longarithm Longarithm marked this pull request as ready for review November 8, 2024 19:28
@Longarithm Longarithm requested a review from a team as a code owner November 8, 2024 19:28
Copy link
Contributor

@shreyan-gupta shreyan-gupta left a comment

Choose a reason for hiding this comment

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

Lol! This PR is a source of inner peace 😂

pub nodes: HashMap<CryptoHash, Arc<[u8]>>,
/// Allows using in-memory tries to construct the trie node changes entirely
/// (for both in-memory and on-disk updates) because it's much faster.
pub enum TrackingMode<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh this is an infinitely better API! Thank you so much!

.entry(value)
.and_modify(|rc| *rc += 1)
.or_insert(1);
nodes_tracker.refcount_inserted_values.entry(value).and_modify(|rc| *rc += 1).or_insert(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

Quick question, isn't it incorrect to return early for the GenericTrieValue::MemtrieAndDisk case above? Why would we not want to track those nodes?

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh yeah, that's confusing method.
In fact, we return early in MemtrieOnly node, not MemtrieAndDisk. We do it because we have don't have full value, so we can't compute its hash and we can't make a record.
Ideally GenericTrieValue should be consistent with nodes_tracker by design. That's a TODO for the future.

Made a little reordering to check GenericTrieValue enum variant only once.

let nodes_tracker = match mode {
TrackingMode::None => None,
TrackingMode::Refcounts => Some(TrieChangesTracker::default()),
TrackingMode::RefcountsAndAccesses(recorder) => Some(TrieChangesTracker {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: TrieChangesTracker::new_with_recorder(recorder)?

Copy link
Contributor

Choose a reason for hiding this comment

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

what about initializing a TrieChangesTracker from a TrackingMode?

let partial_state_len = match &partial_state {
let trie_changes = mem_trie_update.retain_split_shard(&boundary_account, retain_mode);
let partial_storage = trie_recorder.recorded_storage();
let partial_state_len = match &partial_storage.nodes {
Copy link
Contributor

Choose a reason for hiding this comment

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

🤌🤌

Copy link
Contributor

@Trisfald Trisfald left a comment

Choose a reason for hiding this comment

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

Looks good as far as I can tell!

let nodes_tracker = match mode {
TrackingMode::None => None,
TrackingMode::Refcounts => Some(TrieChangesTracker::default()),
TrackingMode::RefcountsAndAccesses(recorder) => Some(TrieChangesTracker {
Copy link
Contributor

Choose a reason for hiding this comment

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

what about initializing a TrieChangesTracker from a TrackingMode?

Copy link
Contributor

@wacban wacban left a comment

Choose a reason for hiding this comment

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

LGTM, what a feat!

fn record<M: ArenaMemory>(&mut self, node: &MemTrieNodeView<'a, M>) {
let node_hash = node.node_hash();
let raw_node_serialized = borsh::to_vec(&node.to_raw_trie_node_with_size()).unwrap();
self.refcount_deleted_hashes.entry(node_hash).and_modify(|rc| *rc += 1).or_insert(1);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Would the following work?

        self.refcount_deleted_hashes.entry(node_hash).or_default() += 1;
        // or
        self.refcount_deleted_hashes.entry(node_hash).or_insert(0) += 1;

Copy link
Member Author

Choose a reason for hiding this comment

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

yes!

root: CryptoHash,
track_trie_changes: bool,
) -> Result<MemTrieUpdate<HybridArenaMemory>, StorageError> {
mode: TrackingMode<'a>,
Copy link
Contributor

Choose a reason for hiding this comment

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

nice

@Longarithm Longarithm enabled auto-merge November 14, 2024 00:13
@Longarithm Longarithm added this pull request to the merge queue Nov 14, 2024
Copy link

codecov bot commented Nov 14, 2024

Codecov Report

Attention: Patch coverage is 92.78351% with 7 lines in your changes missing coverage. Please review.

Project coverage is 71.43%. Comparing base (5d3008b) to head (e0f6ee5).
Report is 33 commits behind head on master.

Files with missing lines Patch % Lines
core/store/src/trie/mem/mem_trie_update.rs 93.84% 2 Missing and 2 partials ⚠️
chain/chain/src/resharding/manager.rs 83.33% 0 Missing and 1 partial ⚠️
core/store/src/trie/mem/loading.rs 0.00% 0 Missing and 1 partial ⚠️
core/store/src/trie/mod.rs 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12418      +/-   ##
==========================================
- Coverage   71.70%   71.43%   -0.27%     
==========================================
  Files         843      838       -5     
  Lines      170777   169315    -1462     
  Branches   170777   169315    -1462     
==========================================
- Hits       122454   120954    -1500     
- Misses      42964    43013      +49     
+ Partials     5359     5348      -11     
Flag Coverage Δ
backward-compatibility 0.16% <0.00%> (+<0.01%) ⬆️
db-migration 0.16% <0.00%> (+<0.01%) ⬆️
genesis-check 1.29% <0.00%> (+0.02%) ⬆️
integration-tests 39.33% <72.16%> (-0.03%) ⬇️
linux 70.77% <86.59%> (+0.06%) ⬆️
linux-nightly 71.00% <92.78%> (-0.28%) ⬇️
macos 51.02% <86.59%> (+0.36%) ⬆️
pytests 1.60% <0.00%> (+0.02%) ⬆️
sanity-checks 1.40% <0.00%> (+0.02%) ⬆️
unittests 63.97% <86.59%> (-0.36%) ⬇️
upgradability 0.21% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Merged via the queue into near:master with commit 6934fc2 Nov 14, 2024
29 checks passed
@Longarithm Longarithm deleted the sw-r-proof branch November 14, 2024 00:58
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.

[ReshardingV3] State Witness - new state root generation
4 participants