Use block number or timestamp to determine fork rules (#2496)
* Use block number or timestamp to determine fork rules Avoid confusion raised by `forkGTE` usage where block informations are present. * Get rid of forkGTE
This commit is contained in:
parent
3bb707422b
commit
916f88a373
|
@ -159,11 +159,16 @@ proc newPayload*(ben: BeaconEngineRef,
|
|||
let ttd = com.ttd.get(high(UInt256))
|
||||
|
||||
if version == Version.V1:
|
||||
let td = db.getScore(header.parentHash).valueOr:
|
||||
let ptd = db.getScore(header.parentHash).valueOr:
|
||||
0.u256
|
||||
if (not com.forkGTE(MergeFork)) and td < ttd:
|
||||
let gptd = db.getScore(parent.parentHash)
|
||||
if ptd < ttd:
|
||||
warn "Ignoring pre-merge payload",
|
||||
number = header.number, hash = blockHash, td, ttd
|
||||
number = header.number, hash = blockHash.short, ptd, ttd
|
||||
return invalidStatus()
|
||||
if parent.difficulty > 0.u256 and gptd.isSome and gptd.value >= ttd:
|
||||
warn "Ignoring pre-merge parent block",
|
||||
number = header.number, hash = blockHash.short, ptd, ttd
|
||||
return invalidStatus()
|
||||
|
||||
if header.timestamp <= parent.timestamp:
|
||||
|
|
|
@ -62,9 +62,6 @@ type
|
|||
# synchronizer need this
|
||||
syncProgress: SyncProgress
|
||||
|
||||
# current hard fork, updated after calling `hardForkTransition`
|
||||
currentFork: HardFork
|
||||
|
||||
# one of POW/POS, updated after calling `hardForkTransition`
|
||||
consensusType: ConsensusType
|
||||
|
||||
|
@ -140,7 +137,7 @@ proc init(com : CommonRef,
|
|||
com.pruneHistory= pruneHistory
|
||||
com.pos = CasperRef.new
|
||||
|
||||
# com.currentFork and com.consensusType
|
||||
# com.consensusType
|
||||
# is set by hardForkTransition.
|
||||
# set it before creating genesis block
|
||||
# TD need to be some(0.u256) because it can be the genesis
|
||||
|
@ -150,16 +147,20 @@ proc init(com : CommonRef,
|
|||
# com.forkIdCalculator and com.genesisHash are set
|
||||
# by setForkId
|
||||
if genesis.isNil.not:
|
||||
com.hardForkTransition(ForkDeterminationInfo(
|
||||
number: 0.BlockNumber,
|
||||
td: Opt.some(0.u256),
|
||||
time: Opt.some(genesis.timestamp)
|
||||
))
|
||||
let
|
||||
forkDeterminer = ForkDeterminationInfo(
|
||||
number: 0.BlockNumber,
|
||||
td: Opt.some(0.u256),
|
||||
time: Opt.some(genesis.timestamp)
|
||||
)
|
||||
fork = toHardFork(com.forkTransitionTable, forkDeterminer)
|
||||
|
||||
com.consensusTransition(fork)
|
||||
|
||||
# Must not overwrite the global state on the single state DB
|
||||
if not db.getBlockHeader(0.BlockNumber, com.genesisHeader):
|
||||
com.genesisHeader = toGenesisHeader(genesis,
|
||||
com.currentFork, com.db)
|
||||
fork, com.db)
|
||||
|
||||
com.setForkId(com.genesisHeader)
|
||||
com.pos.timestamp = genesis.timestamp
|
||||
|
@ -245,7 +246,6 @@ func clone*(com: CommonRef, db: CoreDbRef): CommonRef =
|
|||
genesisHeader: com.genesisHeader,
|
||||
syncProgress : com.syncProgress,
|
||||
networkId : com.networkId,
|
||||
currentFork : com.currentFork,
|
||||
consensusType: com.consensusType,
|
||||
pos : com.pos,
|
||||
pruneHistory : com.pruneHistory)
|
||||
|
@ -270,7 +270,6 @@ func hardForkTransition(
|
|||
## Same thing happen before London block, TD can be ignored.
|
||||
|
||||
let fork = com.toHardFork(forkDeterminer)
|
||||
com.currentFork = fork
|
||||
com.consensusTransition(fork)
|
||||
|
||||
func hardForkTransition*(
|
||||
|
@ -299,24 +298,16 @@ func toEVMFork*(com: CommonRef, forkDeterminer: ForkDeterminationInfo): EVMFork
|
|||
let fork = com.toHardFork(forkDeterminer)
|
||||
ToEVMFork[fork]
|
||||
|
||||
func toEVMFork*(com: CommonRef): EVMFork =
|
||||
ToEVMFork[com.currentFork]
|
||||
|
||||
func isSpuriousOrLater*(com: CommonRef, number: BlockNumber): bool =
|
||||
com.toHardFork(number.forkDeterminationInfo) >= Spurious
|
||||
|
||||
func isByzantiumOrLater*(com: CommonRef, number: BlockNumber): bool =
|
||||
com.toHardFork(number.forkDeterminationInfo) >= Byzantium
|
||||
|
||||
func isLondonOrLater*(com: CommonRef, number: BlockNumber): bool =
|
||||
# TODO: Fixme, use only London comparator
|
||||
com.toHardFork(number.forkDeterminationInfo) >= London
|
||||
|
||||
func forkGTE*(com: CommonRef, fork: HardFork): bool =
|
||||
com.currentFork >= fork
|
||||
|
||||
# TODO: move this consensus code to where it belongs
|
||||
func minerAddress*(com: CommonRef; header: BlockHeader): EthAddress =
|
||||
# POW and POS return header.coinbase
|
||||
return header.coinbase
|
||||
|
||||
func forkId*(com: CommonRef, head, time: uint64): ForkID {.gcsafe.} =
|
||||
## EIP 2364/2124
|
||||
com.forkIdCalculator.newID(head, time)
|
||||
|
@ -432,9 +423,6 @@ func chainId*(com: CommonRef): ChainId =
|
|||
func networkId*(com: CommonRef): NetworkId =
|
||||
com.networkId
|
||||
|
||||
func blockReward*(com: CommonRef): UInt256 =
|
||||
BlockRewards[com.currentFork]
|
||||
|
||||
func genesisHash*(com: CommonRef): Hash256 =
|
||||
## Getter
|
||||
com.genesisHash
|
||||
|
@ -475,12 +463,6 @@ func setTTD*(com: CommonRef, ttd: Opt[DifficultyInt]) =
|
|||
# rebuild the MergeFork piece of the forkTransitionTable
|
||||
com.forkTransitionTable.mergeForkTransitionThreshold = com.config.mergeForkTransitionThreshold
|
||||
|
||||
func setFork*(com: CommonRef, fork: HardFork): HardFork =
|
||||
## useful for testing
|
||||
result = com.currentFork
|
||||
com.currentFork = fork
|
||||
com.consensusTransition(fork)
|
||||
|
||||
func `syncReqNewHead=`*(com: CommonRef; cb: SyncReqNewHeadCB) =
|
||||
## Activate or reset a call back handler for syncing.
|
||||
com.syncReqNewHead = cb
|
||||
|
|
|
@ -318,40 +318,6 @@ const
|
|||
FkPrague, # Prague
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Block reward helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func eth(n: int): UInt256 {.compileTime.} =
|
||||
n.u256 * pow(10.u256, 18)
|
||||
|
||||
const
|
||||
eth5 = 5.eth
|
||||
eth3 = 3.eth
|
||||
eth2 = 2.eth
|
||||
eth0 = 0.u256
|
||||
|
||||
BlockRewards*: array[HardFork, UInt256] = [
|
||||
eth5, # Frontier
|
||||
eth5, # Homestead
|
||||
eth5, # DAOFork
|
||||
eth5, # Tangerine
|
||||
eth5, # Spurious
|
||||
eth3, # Byzantium
|
||||
eth2, # Constantinople
|
||||
eth2, # Petersburg
|
||||
eth2, # Istanbul
|
||||
eth2, # MuirGlacier
|
||||
eth2, # Berlin
|
||||
eth2, # London
|
||||
eth2, # ArrowGlacier
|
||||
eth2, # GrayGlacier
|
||||
eth0, # MergeFork
|
||||
eth0, # Shanghai
|
||||
eth0, # Cancun
|
||||
eth0, # Prague
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Fork ID helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -134,7 +134,7 @@ func validateEip4844Header*(
|
|||
com: CommonRef, header, parentHeader: BlockHeader,
|
||||
txs: openArray[Transaction]): Result[void, string] {.raises: [].} =
|
||||
|
||||
if not com.forkGTE(Cancun):
|
||||
if not com.isCancunOrLater(header.timestamp):
|
||||
if header.blobGasUsed.isSome:
|
||||
return err("unexpected EIP-4844 blobGasUsed in block header")
|
||||
|
||||
|
|
|
@ -16,9 +16,39 @@ import
|
|||
|
||||
{.push raises: [].}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Block reward helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
func eth(n: int): UInt256 {.compileTime.} =
|
||||
n.u256 * pow(10.u256, 18)
|
||||
|
||||
const
|
||||
eth5 = 5.eth
|
||||
eth3 = 3.eth
|
||||
eth2 = 2.eth
|
||||
eth0 = 0.u256
|
||||
|
||||
BlockRewards: array[EVMFork, UInt256] = [
|
||||
eth5, # Frontier
|
||||
eth5, # Homestead
|
||||
eth5, # Tangerine
|
||||
eth5, # Spurious
|
||||
eth3, # Byzantium
|
||||
eth2, # Constantinople
|
||||
eth2, # Petersburg
|
||||
eth2, # Istanbul
|
||||
eth2, # Berlin
|
||||
eth2, # London
|
||||
eth0, # Paris
|
||||
eth0, # Shanghai
|
||||
eth0, # Cancun
|
||||
eth0, # Prague
|
||||
]
|
||||
|
||||
proc calculateReward*(vmState: BaseVMState; account: EthAddress;
|
||||
number: BlockNumber; uncles: openArray[BlockHeader]) =
|
||||
let blockReward = vmState.com.blockReward()
|
||||
let blockReward = BlockRewards[vmState.fork]
|
||||
var mainReward = blockReward
|
||||
|
||||
for uncle in uncles:
|
||||
|
|
|
@ -49,7 +49,7 @@ func createBloom*(receipts: openArray[Receipt]): Bloom =
|
|||
proc makeReceipt*(vmState: BaseVMState; txType: TxType): Receipt =
|
||||
|
||||
var rec: Receipt
|
||||
if vmState.com.forkGTE(Byzantium):
|
||||
if vmState.com.isByzantiumOrLater(vmState.blockNumber):
|
||||
rec.isHash = false
|
||||
rec.status = vmState.status
|
||||
else:
|
||||
|
|
|
@ -648,13 +648,13 @@ proc assembleBlock*(
|
|||
blobsBundle.blobs.add blob
|
||||
|
||||
let com = xp.chain.com
|
||||
if com.forkGTE(Shanghai):
|
||||
if com.isShanghaiOrLater(blk.header.timestamp):
|
||||
blk.withdrawals = Opt.some(com.pos.withdrawals)
|
||||
|
||||
if not com.forkGTE(Cancun) and blobsBundle.commitments.len > 0:
|
||||
if not com.isCancunOrLater(blk.header.timestamp) and blobsBundle.commitments.len > 0:
|
||||
return err("PooledTransaction contains blobs prior to Cancun")
|
||||
let blobsBundleOpt =
|
||||
if com.forkGTE(Cancun):
|
||||
if com.isCancunOrLater(blk.header.timestamp):
|
||||
doAssert blobsBundle.commitments.len == blobsBundle.blobs.len
|
||||
doAssert blobsBundle.proofs.len == blobsBundle.blobs.len
|
||||
Opt.some blobsBundle
|
||||
|
|
|
@ -194,10 +194,10 @@ proc getHeader*(dh: TxChainRef): BlockHeader
|
|||
blobGasUsed: dh.txEnv.blobGasUsed,
|
||||
excessBlobGas: dh.txEnv.excessBlobGas)
|
||||
|
||||
if dh.com.forkGTE(Shanghai):
|
||||
if dh.com.isShanghaiOrLater(result.timestamp):
|
||||
result.withdrawalsRoot = Opt.some(calcWithdrawalsRoot(dh.com.pos.withdrawals))
|
||||
|
||||
if dh.com.forkGTE(Cancun):
|
||||
if dh.com.isCancunOrLater(result.timestamp):
|
||||
result.parentBeaconBlockRoot = Opt.some(dh.com.pos.parentBeaconBlockRoot)
|
||||
|
||||
dh.prepareForSeal(result)
|
||||
|
|
|
@ -253,7 +253,7 @@ proc vmExecCommit(pst: TxPackerStateRef)
|
|||
raiseAssert "vmExecCommit(): state() failed " & $$error
|
||||
xp.chain.stateRoot = vmState.stateDB.rootHash
|
||||
|
||||
if vmState.com.forkGTE(Cancun):
|
||||
if xp.chain.nextFork >= FkCancun:
|
||||
# EIP-4844
|
||||
xp.chain.excessBlobGas = Opt.some(vmState.blockCtx.excessBlobGas)
|
||||
xp.chain.blobGasUsed = Opt.some(vmState.blobGasUsed)
|
||||
|
|
|
@ -16,7 +16,7 @@ import results, ../common/common
|
|||
proc validateWithdrawals*(
|
||||
com: CommonRef, header: BlockHeader, withdrawals: Opt[seq[Withdrawal]]
|
||||
): Result[void, string] =
|
||||
if com.forkGTE(Shanghai):
|
||||
if com.isShanghaiOrLater(header.timestamp):
|
||||
if header.withdrawalsRoot.isNone:
|
||||
return err("Post-Shanghai block header must have withdrawalsRoot")
|
||||
elif withdrawals.isNone:
|
||||
|
|
|
@ -54,7 +54,7 @@ func blockCtx(com: CommonRef, header: BlockHeader):
|
|||
baseFeePerGas: header.baseFeePerGas,
|
||||
prevRandao : header.prevRandao,
|
||||
difficulty : header.difficulty,
|
||||
coinbase : com.minerAddress(header),
|
||||
coinbase : header.coinbase,
|
||||
excessBlobGas: header.excessBlobGas.get(0'u64),
|
||||
)
|
||||
|
||||
|
@ -225,22 +225,22 @@ proc init*(
|
|||
tracer = tracer)
|
||||
return true
|
||||
|
||||
proc coinbase*(vmState: BaseVMState): EthAddress =
|
||||
func coinbase*(vmState: BaseVMState): EthAddress =
|
||||
vmState.blockCtx.coinbase
|
||||
|
||||
proc blockNumber*(vmState: BaseVMState): BlockNumber =
|
||||
func blockNumber*(vmState: BaseVMState): BlockNumber =
|
||||
# it should return current block number
|
||||
# and not head.number
|
||||
vmState.parent.number + 1
|
||||
|
||||
proc difficultyOrPrevRandao*(vmState: BaseVMState): UInt256 =
|
||||
func difficultyOrPrevRandao*(vmState: BaseVMState): UInt256 =
|
||||
if vmState.com.consensus == ConsensusType.POS:
|
||||
# EIP-4399/EIP-3675
|
||||
UInt256.fromBytesBE(vmState.blockCtx.prevRandao.data)
|
||||
else:
|
||||
vmState.blockCtx.difficulty
|
||||
|
||||
proc baseFeePerGas*(vmState: BaseVMState): UInt256 =
|
||||
func baseFeePerGas*(vmState: BaseVMState): UInt256 =
|
||||
vmState.blockCtx.baseFeePerGas.get(0.u256)
|
||||
|
||||
method getAncestorHash*(
|
||||
|
|
|
@ -566,52 +566,16 @@ method handleNewBlock*(ctx: EthWireRef,
|
|||
totalDifficulty: DifficultyInt):
|
||||
Result[void, string]
|
||||
{.gcsafe.} =
|
||||
if ctx.enableTxPool != Enabled:
|
||||
when trMissingOrDisabledGossipOk:
|
||||
notEnabled("handleNewBlock")
|
||||
return ok()
|
||||
try:
|
||||
if ctx.chain.com.forkGTE(MergeFork):
|
||||
debug "Dropping peer for sending NewBlock after merge (EIP-3675)",
|
||||
peer, blockNumber=blk.header.number,
|
||||
blockHash=blk.header.blockHash, totalDifficulty
|
||||
asyncSpawn banPeer(ctx.peerPool, peer, PEER_LONG_BANTIME)
|
||||
return ok()
|
||||
|
||||
if not ctx.newBlockHandler.handler.isNil:
|
||||
ctx.newBlockHandler.handler(
|
||||
ctx.newBlockHandler.arg,
|
||||
peer, blk, totalDifficulty
|
||||
)
|
||||
return ok()
|
||||
except CatchableError as exc:
|
||||
return err(exc.msg)
|
||||
# We dropped support for non-merge networks
|
||||
err("block broadcasts disallowed")
|
||||
|
||||
method handleNewBlockHashes*(ctx: EthWireRef,
|
||||
peer: Peer,
|
||||
hashes: openArray[NewBlockHashesAnnounce]):
|
||||
Result[void, string]
|
||||
{.gcsafe.} =
|
||||
if ctx.enableTxPool != Enabled:
|
||||
when trMissingOrDisabledGossipOk:
|
||||
notEnabled("handleNewBlockHashes")
|
||||
return ok()
|
||||
try:
|
||||
if ctx.chain.com.forkGTE(MergeFork):
|
||||
debug "Dropping peer for sending NewBlockHashes after merge (EIP-3675)",
|
||||
peer, numHashes=hashes.len
|
||||
asyncSpawn banPeer(ctx.peerPool, peer, PEER_LONG_BANTIME)
|
||||
return ok()
|
||||
|
||||
if not ctx.newBlockHashesHandler.handler.isNil:
|
||||
ctx.newBlockHashesHandler.handler(
|
||||
ctx.newBlockHashesHandler.arg,
|
||||
peer,
|
||||
hashes
|
||||
)
|
||||
return ok()
|
||||
except CatchableError as exc:
|
||||
return err(exc.msg)
|
||||
# We dropped support for non-merge networks
|
||||
err("block announcements disallowed")
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
|
|
|
@ -59,6 +59,7 @@ proc assignTime(c: ChainConfig, transitionFork: HardFork, t: EthTime) =
|
|||
let table = createForkTransitionTable(transitionFork,
|
||||
Opt.none(BlockNumber), Opt.some(t), Opt.none(DifficultyInt))
|
||||
c.populateFromForkTransitionTable(table)
|
||||
c.terminalTotalDifficulty = Opt.some(0.u256)
|
||||
|
||||
func getChainConfig*(network: string, c: ChainConfig) =
|
||||
c.daoForkSupport = false
|
||||
|
@ -110,6 +111,7 @@ func getChainConfig*(network: string, c: ChainConfig) =
|
|||
c.assignNumber(HardFork.GrayGlacier, BlockNumberZero)
|
||||
of $TestFork.Merge, $TestFork.Paris:
|
||||
c.assignNumber(HardFork.MergeFork, BlockNumberZero)
|
||||
c.terminalTotalDifficulty = Opt.some(0.u256)
|
||||
of $TestFork.ArrowGlacierToParisAtDiffC0000:
|
||||
c.assignNumber(HardFork.GrayGlacier, BlockNumberZero)
|
||||
c.terminalTotalDifficulty = Opt.some(0xC0000.u256)
|
||||
|
|
|
@ -299,7 +299,6 @@ proc exec(ctx: var TransContext,
|
|||
vmState.stateDB.addBalance(withdrawal.address, withdrawal.weiAmount)
|
||||
|
||||
let miner = ctx.env.currentCoinbase
|
||||
let fork = vmState.com.toEVMFork
|
||||
coinbaseStateClearing(vmState, miner, stateReward.isSome())
|
||||
|
||||
let stateDB = vmState.stateDB
|
||||
|
@ -320,7 +319,7 @@ proc exec(ctx: var TransContext,
|
|||
withdrawalsRoot : header.withdrawalsRoot
|
||||
)
|
||||
|
||||
if fork >= FkCancun:
|
||||
if vmState.com.isCancunOrLater(ctx.env.currentTimestamp):
|
||||
result.result.blobGasUsed = Opt.some vmState.blobGasUsed
|
||||
if ctx.env.currentExcessBlobGas.isSome:
|
||||
result.result.currentExcessBlobGas = ctx.env.currentExcessBlobGas
|
||||
|
@ -459,7 +458,9 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
|
|||
# un-set it if it has been set too early
|
||||
ctx.env.parentBeaconBlockRoot = Opt.none(Hash256)
|
||||
|
||||
if com.forkGTE(MergeFork):
|
||||
let isMerged = config.terminalTotalDifficulty.isSome and
|
||||
config.terminalTotalDifficulty.value == 0.u256
|
||||
if isMerged:
|
||||
if ctx.env.currentRandom.isNone:
|
||||
raise newError(ErrorConfig, "post-merge requires currentRandom to be defined in env")
|
||||
|
||||
|
|
Loading…
Reference in New Issue