mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-12 13:24:21 +00:00
45bc6422a0
The current getCanonicalHead of core db should not be confused with ForkedChain.latestHeader. Therefore we need to use getCanonicalHead to restricted case only, e.g. initializing ForkedChain.
154 lines
4.4 KiB
Nim
154 lines
4.4 KiB
Nim
# Nimbus
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
# http://opensource.org/licenses/MIT)
|
|
# at your option. This file may not be copied, modified, or distributed except
|
|
# according to those terms.
|
|
|
|
import
|
|
std/json,
|
|
unittest2,
|
|
stew/byteutils,
|
|
./test_helpers,
|
|
./test_allowed_to_fail,
|
|
../nimbus/db/ledger,
|
|
../nimbus/core/chain/forked_chain,
|
|
../tools/common/helpers as chp,
|
|
../tools/evmstate/helpers,
|
|
../nimbus/common/common,
|
|
../nimbus/core/eip4844
|
|
|
|
const
|
|
debugMode = false
|
|
|
|
type
|
|
BlockDesc = object
|
|
blk: EthBlock
|
|
badBlock: bool
|
|
|
|
TestEnv = object
|
|
blocks: seq[BlockDesc]
|
|
genesisHeader: Header
|
|
lastBlockHash: Hash32
|
|
network: string
|
|
pre: JsonNode
|
|
|
|
proc parseBlocks(node: JsonNode): seq[BlockDesc] =
|
|
for x in node:
|
|
try:
|
|
let blockRLP = hexToSeqByte(x["rlp"].getStr)
|
|
let blk = rlp.decode(blockRLP, EthBlock)
|
|
result.add BlockDesc(
|
|
blk: blk,
|
|
badBlock: "expectException" in x,
|
|
)
|
|
except RlpError:
|
|
# invalid rlp will not participate in block validation
|
|
# e.g. invalid rlp received from network
|
|
discard
|
|
|
|
proc parseEnv(node: JsonNode): TestEnv =
|
|
result.blocks = parseBlocks(node["blocks"])
|
|
let genesisRLP = hexToSeqByte(node["genesisRLP"].getStr)
|
|
result.genesisHeader = rlp.decode(genesisRLP, EthBlock).header
|
|
result.lastBlockHash = Hash32(hexToByteArray[32](node["lastblockhash"].getStr))
|
|
result.network = node["network"].getStr
|
|
result.pre = node["pre"]
|
|
|
|
proc rootExists(db: CoreDbRef; root: Hash32): bool =
|
|
let state = db.ctx.getAccounts().getStateRoot().valueOr:
|
|
return false
|
|
state == root
|
|
|
|
proc executeCase(node: JsonNode): bool =
|
|
let
|
|
env = parseEnv(node)
|
|
memDB = newCoreDbRef DefaultDbMemory
|
|
stateDB = LedgerRef.init(memDB)
|
|
config = getChainConfig(env.network)
|
|
com = CommonRef.new(memDB, nil, config)
|
|
|
|
setupStateDB(env.pre, stateDB)
|
|
stateDB.persist()
|
|
|
|
com.db.persistHeaderAndSetHead(env.genesisHeader).isOkOr:
|
|
debugEcho "Failed to put genesis header into database: ", error
|
|
return false
|
|
|
|
var c = ForkedChainRef.init(com)
|
|
if c.latestHash != env.genesisHeader.blockHash:
|
|
debugEcho "Genesis block hash in database is different with expected genesis block hash"
|
|
return false
|
|
|
|
var lastStateRoot = env.genesisHeader.stateRoot
|
|
for blk in env.blocks:
|
|
let res = c.importBlock(blk.blk)
|
|
if res.isOk:
|
|
if env.lastBlockHash == blk.blk.header.blockHash:
|
|
lastStateRoot = blk.blk.header.stateRoot
|
|
if blk.badBlock:
|
|
debugEcho "A bug? bad block imported"
|
|
return false
|
|
else:
|
|
if not blk.badBlock:
|
|
debugEcho "A bug? good block rejected: ", res.error
|
|
return false
|
|
|
|
c.forkChoice(env.lastBlockHash, env.lastBlockHash).isOkOr:
|
|
debugEcho error
|
|
return false
|
|
|
|
let headHash = c.latestHash
|
|
if headHash != env.lastBlockHash:
|
|
debugEcho "lastestBlockHash mismatch, get: ", headHash,
|
|
" expect: ", env.lastBlockHash
|
|
return false
|
|
|
|
if not memDB.rootExists(lastStateRoot):
|
|
debugEcho "Last stateRoot not exists"
|
|
return false
|
|
|
|
true
|
|
|
|
proc executeFile(node: JsonNode, testStatusIMPL: var TestStatus) =
|
|
for name, bctCase in node:
|
|
when debugMode:
|
|
debugEcho "TEST NAME: ", name
|
|
check executeCase(bctCase)
|
|
|
|
proc blockchainJsonMain*() =
|
|
const
|
|
legacyFolder = "eth_tests/LegacyTests/Constantinople/BlockchainTests"
|
|
newFolder = "eth_tests/BlockchainTests"
|
|
|
|
loadKzgTrustedSetup().isOkOr:
|
|
echo "FATAL: ", error
|
|
quit(QuitFailure)
|
|
|
|
if false:
|
|
suite "block chain json tests":
|
|
jsonTest(legacyFolder, "BlockchainTests", executeFile, skipBCTests)
|
|
else:
|
|
suite "new block chain json tests":
|
|
jsonTest(newFolder, "newBlockchainTests", executeFile, skipNewBCTests)
|
|
|
|
when isMainModule:
|
|
when debugMode:
|
|
proc executeFile(name: string) =
|
|
loadKzgTrustedSetup().isOkOr:
|
|
echo "FATAL: ", error
|
|
quit(QuitFailure)
|
|
|
|
var testStatusIMPL: TestStatus
|
|
let node = json.parseFile(name)
|
|
executeFile(node, testStatusIMPL)
|
|
if testStatusIMPL == FAILED:
|
|
quit(QuitFailure)
|
|
|
|
executeFile("tests/fixtures/eth_tests/BlockchainTests/GeneralStateTests/stTransactionTest/ValueOverflowParis.json")
|
|
else:
|
|
blockchainJsonMain()
|