Skip to content

Commit 4230cc2

Browse files
committed
add log filters
1 parent 940e7c3 commit 4230cc2

File tree

3 files changed

+102
-15
lines changed

3 files changed

+102
-15
lines changed

nimbus_verified_proxy/rpc/receipts.nim

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
66
# at your option. This file may not be copied, modified, or distributed except according to those terms.
77

8-
<<<<<<< HEAD
98
{.push gcsafe, raises: [].}
109

11-
=======
12-
>>>>>>> 5e3712b73 (add copyright)
1310
import
1411
std/sequtils,
1512
results,
@@ -87,14 +84,17 @@ proc getReceipts*(
8784

8885
await vp.getReceipts(header, numberTag)
8986

90-
proc getLogs*(
91-
vp: VerifiedRpcProxy, filterOptions: FilterOptions
87+
proc verifyLogs*(
88+
vp: VerifiedRpcProxy, logObjs: seq[LogObject]
9289
): Future[Result[seq[LogObject], string]] {.async.} =
93-
let logObjs =
94-
try:
95-
await vp.rpcClient.eth_getLogs(filterOptions)
96-
except CatchableError as e:
97-
return err(e.msg)
90+
let
91+
fromBlock = filter.fromBlock.get(BlockTag(kind:BlockIdentifierKind.bidAlias, alias: "latest"))
92+
toBlock = filter.toBlock.get(BlockTag(kind:BlockIdentifierKind.bidAlias, alias: "latest"))
93+
94+
bottom = if fromBlock.kind == BlockIdentifierKind.bidNumber: fromBlock.number
95+
else: return err("Cannot verify boundaries for block tags in 'fromBlock' field")
96+
top = if toBlock.kind == BlockIdentifierKind.bidNumber: toBlock.number
97+
else: return err("Cannot verify boundaries for block tags in 'toBlock' field")
9898

9999
# store block hashes contains the logs so that we can batch receipt requests
100100
var
@@ -103,7 +103,7 @@ proc getLogs*(
103103

104104
for lg in logObjs:
105105
# none only for pending logs before block is built
106-
if lg.blockHash.isSome() and lg.transactionIndex.isSome() and lg.logIndex.isSome():
106+
if lg.blockNumber.isSome() and lg.blockHash.isSome() and lg.transactionIndex.isSome() and lg.logIndex.isSome():
107107
# exploit sequentiality of logs
108108
if prevBlockHash != lg.blockHash.get():
109109
# TODO: a cache will solve downloading the same block receipts for multiple logs
@@ -119,7 +119,7 @@ proc getLogs*(
119119

120120
if rxLog.address != lg.address or rxLog.data != lg.data or
121121
rxLog.topics != lg.topics or
122-
(not match(toLog(lg), filterOptions.address, filterOptions.topics)):
122+
(not match(toLog(lg), filterOptions.address, filterOptions.topics)) or lg.blockNumber.get < bottom or lg.blockNumber.get > top:
123123
return err("one of the returned logs is invalid")
124124

125125
return ok(logObjs)

nimbus_verified_proxy/rpc/rpc_eth_api.nim

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
237237
await vp.rpcClient.eth_getTransactionByHash(txHash)
238238
except CatchableError as e:
239239
raise newException(ValueError, e.msg)
240+
240241
if tx.hash != txHash:
241242
raise newException(
242243
ValueError,
@@ -271,10 +272,93 @@ proc installEthApiHandlers*(vp: VerifiedRpcProxy) =
271272
raise newException(ValueError, "receipt couldn't be verified")
272273

273274
vp.proxy.rpc("eth_getLogs") do(filterOptions: FilterOptions) -> seq[LogObject]:
274-
(await vp.getLogs(filterOptions)).valueOr:
275+
let
276+
logObjs =
277+
try:
278+
await vp.rpcClient.eth_getLogs(filterOptions)
279+
except CatchableError as e:
280+
raise newException(ValueError, e.msg)
281+
282+
boundsCheck = verifyFilterBoundaries(filterOptions, logObjs).valueOr:
283+
raise newException(ValueError, error)
284+
285+
if not boundsCheck:
286+
raise newException(ValueError, "Logs out of filter block range")
287+
288+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
289+
raise newException(ValueError, error)
290+
291+
return verifiedLogs
292+
293+
vp.proxy.rpc("eth_newFilter") do(filterOptions: FilterOptions) -> int:
294+
let
295+
hexId =
296+
try:
297+
await vp.rpcClient.eth_newFilter(filterOptions)
298+
except CatchableError as e:
299+
raise newException(ValueError, e.msg)
300+
id = fromHex[int](hexId)
301+
302+
vp.filterStore[id] = filterOptions
303+
return id
304+
305+
vp.proxy.rpc("eth_uninstallFilter") do(filterId: int) -> bool:
306+
let status =
307+
try:
308+
await vp.rpcClient.eth_uninstallFilter("0x" & toHex(filterId))
309+
except CatchableError as e:
310+
raise newException(ValueError, e.msg)
311+
312+
if status and filterId in vp.filterStore:
313+
vp.filterStore.del(filterId)
314+
315+
return status
316+
317+
vp.proxy.rpc("eth_getFilterLogs") do(filterId: int) -> seq[LogObject]:
318+
if filterId notin vp.filterStore:
319+
raise newException(ValueError, "Filter doesn't exist")
320+
321+
let
322+
logObjs =
323+
try:
324+
# use locally stored filter and get logs
325+
await vp.rpcClient.eth_getLogs(vp.filterStore[filterId])
326+
except CatchableError as e:
327+
raise newException(ValueError, e.msg)
328+
329+
boundsCheck = verifyFilterBoundaries(vp.filterStore[filterId], logObjs).valueOr:
330+
raise newException(ValueError, error)
331+
332+
if not boundsCheck:
333+
raise newException(ValueError, "Logs out of filter block range")
334+
335+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
275336
raise newException(ValueError, error)
276337

277-
# TODO:
338+
return verifiedLogs
339+
340+
vp.proxy.rpc("eth_getFilterChanges") do(filterId: int) -> seq[LogObject]:
341+
if filterId notin vp.filterStore:
342+
raise newException(ValueError, "Filter doesn't exist")
343+
344+
let
345+
logObjs =
346+
try:
347+
await vp.rpcClient.eth_getFilterChanges("0x" & toHex(filterId))
348+
except CatchableError as e:
349+
raise newException(ValueError, e.msg)
350+
351+
boundsCheck = verifyFilterBoundaries(vp.filterStore[filterId], logObjs).valueOr:
352+
raise newException(ValueError, error)
353+
354+
if not boundsCheck:
355+
raise newException(ValueError, "Logs out of filter block range")
356+
357+
let verifiedLogs = (await vp.verifyLogs(logObjs)).valueOr:
358+
raise newException(ValueError, error)
359+
360+
return verifiedLogs
361+
278362
# Following methods are forwarded directly to the web3 provider and therefore
279363
# are not validated in any way.
280364
vp.proxy.registerProxyMethod("net_version")

nimbus_verified_proxy/types.nim

Lines changed: 4 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
web3/[eth_api, eth_api_types],
1112
stint,
@@ -72,6 +73,7 @@ type
7273

7374
# TODO: when the list grows big add a config object instead
7475
# config parameters
76+
filterStore*: Table[int, FilterOptions]
7577
chainId*: UInt256
7678
maxBlockWalk*: uint64
7779

@@ -88,6 +90,7 @@ proc init*(
8890
accountsCache: AccountsCache.init(ACCOUNTS_CACHE_SIZE),
8991
codeCache: CodeCache.init(CODE_CACHE_SIZE),
9092
storageCache: StorageCache.init(STORAGE_CACHE_SIZE),
93+
filterStore: initTable[int, FilterOptions](),
9194
chainId: chainId,
92-
maxBlockWalk: maxBlockWalk,
95+
maxBlockWalk: maxBlockWalk
9396
)

0 commit comments

Comments
 (0)