Skip to content

Commit 6128e25

Browse files
committed
receipt fix
1 parent 9697b6b commit 6128e25

File tree

3 files changed

+117
-30
lines changed

3 files changed

+117
-30
lines changed
+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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()

nimbus_verified_proxy/rpc/rpc_eth_api.nim

+22-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import
2525
../types,
2626
./blocks,
2727
./accounts,
28-
./transactions
28+
./transactions,
29+
./receipts
2930

3031
logScope:
3132
topics = "verified_proxy"
@@ -115,6 +116,26 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
115116

116117
return tx
117118

119+
# TODO: this method should also support block hashes. For that, the client call should also suupport block hashes
120+
vp.proxy.rpc("eth_getBlockReceipts") do(
121+
blockTag: BlockTag
122+
) -> Opt[seq[ReceiptObject]]:
123+
let rxs = await vp.getReceiptsByBlockTag(blockTag)
124+
return Opt.some(rxs)
125+
126+
vp.proxy.rpc("eth_getTransactionReceipt") do(
127+
txHash: Hash32
128+
) -> ReceiptObject:
129+
let
130+
rx = await vp.rpcClient.eth_getTransactionReceipt(txHash)
131+
rxs = await vp.getReceiptsByBlockHash(rx.blockHash)
132+
133+
for r in rxs:
134+
if r.transactionHash == txHash:
135+
return r
136+
137+
raise newException(ValueError, "receipt couldn't be verified")
138+
118139
# eth_blockNumber - get latest tag from header store
119140
vp.proxy.rpc("eth_blockNumber") do() -> Quantity:
120141
# Returns the number of the most recent block seen by the light client.

nimbus_verified_proxy/rpc/transactions.nim

-29
Original file line numberDiff line numberDiff line change
@@ -73,35 +73,6 @@ proc checkTxHash*(txObj: TransactionObject, txHash: Hash32): bool =
7373

7474
return true
7575

76-
template toLog(lg: LogObject): Log =
77-
Log(
78-
address: lg.address,
79-
topics: lg.topics,
80-
data: lg.data
81-
)
82-
83-
proc toLogs(logs: openArray[LogObject]): seq[Log] =
84-
result = map(logs, proc(x: LogObject): Log = toLog(x))
85-
86-
proc toReceipt(rec: ReceiptObject): Receipt =
87-
let isHash = if rec.status.isSome: false
88-
else: true
89-
90-
var status = false
91-
if rec.status.isSome:
92-
if rec.status.get() == 1.Quantity:
93-
status = true
94-
95-
return Receipt(
96-
hash: rec.transactionHash,
97-
isHash: isHash,
98-
status: status,
99-
cumulativeGasUsed: rec.cumulativeGasUsed.GasInt,
100-
logs: toLogs(rec.logs),
101-
logsBloom: rec.logsBloom,
102-
receiptType: rec.`type`.get(0.Web3Quantity).ReceiptType
103-
)
104-
10576
proc verifyTransactions*(
10677
txRoot: Hash32,
10778
transactions: seq[TxOrHash],

0 commit comments

Comments
 (0)