diff --git a/ethers/providers/jsonrpc/subscriptions.nim b/ethers/providers/jsonrpc/subscriptions.nim index d9ea1dd..a8ed26b 100644 --- a/ethers/providers/jsonrpc/subscriptions.nim +++ b/ethers/providers/jsonrpc/subscriptions.nim @@ -164,8 +164,14 @@ proc new*(_: type JsonRpcSubscriptions, raise e except CatchableError as e: if "filter not found" in e.msg: - let filter = subscriptions.filters[originalId] - let newId = await subscriptions.client.eth_newFilter(filter) + var newId: JsonNode + # If there exists filter for given ID, then the filter was a log filter + # otherwise it was a block filter + if subscriptions.filters.hasKey(originalId): + let filter = subscriptions.filters[originalId] + newId = await subscriptions.client.eth_newFilter(filter) + else: + newId = await subscriptions.client.eth_newBlockFilter() subscriptions.subscriptionMapping[originalId] = newId return await getChanges(originalId) else: diff --git a/testmodule/providers/jsonrpc/rpc_mock.nim b/testmodule/providers/jsonrpc/rpc_mock.nim index 5142a82..b4411e7 100644 --- a/testmodule/providers/jsonrpc/rpc_mock.nim +++ b/testmodule/providers/jsonrpc/rpc_mock.nim @@ -25,6 +25,11 @@ proc start*(server: MockRpcHttpServer) = server.filters.add filterId return filterId + server.srv.router.rpc("eth_newBlockFilter") do() -> string: + let filterId = "0x" & (array[16, byte].example).toHex + server.filters.add filterId + return filterId + server.srv.router.rpc("eth_getFilterChanges") do(id: string) -> seq[string]: if id notin server.filters: raise (ref ApplicationError)(code: -32000, msg: "filter not found") diff --git a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim index d0e2fff..63c239b 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim @@ -124,7 +124,7 @@ suite "HTTP polling subscriptions - filter not found": await client.close() await mockServer.stop() - test "filter not found error recreates filter": + test "filter not found error recreates log filter": let filter = EventFilter(address: Address.example, topics: @[array[32, byte].example]) let emptyHandler = proc(log: Log) = discard @@ -142,7 +142,7 @@ suite "HTTP polling subscriptions - filter not found": check eventually subscriptions.subscriptionMapping[id] != id - test "recreated filter can be still unsubscribed using the original id": + test "recreated log filter can be still unsubscribed using the original id": let filter = EventFilter(address: Address.example, topics: @[array[32, byte].example]) let emptyHandler = proc(log: Log) = discard let id = await subscriptions.subscribeLogs(filter, emptyHandler) @@ -153,3 +153,24 @@ suite "HTTP polling subscriptions - filter not found": check not subscriptions.filters.hasKey id check not subscriptions.subscriptionMapping.hasKey id + + test "filter not found error recreates block filter": + let emptyHandler = proc(blck: Block) = discard + + check subscriptions.subscriptionMapping.len == 0 + let id = await subscriptions.subscribeBlocks(emptyHandler) + check subscriptions.subscriptionMapping[id] == id + + mockServer.invalidateFilter(id) + + check eventually subscriptions.subscriptionMapping[id] != id + + test "recreated block filter can be still unsubscribed using the original id": + let emptyHandler = proc(blck: Block) = discard + let id = await subscriptions.subscribeBlocks(emptyHandler) + mockServer.invalidateFilter(id) + check eventually subscriptions.subscriptionMapping[id] != id + + await subscriptions.unsubscribe(id) + + check not subscriptions.subscriptionMapping.hasKey id