Skip to content

Commit f99aff3

Browse files
committed
add log filters
1 parent 5e3712b commit f99aff3

File tree

3 files changed

+116
-15
lines changed

3 files changed

+116
-15
lines changed

nimbus_verified_proxy/rpc/receipts.nim

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,26 @@ proc getReceipts*(
9090

9191
return ok(rxs.get())
9292

93-
proc getLogs*(
94-
vp: VerifiedRpcProxy, filterOptions: FilterOptions
95-
): Future[Result[seq[LogObject], string]] {.async.} =
96-
let logObjs =
97-
try:
98-
await vp.rpcClient.eth_getLogs(filterOptions)
99-
except CatchableError as e:
100-
return err(e.msg)
93+
proc verifyFilterBoundaries*(filter: FilterOptions, logObjs: seq[LogObject]): Result[bool, string] =
94+
let
95+
fromBlock = filter.fromBlock.get(BlockTag(kind:BlockIdentifierKind.bidAlias, alias: "latest"))
96+
toBlock = filter.toBlock.get(BlockTag(kind:BlockIdentifierKind.bidAlias, alias: "latest"))
10197

98+
bottom = if fromBlock.kind == BlockIdentifierKind.bidNumber: fromBlock.number
99+
else: return err("Cannot verify boundaries for block tags in 'fromBlock' field")
100+
top = if toBlock.kind == BlockIdentifierKind.bidNumber: toBlock.number
101+
else: return err("Cannot verify boundaries for block tags in 'toBlock' field")
102+
103+
for lg in logObjs:
104+
if lg.blockNumber.isSome:
105+
if lg.blockNumber.get < bottom or lg.blockNumber.get > top:
106+
return ok(false)
107+
108+
return ok(true)
109+
110+
proc verifyLogs*(
111+
vp: VerifiedRpcProxy, logObjs: seq[LogObject]
112+
): Future[Result[seq[LogObject], string]] {.async.} =
102113
var res = newSeq[LogObject]()
103114
104115
# store block hashes contains the logs so that we can batch receipt requests
@@ -113,8 +124,8 @@ proc getLogs*(
113124
for rx in rxs:
114125
for rxLog in rx.logs:
115126
# only add verified logs
116-
if rxLog.address == lg.address and rxLog.data == lg.data and
117-
rxLog.topics == lg.topics:
127+
if rxLog.address != lg.address or rxLog.data != lg.data or
128+
rxLog.topics != lg.topics:
118129
res.add(lg)
119130
else:
120131
let
@@ -123,8 +134,8 @@ proc getLogs*(
123134

124135
# only add verified logs
125136
for rxLog in rx.logs:
126-
if rxLog.address == lg.address and rxLog.data == lg.data and
127-
rxLog.topics == lg.topics:
137+
if rxLog.address != lg.address or rxLog.data != lg.data or
138+
rxLog.topics != lg.topics:
128139
res.add(lg)
129140

130141
if res.len == 0:

nimbus_verified_proxy/rpc/rpc_eth_api.nim

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
204204
await vp.rpcClient.eth_getTransactionByHash(txHash)
205205
except CatchableError as e:
206206
raise newException(ValueError, e.msg)
207+
207208
if tx.hash != txHash:
208209
raise newException(
209210
ValueError,
@@ -238,10 +239,93 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
238239
raise newException(ValueError, "receipt couldn't be verified")
239240

240241
vp.proxy.rpc("eth_getLogs") do(filterOptions: FilterOptions) -> seq[LogObject]:
241-
(await vp.getLogs(filterOptions)).valueOr:
242+
let
243+
logObjs =
244+
try:
245+
await vp.rpcClient.eth_getLogs(filterOptions)
246+
except CatchableError as e:
247+
raise newException(ValueError, e.msg)
248+
249+
boundsCheck = verifyFilterBoundaries(filterOptions, logObjs).valueOr:
250+
raise newException(ValueError, error)
251+
252+
if not boundsCheck:
253+
raise newException(ValueError, "Logs out of filter block range")
254+
255+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
256+
raise newException(ValueError, error)
257+
258+
return verifiedLogs
259+
260+
vp.proxy.rpc("eth_newFilter") do(filterOptions: FilterOptions) -> int:
261+
let
262+
hexId =
263+
try:
264+
await vp.rpcClient.eth_newFilter(filterOptions)
265+
except CatchableError as e:
266+
raise newException(ValueError, e.msg)
267+
id = fromHex[int](hexId)
268+
269+
vp.filterStore[id] = filterOptions
270+
return id
271+
272+
vp.proxy.rpc("eth_uninstallFilter") do(filterId: int) -> bool:
273+
let status =
274+
try:
275+
await vp.rpcClient.eth_uninstallFilter("0x" & toHex(filterId))
276+
except CatchableError as e:
277+
raise newException(ValueError, e.msg)
278+
279+
if status and filterId in vp.filterStore:
280+
vp.filterStore.del(filterId)
281+
282+
return status
283+
284+
vp.proxy.rpc("eth_getFilterLogs") do(filterId: int) -> seq[LogObject]:
285+
if filterId notin vp.filterStore:
286+
raise newException(ValueError, "Filter doesn't exist")
287+
288+
let
289+
logObjs =
290+
try:
291+
# use locally stored filter and get logs
292+
await vp.rpcClient.eth_getLogs(vp.filterStore[filterId])
293+
except CatchableError as e:
294+
raise newException(ValueError, e.msg)
295+
296+
boundsCheck = verifyFilterBoundaries(vp.filterStore[filterId], logObjs).valueOr:
297+
raise newException(ValueError, error)
298+
299+
if not boundsCheck:
300+
raise newException(ValueError, "Logs out of filter block range")
301+
302+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
242303
raise newException(ValueError, error)
243304

244-
# TODO:
305+
return verifiedLogs
306+
307+
vp.proxy.rpc("eth_getFilterChanges") do(filterId: int) -> seq[LogObject]:
308+
if filterId notin vp.filterStore:
309+
raise newException(ValueError, "Filter doesn't exist")
310+
311+
let
312+
logObjs =
313+
try:
314+
await vp.rpcClient.eth_getFilterChanges("0x" & toHex(filterId))
315+
except CatchableError as e:
316+
raise newException(ValueError, e.msg)
317+
318+
boundsCheck = verifyFilterBoundaries(vp.filterStore[filterId], logObjs).valueOr:
319+
raise newException(ValueError, error)
320+
321+
if not boundsCheck:
322+
raise newException(ValueError, "Logs out of filter block range")
323+
324+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
325+
raise newException(ValueError, error)
326+
327+
return verifiedLogs
328+
245329
# Following methods are forwarded directly to the web3 provider and therefore
246330
# are not validated in any way.
247331
vp.proxy.registerProxyMethod("net_version")

nimbus_verified_proxy/types.nim

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# at your option. This file may not be copied, modified, or distributed except according to those terms.
77

88
import
9+
std/tables,
910
json_rpc/[rpcproxy, rpcclient],
1011
stint,
1112
./header_store,
@@ -17,6 +18,7 @@ type
1718
evm*: AsyncEvm
1819
proxy*: RpcProxy
1920
headerStore*: HeaderStore
21+
filterStore*: Table[int, FilterOptions]
2022
chainId*: UInt256
2123
maxBlockWalk*: uint64
2224

@@ -33,5 +35,9 @@ proc init*(
3335
maxBlockWalk: uint64,
3436
): T =
3537
VerifiedRpcProxy(
36-
proxy: proxy, headerStore: headerStore, chainId: chainId, maxBlockWalk: maxBlockWalk
38+
proxy: proxy,
39+
headerStore: headerStore,
40+
filterStore: initTable[int, FilterOptions](),
41+
chainId: chainId,
42+
maxBlockWalk: maxBlockWalk
3743
)

0 commit comments

Comments
 (0)