Skip to content

Commit

Permalink
Backward Sync should remember recent finalized blocks. (hyperledger#3808
Browse files Browse the repository at this point in the history
)

* Backward Sync is now remembering recent finalized blocks.

When syncing using BWS we now consider finalized blocks reported by consensus layer.
When no finalized block is specified, nothing strange will go on. When Finalized block is specified
But Besu is not aware of any finalized block yet, we will sync as usual until the finalized block is about to get imported.

A new invariant is introduced when importing blocks using BWS.
All imported blocks has to descent from latest finalized block or a TTD block if we did not finalize yet.

* Importing a finalized block updates the information in Besu Mutable Blockchain.
* It is no longer possible to import blocks into the blockchain below a previously finalized block when using BWS
* When a new finalized block gets announced while BWS is in progress and Besu already has it imported, the Mutable Blockchain gets updated, and the chain gets checked for possible pruning
* When trying to import blocks of equal height as newly announced finalized block, then only the new announced finalized block will be possible to import using BWS
* When importing a new block using BWS after finalized, we can now guarantee that the block descends from latest finalized block

Signed-off-by: Jiri Peinlich <jiri.peinlich@gmail.com>

* BWS now has explicit parametrized check for how deep to sync

Signed-off-by: Jiri Peinlich <jiri.peinlich@gmail.com>

* addressing review comments

Signed-off-by: Jiri Peinlich <jiri.peinlich@gmail.com>

* Addressing review comment

Signed-off-by: Jiri Peinlich <jiri.peinlich@gmail.com>

Co-authored-by: Fabio Di Fabio <fabio.difabio@consensys.net>
  • Loading branch information
gezero and fab-10 authored Jun 16, 2022
1 parent c0631cf commit 2b42f6e
Show file tree
Hide file tree
Showing 22 changed files with 1,178 additions and 436 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -209,15 +209,31 @@ public PayloadIdentifier preparePayload(
}

@Override
public Optional<BlockHeader> getOrSyncHeaderByHash(final Hash blockhash) {
public Optional<BlockHeader> getOrSyncHeaderByHash(final Hash blockHash) {
final var chain = protocolContext.getBlockchain();
final var optHeader = chain.getBlockHeader(blockhash);
final var optHeader = chain.getBlockHeader(blockHash);

if (optHeader.isPresent()) {
debugLambda(LOG, "BlockHeader {} is already present", () -> optHeader.get().toLogString());
} else {
debugLambda(LOG, "appending block hash {} to backward sync", blockhash::toHexString);
backwardSyncContext.syncBackwardsUntil(blockhash);
debugLambda(LOG, "appending block hash {} to backward sync", blockHash::toHexString);
backwardSyncContext.syncBackwardsUntil(blockHash);
}
return optHeader;
}

@Override
public Optional<BlockHeader> getOrSyncHeaderByHash(
final Hash blockHash, final Hash finalizedBlockHash) {
final var chain = protocolContext.getBlockchain();
final var optHeader = chain.getBlockHeader(blockHash);

if (optHeader.isPresent()) {
debugLambda(LOG, "BlockHeader {} is already present", () -> optHeader.get().toLogString());
} else {
debugLambda(LOG, "appending block hash {} to backward sync", blockHash::toHexString);
backwardSyncContext.updateHeads(blockHash, finalizedBlockHash);
backwardSyncContext.syncBackwardsUntil(blockHash);
}
return optHeader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ ForkchoiceResult updateForkChoice(

CompletableFuture<Void> appendNewPayloadToSync(Block newPayload);

Optional<BlockHeader> getOrSyncHeaderByHash(Hash blockhash);
Optional<BlockHeader> getOrSyncHeaderByHash(Hash blockHash);

boolean isMiningBeforeMerge();

Optional<BlockHeader> getOrSyncHeaderByHash(Hash blockHash, Hash finalizedBlockHash);

class ForkchoiceResult {
public enum Status {
VALID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,14 @@ public CompletableFuture<Void> appendNewPayloadToSync(final Block newPayload) {
}

@Override
public Optional<BlockHeader> getOrSyncHeaderByHash(final Hash blockhash) {
return mergeCoordinator.getOrSyncHeaderByHash(blockhash);
public Optional<BlockHeader> getOrSyncHeaderByHash(final Hash blockHash) {
return mergeCoordinator.getOrSyncHeaderByHash(blockHash);
}

@Override
public Optional<BlockHeader> getOrSyncHeaderByHash(
final Hash blockHash, final Hash finalizedBlockHash) {
return mergeCoordinator.getOrSyncHeaderByHash(blockHash, finalizedBlockHash);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ public JsonRpcResponse syncResponse(final JsonRpcRequestContext requestContext)
if (newHead.isEmpty()) {
Optional.ofNullable(forkChoice.getHeadBlockHash())
.filter(hash -> !hash.equals(Hash.ZERO))
.ifPresent(mergeCoordinator::getOrSyncHeaderByHash);
.ifPresent(
blockhash ->
mergeCoordinator.getOrSyncHeaderByHash(
blockhash, forkChoice.getFinalizedBlockHash()));

return syncingResponse(requestId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ public Difficulty getTotalDifficulty() {
public long getHeight() {
return height;
}

public String toLogString() {
return getHeight() + " (" + getHash().toHexString() + ")";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public synchronized void prependAncestorsHeader(final BlockHeader blockHeader) {
if (!firstHeader.getParentHash().equals(blockHeader.getHash())) {
throw new BackwardSyncException(
"Hash of header does not match our expectations, was "
+ blockHeader.getHash().toHexString()
+ blockHeader.toLogString()
+ " when we expected "
+ firstHeader.getParentHash().toHexString());
}
Expand All @@ -116,9 +116,9 @@ public synchronized void prependAncestorsHeader(final BlockHeader blockHeader) {
debugLambda(
LOG,
"Added header {} on height {} to backward chain led by pivot {} on height {}",
() -> blockHeader.getHash().toHexString(),
() -> blockHeader.toLogString(),
blockHeader::getNumber,
() -> lastStoredPivot.orElseThrow().getHash().toHexString(),
() -> lastStoredPivot.orElseThrow().toLogString(),
firstHeader::getNumber);
}

Expand Down Expand Up @@ -185,7 +185,7 @@ public synchronized void addNewHash(final Hash newBlockHash) {
this.hashesToAppend.add(newBlockHash);
}

public synchronized Optional<Hash> getFirstHash() {
public synchronized Optional<Hash> getFirstHashToAppend() {
return Optional.ofNullable(hashesToAppend.poll());
}
}
Loading

0 comments on commit 2b42f6e

Please sign in to comment.