196 lines
4.9 KiB
Nim
196 lines
4.9 KiB
Nim
|
# Nimbus
|
||
|
# Copyright (c) 2023 Status Research & Development GmbH
|
||
|
# Licensed and distributed under either of
|
||
|
# * MIT license (license terms in the root directory or at
|
||
|
# https://opensource.org/licenses/MIT).
|
||
|
# * Apache v2 license (license terms in the root directory or at
|
||
|
# https://www.apache.org/licenses/LICENSE-2.0).
|
||
|
# at your option. This file may not be copied, modified, or distributed
|
||
|
# except according to those terms.
|
||
|
|
||
|
import
|
||
|
stew/byteutils,
|
||
|
../../nimbus/core/chain,
|
||
|
../../nimbus/core/pow/difficulty,
|
||
|
../../nimbus/config,
|
||
|
../../nimbus/common,
|
||
|
../../nimbus/sync/beacon/skeleton_desc
|
||
|
|
||
|
const
|
||
|
genesisFile = "tests/customgenesis/post-merge.json"
|
||
|
|
||
|
type
|
||
|
Subchain* = object
|
||
|
head*: uint64
|
||
|
tail*: uint64
|
||
|
|
||
|
TestEnv* = object
|
||
|
conf* : NimbusConf
|
||
|
chain*: ChainRef
|
||
|
|
||
|
CCModify = proc(cc: NetworkParams)
|
||
|
|
||
|
let
|
||
|
block49* = BlockHeader(
|
||
|
blockNumber: 49.toBlockNumber
|
||
|
)
|
||
|
block49B* = BlockHeader(
|
||
|
blockNumber: 49.toBlockNumber,
|
||
|
extraData: @['B'.byte]
|
||
|
)
|
||
|
block50* = BlockHeader(
|
||
|
blockNumber: 50.toBlockNumber,
|
||
|
parentHash: block49.blockHash
|
||
|
)
|
||
|
block50B* = BlockHeader(
|
||
|
blockNumber: 50.toBlockNumber,
|
||
|
parentHash: block49.blockHash,
|
||
|
gasLimit: 999.GasInt,
|
||
|
)
|
||
|
block51* = BlockHeader(
|
||
|
blockNumber: 51.toBlockNumber,
|
||
|
parentHash: block50.blockHash
|
||
|
)
|
||
|
|
||
|
proc setupEnv*(extraValidation: bool = false, ccm: CCModify = nil): TestEnv =
|
||
|
let
|
||
|
conf = makeConfig(@[
|
||
|
"--custom-network:" & genesisFile
|
||
|
])
|
||
|
|
||
|
if ccm.isNil.not:
|
||
|
ccm(conf.networkParams)
|
||
|
|
||
|
let
|
||
|
com = CommonRef.new(
|
||
|
newCoreDbRef LegacyDbMemory,
|
||
|
conf.pruneMode == PruneMode.Full,
|
||
|
conf.networkId,
|
||
|
conf.networkParams
|
||
|
)
|
||
|
chain = newChain(com, extraValidation)
|
||
|
|
||
|
com.initializeEmptyDb()
|
||
|
TestEnv(
|
||
|
conf : conf,
|
||
|
chain: chain,
|
||
|
)
|
||
|
|
||
|
func subchain*(head, tail: uint64): Subchain =
|
||
|
Subchain(head: head, tail: tail)
|
||
|
|
||
|
func header*(bn: uint64, temp, parent: BlockHeader, diff: uint64): BlockHeader =
|
||
|
BlockHeader(
|
||
|
blockNumber: bn.toBlockNumber,
|
||
|
parentHash : parent.blockHash,
|
||
|
difficulty : diff.u256,
|
||
|
timestamp : fromUnix(parent.timestamp.toUnix + 1),
|
||
|
gasLimit : temp.gasLimit,
|
||
|
stateRoot : temp.stateRoot,
|
||
|
txRoot : temp.txRoot,
|
||
|
fee : temp.fee,
|
||
|
receiptRoot: temp.receiptRoot,
|
||
|
ommersHash : temp.ommersHash,
|
||
|
withdrawalsRoot: temp.withdrawalsRoot,
|
||
|
blobGasUsed: temp.blobGasUsed,
|
||
|
excessBlobGas: temp.excessBlobGas,
|
||
|
parentBeaconBlockRoot: temp.parentBeaconBlockRoot,
|
||
|
)
|
||
|
|
||
|
func header*(com: CommonRef, bn: uint64, temp, parent: BlockHeader): BlockHeader =
|
||
|
result = header(bn, temp, parent, 0)
|
||
|
result.difficulty = com.calcDifficulty(result.timestamp, parent)
|
||
|
|
||
|
func header*(bn: uint64, temp, parent: BlockHeader,
|
||
|
diff: uint64, stateRoot: string): BlockHeader =
|
||
|
result = header(bn, temp, parent, diff)
|
||
|
result.stateRoot = Hash256(data: hextoByteArray[32](stateRoot))
|
||
|
|
||
|
func header*(com: CommonRef, bn: uint64, temp, parent: BlockHeader,
|
||
|
stateRoot: string): BlockHeader =
|
||
|
result = com.header(bn, temp, parent)
|
||
|
result.stateRoot = Hash256(data: hextoByteArray[32](stateRoot))
|
||
|
|
||
|
func emptyBody*(): BlockBody =
|
||
|
BlockBody(
|
||
|
transactions: @[],
|
||
|
uncles: @[],
|
||
|
withdrawals: none(seq[Withdrawal]),
|
||
|
)
|
||
|
|
||
|
template fillCanonical(skel, z, stat) =
|
||
|
if z.status == stat and FillCanonical in z.status:
|
||
|
let xx = skel.fillCanonicalChain()
|
||
|
check xx.isOk
|
||
|
if xx.isErr:
|
||
|
debugEcho "FillCanonicalChain: ", xx.error
|
||
|
break
|
||
|
|
||
|
template initSyncT*(skel, blk: untyped, r = false) =
|
||
|
let x = skel.initSync(blk)
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "initSync:", x.error
|
||
|
break
|
||
|
let z = x.get
|
||
|
check z.reorg == r
|
||
|
|
||
|
template setHeadT*(skel, blk, frc, r) =
|
||
|
let x = skel.setHead(blk, frc)
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "setHead:", x.error
|
||
|
break
|
||
|
let z = x.get
|
||
|
check z.reorg == r
|
||
|
|
||
|
template initSyncT*(skel, blk, r, stat) =
|
||
|
let x = skel.initSync(blk)
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "initSync:", x.error
|
||
|
break
|
||
|
let z = x.get
|
||
|
check z.reorg == r
|
||
|
check z.status == stat
|
||
|
fillCanonical(skel, z, stat)
|
||
|
|
||
|
template setHeadT*(skel, blk, frc, r, stat) =
|
||
|
let x = skel.setHead(blk, frc)
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "setHead:", x.error
|
||
|
break
|
||
|
let z = x.get
|
||
|
check z.reorg == r
|
||
|
check z.status == stat
|
||
|
fillCanonical(skel, z, stat)
|
||
|
|
||
|
template putBlocksT*(skel, blocks, numBlocks, stat) =
|
||
|
let x = skel.putBlocks(blocks)
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "putBlocks: ", x.error
|
||
|
break
|
||
|
let z = x.get
|
||
|
check z.number == numBlocks
|
||
|
check z.status == stat
|
||
|
fillCanonical(skel, z, stat)
|
||
|
|
||
|
template isLinkedT*(skel, r) =
|
||
|
let x = skel.isLinked()
|
||
|
check x.isOk
|
||
|
if x.isErr:
|
||
|
debugEcho "isLinked: ", x.error
|
||
|
break
|
||
|
check x.get == r
|
||
|
|
||
|
template getHeaderClean*(skel, headers) =
|
||
|
for header in headers:
|
||
|
var r = skel.getHeader(header.u64, true)
|
||
|
check r.isOk
|
||
|
check r.get.isNone
|
||
|
r = skel.getHeader(header.blockHash, true)
|
||
|
check r.isOk
|
||
|
check r.get.isNone
|