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

[Merged by Bors] - Reconstruct Payloads using Payload Bodies Methods #4028

Closed
wants to merge 19 commits into from

Conversation

ethDreamer
Copy link
Member

@ethDreamer ethDreamer added work-in-progress PR is a work-in-progress capella labels Feb 23, 2023
@ethDreamer ethDreamer changed the title Payload bodies Reconstruct Payloads using Payload Bodies Methods Feb 23, 2023
@michaelsproul michaelsproul added the v3.5.1 Scheduled for March 2023 label Feb 24, 2023
Copy link
Member

@michaelsproul michaelsproul left a comment

Choose a reason for hiding this comment

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

Looking good overall. I'm still in the process of understanding the block streamer and will come back for a more thorough review next week.

Some thoughts on complexity:

  • The current impl handles a graceful conversion from BlocksByRoot requests to PayloadsByRange. I initially thought this might not be necessary and we could always convert BlocksByRoot to PayloadsByRoot, but the non-finality requirement for using PayloadsByRoot makes that impossible.
  • I'd suggested we could avoid ever using PayloadsByRoot because all unfinalized payloads should be present in the hot database. This works OK in the case where the EL's view of finality is up-to-date or ahead of the CL, but not in the case where the EL's view is behind. In practice I think handling the case where the EL is behind might be important, because the CL can sync ahead using optimistic sync. In this case however the CL's view of the finalized slot is irrelevant to whether or not we should use PayloadsByRoot, so perhaps we should refactor to always use PayloadsByRange and treat PayloadsByRoot as a fallback (like getBlockByHash).

beacon_node/beacon_chain/src/beacon_block_streamer.rs Outdated Show resolved Hide resolved
@paulhauner paulhauner added v4.0.0 Mainnet Capella release expected late March 2023 and removed v3.5.1 Scheduled for March 2023 labels Mar 5, 2023
@ethDreamer ethDreamer added ready-for-review The code is ready for review and removed work-in-progress PR is a work-in-progress labels Mar 8, 2023
@ethDreamer
Copy link
Member Author

I've added some more descriptive logging to the streamer (perhaps we should add metrics?). Looks like most requests are for ~64 blocks. I monitored the logs for ~5 hours. In that time, every single block requested was returned. The overwhelming majority of requests require either 0,1, or 2 requests to the EE. There were three notable exceptions to this however, not sure what causes them:

Mar 08 20:09:51.953 DEBG BeaconBlockStreamer finished            engine requests: 16, failed: 0, succeeded: 510, sent: 510, requested blocks: 510, service: beacon
...
Mar 08 20:49:15.203 DEBG BeaconBlockStreamer finished            engine requests: 4, failed: 0, succeeded: 127, sent: 127, requested blocks: 127, service: beacon
...
Mar 08 22:51:07.699 DEBG BeaconBlockStreamer finished            engine requests: 16, failed: 0, succeeded: 509, sent: 509, requested blocks: 509, service: beacon

here's a random section of continuous logs over the course of ~5 minutes:

Mar 08 20:30:00.318 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:30:03.579 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:30:21.724 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:30:28.218 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 62, sent: 62, requested blocks: 62, service: beacon
Mar 08 20:30:28.241 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:30:49.255 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:30:53.154 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:02.356 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:35.398 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:31:37.064 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:38.663 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:41.035 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:31:42.317 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:46.294 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:47.889 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.154 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.310 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.438 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.558 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.709 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:48.853 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:49.066 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:49.346 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:49.508 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:49.653 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:49.803 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.068 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.280 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.416 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.612 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.774 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:50.926 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.082 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.197 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.205 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:51.346 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.490 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.666 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.822 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:51.973 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:52.238 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:52.422 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:31:55.508 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:31:59.240 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:01.710 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:03.346 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:32:06.802 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 60, sent: 60, requested blocks: 60, service: beacon
Mar 08 20:32:13.114 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:18.552 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:24.376 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:32:26.488 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 61, sent: 61, requested blocks: 61, service: beacon
Mar 08 20:32:28.016 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:31.121 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:46.479 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:48.334 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:32:53.455 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:32:54.810 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:33:05.692 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:33:13.121 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:33:17.148 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:33:32.995 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:33:37.530 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:33:55.265 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:34:37.183 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 1, sent: 1, requested blocks: 1, service: beacon
Mar 08 20:34:49.910 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:34:58.801 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 62, sent: 62, requested blocks: 62, service: beacon
Mar 08 20:35:05.640 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:35:14.421 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon
Mar 08 20:35:25.239 DEBG BeaconBlockStreamer finished            engine requests: 1, failed: 0, succeeded: 32, sent: 32, requested blocks: 32, service: beacon
Mar 08 20:35:28.087 DEBG BeaconBlockStreamer finished            engine requests: 2, failed: 0, succeeded: 63, sent: 63, requested blocks: 63, service: beacon
Mar 08 20:35:31.357 DEBG BeaconBlockStreamer finished            engine requests: 0, failed: 0, succeeded: 64, sent: 64, requested blocks: 64, service: beacon

