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
|
let
|
||||||
client = t.rpcClient
|
client = t.rpcClient
|
||||||
clMock = t.clMock
|
clMock = t.clMock
|
||||||
period = chronos.milliseconds(100)
|
period = chronos.milliseconds(500)
|
||||||
|
|
||||||
while not clMock.ttdReached:
|
while not clMock.ttdReached:
|
||||||
await sleepAsync(period)
|
await sleepAsync(period)
|
||||||
|
@ -1474,6 +1474,55 @@ proc prevRandaoOpcodeTx(t: TestEnv): TestStatus =
|
||||||
expect=2,
|
expect=2,
|
||||||
get=opcodeValueAtBlock
|
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 =
|
proc postMergeSync(t: TestEnv): TestStatus =
|
||||||
result = TestStatus.SKIPPED
|
result = TestStatus.SKIPPED
|
||||||
# TODO: need multiple client
|
# TODO: need multiple client
|
||||||
|
@ -1612,11 +1661,11 @@ const engineTestList* = [
|
||||||
|
|
||||||
# Eth RPC Status on ForkchoiceUpdated Events
|
# Eth RPC Status on ForkchoiceUpdated Events
|
||||||
|
|
||||||
TestSpec(
|
TestSpec( # TODO: fix/debug
|
||||||
name: "Latest Block after NewPayload",
|
name: "Latest Block after NewPayload",
|
||||||
run: blockStatusExecPayload1,
|
run: blockStatusExecPayload1,
|
||||||
),
|
),
|
||||||
TestSpec(
|
TestSpec( # TODO: fix/debug
|
||||||
name: "Latest Block after NewPayload (Transition Block)",
|
name: "Latest Block after NewPayload (Transition Block)",
|
||||||
run: blockStatusExecPayload2,
|
run: blockStatusExecPayload2,
|
||||||
ttd: 5,
|
ttd: 5,
|
||||||
|
@ -1691,7 +1740,6 @@ const engineTestList* = [
|
||||||
run: suggestedFeeRecipient,
|
run: suggestedFeeRecipient,
|
||||||
),
|
),
|
||||||
|
|
||||||
# TODO: debug and fix
|
|
||||||
# PrevRandao opcode tests
|
# PrevRandao opcode tests
|
||||||
TestSpec(
|
TestSpec(
|
||||||
name: "PrevRandao Opcode Transactions",
|
name: "PrevRandao Opcode Transactions",
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import
|
import
|
||||||
std/typetraits,
|
std/[typetraits, json, strutils],
|
||||||
test_env,
|
test_env,
|
||||||
eth/rlp
|
eth/rlp,
|
||||||
|
stew/byteutils,
|
||||||
|
json_rpc/rpcclient,
|
||||||
|
../../../nimbus/rpc/hexstrings
|
||||||
|
|
||||||
type
|
type
|
||||||
ExecutableData* = object
|
ExecutableData* = object
|
||||||
|
@ -144,3 +147,41 @@ proc toExecutableData*(payload: ExecutionPayloadV1): ExecutableData =
|
||||||
for data in payload.transactions:
|
for data in payload.transactions:
|
||||||
let tx = rlp.decode(distinctBase data, Transaction)
|
let tx = rlp.decode(distinctBase data, Transaction)
|
||||||
result.transactions.add tx
|
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,
|
db/db_chain,
|
||||||
rpc/p2p,
|
rpc/p2p,
|
||||||
rpc/engine_api,
|
rpc/engine_api,
|
||||||
|
rpc/debug,
|
||||||
sync/protocol,
|
sync/protocol,
|
||||||
utils/tx_pool
|
utils/tx_pool
|
||||||
],
|
],
|
||||||
|
@ -93,6 +94,7 @@ proc setupELClient*(t: TestEnv) =
|
||||||
|
|
||||||
setupEthRpc(t.ethNode, t.ctx, t.chainDB, txPool, t.rpcServer)
|
setupEthRpc(t.ethNode, t.ctx, t.chainDB, txPool, t.rpcServer)
|
||||||
setupEngineAPI(t.sealingEngine, t.rpcServer)
|
setupEngineAPI(t.sealingEngine, t.rpcServer)
|
||||||
|
setupDebugRpc(t.chainDB, t.rpcServer)
|
||||||
|
|
||||||
t.sealingEngine.start()
|
t.sealingEngine.start()
|
||||||
t.rpcServer.start()
|
t.rpcServer.start()
|
||||||
|
@ -155,6 +157,5 @@ proc verifyPoWProgress*(t: TestEnv, lastBlockHash: Hash256): bool =
|
||||||
if res.isErr:
|
if res.isErr:
|
||||||
error "verify PoW Progress error", msg=res.error
|
error "verify PoW Progress error", msg=res.error
|
||||||
return false
|
return false
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
Loading…
Reference in New Issue