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): flat storage resharding deltas #12271

Merged
merged 4 commits into from
Oct 21, 2024

Conversation

Trisfald
Copy link
Contributor

@Trisfald Trisfald commented Oct 21, 2024

Implementation of flat storage deltas split for flat storage resharding.

Before this change, only flat storage key pairs at flat head height were split during resharding. Now flat storage deltas are part of the splitting process as well.
On a high level, it works by concatenating the iterator over flat storage and the iterator over deltas for all block heights between chain head an flat storage head.

Part of #12174

Copy link

codecov bot commented Oct 21, 2024

Codecov Report

Attention: Patch coverage is 96.37097% with 9 lines in your changes missing coverage. Please review.

Project coverage is 71.61%. Comparing base (1fea9e1) to head (f1be01f).
Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
chain/chain/src/flat_storage_resharder.rs 96.35% 5 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12271      +/-   ##
==========================================
+ Coverage   71.58%   71.61%   +0.02%     
==========================================
  Files         836      836              
  Lines      167470   167697     +227     
  Branches   167470   167697     +227     
==========================================
+ Hits       119891   120096     +205     
- Misses      42347    42366      +19     
- Partials     5232     5235       +3     
Flag Coverage Δ
backward-compatibility 0.16% <0.00%> (-0.01%) ⬇️
db-migration 0.16% <0.00%> (-0.01%) ⬇️
genesis-check 1.24% <0.00%> (-0.01%) ⬇️
integration-tests 38.80% <18.14%> (-0.04%) ⬇️
linux 71.26% <96.37%> (+0.02%) ⬆️
linux-nightly 71.21% <96.37%> (+0.03%) ⬆️
macos 54.33% <96.37%> (+0.08%) ⬆️
pytests 1.56% <0.00%> (-0.01%) ⬇️
sanity-checks 1.37% <0.00%> (-0.01%) ⬇️
unittests 65.41% <96.37%> (+0.05%) ⬆️
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.

@Trisfald Trisfald marked this pull request as ready for review October 21, 2024 12:59
@Trisfald Trisfald requested a review from a team as a code owner October 21, 2024 12:59
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

I really like how few changes you needed to the original code, the delta handling fits like a glove ;)

);

// Get all the blocks from flat head to the wanted block hash.
let flat_storage = self
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused about having flat_store as an argument and getting flat_storage from runtime here. Why do you need both and how do they differ? Is there any way to make it simpler? Ideally there would only be one flat thing or they would be clearly different and both would be obtained same way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's a bit weird. I need flat_store passed to the function due to lifetimes on the iterator - this prevents me from instantiating a flat_store inside the flat_storage_iterator.

And then flat_storage and flat_store, although they have similar name, are totally independent. I couldn't get one from the other

continue;
};
// Chain the iterators effectively adding a block worth of deltas.
// Before doing so insert a commit point to separate changes to the same key in different transactions.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, I wouldn't have thought of that. How did you find that it's needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests failed with transaction overwrite error 😉

Comment on lines +596 to +597
store_update.set(status.left_child_shard, key.clone(), value.clone());
store_update.set(status.right_child_shard, key, value);
Copy link
Contributor

Choose a reason for hiding this comment

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

not related to this PR
It feels like the set method should only need a reference to the key and value. In theory it should serialize those and for that ref should be sufficient. Then the clone would not be needed.

// Buffered receipt '1' shouldn't exist.
for child in [left_child_shard, right_child_shard] {
assert_eq!(flat_store.get(child, &buffered_receipt_1_key.to_vec()), Ok(None));
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Ultimately we should check that the state root matches that on chain (which was calculated from memtrie resharding). I'm not sure how easy would it be to do in test though. We should definitely do it when replacing the temporary memtrie with new one though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes this check should be done at least as part of memtrie replacement test

/// necessary because otherwise deltas might set again the value of a flat storage entry inside the
/// same transaction.
enum FlatStorageAndDeltaIterItem {
Entry(Result<(Vec<u8>, Option<FlatStateValue>), FlatStorageError>),
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Is there any chance to remove the error from here? Would it be nicer?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only way I think would be to map the error into a panic, but that's.. brutal

@wacban
Copy link
Contributor

wacban commented Oct 21, 2024

Just out of curiosity how much of it is copy pasted from resharding V2 (RIP)?

@Trisfald
Copy link
Contributor Author

Just out of curiosity how much of it is copy pasted from resharding V2 (RIP)?

The idea is the same (chaining iterators). In practice though I had to code the solution differently, because resharding-v2 works on trie changes and I'm working directly on flat storage key value pairs.

@Trisfald Trisfald added this pull request to the merge queue Oct 21, 2024
Merged via the queue into near:master with commit 822c62b Oct 21, 2024
29 checks passed
@Trisfald Trisfald deleted the flat-storage-resharding-deltas branch October 21, 2024 20:17
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.

2 participants