@michaelsproul
Copy link
Member

In my previous review I wrote:

the CL's view of the finalized slot is irrelevant to whether or not we should use PayloadsByRoot, so perhaps we should refactor to always use PayloadsByRange and treat PayloadsByRoot as a fallback (like getBlockByHash).

Having thought about it more I'm quite certain we should action this. The current approach of trying to use ByHash if the block's slot is after the finalized slot is faulty because we never actually expect that check to pass: if a block is stored in Lighthouse's database without a payload then it must be prior to the database's split slot, which is <= the finalized slot from fork choice, i.e. the else branch here is unreachable:

if block_parts.slot() <= self.finalized_slot {
// this is a by_range request
by_range_blocks.push(block_parts);
} else {
// this is a by_hash request
by_hash
.push_block_parts(block_parts, &self.beacon_chain.log)
.await;
requests.insert(root, by_hash.clone());
}

The fundamental reason for this is that we always store full payloads for all blocks in the hot part of the database (with slot >= split).

I think there are two approaches we could take to remedy this:

  1. Not using ByHash at all. Try ByRange and if it fails, let it fail. If Lighthouse's view of finality is ahead of the execution node then arguably we are still in a syncing state and shouldn't be burdening the EL with payload reconstruction requests. If all is well the EL will catch up soon enough and we'll be able to return payloads.
  2. Use ByHash only after observing a failure of ByRange. This is trickier because we need to hold on to the BlockParts from the ByRange request to re-use them in the fallback ByHash request. We would also need (?) to do some batching of the ByHash requests to avoid spamming too many individual requests. A simple algorithm would be to batch consecutive errors into a single ByHash request.

I started trying to implement (2) with fallback logic at this point but switched to (1) when I encountered the BlockParts issue. The two commits I made are:

  • General cleanup commit/refactor (relevant to both approaches): 35d6ab8.
  • Deletion of ByHash: 2190ef1.

One option would be to take approach (1) for now, and come back for (2) at a later date.

@ethDreamer
Copy link
Member Author

Looks good to me! I've merged your changes in :)

@michaelsproul michaelsproul added ready-for-merge This PR is ready to merge. and removed ready-for-review The code is ready for review labels Mar 17, 2023
Copy link
Member

@michaelsproul michaelsproul left a comment

Choose a reason for hiding this comment

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

I'm happy to merge this to unstable!

I've added some metrics and this PR is running on both Sepolia + Goerli without issue 👌

@michaelsproul
Copy link
Member

I've seen no issues running this on our testnet infra, merging! 🎉

@michaelsproul
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Mar 19, 2023
## Issue Addressed

* #3895 

Co-authored-by: ethDreamer <37123614+ethDreamer@users.noreply.github.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
@bors bors bot changed the title Reconstruct Payloads using Payload Bodies Methods [Merged by Bors] - Reconstruct Payloads using Payload Bodies Methods Mar 20, 2023
@bors bors bot closed this Mar 20, 2023
bors bot pushed a commit that referenced this pull request Apr 18, 2023
## Proposed Changes

Builds on #4028 to use the new payload bodies methods in the HTTP API as well.

## Caveats

The payloads by range method only works for the finalized chain, so it can't be used in the execution engine integration tests because we try to reconstruct unfinalized payloads there.
xenowits pushed a commit to xenowits/lighthouse that referenced this pull request May 16, 2023
## Proposed Changes

Builds on sigp#4028 to use the new payload bodies methods in the HTTP API as well.

## Caveats

The payloads by range method only works for the finalized chain, so it can't be used in the execution engine integration tests because we try to reconstruct unfinalized payloads there.
ghost pushed a commit to oone-world/lighthouse that referenced this pull request Jul 13, 2023
## Proposed Changes

Builds on sigp#4028 to use the new payload bodies methods in the HTTP API as well.

## Caveats

The payloads by range method only works for the finalized chain, so it can't be used in the execution engine integration tests because we try to reconstruct unfinalized payloads there.
Woodpile37 pushed a commit to Woodpile37/lighthouse that referenced this pull request Jan 6, 2024
* sigp#3895

Co-authored-by: ethDreamer <37123614+ethDreamer@users.noreply.github.com>
Co-authored-by: Michael Sproul <michael@sigmaprime.io>
Woodpile37 pushed a commit to Woodpile37/lighthouse that referenced this pull request Jan 6, 2024
Builds on sigp#4028 to use the new payload bodies methods in the HTTP API as well.

The payloads by range method only works for the finalized chain, so it can't be used in the execution engine integration tests because we try to reconstruct unfinalized payloads there.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
capella ready-for-merge This PR is ready to merge. v4.0.0 Mainnet Capella release expected late March 2023
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants