Add beacon_blocks_by_head ReqResp#5181
Conversation
beacon_blocks_by_head req/resp on Gloasbeacon_blocks_by_head ReqResp
jtraglia
left a comment
There was a problem hiding this comment.
LGTM! I debated whether or not this should be backported to phase0, but that would require a V2 endpoint in Deneb (due to the updated max request blocks config) and this would cause unnecessary implementation overhead. Since this is expected to be used before Gloas (in Fulu) I believe introducing this in Fulu is an acceptable compromise.
| ``` | ||
| ( | ||
| beacon_root: Root | ||
| count: uint64 |
There was a problem hiding this comment.
we could consider making this slot-based so that if we request a finalized block, we end up by construction on an other epoch boundary by choosing an appropriate count (ie divisble by slots_per_epoch).
Not sure if this matters or not but it might make it easier to reason about overlapping ranges in parallel requests (request slots 0-1023 from one peer and 1024-2047 in another).
There was a problem hiding this comment.
One of the points of this request style is to not think in slots so the handling of large ranges of skip slots is not an issue anymore. For the headers variant I added a min_slot parameter, so that the stream stops at that slot. Since the max count of this route is small that feels unnecessary, but I can add it.
There was a problem hiding this comment.
Hm, the way this request is done prevents issuing parallel requests along the same history branch - ie consider:
------A-----B----C
when you request blocks along the C history, you don't know B and A but you still want to refer to them "logically" - so the kind of request you would want to make is "give me 64 blocks from the C history" and in parallel "give be 64 blocks starting at C-64, still from the C history".
For this, we need the request to look something like:
{
beacon_root: Root
slot_count: uint64
slot_offset: uint64
}
where slot_offset moves backwards in time along the history chosen by beacon_root - with the above, if I'm connected to N peers I can issue N parallel request that are guaranteed to be non-overlapping - as they arrive, I can also patch up any holes.
There was a problem hiding this comment.
is to not think in slots so the handling of large ranges of skip slots is not an issue anymore
Skip slots are not really an issue with the suggested replacement - consider that you get at least beacon_root from your request - if there's a big gap, you'll find out about the parent_root from that one block that you get and thus skip any number of slots to reach the next parent - since this case is exceedingly rare, I think the ability to do parallel range downloads in the normal case.
Also, if there is a significant gap, a request for beacon_root and slot_offset >= 1 will normally give you a block after that gap - we can mandate the behavior that you send at least one block in this scenario, even if it would violate slot_count - this would be a small overlap loss but would speed up slot skipping.
There was a problem hiding this comment.
actually, we can have the cake and eat it:
{
beacon_root: Root
count: uint64
offset: uint64
}
if we base the offset off the block count instead of slots we get the skip slot propery and the ability to ask for overlapping ranges.
this has the downside that we will overshoot our own finality point (which is known by slot and normally acts as a boundary on requests - so keeping a slot limit also has some utility)
There was a problem hiding this comment.
If we do your modifications this route becomes mut and it will just be a beacon_blocks_by_range but with the capacity to choose what head to choose from. If your sync benefits significantly from this sort of parallel requests can you propose to modify beacon_blocks_by_range and add a beacon_root?
I feel this discussion is very subjective on how you and I plan to implement sync. With your suggestion I can not implement the algorithm I plan to do, and viceversa for you
There was a problem hiding this comment.
#5265 - with offset, min_slot=0, this request is equivalent to the existing request - however, the additional parameters allow some parallelism.
**Motivation** - ethereum/consensus-specs#5181 - We want to support better syncing strategies in nonfinality **Description** - Add beacon_blocks_by_head serving and requesting code (requesting is currently unused) **AI Assistance Disclosure** - codex assistance

Adds a new req/resp route
beacon_blocks_by_headto Fulu. The request is(beacon_root, count); the responder walks the parent chain ofbeacon_root(inclusive) and emits up tocountblocks in descending slot order, one perresponse_chunkin the same shape asBeaconBlocksByRange v2. Capped atMAX_REQUEST_BLOCKS_DENEB(= 128).Same motivation as #5179 (header-tree forward sync, sigp/lighthouse#7678) — backfill a chain segment from a known head. The trade-off vs. #5179:
#5179 is the bandwidth-optimal version (only headers, single chunk, 2,048 per request) but requires clients to maintain a new headers-by-root DB column. This PR is the lower-cost-to-ship alternative for clients that don't want to add storage.
The two routes are not mutually exclusive — a client can serve either or both.