-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
blockstore: populate merkle root metas column #34097
blockstore: populate merkle root metas column #34097
Conversation
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #34097 +/- ##
========================================
Coverage 81.9% 81.9%
========================================
Files 812 812
Lines 219656 219864 +208
========================================
+ Hits 179989 180238 +249
+ Misses 39667 39626 -41 |
for (erasure_set, merkle_root_meta) in merkle_root_metas { | ||
write_batch.put::<cf::MerkleRootMeta>(erasure_set.key(), &merkle_root_meta)?; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't this overwrite existing merkle-root meta in blockstore?
it seems like at least some entries will be re-written with the same value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right, i just c/p the erasure_metas
logic, but I think we can be smarter and keep track of which entries are dirty and need to be written.
let erasure_set = shred.erasure_set(); | ||
|
||
if let HashMapEntry::Vacant(entry) = merkle_root_metas.entry(erasure_set) { | ||
if let Some(meta) = self.merkle_root_meta(erasure_set).unwrap() { | ||
entry.insert(meta); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand why merkle-root meta is read from the blockstore.
shouldn't it be obtained from the current shred?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea here is to load the merkle entry we already have in blockstore into the in memory map for comparison in the future pr
merkle_root_metas | ||
.entry(erasure_set) | ||
.or_insert(MerkleRootMeta::from_shred(&shred)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need the code in L1204 then?
I guess follow up commits will compare if the merkle-roots are the same.
but then I guess we could read the blockstore-db here instead of pre-emptively fetching it but then not using it if the shred is not inserted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the idea is:
L1204 - load merkle root meta from blockstore -> in memory map
(future commit) L1196 - compare with the current merkle shred meta for conflict
(here) L1287 - if the in memory map is empty and the insert has succeeded, add the current merkle shred meta to the in memory map
L1024 - commit in memory map to blockstore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but then I guess we could read the blockstore-db here instead of pre-emptively fetching it but then not using it if the shred is not inserted.
this is possible, but it would result in 2 blockstore reads, one for the future comparison, and then one to decide whether to insert the newly received merkle root meta.
pub(crate) fn key(&self) -> (Slot, /*fec_set_index:*/ u32) { | ||
(self.0, self.1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, this key
vs store_key
is pretty bad and confusing.
Can you please leave a comment where one should use each?
Maybe we should remove the (_, u64)
version, and do the type cast only at the call-sites which use that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah you're right i'll remove/deprecate the old store_key
and only use the u32
version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for posterity this is being fixed here: #34268
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will update tomorrow to distinguish dirty entries in merkle_root_metas
and deprecate the u32
version of store_key
for (erasure_set, merkle_root_meta) in merkle_root_metas { | ||
write_batch.put::<cf::MerkleRootMeta>(erasure_set.key(), &merkle_root_meta)?; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right, i just c/p the erasure_metas
logic, but I think we can be smarter and keep track of which entries are dirty and need to be written.
let erasure_set = shred.erasure_set(); | ||
|
||
if let HashMapEntry::Vacant(entry) = merkle_root_metas.entry(erasure_set) { | ||
if let Some(meta) = self.merkle_root_meta(erasure_set).unwrap() { | ||
entry.insert(meta); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the idea here is to load the merkle entry we already have in blockstore into the in memory map for comparison in the future pr
merkle_root_metas | ||
.entry(erasure_set) | ||
.or_insert(MerkleRootMeta::from_shred(&shred)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so the idea is:
L1204 - load merkle root meta from blockstore -> in memory map
(future commit) L1196 - compare with the current merkle shred meta for conflict
(here) L1287 - if the in memory map is empty and the insert has succeeded, add the current merkle shred meta to the in memory map
L1024 - commit in memory map to blockstore
pub(crate) fn key(&self) -> (Slot, /*fec_set_index:*/ u32) { | ||
(self.0, self.1) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah you're right i'll remove/deprecate the old store_key
and only use the u32
version.
merkle_root_metas | ||
.entry(erasure_set) | ||
.or_insert(MerkleRootMeta::from_shred(&shred)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but then I guess we could read the blockstore-db here instead of pre-emptively fetching it but then not using it if the shred is not inserted.
this is possible, but it would result in 2 blockstore reads, one for the future comparison, and then one to decide whether to insert the newly received merkle root meta.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, assuming the leftover issues will be addressed in follow up commits.
Backports to the beta branch are to be avoided unless absolutely necessary for fixing bugs, security issues, and perf regressions. Changes intended for backport should be structured such that a minimum effective diff can be committed separately from any refactoring, plumbing, cleanup, etc that are not strictly necessary to achieve the goal. Any of the latter should go only into master and ride the normal stabilization schedule. Exceptions include CI/metrics changes, CLI improvements and documentation updates on a case by case basis. |
(cherry picked from commit e1165aa)
Problem
We don't yet write to this column.
Summary of Changes
When inserting the first shred for each fec set, populate the merkle root metas
Note: we must only create the merkle root meta if the shred was successfully inserted, otherwise there will be a desync on
first_received_shred_index
and what's actually available in blockstore.Split from #33889
Contributes to #33644