Q: When do we trigger it?
Q: Describe the algorithm
## Relevant Spec
### engine_forkchoiceUpdatedV1
https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification-1
1. Client software **MAY** initiate a sync process if `forkchoiceState.headBlockHash` references an unknown payload or a payload that can't be validated because data that are requisite for the validation is missing. The sync process is specified in the [Sync](#sync) section.
### engine_newPayloadV1
https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#specification
2. Client software **MAY** initiate a sync process if requisite data for payload validation is missing. Sync process is specified in the [Sync](#sync) section.
### Sync
https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#sync
In the context of this specification, the sync is understood as the process of obtaining data required to validate a payload. The sync process may consist of the following stages:
1. Pulling data from remote peers in the network.
2. Passing ancestors of a payload through the [Payload validation](#payload-validation) and obtaining a parent state.
*Note:* Each of these stages is optional. Exact behavior of client software during the sync process is implementation dependent.
### Message ordering
https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md#message-ordering
Consensus Layer client software **MUST** respect the order of the corresponding fork choice update events when making calls to the `engine_forkchoiceUpdated` method.
Execution Layer client software **MUST** process `engine_forkchoiceUpdated` method calls
in the same order as they have been received.
## Besu Trigger
We start a new backwards sync (BWS) session on both engine_forkchoiceUpdated (fCU) and engine_newPayload (nP).
*AbstractEngineForkchoiceUpdated.java*
```java!
final Optional<BlockHeader> maybeNewHead =
mergeCoordinator.getOrSyncHeadByHash(forkChoice.getHeadBlockHash(),
forkChoice.getFinalizedBlockHash());
if (maybeNewHead.isEmpty()) {
return syncingResponse(requestId, forkChoice);
}
```
*AbstractEngineNewPayload.java*
```java!
final Optional<BlockHeader> maybeParentHeader =
protocolContext.getBlockchain().getBlockHeader(blockParam.getParentHash());
// ...
if (maybeParentHeader.isEmpty()) {
LOG.atDebug()
.setMessage("Parent of block {} is not present, append it to backward sync")
.addArgument(block::toLogString)
.log();
mergeCoordinator.appendNewPayloadToSync(block);
return respondWith(reqId, blockParam, null, SYNCING);
}
```
*MergeCoordinator.java*
```java!
@Override
public Optional<BlockHeader> getOrSyncHeadByHash(final Hash headHash, final Hash finalizedHash) {
final var chain = protocolContext.getBlockchain();
final var maybeHeadHeader = chain.getBlockHeader(headHash);
if (maybeHeadHeader.isPresent()) {
LOG.atDebug()
.setMessage("BlockHeader {} is already present")
.addArgument(maybeHeadHeader.get()::toLogString)
.log();
} else {
LOG.atDebug()
.setMessage("Appending new head block hash {} to backward sync")
.addArgument(headHash::toHexString)
.log();
backwardSyncContext.maybeUpdateTargetHeight(headHash);
backwardSyncContext
.syncBackwardsUntil(headHash)
.thenRun(() -> updateFinalized(finalizedHash));
}
return maybeHeadHeader;
}
```
```java!
@Override
public CompletableFuture<Void> appendNewPayloadToSync(final Block newPayload) {
return backwardSyncContext.syncBackwardsUntil(newPayload);
}
```
## Algorithm and Structure Design
- `BackwardSyncContext` is the entry point and manages the session.
- `BackwardChain` is the data structure, where chainHead is the _oldest_ block.
- BlockHeaders, Blocks and Hashes are stored on disk, keyed by Hash.
- Also sessionData is stored on disk.
- `hashesToAppend` is Deque representing the work queue (one per session?)
- `isTrusted` means "do we have it stored?" (Maybe "trust" is because it came from the CL).
- `BackwardSyncAlgorithm` consists of `CompletableFuture` Steps composed recursively in a State Pattern.
## Initial Sync BWS INFO Logs
(WorldStateDownload || FastImportBlocks) -> WorldStateHeal -> BWS
```
BackwardSyncContext | Starting a new backward sync session
BackwardSyncStep | Backward sync phase 1 of 2 completed, downloaded a total of 200 headers. Peers: 8
BackwardSyncContext | Backward sync phase 2 of 2, 2.63% completed, imported 1 blocks of at least 38 (current head 3743023, target head 3743060). Peers: 2
BackwardSyncContext | Backward sync phase 2 of 2, 43.59% completed, imported 17 blocks of at least 39 (current head 3743039, target head 3743061). Peers: 2
BackwardSyncContext | Backward sync phase 2 of 2, 97.50% completed, imported 39 blocks of at least 40 (current head 3743061, target head 3743062). Peers: 3
BackwardSyncContext | Backward sync phase 2 of 2 completed, imported a total of 40 blocks. Peers: 2
BackwardSyncAlgorithm | Current backward sync session is done