Skip to content

Commit

Permalink
Bugfix potential chain head and worldstate inconsistency (#4862)
Browse files Browse the repository at this point in the history
* bugfix, ensure setNewHead does not move the chain head forward if the worldstate forward fails

Signed-off-by: garyschulte <[email protected]>
  • Loading branch information
garyschulte authored Dec 23, 2022
1 parent 3ecb09d commit 642d477
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Difficulty;
import org.hyperledger.besu.ethereum.core.MiningParameters;
import org.hyperledger.besu.ethereum.core.MutableWorldState;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BackwardSyncContext;
import org.hyperledger.besu.ethereum.eth.sync.backwardsync.BadChainListener;
Expand Down Expand Up @@ -521,30 +522,42 @@ private boolean setNewHead(final MutableBlockchain blockchain, final BlockHeader
LOG,
"Forwarding chain head to the block {} saved from a previous newPayload invocation",
newHead::toLogString);
forwardWorldStateTo(newHead);
return blockchain.forwardToBlock(newHead);

if (forwardWorldStateTo(newHead)) {
// move chain head forward:
return blockchain.forwardToBlock(newHead);
} else {
debugLambda(
LOG,
"Failed to move the worldstate forward to hash {}, not moving chain head",
newHead::toLogString);
return false;
}
}

debugLambda(LOG, "New head {} is a chain reorg, rewind chain head to it", newHead::toLogString);
return blockchain.rewindToBlock(newHead.getHash());
}

private void forwardWorldStateTo(final BlockHeader newHead) {
protocolContext
.getWorldStateArchive()
.getMutable(newHead.getStateRoot(), newHead.getHash())
.ifPresentOrElse(
mutableWorldState ->
debugLambda(
LOG,
"World state for state root hash {} and block hash {} persisted successfully",
mutableWorldState::rootHash,
newHead::getHash),
() ->
LOG.error(
"Could not persist world for root hash {} and block hash {}",
newHead.getStateRoot(),
newHead.getHash()));
private boolean forwardWorldStateTo(final BlockHeader newHead) {
Optional<MutableWorldState> newWorldState =
protocolContext
.getWorldStateArchive()
.getMutable(newHead.getStateRoot(), newHead.getHash());

newWorldState.ifPresentOrElse(
mutableWorldState ->
debugLambda(
LOG,
"World state for state root hash {} and block hash {} persisted successfully",
mutableWorldState::rootHash,
newHead::getHash),
() ->
LOG.error(
"Could not persist world for root hash {} and block hash {}",
newHead.getStateRoot(),
newHead.getHash()));
return newWorldState.isPresent();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@
import org.apache.tuweni.rlp.RLP;

public class BonsaiWorldStateKeyValueStorage implements WorldStateStorage, AutoCloseable {
// 0x776f726c64526f6f74
public static final byte[] WORLD_ROOT_HASH_KEY = "worldRoot".getBytes(StandardCharsets.UTF_8);

// 0x776f726c64426c6f636b48617368
public static final byte[] WORLD_BLOCK_HASH_KEY =
"worldBlockHash".getBytes(StandardCharsets.UTF_8);

Expand Down

0 comments on commit 642d477

Please sign in to comment.