mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-24 19:19:21 +00:00
engine api test: handle JsonRpcError for each client rpc call
This commit is contained in:
parent
5f0e89a41e
commit
11908c78ec
@ -1,9 +1,9 @@
|
||||
import
|
||||
std/[times, json],
|
||||
std/[times, json, strutils],
|
||||
stew/byteutils,
|
||||
eth/[common, rlp], chronos,
|
||||
web3/engine_api_types,
|
||||
json_rpc/rpcclient,
|
||||
json_rpc/[rpcclient, errors],
|
||||
../../../tests/rpcclient/eth_api,
|
||||
../../../premix/parser,
|
||||
../../../nimbus/rpc/hexstrings,
|
||||
@ -11,31 +11,35 @@ import
|
||||
|
||||
import web3/engine_api as web3_engine_api
|
||||
|
||||
template wrapTry(body: untyped) =
|
||||
try:
|
||||
body
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
except JsonRpcError as ex:
|
||||
return err(ex.msg)
|
||||
|
||||
template wrapTrySimpleRes(body: untyped) =
|
||||
wrapTry:
|
||||
let res = waitFor body
|
||||
return ok(res)
|
||||
|
||||
proc forkchoiceUpdatedV1*(client: RpcClient,
|
||||
update: ForkchoiceStateV1,
|
||||
payloadAttributes = none(PayloadAttributesV1)):
|
||||
Result[ForkchoiceUpdatedResponse, string] =
|
||||
try:
|
||||
let res = waitFor client.engine_forkchoiceUpdatedV1(update, payloadAttributes)
|
||||
return ok(res)
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
wrapTrySimpleRes:
|
||||
client.engine_forkchoiceUpdatedV1(update, payloadAttributes)
|
||||
|
||||
proc getPayloadV1*(client: RpcClient, payloadId: PayloadID): Result[ExecutionPayloadV1, string] =
|
||||
try:
|
||||
let res = waitFor client.engine_getPayloadV1(payloadId)
|
||||
return ok(res)
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
wrapTrySimpleRes:
|
||||
client.engine_getPayloadV1(payloadId)
|
||||
|
||||
proc newPayloadV1*(client: RpcClient,
|
||||
payload: ExecutionPayloadV1):
|
||||
Result[PayloadStatusV1, string] =
|
||||
try:
|
||||
let res = waitFor client.engine_newPayloadV1(payload)
|
||||
return ok(res)
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
wrapTrySimpleRes:
|
||||
client.engine_newPayloadV1(payload)
|
||||
|
||||
proc toBlockNumber(n: Option[HexQuantityStr]): common.BlockNumber =
|
||||
if n.isNone:
|
||||
@ -95,25 +99,21 @@ proc waitForTTD*(client: RpcClient,
|
||||
return (emptyHeader, false)
|
||||
|
||||
proc blockNumber*(client: RpcClient): Result[uint64, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_blockNumber()
|
||||
return ok(hexToInt(string res, uint64))
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc headerByNumber*(client: RpcClient, number: uint64, output: var common.BlockHeader): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let qty = encodeQuantity(number)
|
||||
let res = waitFor client.eth_getBlockByNumber(string qty, false)
|
||||
if res.isNone:
|
||||
return err("failed to get blockHeader: " & $number)
|
||||
output = toBlockHeader(res.get())
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc blockByNumber*(client: RpcClient, number: uint64, output: var common.EthBlock): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let qty = encodeQuantity(number)
|
||||
let res = waitFor client.eth_getBlockByNumber(string qty, true)
|
||||
if res.isNone:
|
||||
@ -122,32 +122,26 @@ proc blockByNumber*(client: RpcClient, number: uint64, output: var common.EthBlo
|
||||
output.header = toBlockHeader(blk)
|
||||
output.txs = toTransactions(blk.transactions)
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc headerByHash*(client: RpcClient, hash: Hash256, output: var common.BlockHeader): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getBlockByHash(hash, false)
|
||||
if res.isNone:
|
||||
return err("failed to get block: " & hash.data.toHex)
|
||||
let blk = res.get()
|
||||
output = toBlockHeader(blk)
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc latestHeader*(client: RpcClient, output: var common.BlockHeader): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getBlockByNumber("latest", false)
|
||||
if res.isNone:
|
||||
return err("failed to get latest blockHeader")
|
||||
output = toBlockHeader(res.get())
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc latestBlock*(client: RpcClient, output: var common.EthBlock): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getBlockByNumber("latest", true)
|
||||
if res.isNone:
|
||||
return err("failed to get latest blockHeader")
|
||||
@ -155,21 +149,17 @@ proc latestBlock*(client: RpcClient, output: var common.EthBlock): Result[void,
|
||||
output.header = toBlockHeader(blk)
|
||||
output.txs = toTransactions(blk.transactions)
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc namedHeader*(client: RpcClient, name: string, output: var common.BlockHeader): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getBlockByNumber(name, false)
|
||||
if res.isNone:
|
||||
return err("failed to get named blockHeader")
|
||||
output = toBlockHeader(res.get())
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc sendTransaction*(client: RpcClient, tx: common.Transaction): Result[void, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let encodedTx = rlp.encode(tx)
|
||||
let res = waitFor client.eth_sendRawTransaction(hexDataStr(encodedTx))
|
||||
let txHash = rlpHash(tx)
|
||||
@ -177,24 +167,18 @@ proc sendTransaction*(client: RpcClient, tx: common.Transaction): Result[void, s
|
||||
if txHash != getHash:
|
||||
return err("sendTransaction: tx hash mismatch")
|
||||
return ok()
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc balanceAt*(client: RpcClient, address: EthAddress): Result[UInt256, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getBalance(ethAddressStr(address), "latest")
|
||||
return ok(UInt256.fromHex(res.string))
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc txReceipt*(client: RpcClient, txHash: Hash256): Result[eth_api.ReceiptObject, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getTransactionReceipt(txHash)
|
||||
if res.isNone:
|
||||
return err("failed to get receipt: " & txHash.data.toHex)
|
||||
return ok(res.get)
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc toDataStr(slot: UInt256): HexDataStr =
|
||||
let hex = slot.toHex
|
||||
@ -202,19 +186,15 @@ proc toDataStr(slot: UInt256): HexDataStr =
|
||||
HexDataStr(prefix & hex)
|
||||
|
||||
proc storageAt*(client: RpcClient, address: EthAddress, slot: UInt256): Result[UInt256, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let res = waitFor client.eth_getStorageAt(ethAddressStr(address), toDataStr(slot), "latest")
|
||||
return ok(UInt256.fromHex(res.string))
|
||||
except ValueError as e:
|
||||
return err(e.msg)
|
||||
|
||||
proc storageAt*(client: RpcClient, address: EthAddress, slot: UInt256, number: common.BlockNumber): Result[UInt256, string] =
|
||||
try:
|
||||
wrapTry:
|
||||
let tag = encodeQuantity(number)
|
||||
let res = waitFor client.eth_getStorageAt(ethAddressStr(address), toDataStr(slot), tag.string)
|
||||
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)
|
||||
@ -245,3 +225,40 @@ proc verifyPoWProgress*(client: RpcClient, lastBlockHash: Hash256): Future[Resul
|
||||
inc loop
|
||||
|
||||
return err("verify PoW Progress timeout")
|
||||
|
||||
|
||||
proc debugPrevRandaoTransaction*(client: RpcClient, tx: Transaction, expectedPrevRandao: Hash256): Result[void, string] =
|
||||
wrapTry:
|
||||
let hash = tx.rlpHash
|
||||
# we only interested in stack, disable all other elems
|
||||
let opts = %* {
|
||||
"disableStorage": true,
|
||||
"disableMemory": true,
|
||||
"disableState": true,
|
||||
"disableStateDiff": true
|
||||
}
|
||||
|
||||
let res = waitFor client.call("debug_traceTransaction", %[%hash, opts])
|
||||
let structLogs = res["structLogs"]
|
||||
|
||||
var prevRandaoFound = false
|
||||
for i, x in structLogs.elems:
|
||||
let op = x["op"].getStr
|
||||
if op != "DIFFICULTY": continue
|
||||
|
||||
if i+1 >= structLogs.len:
|
||||
return err("No information after PREVRANDAO operation")
|
||||
|
||||
prevRandaoFound = true
|
||||
let stack = structLogs[i+1]["stack"]
|
||||
if stack.len < 1:
|
||||
return err("Invalid stack after PREVRANDAO operation")
|
||||
|
||||
let stackHash = Hash256(data: hextoByteArray[32](stack[0].getStr))
|
||||
if stackHash != expectedPrevRandao:
|
||||
return err("Invalid stack after PREVRANDAO operation $1 != $2" % [stackHash.data.toHex, expectedPrevRandao.data.toHex])
|
||||
|
||||
if not prevRandaoFound:
|
||||
return err("PREVRANDAO opcode not found")
|
||||
|
||||
return ok()
|
||||
|
@ -1736,6 +1736,8 @@ proc prevRandaoOpcodeTx(t: TestEnv): TestStatus =
|
||||
return true
|
||||
))
|
||||
|
||||
testCond produceBlockRes
|
||||
|
||||
let rr = client.blockNumber()
|
||||
testCond rr.isOk:
|
||||
error "Unable to get latest block number"
|
||||
|
@ -1,10 +1,10 @@
|
||||
import
|
||||
std/[typetraits, json, strutils],
|
||||
std/[typetraits, json],
|
||||
nimcrypto,
|
||||
test_env,
|
||||
eth/[common, rlp, keys],
|
||||
stew/byteutils,
|
||||
json_rpc/[rpcclient, errors],
|
||||
json_rpc/[rpcclient],
|
||||
../../../nimbus/rpc/hexstrings,
|
||||
../../../nimbus/transaction
|
||||
|
||||
@ -183,48 +183,6 @@ proc toExecutableData*(payload: ExecutionPayloadV1): ExecutableData =
|
||||
proc customizePayload*(basePayload: ExecutionPayloadV1, customData: CustomPayload): ExecutionPayloadV1 =
|
||||
customizePayload(basePayload.toExecutableData, customData)
|
||||
|
||||
proc debugPrevRandaoTransaction*(client: RpcClient, tx: Transaction, expectedPrevRandao: Hash256): Result[void, string] =
|
||||
try:
|
||||
let hash = tx.rlpHash
|
||||
# we only interested in stack, disable all other elems
|
||||
let opts = %* {
|
||||
"disableStorage": true,
|
||||
"disableMemory": true,
|
||||
"disableState": true,
|
||||
"disableStateDiff": true
|
||||
}
|
||||
|
||||
let res = waitFor client.call("debug_traceTransaction", %[%hash, opts])
|
||||
let structLogs = res["structLogs"]
|
||||
|
||||
var prevRandaoFound = false
|
||||
for i, x in structLogs.elems:
|
||||
let op = x["op"].getStr
|
||||
if op != "DIFFICULTY": continue
|
||||
|
||||
if i+1 >= structLogs.len:
|
||||
return err("No information after PREVRANDAO operation")
|
||||
|
||||
prevRandaoFound = true
|
||||
let stack = structLogs[i+1]["stack"]
|
||||
if stack.len < 1:
|
||||
return err("Invalid stack after PREVRANDAO operation")
|
||||
|
||||
let stackHash = Hash256(data: hextoByteArray[32](stack[0].getStr))
|
||||
if stackHash != expectedPrevRandao:
|
||||
return err("Invalid stack after PREVRANDAO operation $1 != $2" % [stackHash.data.toHex, expectedPrevRandao.data.toHex])
|
||||
|
||||
if not prevRandaoFound:
|
||||
return err("PREVRANDAO opcode not found")
|
||||
|
||||
ok()
|
||||
except ValueError as e:
|
||||
err(e.msg)
|
||||
except JsonRpcError as ex:
|
||||
# occasionally for unknown reason this proc will fail in CI
|
||||
# let's see what actually trigger it
|
||||
err(ex.msg)
|
||||
|
||||
proc customizeTx(baseTx: Transaction, vaultKey: PrivateKey, customTx: CustomTx): Transaction =
|
||||
# Create a modified transaction base, from the base transaction and customData mix
|
||||
var modTx = Transaction(
|
||||
|
@ -11,13 +11,18 @@ import
|
||||
std/[typetraits, times, strutils],
|
||||
stew/[objects, results, byteutils],
|
||||
json_rpc/[rpcserver, errors],
|
||||
web3/[conversions, engine_api_types], chronicles,
|
||||
web3/[conversions, engine_api_types],
|
||||
eth/[rlp, common],
|
||||
".."/db/db_chain,
|
||||
".."/p2p/chain/[chain_desc, persist_blocks],
|
||||
".."/[sealer, constants],
|
||||
".."/merge/[mergetypes, mergeutils],
|
||||
".."/utils/tx_pool
|
||||
".."/utils/tx_pool,
|
||||
# put chronicles import last because Nim
|
||||
# compiler resolve `$` for logging
|
||||
# arguments differently on Windows vs posix
|
||||
# if chronicles import is in the middle
|
||||
chronicles
|
||||
|
||||
proc latestValidHash(db: BaseChainDB, parent: EthBlockHeader, ttd: DifficultyInt): Hash256 =
|
||||
let ptd = db.getScore(parent.parentHash)
|
||||
|
Loading…
x
Reference in New Issue
Block a user