Skip to content

Commit 8525c16

Browse files
committed
fixes
1 parent 9d264b7 commit 8525c16

File tree

4 files changed

+118
-52
lines changed

4 files changed

+118
-52
lines changed

nimbus_verified_proxy/rpc/rpc_eth_api.nim

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import
1111
results,
1212
chronicles,
1313
stew/byteutils,
14+
nimcrypto/sysrand,
1415
json_rpc/[rpcserver, rpcclient, rpcproxy],
1516
eth/common/accounts,
1617
web3/eth_api,
@@ -276,55 +277,69 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
276277
raise newException(ValueError, error)
277278

278279
vp.proxy.rpc("eth_newFilter") do(filterOptions: FilterOptions) -> string:
279-
let id =
280-
try:
281-
# filter is not resolved when storing only while fetching
282-
await vp.rpcClient.eth_newFilter(filterOptions)
283-
except CatchableError as e:
284-
raise newException(ValueError, e.msg)
280+
var id: array[8, byte] # 64bits
285281

286-
vp.filterStore[id] = filterOptions
287-
return id
282+
if randomBytes(id) != len(id):
283+
raise newException(ValueError, "Couldn't assign a identifier for the filter")
288284

289-
vp.proxy.rpc("eth_uninstallFilter") do(filterId: string) -> bool:
290-
let status =
291-
try:
292-
await vp.rpcClient.eth_uninstallFilter(filterId)
293-
except CatchableError as e:
294-
raise newException(ValueError, e.msg)
285+
let strId = toHex(id)
286+
287+
vp.filterStore[strId] =
288+
FilterStoreItem(filter: filterOptions, blockMarker: Opt.none(Quantity))
289+
290+
return strId
295291

296-
if status and filterId in vp.filterStore:
292+
vp.proxy.rpc("eth_uninstallFilter") do(filterId: string) -> bool:
293+
if filterId in vp.filterStore:
297294
vp.filterStore.del(filterId)
295+
return true
298296

299-
return status
297+
return false
300298

301299
vp.proxy.rpc("eth_getFilterLogs") do(filterId: string) -> seq[LogObject]:
302300
if filterId notin vp.filterStore:
303301
raise newException(ValueError, "Filter doesn't exist")
304302

305-
(await vp.getLogs(vp.filterStore[filterId])).valueOr:
303+
(await vp.getLogs(vp.filterStore[filterId].filter)).valueOr:
306304
raise newException(ValueError, error)
307305

308306
vp.proxy.rpc("eth_getFilterChanges") do(filterId: string) -> seq[LogObject]:
309307
if filterId notin vp.filterStore:
310308
raise newException(ValueError, "Filter doesn't exist")
311309

312310
let
313-
filter = vp.resolveFilterTags(vp.filterStore[filterId]).valueOr:
311+
filterItem = vp.filterStore[filterId]
312+
filter = vp.resolveFilterTags(filterItem.filter).valueOr:
314313
raise newException(ValueError, error)
315-
logObjs =
316-
try:
317-
await vp.rpcClient.eth_getFilterChanges(filterId)
318-
except CatchableError as e:
319-
raise newException(ValueError, e.msg)
314+
# after resolving toBlock is always some and a number tag
315+
toBlock = filter.toBlock.get().number
320316

321-
unmarshalledLogs = logObjs.to(seq[LogObject])
322-
verified = (await vp.verifyLogs(filter, unmarshalledLogs))
317+
if filterItem.blockMarker.isSome() and toBlock <= filterItem.blockMarker.get():
318+
raise newException(ValueError, "No changes for the filter since the last query")
319+
320+
let
321+
fromBlock =
322+
if filterItem.blockMarker.isSome():
323+
Opt.some(
324+
types.BlockTag(kind: bidNumber, number: filterItem.blockMarker.get())
325+
)
326+
else:
327+
filter.fromBlock
328+
329+
changesFilter = FilterOptions(
330+
fromBlock: fromBlock,
331+
toBlock: filter.toBlock,
332+
address: filter.address,
333+
topics: filter.topics,
334+
blockHash: filter.blockHash,
335+
)
336+
logObjs = (await vp.getLogs(changesFilter)).valueOr:
337+
raise newException(ValueError, error)
323338

324-
if verified.isErr():
325-
raise newException(ValueError, verified.error)
339+
# all logs verified so we can update blockMarker
340+
vp.filterStore[filterId].blockMarker = Opt.some(toBlock)
326341

327-
return unmarshalledLogs
342+
return logObjs
328343

329344
# Following methods are forwarded directly to the web3 provider and therefore
330345
# are not validated in any way.

nimbus_verified_proxy/rpc_api_backend.nim

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,6 @@ proc initNetworkApiBackend*(vp: VerifiedRpcProxy): EthApiBackend =
6464
): Future[seq[LogObject]] {.async: (raw: true).} =
6565
vp.proxy.getClient.eth_getLogs(filterOptions)
6666

67-
newFilterProc = proc(
68-
filterOptions: FilterOptions
69-
): Future[string] {.async: (raw: true).} =
70-
vp.proxy.getClient.eth_newFilter(filterOptions)
71-
72-
uninstallFilterProc = proc(filterId: string): Future[bool] {.async: (raw: true).} =
73-
vp.proxy.getClient.eth_uninstallFilter(filterId)
74-
75-
getFilterChangesProc = proc(
76-
filterId: string
77-
): Future[JsonNode] {.async: (raw: true).} =
78-
vp.proxy.getClient.eth_getFilterChanges(filterId)
79-
8067
EthApiBackend(
8168
eth_chainId: ethChainIdProc,
8269
eth_getBlockByHash: getBlockByHashProc,
@@ -88,7 +75,4 @@ proc initNetworkApiBackend*(vp: VerifiedRpcProxy): EthApiBackend =
8875
eth_getLogs: getLogsProc,
8976
eth_getTransactionByHash: getTransactionByHashProc,
9077
eth_getTransactionReceipt: getTransactionReceiptProc,
91-
eth_newFilter: newFilterProc,
92-
eth_uninstallFilter: uninstallFilterProc,
93-
eth_getFilterChanges: getFilterChangesProc,
9478
)

nimbus_verified_proxy/tests/test_receipts.nim

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,73 @@ suite "test receipts verification":
9292
ts.loadLogs(filterOptions, logs)
9393
let verifiedLogs = waitFor vp.proxy.getClient().eth_getLogs(filterOptions)
9494
check verifiedLogs.len == logs.len
95+
96+
test "create filters and uninstall filters":
97+
# filter options without any tags would test resolving default "latest"
98+
let filterOptions = FilterOptions(
99+
topics:
100+
@[
101+
TopicOrList(
102+
kind: SingleOrListKind.slkSingle,
103+
single:
104+
bytes32"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
105+
)
106+
],
107+
blockHash: Opt.none(Hash32),
108+
)
109+
110+
let
111+
# create a filter
112+
newFilter = waitFor vp.proxy.getClient().eth_newFilter(filterOptions)
113+
# deleting will prove if the filter was created
114+
delStatus = waitFor vp.proxy.getClient().eth_uninstallFilter(newFilter)
115+
116+
check delStatus
117+
118+
let
119+
unknownFilterId = "thisisacorrectfilterid"
120+
delStatus2 = waitFor vp.proxy.getClient().eth_uninstallFilter(newFilter)
121+
122+
check not delStatus2
123+
124+
test "get logs using filter changes":
125+
let
126+
blk = getBlockFromJson("nimbus_verified_proxy/tests/data/Paris.json")
127+
rxs = getReceiptsFromJson("nimbus_verified_proxy/tests/data/receipts.json")
128+
logs = getLogsFromJson("nimbus_verified_proxy/tests/data/logs.json")
129+
130+
# update block tags because getLogs (uses)-> getReceipts (uses)-> getHeader
131+
ts.loadBlockReceipts(blk, rxs)
132+
discard vp.headerStore.add(convHeader(blk), blk.hash)
133+
discard vp.headerStore.updateFinalized(convHeader(blk), blk.hash)
134+
135+
# filter options without any tags would test resolving default "latest"
136+
let filterOptions = FilterOptions(
137+
topics:
138+
@[
139+
TopicOrList(
140+
kind: SingleOrListKind.slkSingle,
141+
single:
142+
bytes32"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
143+
)
144+
],
145+
blockHash: Opt.none(Hash32),
146+
)
147+
148+
ts.loadLogs(filterOptions, logs)
149+
150+
let
151+
# create a filter
152+
newFilter = waitFor vp.proxy.getClient().eth_newFilter(filterOptions)
153+
filterLogs = waitFor vp.proxy.getClient().eth_getFilterLogs(newFilter)
154+
filterChanges = waitFor vp.proxy.getClient().eth_getFilterChanges(newFilter)
155+
156+
check filterLogs.len == logs.len
157+
check filterChanges.len == logs.len
158+
159+
try:
160+
let againFilterChanges =
161+
waitFor vp.proxy.getClient().eth_getFilterChanges(newFilter)
162+
check false
163+
except CatchableError as e:
164+
check true

nimbus_verified_proxy/types.nim

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import
1212
json_rpc/[rpcproxy, rpcclient],
1313
web3/[eth_api, eth_api_types],
1414
stint,
15-
std/json,
1615
minilru,
1716
./header_store,
1817
../execution_chain/evm/async_evm
@@ -52,9 +51,6 @@ type
5251
GetTransactionReceiptProc = proc(txHash: Hash32): Future[ReceiptObject] {.async.}
5352
GetTransactionByHashProc = proc(txHash: Hash32): Future[TransactionObject] {.async.}
5453
GetLogsProc = proc(filterOptions: FilterOptions): Future[seq[LogObject]] {.async.}
55-
NewFilterProc = proc(filterOptions: FilterOptions): Future[string] {.async.}
56-
UninstallFilterProc = proc(filterId: string): Future[bool] {.async.}
57-
GetFilterChangesProc = proc(filterid: string): Future[JsonNode] {.async.}
5854

5955
EthApiBackend* = object
6056
eth_chainId*: ChainIdProc
@@ -67,9 +63,10 @@ type
6763
eth_getTransactionReceipt*: GetTransactionReceiptProc
6864
eth_getTransactionByHash*: GetTransactionByHashProc
6965
eth_getLogs*: GetLogsProc
70-
eth_newFilter*: NewFilterProc
71-
eth_uninstallFilter*: UninstallFilterProc
72-
eth_getFilterChanges*: GetFilterChangesProc
66+
67+
FilterStoreItem* = object
68+
filter*: FilterOptions
69+
blockMarker*: Opt[Quantity]
7370

7471
VerifiedRpcProxy* = ref object
7572
evm*: AsyncEvm
@@ -82,7 +79,7 @@ type
8279

8380
# TODO: when the list grows big add a config object instead
8481
# config parameters
85-
filterStore*: Table[string, FilterOptions]
82+
filterStore*: Table[string, FilterStoreItem]
8683
chainId*: UInt256
8784
maxBlockWalk*: uint64
8885

0 commit comments

Comments
 (0)