reth
reth copied to clipboard
Optimistic syncing when `finalized_hash` is zero
Optimistic syncing
There are situations when a CL might not have a finalized block to gives us on first sync, and still expect us to sync in an optimistic way, handling any potential reorg. Currently Pipeline and BT are not ready for that, and need to be extended.
- [x] Engine should be able to set head hash as pipeline target (https://github.com/paradigmxyz/reth/pull/7552)
- [x] BT should be able to unwind from a reorged optimistic target that happens on pipeline (https://github.com/paradigmxyz/reth/pull/7552)
- [ ] Pipeline should be able to detect a reorged optimistic target during Header/Bodies stage so it does not hang looking for unexisting blocks/headers
--
Proposed Pipeline flow for Header, Bodies and Finish stage
Optimistically sync to the given unfinalized tip. When a reorg is detected, do the minimum amount of work necessary, meaning that we try to unwind to the highest unreorged block and continue.
- Header stage:
- Checks if we were reorged, in case we time out on obtaining a block header. If so, complete the stage to the highest unreorged block known (which now becomes the new pipeline target).
- BodiesStage
- Checks if we were reorged, in case we time out on obtaining a block. If so, call a Header unwind and complete the stage to the highest unreorged block known (which now becomes the new pipeline target).
- FinishStage
- Checks if we were reorged. If so, issue a pipeline unwind to the highest unreorged block known.
Attention: highest unreorged block known does not mean that it's a finalized block.
graph TB
Start[Start]
Done[Done]
subgraph HeaderStage
HeaderExecution(Execution)
HeaderDownloader(Downloader)
HeaderTimeout{Timeout occurred?}
HeaderReorg{isUnfinalizedTarget && isReorged}
TruncateGap(Truncate Gap)
HeaderUnwind(HeaderUnwind)
end
Start --> |Unfinalized target block| HeaderDownloader
HeaderDownloader --> HeaderTimeout
HeaderTimeout --> |Yes| HeaderReorg
HeaderTimeout --> |No| HeaderExecution
HeaderReorg --> |No| HeaderDownloader
HeaderReorg --> |Yes| TruncateGap
TruncateGap --> |New target block| HeaderExecution
HeaderExecution --> |Unfinalized target block| BodiesDownloader
subgraph BodiesStage
BodiesExecution(Execution)
BodiesDownloader(Downloader)
BodiesTimeout{Timeout occurred?}
BodiesReorg{isUnfinalizedTarget && isReorged}
TruncateGap(Truncate Gap)
end
BodiesDownloader --> BodiesTimeout
BodiesTimeout --> |Yes| BodiesReorg
BodiesTimeout --> |No| BodiesExecution
BodiesReorg --> |No| BodiesDownloader
BodiesReorg --> |"Yes 1*"| HeaderUnwind
HeaderUnwind --> BodiesExecution
subgraph Other Stages
OtherStagesExecution(Execution)
end
BodiesExecution --> OtherStagesExecution
subgraph FinishStage
FinishExecution(Execution)
FinishReorg{isUnfinalizedTarget && isReorged}
end
OtherStagesExecution --> FinishExecution
FinishExecution --> FinishReorg
FinishReorg --> |"Yes (N blocks)"| PipelineUnwind("PipelineUnwind (N)")
FinishReorg --> |No| Done
- We can either call
HeaderStage::unwindfrom the body stage, or end the current stage with the new target block and then call pipeline unwind to the new target block
Additional context
No response
This issue is stale because it has been open for 21 days with no activity.
@joshieDo please link the PR you have open for this