completing 'PrevRandao Opcode Transactions' test case in engine api test
This commit is contained in:
parent
77be2f66d2
commit
ee13e5fdae
|
@ -1421,7 +1421,7 @@ proc sendTx(t: TestEnv): Future[void] {.async.} =
|
|||
let
|
||||
client = t.rpcClient
|
||||
clMock = t.clMock
|
||||
period = chronos.milliseconds(100)
|
||||
period = chronos.milliseconds(500)
|
||||
|
||||
while not clMock.ttdReached:
|
||||
await sleepAsync(period)
|
||||
|
@ -1474,6 +1474,55 @@ proc prevRandaoOpcodeTx(t: TestEnv): TestStatus =
|
|||
expect=2,
|
||||
get=opcodeValueAtBlock
|
||||
|
||||
# Send transactions now past TTD, the value of the storage in these blocks must match the prevRandao value
|
||||
type
|
||||
ShadowTx = ref object
|
||||
currentTxIndex: int
|
||||
txs: seq[Transaction]
|
||||
|
||||
let shadow = ShadowTx(currentTxIndex: 0)
|
||||
|
||||
let produceBlockRes = clMock.produceBlocks(1, BlockProcessCallbacks(
|
||||
onPayloadProducerSelected: proc(): bool =
|
||||
let
|
||||
tx = t.makeNextTransaction(prevRandaoContractAddr, 0.u256)
|
||||
rr = client.sendTransaction(tx)
|
||||
|
||||
if rr.isErr:
|
||||
error "Unable to send transaction", msg=rr.error
|
||||
return false
|
||||
|
||||
shadow.txs.add tx
|
||||
inc shadow.currentTxIndex
|
||||
return true
|
||||
,
|
||||
onForkchoiceBroadcast: proc(): bool =
|
||||
# Check the transaction tracing, which is client specific
|
||||
let expectedPrevRandao = clMock.prevRandaoHistory[clMock.latestHeadNumber + 1'u64]
|
||||
let res = debugPrevRandaoTransaction(client, shadow.txs[shadow.currentTxIndex-1], expectedPrevRandao)
|
||||
if res.isErr:
|
||||
error "unable to debug prev randao", msg=res.error
|
||||
return false
|
||||
return true
|
||||
))
|
||||
|
||||
let rr = client.blockNumber()
|
||||
testCond rr.isOk:
|
||||
error "Unable to get latest block number"
|
||||
|
||||
let lastBlockNumber = rr.get()
|
||||
for i in ttdBlockNumber + 1 ..< lastBlockNumber:
|
||||
let expectedPrevRandao = UInt256.fromBytesBE(clMock.prevRandaoHistory[i].data)
|
||||
let storageKey = i.u256
|
||||
|
||||
let rz = client.storageAt(prevRandaoContractAddr, storageKey)
|
||||
testCond rz.isOk:
|
||||
error "Unable to get storage", msg=rz.error
|
||||
|
||||
let storage = rz.get()
|
||||
testCond storage == expectedPrevRandao:
|
||||
error "Unexpected storage", expected=expectedPrevRandao.toHex, get=storage.toHex
|
||||
|
||||
proc postMergeSync(t: TestEnv): TestStatus =
|
||||
result = TestStatus.SKIPPED
|
||||
# TODO: need multiple client
|
||||
|
@ -1612,11 +1661,11 @@ const engineTestList* = [
|
|||
|
||||
# Eth RPC Status on ForkchoiceUpdated Events
|
||||
|
||||
TestSpec(
|
||||
TestSpec( # TODO: fix/debug
|
||||
name: "Latest Block after NewPayload",
|
||||
run: blockStatusExecPayload1,
|
||||
),
|
||||
TestSpec(
|
||||
TestSpec( # TODO: fix/debug
|
||||
name: "Latest Block after NewPayload (Transition Block)",
|
||||
run: blockStatusExecPayload2,
|
||||
ttd: 5,
|
||||
|
@ -1691,7 +1740,6 @@ const engineTestList* = [
|
|||
run: suggestedFeeRecipient,
|
||||
),
|
||||
|
||||
# TODO: debug and fix
|
||||
# PrevRandao opcode tests
|
||||
TestSpec(
|
||||
name: "PrevRandao Opcode Transactions",
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import
|
||||
std/typetraits,
|
||||
std/[typetraits, json, strutils],
|
||||
test_env,
|
||||
eth/rlp
|
||||
eth/rlp,
|
||||
stew/byteutils,
|
||||
json_rpc/rpcclient,
|
||||
../../../nimbus/rpc/hexstrings
|
||||
|
||||
type
|
||||
ExecutableData* = object
|
||||
|
@ -144,3 +147,41 @@ proc toExecutableData*(payload: ExecutionPayloadV1): ExecutableData =
|
|||
for data in payload.transactions:
|
||||
let tx = rlp.decode(distinctBase data, Transaction)
|
||||
result.transactions.add tx
|
||||
|
||||
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)
|
||||
|
|
|
@ -18,6 +18,7 @@ import
|
|||
db/db_chain,
|
||||
rpc/p2p,
|
||||
rpc/engine_api,
|
||||
rpc/debug,
|
||||
sync/protocol,
|
||||
utils/tx_pool
|
||||
],
|
||||
|
@ -93,6 +94,7 @@ proc setupELClient*(t: TestEnv) =
|
|||
|
||||
setupEthRpc(t.ethNode, t.ctx, t.chainDB, txPool, t.rpcServer)
|
||||
setupEngineAPI(t.sealingEngine, t.rpcServer)
|
||||
setupDebugRpc(t.chainDB, t.rpcServer)
|
||||
|
||||
t.sealingEngine.start()
|
||||
t.rpcServer.start()
|
||||
|
@ -155,6 +157,5 @@ proc verifyPoWProgress*(t: TestEnv, lastBlockHash: Hash256): bool =
|
|||
if res.isErr:
|
||||
error "verify PoW Progress error", msg=res.error
|
||||
return false
|
||||
|
||||
|
||||
true
|
||||
|
Loading…
Reference in New Issue