|
| 1 | +# nimbus_verified_proxy |
| 2 | +# Copyright (c) 2022-2024 Status Research & Development GmbH |
| 3 | +# Licensed and distributed under either of |
| 4 | +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). |
| 5 | +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). |
| 6 | +# at your option. This file may not be copied, modified, or distributed except according to those terms. |
| 7 | + |
| 8 | +{.push raises: [].} |
| 9 | + |
| 10 | +import |
| 11 | + std/sequtils, |
| 12 | + stint, |
| 13 | + results, |
| 14 | + chronicles, |
| 15 | + eth/common/[base_rlp, transactions_rlp, receipts_rlp, hashes_rlp], |
| 16 | + ../../execution_chain/beacon/web3_eth_conv, |
| 17 | + eth/common/addresses, |
| 18 | + eth/common/eth_types_rlp, |
| 19 | + eth/trie/[hexary, ordered_trie, db, trie_defs], |
| 20 | + json_rpc/[rpcproxy, rpcserver, rpcclient], |
| 21 | + web3/[primitives, eth_api_types, eth_api], |
| 22 | + ../types, |
| 23 | + ./blocks, |
| 24 | + ../header_store |
| 25 | + |
| 26 | +export results, stint, hashes_rlp, accounts_rlp, eth_api_types |
| 27 | + |
| 28 | +template rpcClient(vp: VerifiedRpcProxy): RpcClient = |
| 29 | + vp.proxy.getClient() |
| 30 | + |
| 31 | +template toLog(lg: LogObject): Log = |
| 32 | + Log( |
| 33 | + address: lg.address, |
| 34 | + topics: lg.topics, |
| 35 | + data: lg.data |
| 36 | + ) |
| 37 | + |
| 38 | +proc toLogs(logs: openArray[LogObject]): seq[Log] = |
| 39 | + result = map(logs, proc(x: LogObject): Log = toLog(x)) |
| 40 | + |
| 41 | +proc toReceipt(rec: ReceiptObject): Receipt = |
| 42 | + let isHash = if rec.status.isSome: false |
| 43 | + else: true |
| 44 | + |
| 45 | + var status = false |
| 46 | + if rec.status.isSome: |
| 47 | + if rec.status.get() == 1.Quantity: |
| 48 | + status = true |
| 49 | + |
| 50 | + return Receipt( |
| 51 | + hash: rec.transactionHash, |
| 52 | + isHash: isHash, |
| 53 | + status: status, |
| 54 | + cumulativeGasUsed: rec.cumulativeGasUsed.GasInt, |
| 55 | + logs: toLogs(rec.logs), |
| 56 | + logsBloom: rec.logsBloom, |
| 57 | + receiptType: rec.`type`.get(0.Web3Quantity).ReceiptType |
| 58 | + ) |
| 59 | + |
| 60 | +proc toReceipts(recs: openArray[ReceiptObject]): seq[Receipt] = |
| 61 | + for r in recs: |
| 62 | + result.add(toReceipt(r)) |
| 63 | + |
| 64 | +proc getReceiptsByBlockTag*( |
| 65 | + vp: VerifiedRpcProxy, blockTag: BlockTag |
| 66 | +): Future[seq[ReceiptObject]] {.async: (raises: [ValueError, CatchableError]).} = |
| 67 | + |
| 68 | + let |
| 69 | + header = await vp.getHeaderByTag(blockTag) |
| 70 | + rxs = await vp.rpcClient.eth_getBlockReceipts(blockTag) |
| 71 | + |
| 72 | + if rxs.isSome(): |
| 73 | + if orderedTrieRoot(toReceipts(rxs.get())) != header.receiptsRoot: |
| 74 | + raise newException(ValueError, "downloaded receipts do not evaluate to the receipts root of the block") |
| 75 | + else: |
| 76 | + raise newException(ValueError, "error downloading the receipts") |
| 77 | + |
| 78 | + return rxs.get() |
| 79 | + |
| 80 | +proc getReceiptsByBlockHash*( |
| 81 | + vp: VerifiedRpcProxy, blockHash: Hash32 |
| 82 | +): Future[seq[ReceiptObject]] {.async: (raises: [ValueError, CatchableError]).} = |
| 83 | + |
| 84 | + let |
| 85 | + header = await vp.getHeaderByHash(blockHash) |
| 86 | + blockTag = BlockTag(RtBlockIdentifier(kind: bidNumber, number: Quantity(header.number))) |
| 87 | + rxs = await vp.rpcClient.eth_getBlockReceipts(blockTag) |
| 88 | + |
| 89 | + if rxs.isSome(): |
| 90 | + if orderedTrieRoot(toReceipts(rxs.get())) != header.receiptsRoot: |
| 91 | + raise newException(ValueError, "downloaded receipts do not evaluate to the receipts root of the block") |
| 92 | + else: |
| 93 | + raise newException(ValueError, "error downloading the receipts") |
| 94 | + |
| 95 | + return rxs.get() |
0 commit comments