2022-02-22 08:55:04 +00:00
|
|
|
# Nimbus
|
2024-01-13 01:41:57 +00:00
|
|
|
# Copyright (c) 2018-2024 Status Research & Development GmbH
|
2022-02-22 08:55:04 +00:00
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
|
|
# at your option.
|
|
|
|
# This file may not be copied, modified, or distributed except according to
|
|
|
|
# those terms.
|
|
|
|
|
|
|
|
import
|
2024-01-13 01:41:57 +00:00
|
|
|
std/[json, os, typetraits],
|
2022-12-02 04:39:12 +00:00
|
|
|
unittest2,
|
|
|
|
json_rpc/[rpcserver, rpcclient],
|
2024-01-13 01:41:57 +00:00
|
|
|
web3/[engine_api_types, conversions],
|
2022-05-13 16:30:10 +00:00
|
|
|
../nimbus/sync/protocol,
|
2022-12-02 04:39:12 +00:00
|
|
|
../nimbus/rpc,
|
|
|
|
../nimbus/common,
|
|
|
|
../nimbus/config,
|
|
|
|
../nimbus/core/[sealer, tx_pool, chain],
|
2023-08-27 01:23:45 +00:00
|
|
|
../nimbus/beacon/[beacon_engine, payload_queue],
|
2022-02-22 08:55:04 +00:00
|
|
|
./test_helpers
|
|
|
|
|
|
|
|
const
|
|
|
|
baseDir = "tests" / "merge"
|
|
|
|
paramsFile = baseDir / "params.json"
|
|
|
|
stepsFile = baseDir / "steps.json"
|
|
|
|
|
|
|
|
type
|
2024-01-13 01:41:57 +00:00
|
|
|
StepObj = object
|
2022-02-22 08:55:04 +00:00
|
|
|
name: string
|
2024-01-13 01:41:57 +00:00
|
|
|
`method`: string
|
2022-02-22 08:55:04 +00:00
|
|
|
params: JSonNode
|
2024-01-13 01:41:57 +00:00
|
|
|
expect: JsonString
|
|
|
|
error : JsonString
|
2022-02-22 08:55:04 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
Step = ref StepObj
|
|
|
|
Steps = seq[Step]
|
|
|
|
|
|
|
|
StepObj.useDefaultSerializationIn JrpcConv
|
2022-02-22 08:55:04 +00:00
|
|
|
|
2024-01-13 01:41:57 +00:00
|
|
|
proc forkChoiceUpdate(step: Step, client: RpcClient, testStatusIMPL: var TestStatus) =
|
|
|
|
let jsonBytes = waitFor client.call(step.`method`, step.params)
|
|
|
|
let resA = JrpcConv.decode(jsonBytes.string, ForkchoiceUpdatedResponse)
|
|
|
|
let resB = JrpcConv.decode(step.expect.string, ForkchoiceUpdatedResponse)
|
|
|
|
check resA == resB
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
proc getPayload(step: Step, client: RpcClient, testStatusIMPL: var TestStatus) =
|
|
|
|
try:
|
2024-01-13 01:41:57 +00:00
|
|
|
let jsonBytes = waitFor client.call(step.`method`, step.params)
|
|
|
|
let resA = JrpcConv.decode(jsonBytes.string, ExecutionPayloadV1)
|
|
|
|
let resB = JrpcConv.decode(step.expect.string, ExecutionPayloadV1)
|
|
|
|
check resA == resB
|
2023-08-27 01:23:45 +00:00
|
|
|
except CatchableError:
|
2024-01-13 01:41:57 +00:00
|
|
|
check step.error.string.len > 0
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
proc newPayload(step: Step, client: RpcClient, testStatusIMPL: var TestStatus) =
|
2024-01-13 01:41:57 +00:00
|
|
|
let jsonBytes = waitFor client.call(step.`method`, step.params)
|
|
|
|
let resA = JrpcConv.decode(jsonBytes.string, PayloadStatusV1)
|
|
|
|
let resB = JrpcConv.decode(step.expect.string, PayloadStatusV1)
|
|
|
|
check resA == resB
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
proc runTest(steps: Steps) =
|
|
|
|
let
|
|
|
|
conf = makeConfig(@["--custom-network:" & paramsFile])
|
|
|
|
ctx = newEthContext()
|
|
|
|
ethNode = setupEthNode(conf, ctx, eth)
|
2022-12-02 04:39:12 +00:00
|
|
|
com = CommonRef.new(
|
2024-05-20 10:17:51 +00:00
|
|
|
newCoreDbRef DefaultDbMemory,
|
2022-02-22 08:55:04 +00:00
|
|
|
conf.networkId,
|
|
|
|
conf.networkParams
|
|
|
|
)
|
2022-12-02 04:39:12 +00:00
|
|
|
chainRef = newChain(com)
|
2022-02-22 08:55:04 +00:00
|
|
|
|
2022-12-02 04:39:12 +00:00
|
|
|
com.initializeEmptyDb()
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
var
|
2024-02-19 09:33:43 +00:00
|
|
|
rpcServer = newRpcSocketServer(["127.0.0.1:0"])
|
2022-02-22 08:55:04 +00:00
|
|
|
client = newRpcSocketClient()
|
2022-12-02 04:39:12 +00:00
|
|
|
txPool = TxPoolRef.new(com, conf.engineSigner)
|
2022-02-22 08:55:04 +00:00
|
|
|
sealingEngine = SealingEngineRef.new(
|
|
|
|
chainRef, ctx, conf.engineSigner,
|
|
|
|
txPool, EnginePostMerge
|
|
|
|
)
|
2023-08-27 01:23:45 +00:00
|
|
|
beaconEngine = BeaconEngineRef.new(txPool, chainRef)
|
2024-04-16 01:02:42 +00:00
|
|
|
oracle = Oracle.new(com)
|
2022-02-22 08:55:04 +00:00
|
|
|
|
2024-04-16 01:02:42 +00:00
|
|
|
setupEthRpc(ethNode, ctx, com, txPool, oracle, rpcServer)
|
2023-08-27 01:23:45 +00:00
|
|
|
setupEngineAPI(beaconEngine, rpcServer)
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
sealingEngine.start()
|
|
|
|
rpcServer.start()
|
2024-02-19 09:33:43 +00:00
|
|
|
waitFor client.connect(rpcServer.localAddress()[0])
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
suite "Engine API tests":
|
2024-01-13 01:41:57 +00:00
|
|
|
for i, step in steps:
|
2022-02-22 08:55:04 +00:00
|
|
|
test $i & " " & step.name:
|
2024-01-13 01:41:57 +00:00
|
|
|
case step.`method`
|
2022-02-22 08:55:04 +00:00
|
|
|
of "engine_forkchoiceUpdatedV1":
|
|
|
|
forkChoiceUpdate(step, client, testStatusIMPL)
|
|
|
|
of "engine_getPayloadV1":
|
|
|
|
getPayload(step, client, testStatusIMPL)
|
|
|
|
of "engine_newPayloadV1":
|
|
|
|
newPayload(step, client, testStatusIMPL)
|
|
|
|
else:
|
2024-01-13 01:41:57 +00:00
|
|
|
doAssert(false, "unknown method: " & step.`method`)
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
waitFor sealingEngine.stop()
|
|
|
|
rpcServer.stop()
|
|
|
|
waitFor rpcServer.closeWait()
|
|
|
|
|
|
|
|
proc testEngineAPI() =
|
2024-01-13 01:41:57 +00:00
|
|
|
let steps = JrpcConv.loadFile(stepsFile, Steps)
|
2022-02-22 08:55:04 +00:00
|
|
|
runTest(steps)
|
|
|
|
|
|
|
|
proc toId(x: int): PayloadId =
|
|
|
|
var id: distinctBase PayloadId
|
|
|
|
id[^1] = x.byte
|
|
|
|
PayloadId(id)
|
|
|
|
|
|
|
|
proc `==`(a, b: Quantity): bool =
|
|
|
|
uint64(a) == uint64(b)
|
|
|
|
|
2022-03-11 09:25:23 +00:00
|
|
|
proc testEngineApiSupport() =
|
2023-08-27 01:23:45 +00:00
|
|
|
var api = PayloadQueue()
|
2022-02-22 08:55:04 +00:00
|
|
|
let
|
|
|
|
id1 = toId(1)
|
|
|
|
id2 = toId(2)
|
|
|
|
ep1 = ExecutionPayloadV1(gasLimit: Quantity 100)
|
|
|
|
ep2 = ExecutionPayloadV1(gasLimit: Quantity 101)
|
2023-08-27 01:23:45 +00:00
|
|
|
hdr1 = common.BlockHeader(gasLimit: 100)
|
|
|
|
hdr2 = common.BlockHeader(gasLimit: 101)
|
2022-02-22 08:55:04 +00:00
|
|
|
hash1 = hdr1.blockHash
|
|
|
|
hash2 = hdr2.blockHash
|
|
|
|
|
|
|
|
suite "Test engine api support":
|
|
|
|
test "test payload queue":
|
2023-08-18 07:49:11 +00:00
|
|
|
api.put(id1, 123.u256, ep1)
|
|
|
|
api.put(id2, 456.u256, ep2)
|
2022-02-22 08:55:04 +00:00
|
|
|
var eep1, eep2: ExecutionPayloadV1
|
2023-08-18 07:49:11 +00:00
|
|
|
var bv1, bv2: UInt256
|
|
|
|
check api.get(id1, bv1, eep1)
|
|
|
|
check api.get(id2, bv2, eep2)
|
2022-02-22 08:55:04 +00:00
|
|
|
check eep1.gasLimit == ep1.gasLimit
|
|
|
|
check eep2.gasLimit == ep2.gasLimit
|
2023-08-18 07:49:11 +00:00
|
|
|
check bv1 == 123.u256
|
|
|
|
check bv2 == 456.u256
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
test "test header queue":
|
|
|
|
api.put(hash1, hdr1)
|
|
|
|
api.put(hash2, hdr2)
|
2023-08-27 01:23:45 +00:00
|
|
|
var eh1, eh2: common.BlockHeader
|
2022-02-22 08:55:04 +00:00
|
|
|
check api.get(hash1, eh1)
|
|
|
|
check api.get(hash2, eh2)
|
|
|
|
check eh1.gasLimit == hdr1.gasLimit
|
|
|
|
check eh2.gasLimit == hdr2.gasLimit
|
|
|
|
|
|
|
|
proc mergeMain*() =
|
2022-03-11 09:25:23 +00:00
|
|
|
# temporary disable it until engine API more stable
|
2022-03-17 05:54:04 +00:00
|
|
|
testEngineAPI()
|
2022-03-11 09:25:23 +00:00
|
|
|
testEngineApiSupport()
|
2022-02-22 08:55:04 +00:00
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
mergeMain()
|