Fix ForkID calculation
This commit is contained in:
parent
6e59cccc5b
commit
0ee448c1eb
|
@ -262,10 +262,6 @@ proc toHardFork*(map: ForkTransitionTable, forkDeterminer: ForkDeterminationInfo
|
|||
# should always have a match
|
||||
doAssert(false, "unreachable code")
|
||||
|
||||
func forkDeterminationInfoForHeader*(header: BlockHeader): ForkDeterminationInfo =
|
||||
# FIXME-Adam-mightAlsoNeedTTD?
|
||||
forkDeterminationInfo(header.blockNumber, header.timestamp)
|
||||
|
||||
proc validateChainConfig*(conf: ChainConfig): bool =
|
||||
result = true
|
||||
|
||||
|
@ -448,6 +444,7 @@ proc chainConfigForNetwork*(id: NetworkId): ChainConfig =
|
|||
muirGlacierBlock: some(0.toBlockNumber),
|
||||
berlinBlock: some(0.toBlockNumber),
|
||||
londonBlock: some(0.toBlockNumber),
|
||||
mergeForkBlock: some(1735371.toBlockNumber),
|
||||
terminalTotalDifficulty: some(sepoliaTTD),
|
||||
shanghaiTime: some(1_677_557_088.EthTime)
|
||||
)
|
||||
|
|
|
@ -58,7 +58,7 @@ type
|
|||
forkTransitionTable: ForkTransitionTable
|
||||
|
||||
# Eth wire protocol need this
|
||||
forkIds: array[HardFork, ForkID]
|
||||
forkIdCalculator: ForkIdCalculator
|
||||
networkId: NetworkId
|
||||
|
||||
# synchronizer need this
|
||||
|
@ -117,10 +117,13 @@ proc consensusTransition(com: CommonRef, fork: HardFork) =
|
|||
# this could happen during reorg
|
||||
com.consensusType = com.config.consensusType
|
||||
|
||||
proc setForkId(com: CommonRef, blockZero: BlockHeader) =
|
||||
com.genesisHash = blockZero.blockHash
|
||||
proc setForkId(com: CommonRef, genesis: BlockHeader) =
|
||||
com.genesisHash = genesis.blockHash
|
||||
let genesisCRC = crc32(0, com.genesisHash.data)
|
||||
com.forkIds = calculateForkIds(com.config, genesisCRC)
|
||||
com.forkIdCalculator = initForkIdCalculator(
|
||||
com.forkTransitionTable,
|
||||
genesisCRC,
|
||||
genesis.timestamp.uint64)
|
||||
|
||||
proc daoCheck(conf: ChainConfig) =
|
||||
if not conf.daoForkSupport or conf.daoForkBlock.isNone:
|
||||
|
@ -160,7 +163,7 @@ proc init(com : CommonRef,
|
|||
# already at the MergeFork
|
||||
const TimeZero = EthTime(0)
|
||||
|
||||
# com.forkIds and com.blockZeroHash is set
|
||||
# com.forkIdCalculator and com.genesisHash are set
|
||||
# by setForkId
|
||||
if genesis.isNil.not:
|
||||
com.hardForkTransition(ForkDeterminationInfo(
|
||||
|
@ -246,7 +249,7 @@ proc clone*(com: CommonRef, db: CoreDbRef): CommonRef =
|
|||
pruneTrie : com.pruneTrie,
|
||||
config : com.config,
|
||||
forkTransitionTable: com.forkTransitionTable,
|
||||
forkIds : com.forkIds,
|
||||
forkIdCalculator: com.forkIdCalculator,
|
||||
genesisHash : com.genesisHash,
|
||||
genesisHeader: com.genesisHeader,
|
||||
syncProgress : com.syncProgress,
|
||||
|
@ -315,7 +318,7 @@ func toEVMFork*(com: CommonRef): EVMFork =
|
|||
|
||||
func isLondon*(com: CommonRef, number: BlockNumber): bool =
|
||||
# TODO: Fixme, use only London comparator
|
||||
com.toHardFork(number.blockNumberToForkDeterminationInfo) >= London
|
||||
com.toHardFork(number.forkDeterminationInfo) >= London
|
||||
|
||||
func isLondon*(com: CommonRef, number: BlockNumber, timestamp: EthTime): bool =
|
||||
# TODO: Fixme, use only London comparator
|
||||
|
@ -339,10 +342,13 @@ proc minerAddress*(com: CommonRef; header: BlockHeader): EthAddress
|
|||
|
||||
account.value
|
||||
|
||||
func forkId*(com: CommonRef, forkDeterminer: ForkDeterminationInfo): ForkID {.gcsafe.} =
|
||||
func forkId*(com: CommonRef, head, time: uint64): ForkID {.gcsafe.} =
|
||||
## EIP 2364/2124
|
||||
let fork = com.toHardFork(forkDeterminer)
|
||||
com.forkIds[fork]
|
||||
com.forkIdCalculator.newID(head, time)
|
||||
|
||||
func forkId*(com: CommonRef, head: BlockNumber, time: EthTime): ForkID {.gcsafe.} =
|
||||
## EIP 2364/2124
|
||||
com.forkIdCalculator.newID(head.truncate(uint64), time.uint64)
|
||||
|
||||
func isEIP155*(com: CommonRef, number: BlockNumber): bool =
|
||||
com.config.eip155Block.isSome and number >= com.config.eip155Block.get
|
||||
|
|
|
@ -84,13 +84,13 @@ type
|
|||
# is because it's perfectly fine, if mergeForkBlock is
|
||||
# set, to not bother with TTD anymore. But I'm not sure
|
||||
# it makes sense to allow time to be optional. See the
|
||||
# comment below on blockNumberToForkDeterminationInfo.
|
||||
# comment below on forkDeterminationInfo.
|
||||
ForkDeterminationInfo* = object
|
||||
blockNumber*: BlockNumber
|
||||
time*: Option[EthTime]
|
||||
td*: Option[DifficultyInt]
|
||||
|
||||
func blockNumberToForkDeterminationInfo*(n: BlockNumber): ForkDeterminationInfo =
|
||||
func forkDeterminationInfo*(n: BlockNumber): ForkDeterminationInfo =
|
||||
# FIXME: All callers of this function are suspect; I'm guess we should
|
||||
# always be using both block number and time. But we have a few places,
|
||||
# like various tests, where we only have block number and the tests are
|
||||
|
@ -104,6 +104,10 @@ func forkDeterminationInfo*(n: BlockNumber, t: EthTime): ForkDeterminationInfo =
|
|||
func forkDeterminationInfoIncludingTd*(n: BlockNumber, t: EthTime, td: DifficultyInt): ForkDeterminationInfo =
|
||||
ForkDeterminationInfo(blockNumber: n, time: some(t), td: some(td))
|
||||
|
||||
func forkDeterminationInfo*(header: BlockHeader): ForkDeterminationInfo =
|
||||
# FIXME-Adam-mightAlsoNeedTTD?
|
||||
forkDeterminationInfo(header.blockNumber, header.timestamp)
|
||||
|
||||
proc adjustForNextBlock*(n: BlockNumber): BlockNumber =
|
||||
n + 1
|
||||
|
||||
|
@ -343,72 +347,74 @@ const
|
|||
# ------------------------------------------------------------------------------
|
||||
# Fork ID helpers
|
||||
# ------------------------------------------------------------------------------
|
||||
type
|
||||
ForkIdCalculator* = object
|
||||
byBlock: seq[uint64]
|
||||
byTime: seq[uint64]
|
||||
genesisCRC: uint32
|
||||
|
||||
func toNextFork(n: Option[BlockNumber]): uint64 =
|
||||
if n.isSome:
|
||||
n.get.truncate(uint64)
|
||||
else:
|
||||
0'u64
|
||||
func newID*(calc: ForkIdCalculator, head, time: uint64): ForkID =
|
||||
var hash = calc.genesisCRC
|
||||
for fork in calc.byBlock:
|
||||
if fork <= head:
|
||||
# Fork already passed, checksum the previous hash and the fork number
|
||||
hash = crc32(hash, fork.toBytesBE)
|
||||
continue
|
||||
return (hash, fork)
|
||||
|
||||
# EIP-6122: ForkID now works with timestamps too.
|
||||
func toNextFork(t: Option[EthTime]): uint64 =
|
||||
if t.isSome:
|
||||
t.get.uint64
|
||||
else:
|
||||
0'u64
|
||||
for fork in calc.byTime:
|
||||
if fork <= time:
|
||||
# Fork already passed, checksum the previous hash and fork timestamp
|
||||
hash = crc32(hash, fork.toBytesBE)
|
||||
continue
|
||||
return (hash, fork)
|
||||
|
||||
func arrayMappingHardForkToNextFork(c: ChainConfig): array[HardFork, uint64] =
|
||||
return [
|
||||
0'u64,
|
||||
toNextFork(c.homesteadBlock),
|
||||
toNextFork(c.daoForkBlock),
|
||||
toNextFork(c.eip150Block),
|
||||
toNextFork(c.eip158Block),
|
||||
toNextFork(c.byzantiumBlock),
|
||||
toNextFork(c.constantinopleBlock),
|
||||
toNextFork(c.petersburgBlock),
|
||||
toNextFork(c.istanbulBlock),
|
||||
toNextFork(c.muirGlacierBlock),
|
||||
toNextFork(c.berlinBlock),
|
||||
toNextFork(c.londonBlock),
|
||||
toNextFork(c.arrowGlacierBlock),
|
||||
toNextFork(c.grayGlacierBlock),
|
||||
toNextFork(c.mergeForkBlock),
|
||||
toNextFork(c.shanghaiTime),
|
||||
toNextFork(c.cancunTime),
|
||||
]
|
||||
(hash, 0'u64)
|
||||
|
||||
func getNextFork(next: array[HardFork, uint64], fork: HardFork): uint64 =
|
||||
if fork == high(HardFork):
|
||||
result = 0
|
||||
return
|
||||
func initForkIdCalculator*(map: ForkTransitionTable,
|
||||
genesisCRC: uint32,
|
||||
genesisTime: uint64): ForkIdCalculator =
|
||||
|
||||
result = next[fork]
|
||||
for x in fork..high(HardFork):
|
||||
if result != next[x]:
|
||||
result = next[x]
|
||||
break
|
||||
# Extract the fork rule block number aggregate it
|
||||
var forksByBlock: seq[uint64]
|
||||
for fork, val in map.blockNumberThresholds:
|
||||
if val.isNone: continue
|
||||
let val64 = val.get.truncate(uint64)
|
||||
if forksByBlock.len == 0:
|
||||
forksByBlock.add val64
|
||||
elif forksByBlock[^1] != val64:
|
||||
# Deduplicate fork identifiers applying multiple forks
|
||||
forksByBlock.add val64
|
||||
|
||||
func calculateForkId(next: array[HardFork, uint64], fork: HardFork,
|
||||
prevCRC: uint32, prevFork: uint64): ForkID =
|
||||
result.nextFork = getNextFork(next, fork)
|
||||
if map.mergeForkTransitionThreshold.blockNumber.isSome:
|
||||
let val64 = map.mergeForkTransitionThreshold.blockNumber.get.truncate(uint64)
|
||||
if forksByBlock.len == 0:
|
||||
forksByBlock.add val64
|
||||
elif forksByBlock[^1] != val64:
|
||||
# Deduplicate fork identifiers applying multiple forks
|
||||
forksByBlock.add val64
|
||||
|
||||
if result.nextFork != prevFork:
|
||||
result.crc = crc32(prevCRC, toBytesBE(prevFork))
|
||||
else:
|
||||
result.crc = prevCRC
|
||||
# Skip any forks in block 0, that's the genesis ruleset
|
||||
if forksByBlock.len > 0 and forksByBlock[0] == 0:
|
||||
forksByBlock.delete(0)
|
||||
|
||||
func calculateForkIds*(c: ChainConfig,
|
||||
genesisCRC: uint32): array[HardFork, ForkID] =
|
||||
let next = arrayMappingHardForkToNextFork(c)
|
||||
# Extract the fork rule timestamp number aggregate it
|
||||
var forksByTime: seq[uint64]
|
||||
for fork, val in map.timeThresholds:
|
||||
if val.isNone: continue
|
||||
let val64 = val.get.uint64
|
||||
if forksByTime.len == 0:
|
||||
forksByTime.add val64
|
||||
elif forksByTime[^1] != val64:
|
||||
forksByTime.add val64
|
||||
|
||||
var prevCRC = genesisCRC
|
||||
var prevFork = getNextFork(next, Frontier)
|
||||
# Skip any forks before genesis.
|
||||
while forksByTime.len > 0 and forksByTime[0] <= genesisTime:
|
||||
forksByTime.delete(0)
|
||||
|
||||
for fork in HardFork:
|
||||
result[fork] = calculateForkId(next, fork, prevCRC, prevFork)
|
||||
prevFork = result[fork].nextFork
|
||||
prevCRC = result[fork].crc
|
||||
result.genesisCRC = genesisCRC
|
||||
result.byBlock = system.move(forksByBlock)
|
||||
result.byTime = system.move(forksByTime)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# End
|
||||
|
|
|
@ -182,7 +182,7 @@ proc asyncProcessTransaction*(
|
|||
{.async, gcsafe.} =
|
||||
## Variant of `asyncProcessTransaction()` with `*fork* derived
|
||||
## from the `vmState` argument.
|
||||
let fork = vmState.com.toEVMFork(header.forkDeterminationInfoForHeader)
|
||||
let fork = vmState.com.toEVMFork(header.forkDeterminationInfo)
|
||||
return await vmState.asyncProcessTransaction(tx, sender, header, fork)
|
||||
|
||||
proc processTransaction*(
|
||||
|
|
|
@ -171,7 +171,7 @@ template calcDifficultyGrayGlacier*(timeStamp: EthTime, parent: BlockHeader): Di
|
|||
makeDifficultyCalculator(11_400_000, timeStamp, parent)
|
||||
|
||||
func calcDifficulty*(com: CommonRef, timeStamp: EthTime, parent: BlockHeader): DifficultyInt =
|
||||
let next = com.toHardFork(parent.forkDeterminationInfoForHeader.adjustForNextBlock)
|
||||
let next = com.toHardFork(parent.forkDeterminationInfo.adjustForNextBlock)
|
||||
if next >= GrayGlacier:
|
||||
result = calcDifficultyGrayGlacier(timeStamp, parent)
|
||||
elif next >= ArrowGlacier:
|
||||
|
|
|
@ -35,7 +35,7 @@ proc baseFeeGet*(com: CommonRef; parent: BlockHeader): GasPrice =
|
|||
|
||||
# Note that the baseFee is calculated for the next header
|
||||
let
|
||||
forkDeterminer = forkDeterminationInfoForHeader(parent)
|
||||
forkDeterminer = forkDeterminationInfo(parent)
|
||||
parentFork = com.toEVMFork(forkDeterminer)
|
||||
nextFork = com.toEVMFork(forkDeterminer.adjustForNextBlock)
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ method getStatus*(ctx: EthWireRef): EthState
|
|||
db = ctx.db
|
||||
com = ctx.chain.com
|
||||
bestBlock = db.getCanonicalHead()
|
||||
forkId = com.forkId(bestBlock.forkDeterminationInfoForHeader)
|
||||
forkId = com.forkId(bestBlock.blockNumber, bestBlock.timestamp)
|
||||
|
||||
EthState(
|
||||
totalDifficulty: db.headTotalDifficulty,
|
||||
|
@ -400,7 +400,7 @@ method getStatus*(ctx: EthWireRef): EthState
|
|||
bestBlockHash: bestBlock.blockHash,
|
||||
forkId: ChainForkId(
|
||||
forkHash: forkId.crc.toBytesBE,
|
||||
forkNext: forkId.nextFork.toBlockNumber
|
||||
forkNext: forkId.nextFork
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ type
|
|||
|
||||
ChainForkId* = object
|
||||
forkHash*: array[4, byte] # The RLP encoding must be exactly 4 bytes.
|
||||
forkNext*: BlockNumber # The RLP encoding must be variable-length
|
||||
forkNext*: uint64 # The RLP encoding must be variable-length
|
||||
|
||||
EthWireBase* = ref object of RootRef
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ proc genesisLoadRunner(noisy = true;
|
|||
params = params)
|
||||
|
||||
check mcom.ttd.get == sSpcs.termTotalDff
|
||||
check mcom.toHardFork(sSpcs.mergeFork.toBlockNumber.blockNumberToForkDeterminationInfo) == MergeFork
|
||||
check mcom.toHardFork(sSpcs.mergeFork.toBlockNumber.forkDeterminationInfo) == MergeFork
|
||||
|
||||
test &"Construct persistent ChainDBRef on {tmpDir}, {persistPruneInfo}":
|
||||
# Before allocating the database, the data directory needs to be
|
||||
|
@ -229,7 +229,7 @@ proc genesisLoadRunner(noisy = true;
|
|||
params = params)
|
||||
|
||||
check dcom.ttd.get == sSpcs.termTotalDff
|
||||
check dcom.toHardFork(sSpcs.mergeFork.toBlockNumber.blockNumberToForkDeterminationInfo) == MergeFork
|
||||
check dcom.toHardFork(sSpcs.mergeFork.toBlockNumber.forkDeterminationInfo) == MergeFork
|
||||
|
||||
test "Initialise in-memory Genesis":
|
||||
mcom.initializeEmptyDb
|
||||
|
|
|
@ -1,47 +1,60 @@
|
|||
import
|
||||
unittest2,
|
||||
../nimbus/common/common
|
||||
../nimbus/common/common,
|
||||
../nimbus/utils/utils
|
||||
|
||||
const
|
||||
MainNetIDs = [
|
||||
(blockNumber: 0'u64, id: (crc: 0xfc64ec04'u32, nextFork: 1150000'u64)), # Unsynced
|
||||
(blockNumber: 1149999'u64, id: (crc: 0xfc64ec04'u32, nextFork: 1150000'u64)), # Last Frontier block
|
||||
(blockNumber: 1150000'u64, id: (crc: 0x97c2c34c'u32, nextFork: 1920000'u64)), # First Homestead block
|
||||
(blockNumber: 1919999'u64, id: (crc: 0x97c2c34c'u32, nextFork: 1920000'u64)), # Last Homestead block
|
||||
(blockNumber: 1920000'u64, id: (crc: 0x91d1f948'u32, nextFork: 2463000'u64)), # First DAO block
|
||||
(blockNumber: 2462999'u64, id: (crc: 0x91d1f948'u32, nextFork: 2463000'u64)), # Last DAO block
|
||||
(blockNumber: 2463000'u64, id: (crc: 0x7a64da13'u32, nextFork: 2675000'u64)), # First Tangerine block
|
||||
(blockNumber: 2674999'u64, id: (crc: 0x7a64da13'u32, nextFork: 2675000'u64)), # Last Tangerine block
|
||||
(blockNumber: 2675000'u64, id: (crc: 0x3edd5b10'u32, nextFork: 4370000'u64)), # First Spurious block
|
||||
(blockNumber: 4369999'u64, id: (crc: 0x3edd5b10'u32, nextFork: 4370000'u64)), # Last Spurious block
|
||||
(blockNumber: 4370000'u64, id: (crc: 0xa00bc324'u32, nextFork: 7280000'u64)), # First Byzantium block
|
||||
(blockNumber: 7279999'u64, id: (crc: 0xa00bc324'u32, nextFork: 7280000'u64)), # Last Byzantium block
|
||||
(blockNumber: 7280000'u64, id: (crc: 0x668db0af'u32, nextFork: 9069000'u64)), # First and last Constantinople, first Petersburg block
|
||||
(blockNumber: 7987396'u64, id: (crc: 0x668db0af'u32, nextFork: 9069000'u64)), # Past Petersburg block
|
||||
(blockNumber: 9068999'u64, id: (crc: 0x668db0af'u32, nextFork: 9069000'u64)), # Last Petersburg block
|
||||
(blockNumber: 9069000'u64, id: (crc: 0x879D6E30'u32, nextFork: 9200000'u64)), # First Istanbul block
|
||||
(blockNumber: 9199999'u64, id: (crc: 0x879D6E30'u32, nextFork: 9200000'u64)), # Last Istanbul block
|
||||
(blockNumber: 9200000'u64, id: (crc: 0xE029E991'u32, nextFork: 12244000'u64)), # First MuirGlacier block
|
||||
(blockNumber: 12243999'u64, id: (crc: 0xE029E991'u32, nextFork: 12244000'u64)), # Last MuirGlacier block
|
||||
(blockNumber: 12244000'u64, id: (crc: 0x0eb440f6'u32, nextFork: 12965000'u64)), # First Berlin block
|
||||
(blockNumber: 12964999'u64, id: (crc: 0x0eb440f6'u32, nextFork: 12965000'u64)), # Last Berlin block
|
||||
(blockNumber: 12965000'u64, id: (crc: 0xb715077d'u32, nextFork: 13773000'u64)), # First London block
|
||||
(blockNumber: 13772999'u64, id: (crc: 0xb715077d'u32, nextFork: 13773000'u64)), # Last London block
|
||||
(blockNumber: 13773000'u64, id: (crc: 0x20c327fc'u32, nextFork: 15050000'u64)), # First Arrow Glacier block
|
||||
(blockNumber: 15049999'u64, id: (crc: 0x20c327fc'u32, nextFork: 15050000'u64)), # Last Arrow Glacier block
|
||||
(blockNumber: 15050000'u64, id: (crc: 0xf0afd0e3'u32, nextFork: 0'u64)), # First Gray Glacier block
|
||||
(blockNumber: 20000000'u64, id: (crc: 0xf0afd0e3'u32, nextFork: 0'u64)), # Future Gray Glacier block
|
||||
(number: 0'u64 , time: 0'u64, id: (crc: 0xfc64ec04'u32, next: 1150000'u64)), # Unsynced
|
||||
(number: 1149999'u64 , time: 0'u64, id: (crc: 0xfc64ec04'u32, next: 1150000'u64)), # Last Frontier block
|
||||
(number: 1150000'u64 , time: 0'u64, id: (crc: 0x97c2c34c'u32, next: 1920000'u64)), # First Homestead block
|
||||
(number: 1919999'u64 , time: 0'u64, id: (crc: 0x97c2c34c'u32, next: 1920000'u64)), # Last Homestead block
|
||||
(number: 1920000'u64 , time: 0'u64, id: (crc: 0x91d1f948'u32, next: 2463000'u64)), # First DAO block
|
||||
(number: 2462999'u64 , time: 0'u64, id: (crc: 0x91d1f948'u32, next: 2463000'u64)), # Last DAO block
|
||||
(number: 2463000'u64 , time: 0'u64, id: (crc: 0x7a64da13'u32, next: 2675000'u64)), # First Tangerine block
|
||||
(number: 2674999'u64 , time: 0'u64, id: (crc: 0x7a64da13'u32, next: 2675000'u64)), # Last Tangerine block
|
||||
(number: 2675000'u64 , time: 0'u64, id: (crc: 0x3edd5b10'u32, next: 4370000'u64)), # First Spurious block
|
||||
(number: 4369999'u64 , time: 0'u64, id: (crc: 0x3edd5b10'u32, next: 4370000'u64)), # Last Spurious block
|
||||
(number: 4370000'u64 , time: 0'u64, id: (crc: 0xa00bc324'u32, next: 7280000'u64)), # First Byzantium block
|
||||
(number: 7279999'u64 , time: 0'u64, id: (crc: 0xa00bc324'u32, next: 7280000'u64)), # Last Byzantium block
|
||||
(number: 7280000'u64 , time: 0'u64, id: (crc: 0x668db0af'u32, next: 9069000'u64)), # First and last Constantinople, first Petersburg block
|
||||
(number: 7987396'u64 , time: 0'u64, id: (crc: 0x668db0af'u32, next: 9069000'u64)), # Past Petersburg block
|
||||
(number: 9068999'u64 , time: 0'u64, id: (crc: 0x668db0af'u32, next: 9069000'u64)), # Last Petersburg block
|
||||
(number: 9069000'u64 , time: 0'u64, id: (crc: 0x879D6E30'u32, next: 9200000'u64)), # First Istanbul block
|
||||
(number: 9199999'u64 , time: 0'u64, id: (crc: 0x879D6E30'u32, next: 9200000'u64)), # Last Istanbul block
|
||||
(number: 9200000'u64 , time: 0'u64, id: (crc: 0xE029E991'u32, next: 12244000'u64)), # First MuirGlacier block
|
||||
(number: 12243999'u64, time: 0'u64, id: (crc: 0xE029E991'u32, next: 12244000'u64)), # Last MuirGlacier block
|
||||
(number: 12244000'u64, time: 0'u64, id: (crc: 0x0eb440f6'u32, next: 12965000'u64)), # First Berlin block
|
||||
(number: 12964999'u64, time: 0'u64, id: (crc: 0x0eb440f6'u32, next: 12965000'u64)), # Last Berlin block
|
||||
(number: 12965000'u64, time: 0'u64, id: (crc: 0xb715077d'u32, next: 13773000'u64)), # First London block
|
||||
(number: 13772999'u64, time: 0'u64, id: (crc: 0xb715077d'u32, next: 13773000'u64)), # Last London block
|
||||
(number: 13773000'u64, time: 0'u64, id: (crc: 0x20c327fc'u32, next: 15050000'u64)), # First Arrow Glacier block
|
||||
(number: 15049999'u64, time: 0'u64, id: (crc: 0x20c327fc'u32, next: 15050000'u64)), # Last Arrow Glacier block
|
||||
(number: 15050000'u64, time: 0'u64, id: (crc: 0xf0afd0e3'u32, next: 1681338455'u64)), # First Gray Glacier block
|
||||
(number: 20000000'u64, time: 1681338454'u64, id: (crc: 0xf0afd0e3'u32, next: 1681338455'u64)), # Last Gray Glacier block
|
||||
(number: 20000000'u64, time: 1681338455'u64, id: (crc: 0xdce96c2d'u32, next: 0'u64)), # First Shanghai block
|
||||
(number: 30000000'u64, time: 2000000000'u64, id: (crc: 0xdce96c2d'u32, next: 0'u64)), # Future Shanghai block
|
||||
]
|
||||
|
||||
GoerliNetIDs = [
|
||||
(blockNumber: 0'u64, id: (crc: 0xa3f5ab08'u32, nextFork: 1561651'u64)), # Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block
|
||||
(blockNumber: 1561650'u64, id: (crc: 0xa3f5ab08'u32, nextFork: 1561651'u64)), # Last Petersburg block
|
||||
(blockNumber: 1561651'u64, id: (crc: 0xc25efa5c'u32, nextFork: 4460644'u64)), # First Istanbul block
|
||||
(blockNumber: 4460643'u64, id: (crc: 0xc25efa5c'u32, nextFork: 4460644'u64)), # Future Istanbul block
|
||||
(blockNumber: 4460644'u64, id: (crc: 0x757a1c47'u32, nextFork: 5062605'u64)), # First Berlin block
|
||||
(blockNumber: 5062604'u64, id: (crc: 0x757a1c47'u32, nextFork: 5062605'u64)), # Last Berlin block
|
||||
(blockNumber: 5062605'u64, id: (crc: 0xb8c6299d'u32, nextFork: 0'u64)), # First London block
|
||||
(blockNumber: 10000000'u64, id: (crc: 0xb8c6299d'u32, nextFork: 0'u64)), # Future London block
|
||||
(number: 0'u64 , time: 0'u64, id: (crc: 0xa3f5ab08'u32, next: 1561651'u64)), # Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople and first Petersburg block
|
||||
(number: 1561650'u64, time: 0'u64, id: (crc: 0xa3f5ab08'u32, next: 1561651'u64)), # Last Petersburg block
|
||||
(number: 1561651'u64, time: 0'u64, id: (crc: 0xc25efa5c'u32, next: 4460644'u64)), # First Istanbul block
|
||||
(number: 4460643'u64, time: 0'u64, id: (crc: 0xc25efa5c'u32, next: 4460644'u64)), # Future Istanbul block
|
||||
(number: 4460644'u64, time: 0'u64, id: (crc: 0x757a1c47'u32, next: 5062605'u64)), # First Berlin block
|
||||
(number: 5062604'u64, time: 0'u64, id: (crc: 0x757a1c47'u32, next: 5062605'u64)), # Last Berlin block
|
||||
(number: 5062605'u64, time: 0'u64, id: (crc: 0xb8c6299d'u32, next: 1678832736'u64)), # First London block
|
||||
(number: 6000000'u64, time: 1678832735'u64, id: (crc: 0xB8C6299D'u32, next: 1678832736'u64)), # Last London block
|
||||
(number: 6000001'u64, time: 1678832736'u64, id: (crc: 0xf9843abf'u32, next: 0'u64)), # First Shanghai block
|
||||
(number: 6500000'u64, time: 2678832736'u64, id: (crc: 0xf9843abf'u32, next: 0'u64)), # Future Shanghai block
|
||||
]
|
||||
|
||||
SepoliaNetIDs = [
|
||||
(number: 0'u64, time: 0'u64, id: (crc: 0xfe3366e7'u32, next: 1735371'u64)), # Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople, Petersburg, Istanbul, Berlin and first London block
|
||||
(number: 1735370'u64, time: 0'u64, id: (crc: 0xfe3366e7'u32, next: 1735371'u64)), # Last London block
|
||||
(number: 1735371'u64, time: 0'u64, id: (crc: 0xb96cbd13'u32, next: 1677557088'u64)), # First MergeNetsplit block
|
||||
(number: 1735372'u64, time: 1677557087'u64, id: (crc: 0xb96cbd13'u32, next: 1677557088'u64)), # Last MergeNetsplit block
|
||||
(number: 1735372'u64, time: 1677557088'u64, id: (crc: 0xf7f9bc08'u32, next: 0'u64)), # First Shanghai block
|
||||
]
|
||||
|
||||
template runTest(network: untyped, name: string) =
|
||||
|
@ -50,15 +63,67 @@ template runTest(network: untyped, name: string) =
|
|||
params = networkParams(network)
|
||||
com = CommonRef.new(newCoreDbRef LegacyDbMemory, true, network, params)
|
||||
|
||||
for x in `network IDs`:
|
||||
let id = com.forkId(x.blockNumber.toBlockNumber.blockNumberToForkDeterminationInfo)
|
||||
for i, x in `network IDs`:
|
||||
let id = com.forkId(x.number, x.time)
|
||||
check id.crc == x.id.crc
|
||||
check id.nextFork == x.id.nextFork
|
||||
check id.nextFork == x.id.next
|
||||
|
||||
func config(shanghai, cancun: uint64): ChainConfig =
|
||||
ChainConfig(
|
||||
chainID: ChainId(1337),
|
||||
homesteadBlock: some(0.u256),
|
||||
dAOForkBlock: none(BlockNumber),
|
||||
dAOForkSupport: true,
|
||||
eIP150Block: some(0.u256),
|
||||
eIP155Block: some(0.u256),
|
||||
eIP158Block: some(0.u256),
|
||||
byzantiumBlock: some(0.u256),
|
||||
constantinopleBlock: some(0.u256),
|
||||
petersburgBlock: some(0.u256),
|
||||
istanbulBlock: some(0.u256),
|
||||
muirGlacierBlock: some(0.u256),
|
||||
berlinBlock: some(0.u256),
|
||||
londonBlock: some(0.u256),
|
||||
terminalTotalDifficulty: some(0.u256),
|
||||
terminalTotalDifficultyPassed: some(true),
|
||||
mergeForkBlock: some(0.u256),
|
||||
shanghaiTime: some(shanghai.EthTime),
|
||||
cancunTime: some(cancun.EthTime),
|
||||
)
|
||||
|
||||
func calcID(conf: ChainConfig, crc: uint32, time: uint64): ForkID =
|
||||
let map = conf.toForkTransitionTable
|
||||
let calc = map.initForkIdCalculator(crc, time)
|
||||
calc.newID(0, time)
|
||||
|
||||
template runGenesisTimeIdTests() =
|
||||
let
|
||||
time = 1690475657'u64
|
||||
genesis = common.BlockHeader(timestamp: time.EthTime)
|
||||
genesisCRC = crc32(0, genesis.blockHash.data)
|
||||
cases = [
|
||||
# Shanghai active before genesis, skip
|
||||
(c: config(time-1, time+1), want: (crc: genesisCRC, next: time + 1)),
|
||||
|
||||
# Shanghai active at genesis, skip
|
||||
(c: config(time, time+1), want: (crc: genesisCRC, next: time + 1)),
|
||||
|
||||
# Shanghai not active, skip
|
||||
(c: config(time+1, time+2), want: (crc: genesisCRC, next: time + 1)),
|
||||
]
|
||||
|
||||
for i, x in cases:
|
||||
let get = calcID(x.c, genesisCRC, time)
|
||||
check get.crc == x.want.crc
|
||||
check get.nextFork == x.want.next
|
||||
|
||||
proc forkIdMain*() =
|
||||
suite "Fork ID tests":
|
||||
runTest(MainNet, "MainNet")
|
||||
runTest(GoerliNet, "GoerliNet")
|
||||
runTest(SepoliaNet, "SepoliaNet")
|
||||
test "Genesis Time Fork ID":
|
||||
runGenesisTimeIdTests()
|
||||
|
||||
when isMainModule:
|
||||
forkIdMain()
|
||||
|
|
|
@ -92,7 +92,7 @@ proc testFixtureIndexes(ctx: var TestCtx, testStatusIMPL: var TestStatus) =
|
|||
|
||||
var gasUsed: GasInt
|
||||
let sender = ctx.tx.getSender()
|
||||
let fork = com.toEVMFork(ctx.header.forkDeterminationInfoForHeader)
|
||||
let fork = com.toEVMFork(ctx.header.forkDeterminationInfo)
|
||||
|
||||
vmState.mutateStateDB:
|
||||
setupStateDB(ctx.pre, db)
|
||||
|
|
|
@ -107,7 +107,7 @@ proc writeRootHashToStderr(vmState: BaseVMState) =
|
|||
proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateResult =
|
||||
let
|
||||
com = CommonRef.new(newCoreDbRef LegacyDbMemory, ctx.chainConfig, pruneTrie = false)
|
||||
fork = com.toEVMFork(ctx.header.forkDeterminationInfoForHeader)
|
||||
fork = com.toEVMFork(ctx.header.forkDeterminationInfo)
|
||||
stream = newFileStream(stderr)
|
||||
tracer = if conf.jsonEnabled:
|
||||
newJSonTracer(stream, ctx.tracerFlags, conf.pretty)
|
||||
|
|
Loading…
Reference in New Issue