From 9843c9428fc01a1604e8fa8e7d2909ea3634990d Mon Sep 17 00:00:00 2001 From: jangko Date: Sun, 29 May 2022 11:23:03 +0700 Subject: [PATCH] fix related to engine api alpha.9 --- hive_integration/nodocker/engine/clmock.nim | 2 +- .../nodocker/engine/engine_client.nim | 32 ++++++++++++++++- .../nodocker/engine/engine_tests.nim | 35 +++++++++++++------ hive_integration/nodocker/engine/test_env.nim | 9 +++++ nimbus/rpc/engine_api.nim | 4 +-- 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/hive_integration/nodocker/engine/clmock.nim b/hive_integration/nodocker/engine/clmock.nim index 3913e195c..b3b42519e 100644 --- a/hive_integration/nodocker/engine/clmock.nim +++ b/hive_integration/nodocker/engine/clmock.nim @@ -29,7 +29,7 @@ type # Merge related firstPoSBlockNumber : Option[uint64] - ttdReached : bool + ttdReached* : bool client : RpcClient ttd : DifficultyInt diff --git a/hive_integration/nodocker/engine/engine_client.nim b/hive_integration/nodocker/engine/engine_client.nim index d8ef0a892..a106da0d8 100644 --- a/hive_integration/nodocker/engine/engine_client.nim +++ b/hive_integration/nodocker/engine/engine_client.nim @@ -124,7 +124,7 @@ proc blockByNumber*(client: RpcClient, number: uint64, output: var common.EthBlo return ok() except ValueError as e: return err(e.msg) - + proc latestHeader*(client: RpcClient, output: var common.BlockHeader): Result[void, string] = try: let res = waitFor client.eth_getBlockByNumber("latest", false) @@ -189,3 +189,33 @@ proc storageAt*(client: RpcClient, address: EthAddress, slot: UInt256, number: c return ok(UInt256.fromHex(res.string)) except ValueError as e: return err(e.msg) + +proc verifyPoWProgress*(client: RpcClient, lastBlockHash: Hash256): Future[Result[void, string]] {.async.} = + let res = await client.eth_getBlockByHash(lastBlockHash, false) + if res.isNone: + return err("cannot get block by hash " & lastBlockHash.data.toHex) + + let header = res.get() + let number = toBlockNumber(header.number) + + let period = chronos.seconds(3) + var loop = 0 + while loop < 5: + let res = await client.eth_getBlockByNumber("latest", false) + if res.isNone: + return err("cannot get latest block") + + # Chain has progressed, check that the next block is also PoW + # Difficulty must NOT be zero + let bc = res.get() + let diff = hexToInt(string bc.difficulty, int64) + if diff == 0: + return err("Expected PoW chain to progress in PoW mode, but following block difficulty: " & $diff) + + if toBlockNumber(bc.number) > number: + return ok() + + await sleepAsync(period) + inc loop + + return err("verify PoW Progress timeout") diff --git a/hive_integration/nodocker/engine/engine_tests.nim b/hive_integration/nodocker/engine/engine_tests.nim index 3f5fbab6a..d270119a3 100644 --- a/hive_integration/nodocker/engine/engine_tests.nim +++ b/hive_integration/nodocker/engine/engine_tests.nim @@ -45,17 +45,20 @@ proc invalidTerminalBlockForkchoiceUpdated(t: TestEnv): TestStatus = let res = t.rpcClient.forkchoiceUpdatedV1(forkchoiceState) # Execution specification: - # {payloadStatus: {status: INVALID_TERMINAL_BLOCK, latestValidHash: null, validationError: errorMessage | null}, payloadId: null} + # {payloadStatus: {status: INVALID, latestValidHash=0x00..00}, payloadId: null} # either obtained from the Payload validation process or as a result of validating a PoW block referenced by forkchoiceState.headBlockHash testCond res.isOk let s = res.get() - testCond s.payloadStatus.status == PayloadExecutionStatus.invalid_terminal_block + testCond s.payloadStatus.status == PayloadExecutionStatus.invalid testCond s.payloadStatus.latestValidHash.isNone testCond s.payloadId.isNone # ValidationError is not validated since it can be either null or a string message + # Check that PoW chain progresses + testCond t.verifyPoWProgress(t.gHeader.blockHash) + # Invalid GetPayload Under PoW: Client must reject GetPayload directives under PoW. proc invalidGetPayloadUnderPoW(t: TestEnv): TestStatus = result = TestStatus.OK @@ -90,7 +93,7 @@ proc invalidTerminalBlockNewPayload(t: TestEnv): TestStatus = testCond res.isOk let s = res.get() - testCond s.status == PayloadExecutionStatus.invalid_terminal_block + testCond s.status == PayloadExecutionStatus.invalid testCond s.latestValidHash.isNone proc unknownHeadBlockHash(t: TestEnv): TestStatus = @@ -989,17 +992,29 @@ proc suggestedFeeRecipient(t: TestEnv): TestStatus = error "balance does not match fees", feeRecipientBalance, feeRecipientFees +proc sendTx(t: TestEnv): Future[void] {.async.} = + let + client = t.rpcClient + clMock = t.clMock + period = chronos.milliseconds(100) + + while not clMock.ttdReached: + await sleepAsync(period) + + let + tx = t.makeNextTransaction(prevRandaoContractAddr, 0.u256) + rr = client.sendTransaction(tx) + + if rr.isErr: + error "Unable to send transaction", msg=rr.error + proc prevRandaoOpcodeTx(t: TestEnv): TestStatus = result = TestStatus.OK let client = t.rpcClient clMock = t.clMock - tx = t.makeNextTransaction(prevRandaoContractAddr, 0.u256) - rr = client.sendTransaction(tx) - - testCond rr.isOk: - error "Unable to send transaction", msg=rr.error + sendTxFuture = sendTx(t) # Wait until TTD is reached by this client let ok = waitFor clMock.waitForTTD() @@ -1039,7 +1054,7 @@ proc postMergeSync(t: TestEnv): TestStatus = # TODO: need multiple client const engineTestList* = [ - TestSpec( + #[TestSpec( name: "Invalid Terminal Block in ForkchoiceUpdated", run: invalidTerminalBlockForkchoiceUpdated, ttd: 1000000 @@ -1186,7 +1201,7 @@ const engineTestList* = [ TestSpec( name: "Suggested Fee Recipient Test", run: suggestedFeeRecipient, - ), + ),]# # TODO: debug and fix # PrevRandao opcode tests diff --git a/hive_integration/nodocker/engine/test_env.nim b/hive_integration/nodocker/engine/test_env.nim index f25c87e1d..9e4b2693e 100644 --- a/hive_integration/nodocker/engine/test_env.nim +++ b/hive_integration/nodocker/engine/test_env.nim @@ -149,3 +149,12 @@ proc makeNextTransaction*(t: TestEnv, recipient: EthAddress, amount: UInt256, pa inc t.nonce signTransaction(tx, t.vaultKey, chainId, eip155 = true) + +proc verifyPoWProgress*(t: TestEnv, lastBlockHash: Hash256): bool = + let res = waitFor verifyPoWProgress(t.rpcClient, lastBlockHash) + if res.isErr: + error "verify PoW Progress error", msg=res.error + return false + + true + \ No newline at end of file diff --git a/nimbus/rpc/engine_api.nim b/nimbus/rpc/engine_api.nim index 9a286797e..fd52fca4b 100644 --- a/nimbus/rpc/engine_api.nim +++ b/nimbus/rpc/engine_api.nim @@ -84,7 +84,7 @@ proc setupEngineAPI*( if td < ttd: warn "Ignoring pre-merge payload", number = header.blockNumber, hash = blockHash.data.toHex, td, ttd - return PayloadStatusV1(status: PayloadExecutionStatus.invalid_terminal_block) + return PayloadStatusV1(status: PayloadExecutionStatus.invalid) if header.timestamp <= parent.timestamp: warn "Invalid timestamp", @@ -231,7 +231,7 @@ proc setupEngineAPI*( ptd = ptd, ttd = ttd - return simpleFCU(PayloadExecutionStatus.invalid_terminal_block) + return simpleFCU(PayloadExecutionStatus.invalid) # If the head block is already in our canonical chain, the beacon client is # probably resyncing. Ignore the update.