Skip to content

feat(consensus): beacon consensus engine#1845

Merged
gakonst merged 19 commits intomainfrom
rkrasiuk/sync-controller
Mar 23, 2023
Merged

feat(consensus): beacon consensus engine#1845
gakonst merged 19 commits intomainfrom
rkrasiuk/sync-controller

Conversation

@rkrasiuk
Copy link
Copy Markdown
Contributor

@rkrasiuk rkrasiuk commented Mar 19, 2023

Replacement for #1662
Closes #1528

This PR introduces the Beacon Consensus Engine.

The Beacon Consensus Engine is responsible for initiating the historical sync and driving the real-time sync by consuming messages from the Engine API. The consensus engine will start syncing as soon as it receives first ForkchoiceUpdated message from the CL (or manually set forkchoice through --debug.tip cli argument).

@rkrasiuk rkrasiuk added A-staged-sync Related to staged sync (pipelines and stages) A-engine Related to the engine implementation labels Mar 19, 2023
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 19, 2023

Codecov Report

Merging #1845 (043a0c4) into main (6afdd33) will increase coverage by 11.70%.
The diff coverage is 86.01%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@             Coverage Diff             @@
##             main    #1845       +/-   ##
===========================================
+ Coverage   61.41%   73.12%   +11.70%     
===========================================
  Files         418      423        +5     
  Lines       51340    51803      +463     
===========================================
+ Hits        31532    37882     +6350     
+ Misses      19808    13921     -5887     
Flag Coverage Δ
integration-tests 19.41% <0.00%> (+3.69%) ⬆️
unit-tests 67.49% <86.01%> (+10.18%) ⬆️

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

Impacted Files Coverage Δ
bin/reth/src/args/rpc_server_args.rs 54.05% <0.00%> (+30.42%) ⬆️
bin/reth/src/node/mod.rs 6.13% <0.00%> (+2.39%) ⬆️
crates/consensus/beacon/src/engine/message.rs 0.00% <0.00%> (ø)
crates/consensus/beacon/src/lib.rs 100.00% <ø> (ø)
crates/interfaces/src/executor.rs 100.00% <ø> (ø)
crates/rpc/rpc-builder/src/auth.rs 0.00% <0.00%> (ø)
crates/rpc/rpc-engine-api/src/error.rs 0.00% <0.00%> (-100.00%) ⬇️
crates/rpc/rpc-engine-api/src/message.rs 0.00% <ø> (ø)
crates/rpc/rpc/src/engine.rs 0.00% <0.00%> (ø)
crates/storage/provider/src/test_utils/blocks.rs 100.00% <ø> (ø)
... and 10 more

... and 150 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

Copy link
Copy Markdown
Collaborator

@onbjerg onbjerg 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 to me overall, very simple. Some minor nits and a question

Comment on lines +164 to +165
/// While the pipeline is syncing, the controller will keep processing messages from the receiver
/// and forwarding them to the blockchain tree.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does this mean that all new payloads etc. are sent to the blockchain tree while we sync? My worry here is that if you start sync from block 0 to e.g. 16m on mainnet that blockchain tree will grow unbounded in that period since the state in the tree is never flushed. However, this assumes that CL will send us new payloads if we are not synced yet, which might not be true.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah I would consider dropping messages as long as we're still syncing - beyond the first msg

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would just buffer the last N.
This is needed when the pipeline is close to the tip and the transition to the tree needs to be made, buffering blocks would make the transition better.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@onbjerg it doesn't forward if the pipeline is syncing

}
}

/// Consume the pipeline and run it. Return the pipeline and its result as a future.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I would add more docs here and on run that line out the distinction between the two and when to use one over the other (for crate consumers)

Copy link
Copy Markdown
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

Took a close look. I really like this. What is the integration point with Engine API going to look like, and how/where are we going to instantiate this?

Other thoughts:

  • Maybe we can clone a handle to the txpool in this to support block building
  • We might want a Pending / InMempool state provider separately

Comment on lines +164 to +165
/// While the pipeline is syncing, the controller will keep processing messages from the receiver
/// and forwarding them to the blockchain tree.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah I would consider dropping messages as long as we're still syncing - beyond the first msg

Comment on lines +217 to +218
// Get next pipeline state.
this.next_pipeline_state(pipeline, tip)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the current pipeline tip is the same as tip should this set the state to Idle?

@gakonst gakonst mentioned this pull request Mar 21, 2023
@rkrasiuk rkrasiuk marked this pull request as ready for review March 21, 2023 22:01
Copy link
Copy Markdown
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

Generally LGTM. Clean. I would add some more tests for the happy cases, e.g. newPayload -> newPayload -> FCU

Copy link
Copy Markdown
Collaborator

@rakita rakita left a comment

Choose a reason for hiding this comment

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

lgtm, did you maybe try it on testnet?

Copy link
Copy Markdown
Collaborator

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

looks pretty good, could follow easily.

left some nits, suggestions.

{
type Output = Result<(), BeaconEngineError>;

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this logic seems ok:

drain all messages
poll pipeline
repeat if pipeline not pending

Copy link
Copy Markdown
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

Alright. Full send, given our existing testing is solid and it looks like running CL <> EL correctly makes the EL get driven by the CL's headers. We can iterate as we run this live etc.

Comment on lines +246 to +251
None => {
let warn_msg = "No tip specified. \
reth cannot communicate with consensus clients, \
so a tip must manually be provided for the online stages with --debug.tip <HASH>.";
warn!(target: "reth::cli", warn_msg);
None
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably remove this warning if a CL is detected

@gakonst gakonst merged commit ce40bea into main Mar 23, 2023
@gakonst gakonst deleted the rkrasiuk/sync-controller branch March 23, 2023 18:18
@rkrasiuk rkrasiuk added A-consensus Related to the consensus engine C-enhancement New feature or request and removed A-staged-sync Related to staged sync (pipelines and stages) labels Mar 24, 2023
@rkrasiuk rkrasiuk changed the title feat(sync): beacon consensus engine feat(consensus): beacon consensus engine Mar 24, 2023
@rakita rakita restored the rkrasiuk/sync-controller branch March 27, 2023 11:29
@rakita rakita deleted the rkrasiuk/sync-controller branch March 27, 2023 11:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-consensus Related to the consensus engine A-engine Related to the engine implementation C-enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Real-Time Sync Switch

6 participants