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

retains chained Merkle root across leader slots #1057

Merged

Conversation

behzadnouri
Copy link

Problem

Looking up Merkle root of the last erasure batch for the parent block can fail if the slot meta are not yet available in blockstore.
When a leader generates blocks for its consecutive leader slots, instead of using blockstore, it can retain chained Merkle root across its leader slots.

Summary of Changes

Retain chained Merkle roots across leader slots.

@behzadnouri behzadnouri force-pushed the retain-chained-merkle-root-flat branch from c39a28f to e9d29f6 Compare April 26, 2024 02:05
@codecov-commenter
Copy link

codecov-commenter commented Apr 26, 2024

Codecov Report

Attention: Patch coverage is 94.87179% with 6 lines in your changes are missing coverage. Please review.

Project coverage is 82.1%. Comparing base (d9d52be) to head (c9937d1).
Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##           master    #1057     +/-   ##
=========================================
- Coverage    82.1%    82.1%   -0.1%     
=========================================
  Files         868      868             
  Lines      234074   234054     -20     
=========================================
- Hits       192373   192338     -35     
- Misses      41701    41716     +15     

Looking up Merkle root of the last erasure batch for the parent block
can fail if the slot-meta is not yet available in blockstore.
This commit instead retains chained Merkle root across leader slots. If
the parent of the current block is the previous leader slot, then the
chained Merkle root is readily available and we can bypass blockstore
lookup.
@behzadnouri behzadnouri force-pushed the retain-chained-merkle-root-flat branch from e9d29f6 to c9937d1 Compare April 26, 2024 14:54
@behzadnouri
Copy link
Author

anyone interested to review this change?

@behzadnouri
Copy link
Author

@carllin @AshwinSekar @bw-solana can any one of you review this change?

Copy link

@AshwinSekar AshwinSekar left a comment

Choose a reason for hiding this comment

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

The logic for caching the chained_merkle_root looks correct, just a small nit.
The UnfinishedSlotInfo refactor also looks fine, but would appreciate some more eyes on it.

return Err(Error::DuplicateSlotBroadcast(bank.slot()));
}
// Reinitialize state for this slot.
let chained_merkle_root = (self.slot == bank.parent_slot())

Choose a reason for hiding this comment

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

This is the only logical change right?

Copy link
Author

Choose a reason for hiding this comment

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

This and maintaining self.chained_merkle_root across slots.

