diff --git a/nimbus/beacon/api_handler/api_newpayload.nim b/nimbus/beacon/api_handler/api_newpayload.nim index 17e88b201..7a50b5ab6 100644 --- a/nimbus/beacon/api_handler/api_newpayload.nim +++ b/nimbus/beacon/api_handler/api_newpayload.nim @@ -197,8 +197,8 @@ proc newPayload*(ben: BeaconEngineRef, return invalidStatus(blockHash, vres.error()) info "New payload received and validated", - number = header.number, - hash = blockHash.short, + number = header.number, + hash = blockHash.short, parent = header.parentHash.short, txs = blk.transactions.len, gasUsed = header.gasUsed, diff --git a/nimbus/beacon/api_handler/api_utils.nim b/nimbus/beacon/api_handler/api_utils.nim index 5717004f2..08084da35 100644 --- a/nimbus/beacon/api_handler/api_utils.nim +++ b/nimbus/beacon/api_handler/api_utils.nim @@ -48,10 +48,10 @@ proc computePayloadId*(blockHash: common.Hash32, (distinctBase result)[0..7] = dest.data[0..7] proc validateBlockHash*(header: common.Header, - gotHash: common.Hash32, + wantHash: common.Hash32, version: Version): Result[void, PayloadStatusV1] {.gcsafe, raises: [ValueError].} = - let wantHash = header.blockHash + let gotHash = header.blockHash if wantHash != gotHash: let status = if version == Version.V1: PayloadExecutionStatus.invalid_block_hash diff --git a/nimbus/core/executor/process_block.nim b/nimbus/core/executor/process_block.nim index 77c9c5d8b..9222e5b13 100644 --- a/nimbus/core/executor/process_block.nim +++ b/nimbus/core/executor/process_block.nim @@ -191,7 +191,7 @@ proc procBlkEpilogue( if header.requestsHash.isSome: let depositReqs = ?parseDepositLogs(vmState.allLogs) - requestsHash = calcRequestsHashInsertType(depositReqs, withdrawalReqs, consolidationReqs) + requestsHash = calcRequestsHash(depositReqs, withdrawalReqs, consolidationReqs) if header.requestsHash.get != requestsHash: debug "wrong requestsHash in block", diff --git a/nimbus/core/tx_pool.nim b/nimbus/core/tx_pool.nim index 664b2794f..2f058b742 100644 --- a/nimbus/core/tx_pool.nim +++ b/nimbus/core/tx_pool.nim @@ -482,7 +482,7 @@ proc assembleBlock*( ## Note that this getter runs *ad hoc* all the txs through the VM in ## order to build the block. - let pst = xp.packerVmExec().valueOr: # updates vmState + var pst = xp.packerVmExec().valueOr: # updates vmState return err(error) var blk = EthBlock( diff --git a/nimbus/core/tx_pool/tx_packer.nim b/nimbus/core/tx_pool/tx_packer.nim index d2a298c51..2f4a4864f 100644 --- a/nimbus/core/tx_pool/tx_packer.nim +++ b/nimbus/core/tx_pool/tx_packer.nim @@ -346,23 +346,17 @@ proc assembleHeader*(pst: TxPacker): Header = result.excessBlobGas = Opt.some vmState.blockCtx.excessBlobGas if com.isPragueOrLater(pos.timestamp): - let requestsHash = calcRequestsHashInsertType(pst.depositReqs, + let requestsHash = calcRequestsHash(pst.depositReqs, pst.withdrawalReqs, pst.consolidationReqs) result.requestsHash = Opt.some(requestsHash) func blockValue*(pst: TxPacker): UInt256 = pst.blockValue -func executionRequests*(pst: TxPacker): array[3, seq[byte]] = - result[0] = newSeqOfCap[byte](pst.depositReqs.len+1) - result[0].add 0x00.byte - result[0].add pst.depositReqs - result[1] = newSeqOfCap[byte](pst.withdrawalReqs.len+1) - result[1].add 0x01.byte - result[1].add pst.withdrawalReqs - result[2] = newSeqOfCap[byte](pst.consolidationReqs.len+1) - result[2].add 0x02.byte - result[2].add pst.consolidationReqs +func executionRequests*(pst: var TxPacker): array[3, seq[byte]] = + result[0] = move(pst.depositReqs) + result[1] = move(pst.withdrawalReqs) + result[2] = move(pst.consolidationReqs) # ------------------------------------------------------------------------------ # End diff --git a/nimbus/utils/utils.nim b/nimbus/utils/utils.nim index 8f2b68879..456ba7bed 100644 --- a/nimbus/utils/utils.nim +++ b/nimbus/utils/utils.nim @@ -28,20 +28,19 @@ template calcWithdrawalsRoot*(withdrawals: openArray[Withdrawal]): Root = template calcReceiptsRoot*(receipts: openArray[Receipt]): Root = orderedTrieRoot(receipts) -func calcRequestsHashInsertType*(requests: varargs[seq[byte]]): Hash32 = - var ctx: sha256 - ctx.init() - for i, data in requests: - ctx.update([i.byte]) # request type - ctx.update data - ctx.finish(result.data) - ctx.clear() - func calcRequestsHash*(requests: varargs[seq[byte]]): Hash32 = + func calcHash(reqType: byte, data: openArray[byte]): Hash32 = + var ctx: sha256 + ctx.init() + ctx.update([reqType]) # request type + ctx.update data + ctx.finish(result.data) + ctx.clear() + var ctx: sha256 ctx.init() for i, data in requests: - ctx.update data + ctx.update(calcHash(i.byte, data).data) ctx.finish(result.data) ctx.clear() diff --git a/tests/engine_api/newPayloadV4_invalid_blockhash.json b/tests/engine_api/newPayloadV4_invalid_blockhash.json new file mode 100644 index 000000000..5a0d3d866 --- /dev/null +++ b/tests/engine_api/newPayloadV4_invalid_blockhash.json @@ -0,0 +1,42 @@ +{ + "payload": { + "baseFeePerGas": "0x7", + "blobGasUsed": "0x40000", + "blockHash": "0x187307d7dc9beb87af2a1d8340e9f17a3bbe4738963daeaf6d8e13b27b2d6a7f", + "blockNumber": "0x94b2", + "excessBlobGas": "0x0", + "extraData": "0xd883010e0c846765746888676f312e32332e32856c696e7578", + "feeRecipient": "0xf97e180c050e5ab072211ad2c213eb5aee4df134", + "gasLimit": "0x1c9c380", + "gasUsed": "0x33450", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "parentHash": "0xb647cb4bb1671b0c619c4c71b40effc80ce96819cb2832b52be6cda03d0e5fee", + "prevRandao": "0x7054943af1e7e26984ce8b44069f82d2a8d43ba4ce8a6ca5332978032db9acd3", + "receiptsRoot": "0x86b0c83ced5201a87641678023531e90eddfacb8e3ce78256bf7417037d387b9", + "stateRoot": "0x4a7f23a99ac14da1af4f1d0ca0b740c8cda0753676f2cf079089a74dcb2d4f24", + "timestamp": "0x671b65c6", + "transactions": [ + "0xf86b8233c8858bb2c972bc82520894d3248ba3e5492d767f8e427cb9c7b9d5c3972d7b01808503479468b7a0db0d13a11dc81e1b9297eb0322f26f6ff3380d7c7ec3929ee839fb7e9961b2ffa02588e1e28146dfc70e475ed89720db3dd7deeb4bdf16d67d33246465ab9fbcc1", + "0xf86b8233c9858bb2c972bc82520894d3248ba3e5492d767f8e427cb9c7b9d5c3972d7b01808503479468b7a005ddb5765e447c0cfe7394804bc868b95ec89e3aad4ce75142b94964648dcbc8a032edba7aa886708e13418b27325de673dd992fe0fc16e2432201320c737a8ebc", + "0xf86b8233ca858bb2c972bc82520894d3248ba3e5492d767f8e427cb9c7b9d5c3972d7b01808503479468b7a058303cc9724abc56bf143ce355f26042fd19dec468783b7dec3144ee378a7870a00d00461b597d96144fed4134cef4399d61f490d7dba3552faf32a7d4ff651956", + "0xf86b8233cb858bb2c972bc82520894d3248ba3e5492d767f8e427cb9c7b9d5c3972d7b01808503479468b7a0687ca518efea103a78c902b6dec99bae14e3d7e7c8c669cf34731ee326d8aa26a0641d4c0f4e51c7031b5d127b109f2f0c3faec4f4af6666aee4ec28576aa989db", + "0xf86b823360858bb2c972bc82520894454b0ea7d8ad3c56d0cf2e44ed97b2feab4d7af201808503479468b8a0ba0ceedcb6ecf00c691f319aa3e290162aa6a7c1904d8d037ff673aa22022069a062d9a5866974973a83ef187e95ab73db1036deca8e0ba8da19399159d8e5aead", + "0xf86b823361858bb2c972bc82520894454b0ea7d8ad3c56d0cf2e44ed97b2feab4d7af201808503479468b8a0ddbf85460a81bd05f260e539565af01e92e9e6727d3d07263bd84b42663cd1cfa0058600ed2e85cd0ccc36519d474def27b04f56e3dd9d8a8bd91c66dda2de8fe9", + "0xf86b823362858bb2c972bc82520894454b0ea7d8ad3c56d0cf2e44ed97b2feab4d7af201808503479468b8a063d1f8b06a59c32d01cbb07e90c6efaedf5ae2d898b2e391293faba38552a784a01dcb02b8273e9db61cdf072ad170bb102bf26d467bb0082796c45dff44c62c2c", + "0xf86b823363858bb2c972bc82520894454b0ea7d8ad3c56d0cf2e44ed97b2feab4d7af201808503479468b7a01481bb0af1c56554c8ce345ba305fa4c80efcf66b9900f75cc2a0b3e76e6014ba04b019b2ed72d9f078dc10485b5948cafa284ac5d7ab15c47925d37ec4477a0ee", + "0x03f89a8501a3ca344a8212cb84773594008504a817c8008252089407e25e7883c6466d579c0df73bff083ce63084e88080c08504a817c800e1a0012b9d1f8cf08c0a807e226a130be45165e48cae7e7be5ee4d3079bc629c487980a0be40054b628bc6f8cdf110cb98064a6128584baea76b283c0a565f716f1a7f39a046566f55da48b57cac3b5acd0f1ee1a8cd07c9ed99aa8a85b8aa0fad02f26824", + "0x03f89a8501a3ca344a8212f584773594008504a817c80082520894a49dfd382668a2d7778fadd68da1bac21d3c78ac8080c08504a817c800e1a00139c61fb5022f854e37742230a76e524166c0f1b2d67a152d4f5a488b5159c101a0dd6b92a173426adbf4052dc6b92a895a14a0f8f80d4007dc2d9a3a9bee5675f8a03b4ed09b34720a911d5a89041f45d76ce817eb073b00b35ae23063963abb572c" + ], + "withdrawals": [] + }, + "expectedBlobVersionedHashes": [ + "0x012b9d1f8cf08c0a807e226a130be45165e48cae7e7be5ee4d3079bc629c4879", + "0x0139c61fb5022f854e37742230a76e524166c0f1b2d67a152d4f5a488b5159c1" + ], + "parentBeaconBlockRoot": "0x25b66ce21990ffcbbb6248952c6ef7939dbddfb90f6659a2bb43ff369f47c23b", + "executionRequests": [ + "0x", + "0x", + "0x" + ] +} diff --git a/tests/test_engine_api.nim b/tests/test_engine_api.nim index 4d081f0ef..a8f5b9cf8 100644 --- a/tests/test_engine_api.nim +++ b/tests/test_engine_api.nim @@ -14,6 +14,8 @@ import json_rpc/rpcclient, json_rpc/rpcserver, web3/engine_api, + web3/conversions, + web3/execution_types, unittest2 import @@ -166,6 +168,38 @@ proc runNewPayloadV4Test(env: TestEnv): Result[void, string] = ok() +type + NewPayloadV4Params* = object + payload*: ExecutionPayload + expectedBlobVersionedHashes*: Opt[seq[Hash32]] + parentBeaconBlockRoot*: Opt[Hash32] + executionRequests*: Opt[array[3, seq[byte]]] + +NewPayloadV4Params.useDefaultSerializationIn JrpcConv + +const paramsFile = "tests/engine_api/newPayloadV4_invalid_blockhash.json" + +proc newPayloadV4ParamsTest(env: TestEnv): Result[void, string] = + let + client = env.client + params = JrpcConv.loadFile(paramsFile, NewPayloadV4Params) + res = ? client.newPayloadV4( + params.payload, + params.expectedBlobVersionedHashes, + params.parentBeaconBlockRoot, + params.executionRequests) + + if res.status != PayloadExecutionStatus.syncing: + return err("res.status should equals to PayloadExecutionStatus.syncing") + + if res.latestValidHash.isSome: + return err("lastestValidHash should empty") + + if res.validationError.isSome: + return err("validationError should empty") + + ok() + proc engineApiMain*() = suite "Engine API": test "Basic cycle": @@ -175,7 +209,7 @@ proc engineApiMain*() = debugEcho "FAILED TO EXECUTE TEST: ", res.error check res.isOk env.close() - + test "newPayloadV4": let env = setupEnv(Prague) let res = env.runNewPayloadV4Test() @@ -184,5 +218,13 @@ proc engineApiMain*() = check res.isOk env.close() + test "newPayloadV4 params": + let env = setupEnv(Prague) + let res = env.newPayloadV4ParamsTest() + if res.isErr: + debugEcho "FAILED TO EXECUTE TEST: ", res.error + check res.isOk + env.close() + when isMainModule: engineApiMain() diff --git a/tools/t8n/transition.nim b/tools/t8n/transition.nim index 85f312c37..587cfdecf 100644 --- a/tools/t8n/transition.nim +++ b/tools/t8n/transition.nim @@ -359,7 +359,7 @@ proc exec(ctx: TransContext, let depositReqs = parseDepositLogs(allLogs).valueOr: raise newError(ErrorEVM, error) - requestsHash = calcRequestsHashInsertType(depositReqs, withdrawalReqs, consolidationReqs) + requestsHash = calcRequestsHash(depositReqs, withdrawalReqs, consolidationReqs) result.result.requestsHash = Opt.some(requestsHash) template wrapException(body: untyped) =