Skip to content

Wire up blob fetching with request manager#4527

Merged
tersec merged 11 commits intostatus-im:unstablefrom
henridf:eip4844-sync
Jan 31, 2023
Merged

Wire up blob fetching with request manager#4527
tersec merged 11 commits intostatus-im:unstablefrom
henridf:eip4844-sync

Conversation

@henridf
Copy link
Contributor

@henridf henridf commented Jan 19, 2023

(Putting this up while I work on using BlobsSidecarsbyRange in the sync manager, which is proving to be a challenge).

if not(isNil(peer)):
rman.network.peerPool.release(peer)

proc fetchAncestorBlocksAndBlobsFromNetwork(rman: RequestManager,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

(This has a lot of duplication with fetchAncestorBlocksFromNetwork, but there isn't a shared chunk that can be cleanly factored out.)

@henridf henridf changed the base branch from stable to unstable January 19, 2023 15:39
@github-actions
Copy link

github-actions bot commented Jan 19, 2023

Unit Test Results

         9 files  ±0    1 065 suites  ±0   31m 3s ⏱️ - 1m 25s
  3 555 tests ±0    3 318 ✔️ ±0  237 💤 ±0  0 ±0 
15 410 runs  ±0  15 145 ✔️ ±0  265 💤 ±0  0 ±0 

Results for commit ccfc99d. ± Comparison against base commit c71bddb.

♻️ This comment has been updated with latest results.

@henridf
Copy link
Contributor Author

henridf commented Jan 20, 2023

Not sure why just one build is failing, but this message makes me wonder if it's some infra issue

Error: The log was not found. It may have been deleted based on retention settings.

@henridf
Copy link
Contributor Author

henridf commented Jan 21, 2023

CI is green.

@henridf henridf mentioned this pull request Jan 21, 2023
21 tasks

let start = SyncMoment.now(0)

let getBlobs = rman.isSlotWithBlobs(rman.dag.head.slot)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the only reason RequestManager needs a reference to the DAG?

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. I don't really like bringing in that reference, but the RequestManager needs to know where the head is at.

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 not sure I understand why though. My read of https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/p2p-interface.md#beaconblockandblobssidecarbyroot-v1 is that /eth2/beacon_chain/req/beacon_block_and_blobs_sidecar_by_root/1/ will only work for EIP4844 blocks, so even if the head has s.epoch >= rman.dag.cfg.EIP4844_FORK_EPOCH (isSlotWithBlobs), Nimbus might request a root which is pre-EIP4844.

This could happen a few ways, e.g., a nonfinalizing network where one fork advances through EIP4844_FORK_EPOCH, and another has been a side chain, but then the network as a whole reorgs to a new chain -- but this node doesn't have those blocks or blobs, so it has to request them. If it looks like

slot 600: ancestor of current head
slot 610: ancestor of another sidechain

-------------------
EIP-4844 fork epoch
-------------------

slot 700: current head, based on 600
slot 710: future reorg target based on 610 (which this node rejected, for any of several reasons. either way, needs to request it)

But the current logic requests from slot 610 via an EIP4844 req/resp protocol endpoint which won't support it, from what I can tell, because once its head reaches EIP4844, it will become unable to request pre-EIP4844 slots in the event of such reorgs.

This isn't a major hazard on a finalizing network, but I'm not sure it's a reliable heuristic on a nonfinalizing network.

One can also construct failure scenarios the opposite direction -- this node's head is stuck just before EIP4844 fork epoch, while a side chain it's not for whatever reason following reaches/passes the EIP4844 fork epoch.

Rather, is this something that needs to be know specifically root by root, or am I missing something, and it's somehow possible to extrapolate from the DAG head to all the roots one might request?

Copy link
Contributor Author

@henridf henridf Jan 21, 2023

Choose a reason for hiding this comment

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

Hmm, I had come up with simpler scenarios, and had sort of convinced myself they would work, but I realize now that's not the case. Even in this simpler example without forks:

------------------
slot 599: current head
slot 600: EIP-4844 fork epoch
slot 601
slot 602: we received this block and need to fill in 600,601
------------------

where we would request 600 and 601 using the pre-EIP488 RPC, which would give no results. (from https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/p2p-interface.md#beaconblocksbyroot-v2: "After EIP4844_FORK_EPOCH, BeaconBlocksByRootV2 is replaced by BeaconBlockAndBlobsSidecarByRootV1").

And so we get stuck, I think.

It seems like there's a fundamental issue here, since we have no idea of knowing based on a root whether it's pre or post a particular epoch.

The only thing I can think of is some sort of fallback where we try the other endpoint if one doesn't return results. Not great but I'm not seeing any other way.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, what are other CLs doing, I guess? Seems ugly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking the same thing. Will be a good discussion topic soon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tersec: in 26b8cc9, I modified the "fetch blocks vs blobs" logic. Per the comment:

      # As soon as EIP4844_FORK_EPOCH comes around in wall time, we
      # switch to requesting blocks and blobs. In the vicinity of the
      # transition, that means that we *may* request blobs for a
      # pre-eip4844. In that case, we get ResourceUnavailable from the
      # peer and fall back to requesting blocks only.

# transition, that means that we *may* request blobs for a
# pre-eip4844. In that case, we get ResourceUnavailable from the
# peer and fall back to requesting blocks only.
let getBlobs = rman.isBlobsTime(rman.dag.head.slot)
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't wall time -- the comment's logic I agree with, but that's not what this does. As a bonus, by following wall time rather than head, no need to pass the DAG anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the slot parameter to isBlobsTime (which was looking at wall clock, the slot parameter was leftover from before).

d78ec80

Re the dag, we do at least need EIP4844_FORK_EPOCH. I could just pass the RuntimeConfig (dag.cfg) to the request manager.

@tersec tersec enabled auto-merge (squash) January 31, 2023 18:42
auto-merge was automatically disabled January 31, 2023 19:28

Head branch was pushed to by a user without write access

@tersec tersec enabled auto-merge (squash) January 31, 2023 19:36
@tersec tersec merged commit d7316ac into status-im:unstable Jan 31, 2023
@henridf henridf deleted the eip4844-sync branch February 1, 2023 08:33
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