Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wiring ForkedChainRef to other components #2423

Merged
merged 22 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 10 additions & 14 deletions hive_integration/nodocker/build_sims.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,16 @@ USE_SYSTEM_NIM=1

ENV_SCRIPT="vendor/nimbus-build-system/scripts/env.sh"

# nimbus_db_backend:none -> we only use memory db in simulators
# we only use memory db in simulators
NIM_FLAGS="c -d:release"

${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/engine/engine_sim
${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/consensus/consensus_sim
${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/graphql/graphql_sim
${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/rpc/rpc_sim
${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/pyspec/pyspec_sim

${SIM_DIR}/engine/engine_sim
${SIM_DIR}/consensus/consensus_sim
${SIM_DIR}/graphql/graphql_sim
${SIM_DIR}/rpc/rpc_sim
${SIM_DIR}/pyspec/pyspec_sim

echo "## ${1}" > simulators.md
cat engine.md consensus.md graphql.md rpc.md pyspec.md >> simulators.md

# more suites: engine, graphql, rpc
suites=(consensus pyspec engine)
for suite in "${suites[@]}"
do
${ENV_SCRIPT} nim ${NIM_FLAGS} ${SIM_DIR}/${suite}/${suite}_sim
${SIM_DIR}/${suite}/${suite}_sim
cat ${suite}.md >> simulators.md
done
36 changes: 28 additions & 8 deletions hive_integration/nodocker/consensus/consensus_sim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import
stew/byteutils,
results,
chronicles,
../../../nimbus/core/chain,
../../../nimbus/core/block_import,
../../../nimbus/common,
../../../nimbus/core/eip4844,
Expand All @@ -26,11 +27,13 @@ proc processChainData(cd: ChainData): TestStatus =
cd.params
)

let c = newForkedChain(com, com.genesisHeader)

for bytes in cd.blocksRlp:
# ignore return value here
# because good blocks maybe interleaved with
# bad blocks
discard importRlpBlock(bytes, com, "consensus_sim")
discard importRlpBlocks(bytes, c, finalize = true)

let head = com.db.getCanonicalHead()
let blockHash = "0x" & head.blockHash.data.toHex
Expand All @@ -43,8 +46,23 @@ proc processChainData(cd: ChainData): TestStatus =
expected=cd.lastBlockHash
TestStatus.Failed

# except loopMul, all other tests are related to total difficulty
# which is not supported in ForkedChain
const unsupportedTests = [
"lotsOfBranchesOverrideAtTheMiddle.json",
"sideChainWithMoreTransactions.json",
"uncleBlockAtBlock3afterBlock4.json",
"CallContractFromNotBestBlock.json",
"ChainAtoChainB_difficultyB.json",
"ForkStressTest.json",
"blockChainFrontierWithLargerTDvsHomesteadBlockchain.json",
"blockChainFrontierWithLargerTDvsHomesteadBlockchain2.json",
"lotsOfLeafs.json",
"loopMul.json"
]

proc main() =
const basePath = "tests" / "fixtures" / "eth_tests" / "BlockchainTests"
const basePath = "tests/fixtures/eth_tests/BlockchainTests"
var stat: SimStat
let start = getTime()

Expand All @@ -57,15 +75,17 @@ proc main() =
if not fileName.endsWith(".json"):
continue

let n = json.parseFile(fileName)
for name, unit in n:
if "loopMul" in name:
inc stat.skipped
continue
let (_, name) = fileName.splitPath()
if name in unsupportedTests:
let n = json.parseFile(fileName)
stat.skipped += n.len
continue

let n = json.parseFile(fileName)
for caseName, unit in n:
let cd = extractChainData(unit)
let status = processChainData(cd)
stat.inc(name, status)
stat.inc(caseName, status)

let elpd = getTime() - start
print(stat, elpd, "consensus")
Expand Down
24 changes: 13 additions & 11 deletions hive_integration/nodocker/engine/engine_env.nim
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type
client : RpcHttpClient
sync : BeaconSyncRef
txPool : TxPoolRef
chain : ChainRef
chain : ForkedChainRef

const
baseFolder = "hive_integration/nodocker/engine"
Expand All @@ -66,7 +66,6 @@ proc makeCom*(conf: NimbusConf): CommonRef =

proc envConfig*(): NimbusConf =
makeConfig(@[
"--engine-signer:658bdf435d810c91414ec09147daa6db62406379",
"--custom-network:" & genesisFile,
"--listen-address: 127.0.0.1",
])
Expand All @@ -88,7 +87,8 @@ proc newEngineEnv*(conf: var NimbusConf, chainFile: string, enableAuth: bool): E
let
node = setupEthNode(conf, ctx)
com = makeCom(conf)
chain = newChain(com)
head = com.db.getCanonicalHead()
chain = newForkedChain(com, head)

let txPool = TxPoolRef.new(com)

Expand All @@ -99,8 +99,7 @@ proc newEngineEnv*(conf: var NimbusConf, chainFile: string, enableAuth: bool): E

# txPool must be informed of active head
# so it can know the latest account state
let head = com.db.getCanonicalHead()
doAssert txPool.smartHead(head)
doAssert txPool.smartHead(head, chain)

var key: JwtSharedKey
key.fromHex(jwtSecret).isOkOr:
Expand All @@ -120,14 +119,16 @@ proc newEngineEnv*(conf: var NimbusConf, chainFile: string, enableAuth: bool): E
BeaconSyncRef(nil)
beaconEngine = BeaconEngineRef.new(txPool, chain)
oracle = Oracle.new(com)
serverApi = newServerAPI(chain)

setupEthRpc(node, ctx, com, txPool, oracle, server)
setupServerAPI(serverApi, server)
setupEngineAPI(beaconEngine, server)
setupDebugRpc(com, txPool, server)
# temporary disabled
#setupDebugRpc(com, txPool, server)
jangko marked this conversation as resolved.
Show resolved Hide resolved

# Do not start clique sealing engine if we are using a Proof of Work chain file
if chainFile.len > 0:
if not importRlpBlock(chainFolder / chainFile, com):
importRlpBlocks(chainFolder / chainFile, chain, true).isOkOr:
echo "Failed to import RLP blocks: ", error
quit(QuitFailure)

server.start()
Expand Down Expand Up @@ -183,7 +184,6 @@ proc connect*(env: EngineEnv, node: ENode) =
waitFor env.node.connectToNode(node)

func ID*(env: EngineEnv): string =
# $env.node.listeningAddress
$env.conf.httpPort

proc peer*(env: EngineEnv): Peer =
Expand Down Expand Up @@ -218,4 +218,6 @@ func version*(env: EngineEnv, time: uint64): Version =
env.version(time.EthTime)

proc setBlock*(env: EngineEnv, blk: common.EthBlock): bool =
env.chain.setBlock(blk).isOk()
# env.chain.setBlock(blk).isOk()
debugEcho "TODO: fix setBlock"
false
14 changes: 7 additions & 7 deletions hive_integration/nodocker/engine/engine_sim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ import
../../../nimbus/core/eip4844

import
./engine_tests,
# ./engine_tests,
./auths_tests,
./exchange_cap_tests,
./withdrawal_tests,
./cancun_tests
./exchange_cap_tests#,
#./withdrawal_tests,
#./cancun_tests

proc combineTests(): seq[TestDesc] =
result.add wdTestList
#result.add wdTestList
result.add ecTestList
result.add authTestList
result.add engineTestList
result.add cancunTestList
#result.add engineTestList
#result.add cancunTestList

let
testList = combineTests()
Expand Down
2 changes: 1 addition & 1 deletion hive_integration/nodocker/engine/node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ proc setBlock*(c: ChainRef; blk: EthBlock): Result[void, string] =
c.db.persistReceipts(header.receiptsRoot, vmState.receipts)

if blk.withdrawals.isSome:
c.db.persistWithdrawals(header.withdrawalsRoot, blk.withdrawals.get)
c.db.persistWithdrawals(header.withdrawalsRoot.get, blk.withdrawals.get)
except CatchableError as exc:
return err(exc.msg)

Expand Down
3 changes: 2 additions & 1 deletion hive_integration/nodocker/graphql/graphql_sim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ proc main() =
# so it can know the latest account state
# e.g. "sendRawTransaction Nonce too low" case
let head = com.db.getCanonicalHead()
doAssert txPool.smartHead(head)
let chainRef = newForkedChain(com, head)
doAssert txPool.smartHead(head, chainRef)

for fileName in walkDirRec(
caseFolder, yieldFilter = {pcFile,pcLinkToFile}):
Expand Down
18 changes: 8 additions & 10 deletions hive_integration/nodocker/pyspec/pyspec_sim.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import
../sim_utils,
../../../tools/common/helpers as chp,
../../../tools/evmstate/helpers as ehp,
../../../tests/test_helpers,
../../../nimbus/beacon/web3_eth_conv,
../../../nimbus/beacon/payload_conv,
../../../nimbus/core/eip4844,
Expand Down Expand Up @@ -116,8 +115,7 @@ proc validatePostState(node: JsonNode, t: TestEnv): bool =

proc runTest(node: JsonNode, network: string): TestStatus =
let conf = getChainConfig(network)
var t = TestEnv(conf: makeTestConfig())
t.setupELClient(conf, node)
var env = setupELClient(conf, node)

let blks = node["blocks"]
var
Expand All @@ -143,7 +141,7 @@ proc runTest(node: JsonNode, network: string): TestStatus =

latestVersion = payload.payload.version

let res = t.rpcClient.newPayload(payload.payload, payload.beaconRoot)
let res = env.rpcClient.newPayload(payload.payload, payload.beaconRoot)
if res.isErr:
result = TestStatus.Failed
echo "unable to send block ",
Expand All @@ -164,22 +162,22 @@ proc runTest(node: JsonNode, network: string): TestStatus =
echo pStatus.validationError.get
break

block:
block blockOne:
# only update head of beacon chain if valid response occurred
if latestValidHash != common.Hash256():
# update with latest valid response
let fcState = ForkchoiceStateV1(headBlockHash: BlockHash latestValidHash.data)
let res = t.rpcClient.forkchoiceUpdated(latestVersion, fcState)
let res = env.rpcClient.forkchoiceUpdated(latestVersion, fcState)
if res.isErr:
result = TestStatus.Failed
echo "unable to update head of beacon chain: ", res.error
break
break blockOne

if not validatePostState(node, t):
if not validatePostState(node, env):
result = TestStatus.Failed
break
break blockOne

t.stopELClient()
env.stopELClient()

const
skipName = [
Expand Down
65 changes: 29 additions & 36 deletions hive_integration/nodocker/pyspec/test_env.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

import
std/[json],
eth/p2p as eth_p2p,
eth/trie/trie_defs,
stew/[byteutils],
json_rpc/[rpcserver, rpcclient],
../../../nimbus/[
Expand All @@ -22,62 +20,57 @@ import
core/chain,
core/tx_pool,
rpc,
sync/protocol,
beacon/beacon_engine,
common
],
../../../tests/test_helpers,
../../../tools/evmstate/helpers

type
TestEnv* = ref object
conf*: NimbusConf
ctx: EthContext
ethNode: EthereumNode
com: CommonRef
chainRef: ChainRef
rpcServer: RpcHttpServer
chain : ForkedChainRef
rpcServer : RpcHttpServer
rpcClient*: RpcHttpClient

proc genesisHeader(node: JsonNode): BlockHeader =
let genesisRLP = hexToSeqByte(node["genesisRLP"].getStr)
rlp.decode(genesisRLP, EthBlock).header

proc setupELClient*(t: TestEnv, conf: ChainConfig, node: JsonNode) =
let memDB = newCoreDbRef DefaultDbMemory
t.ctx = newEthContext()
t.ethNode = setupEthNode(t.conf, t.ctx, eth)
t.com = CommonRef.new(
memDB,
conf
)
t.chainRef = newChain(t.com, extraValidation = true)
proc setupELClient*(conf: ChainConfig, node: JsonNode): TestEnv =
let
stateDB = LedgerRef.init(memDB, emptyRlpHash)
memDB = newCoreDbRef DefaultDbMemory
genesisHeader = node.genesisHeader
com = CommonRef.new(memDB, conf)
stateDB = LedgerRef.init(memDB, EMPTY_ROOT_HASH)
chain = newForkedChain(com, genesisHeader)

setupStateDB(node["pre"], stateDB)
stateDB.persist()

doAssert stateDB.rootHash == genesisHeader.stateRoot

doAssert t.com.db.persistHeader(genesisHeader,
t.com.consensus == ConsensusType.POS)
doAssert(t.com.db.getCanonicalHead().blockHash == genesisHeader.blockHash)
doAssert com.db.persistHeader(genesisHeader,
com.consensus == ConsensusType.POS)
doAssert(com.db.getCanonicalHead().blockHash ==
genesisHeader.blockHash)

let txPool = TxPoolRef.new(t.com)
t.rpcServer = newRpcHttpServer(["127.0.0.1:8545"])
let
txPool = TxPoolRef.new(com)
beaconEngine = BeaconEngineRef.new(txPool, chain)
serverApi = newServerAPI(chain)
rpcServer = newRpcHttpServer(["127.0.0.1:0"])
rpcClient = newRpcHttpClient()

let beaconEngine = BeaconEngineRef.new(txPool, t.chainRef)
let oracle = Oracle.new(t.com)
setupEthRpc(t.ethNode, t.ctx, t.com, txPool, oracle, t.rpcServer)
setupEngineAPI(beaconEngine, t.rpcServer)
setupServerAPI(serverApi, rpcServer)
setupEngineAPI(beaconEngine, rpcServer)

t.rpcServer.start()
rpcServer.start()
waitFor rpcClient.connect("127.0.0.1", rpcServer.localAddress[0].port, false)

t.rpcClient = newRpcHttpClient()
waitFor t.rpcClient.connect("127.0.0.1", 8545.Port, false)
TestEnv(
chain: chain,
rpcServer: rpcServer,
rpcClient: rpcClient,
)

proc stopELClient*(t: TestEnv) =
waitFor t.rpcClient.close()
waitFor t.rpcServer.closeWait()
proc stopELClient*(env: TestEnv) =
waitFor env.rpcClient.close()
waitFor env.rpcServer.closeWait()
6 changes: 3 additions & 3 deletions hive_integration/nodocker/rpc/test_env.nim
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ proc setupEnv*(): TestEnv =

manageAccounts(ethCtx, conf)

let chainRef = newChain(com)
let head = com.db.getCanonicalHead()
let chainRef = newForkedChain(com, head)
let txPool = TxPoolRef.new(com)

# txPool must be informed of active head
# so it can know the latest account state
let head = com.db.getCanonicalHead()
doAssert txPool.smartHead(head)
doAssert txPool.smartHead(head, chainRef)

let rpcServer = setupRpcServer(ethCtx, com, ethNode, txPool, conf)
let rpcClient = newRpcHttpClient()
Expand Down
Loading
Loading