shreds.extend(coding_shreds);
shreds
}
if let Some(shred) = shreds.iter().max_by_key(|shred| shred.index()) {

Choose a reason for hiding this comment

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

we should always generate 1 shred for the LAST_SHRED_IN_SLOT flag right? better to panic here?

Copy link
Author

Choose a reason for hiding this comment

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

yeah, but we don't need to rely on that here, and kind of hesitant if the panic here is worth it.

@behzadnouri
Copy link
Author

The logic for caching the chained_merkle_root looks correct, just a small nit. The UnfinishedSlotInfo refactor also looks fine, but would appreciate some more eyes on it.

I can split changes to UnfinshedSlotInfo into a separate PR for easier review.

@behzadnouri
Copy link
Author

The logic for caching the chained_merkle_root looks correct, just a small nit. The UnfinishedSlotInfo refactor also looks fine, but would appreciate some more eyes on it.

I can split changes to UnfinshedSlotInfo into a separate PR for easier review.

Actually trying this locally, the changes separate from UnfinishedSlotInfo are basically couple of lines so wouldn't change things much.

@behzadnouri behzadnouri requested a review from AshwinSekar May 3, 2024 18:16
Copy link

@AshwinSekar AshwinSekar left a comment

Choose a reason for hiding this comment

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

lgtm

@behzadnouri behzadnouri merged commit 6b45dc9 into anza-xyz:master May 3, 2024
38 checks passed
@behzadnouri behzadnouri deleted the retain-chained-merkle-root-flat branch May 3, 2024 20:20
Copy link

mergify bot commented May 3, 2024

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.

mergify bot pushed a commit that referenced this pull request May 3, 2024
Looking up Merkle root of the last erasure batch for the parent block
can fail if the slot-meta is not yet available in blockstore.
This commit instead retains chained Merkle root across leader slots. If
the parent of the current block is the previous leader slot, then the
chained Merkle root is readily available and we can bypass blockstore
lookup.

(cherry picked from commit 6b45dc9)
ilya-bobyr added a commit to ilya-bobyr/agave that referenced this pull request May 11, 2024
`if/else` seems easier to follow, as it produces less nesting.

Assignment of `self.chained_merkle_root` into `chained_merkle_root`,
that is then assigned back into `self.chained_merkle_root` is a no-op.
While I can see how it is separating the computation of the
`chained_merkle_root` for the current step from the update of the
`self`, I think, overall, it is more confusing then helpful.

The `Finish previous slot ...` comment is actually part of a
multi-paragraph sequence of steps, that document the whole
`process_receive_results()`.  Step number was accidentally removed in
`anza-xyz#1057`:

    commit 6b45dc9
    Author: behzad nouri <behzadnouri@gmail.com>
    Date:   Fri May 3 20:20:10 2024 +0000

        retains chained Merkle root across leader slots (anza-xyz#1057)
ilya-bobyr added a commit to ilya-bobyr/agave that referenced this pull request May 13, 2024
`if/else` seems easier to follow, as it produces less nesting.

Assignment of `self.chained_merkle_root` into `chained_merkle_root`,
that is then assigned back into `self.chained_merkle_root` is a no-op.
While I can see how it is separating the computation of the
`chained_merkle_root` for the current step from the update of the
`self`, I think, overall, it is more confusing then helpful.

The `Finish previous slot ...` comment is actually part of a
multi-paragraph sequence of steps, that document the whole
`process_receive_results()`.  Step number was accidentally removed in
`anza-xyz#1057`:

    commit 6b45dc9
    Author: behzad nouri <behzadnouri@gmail.com>
    Date:   Fri May 3 20:20:10 2024 +0000

        retains chained Merkle root across leader slots (anza-xyz#1057)
ilya-bobyr added a commit to ilya-bobyr/agave that referenced this pull request May 13, 2024
`if/else` seems easier to follow, as it produces less nesting.

Assignment of `self.chained_merkle_root` into `chained_merkle_root`,
that is then assigned back into `self.chained_merkle_root` is a no-op.
While I can see how it is separating the computation of the
`chained_merkle_root` for the current step from the update of the
`self`, I think, overall, it is more confusing then helpful.

The `Finish previous slot ...` comment is actually part of a
multi-paragraph sequence of steps, that document the whole
`process_receive_results()`.  Step number was accidentally removed in
`anza-xyz#1057`:

    commit 6b45dc9
    Author: behzad nouri <behzadnouri@gmail.com>
    Date:   Fri May 3 20:20:10 2024 +0000

        retains chained Merkle root across leader slots (anza-xyz#1057)
ilya-bobyr added a commit to ilya-bobyr/agave that referenced this pull request May 14, 2024
`if/else` seems easier to follow, as it produces less nesting.

Assignment of `self.chained_merkle_root` into `chained_merkle_root`,
that is then assigned back into `self.chained_merkle_root` is a no-op.
While I can see how it is separating the computation of the
`chained_merkle_root` for the current step from the update of the
`self`, I think, overall, it is more confusing then helpful.

The `Finish previous slot ...` comment is actually part of a
multi-paragraph sequence of steps, that document the whole
`process_receive_results()`.  Step number was accidentally removed in
`anza-xyz#1057`:

    commit 6b45dc9
    Author: behzad nouri <behzadnouri@gmail.com>
    Date:   Fri May 3 20:20:10 2024 +0000

        retains chained Merkle root across leader slots (anza-xyz#1057)
behzadnouri added a commit that referenced this pull request Jun 6, 2024
…1057) (#1182)

retains chained Merkle root across leader slots (#1057)

Looking up Merkle root of the last erasure batch for the parent block
can fail if the slot-meta is not yet available in blockstore.
This commit instead retains chained Merkle root across leader slots. If
the parent of the current block is the previous leader slot, then the
chained Merkle root is readily available and we can bypass blockstore
lookup.

(cherry picked from commit 6b45dc9)

Co-authored-by: behzad nouri <behzadnouri@gmail.com>
anwayde pushed a commit to firedancer-io/agave that referenced this pull request Jul 23, 2024
…nza-xyz#1057) (anza-xyz#1182)

retains chained Merkle root across leader slots (anza-xyz#1057)

Looking up Merkle root of the last erasure batch for the parent block
can fail if the slot-meta is not yet available in blockstore.
This commit instead retains chained Merkle root across leader slots. If
the parent of the current block is the previous leader slot, then the
chained Merkle root is readily available and we can bypass blockstore
lookup.

(cherry picked from commit 6b45dc9)

Co-authored-by: behzad nouri <behzadnouri@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants