Fix engine_forkchoiceUpdated bug (#2274)
* fCU Ignore update to old head * Only enable terminal PoW block conditions for fCUV1 * Typo fix: TDD -> TTD * Add link to Shanghai fCUV2 specification * Add link to Paris fCUV1 specification
This commit is contained in:
parent
0f0ac0bc14
commit
1565c57ae6
|
@ -102,38 +102,45 @@ proc forkchoiceUpdated*(ben: BeaconEngineRef,
|
||||||
|
|
||||||
# Block is known locally, just sanity check that the beacon client does not
|
# Block is known locally, just sanity check that the beacon client does not
|
||||||
# attempt to push us back to before the merge.
|
# attempt to push us back to before the merge.
|
||||||
let blockNumber = header.blockNumber.truncate(uint64)
|
#
|
||||||
if header.difficulty > 0.u256 or blockNumber == 0'u64:
|
# Disable terminal PoW block conditions validation for fCUV2 and later.
|
||||||
var
|
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/shanghai.md#specification-1
|
||||||
td, ptd: DifficultyInt
|
if apiVersion == Version.V1:
|
||||||
ttd = com.ttd.get(high(common.BlockNumber))
|
let blockNumber = header.blockNumber.truncate(uint64)
|
||||||
|
if header.difficulty > 0.u256 or blockNumber == 0'u64:
|
||||||
|
var
|
||||||
|
td, ptd: DifficultyInt
|
||||||
|
ttd = com.ttd.get(high(common.BlockNumber))
|
||||||
|
|
||||||
if not db.getTd(blockHash, td) or (blockNumber > 0'u64 and not db.getTd(header.parentHash, ptd)):
|
if not db.getTd(blockHash, td) or (blockNumber > 0'u64 and not db.getTd(header.parentHash, ptd)):
|
||||||
error "TDs unavailable for TTD check",
|
error "TDs unavailable for TTD check",
|
||||||
number = blockNumber,
|
number = blockNumber,
|
||||||
hash = blockHash.short,
|
hash = blockHash.short,
|
||||||
td = td,
|
td = td,
|
||||||
parent = header.parentHash.short,
|
parent = header.parentHash.short,
|
||||||
ptd = ptd
|
ptd = ptd
|
||||||
return simpleFCU(PayloadExecutionStatus.invalid, "TDs unavailable for TDD check")
|
return simpleFCU(PayloadExecutionStatus.invalid, "TDs unavailable for TTD check")
|
||||||
|
|
||||||
if td < ttd or (blockNumber > 0'u64 and ptd > ttd):
|
if td < ttd or (blockNumber > 0'u64 and ptd > ttd):
|
||||||
notice "Refusing beacon update to pre-merge",
|
notice "Refusing beacon update to pre-merge",
|
||||||
number = blockNumber,
|
number = blockNumber,
|
||||||
hash = blockHash.short,
|
hash = blockHash.short,
|
||||||
diff = header.difficulty,
|
diff = header.difficulty,
|
||||||
ptd = ptd,
|
ptd = ptd,
|
||||||
ttd = ttd
|
ttd = ttd
|
||||||
|
|
||||||
return invalidFCU("Refusing beacon update to pre-merge")
|
return invalidFCU("Refusing beacon update to pre-merge")
|
||||||
|
|
||||||
# If the head block is already in our canonical chain, the beacon client is
|
# If the head block is already in our canonical chain, the beacon client is
|
||||||
# probably resyncing. Ignore the update.
|
# probably resyncing. Ignore the update.
|
||||||
|
# See point 2 of fCUV1 specification
|
||||||
|
# https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.4/src/engine/paris.md#specification-1
|
||||||
var canonHash: common.Hash256
|
var canonHash: common.Hash256
|
||||||
if db.getBlockHash(header.blockNumber, canonHash) and canonHash == blockHash:
|
if db.getBlockHash(header.blockNumber, canonHash) and canonHash == blockHash:
|
||||||
# TODO should this be possible?
|
notice "Ignoring beacon update to old head",
|
||||||
# If we allow these types of reorgs, we will do lots and lots of reorgs during sync
|
blockHash=blockHash.short,
|
||||||
notice "Reorg to previous block", blockHash
|
blockNumber=header.blockNumber
|
||||||
|
return validFCU(none(PayloadID), blockHash)
|
||||||
|
|
||||||
chain.setCanonical(header).isOkOr:
|
chain.setCanonical(header).isOkOr:
|
||||||
return invalidFCU(error, com, header)
|
return invalidFCU(error, com, header)
|
||||||
|
|
Loading…
Reference in New Issue