From a27c2de41ca60a1056a85fbb4576ee68fe73c0df Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Tue, 27 Jun 2023 16:40:29 +0200 Subject: [PATCH] Close provider by unsubscribing and closing client --- Readme.md | 6 +++++ ethers/provider.nim | 3 +++ ethers/providers/jsonrpc.nim | 7 ++++++ ethers/providers/jsonrpc/subscriptions.nim | 5 ++++ .../providers/jsonrpc/testJsonRpcProvider.nim | 4 +++ .../providers/jsonrpc/testJsonRpcSigner.nim | 3 +++ .../jsonrpc/testJsonRpcSubscriptions.nim | 25 +++++++++++++++++-- testmodule/testContracts.nim | 1 + testmodule/testEnums.nim | 1 + testmodule/testErc20.nim | 1 + testmodule/testReturns.nim | 1 + testmodule/testTesting.nim | 1 + testmodule/testWallet.nim | 5 ++-- 13 files changed, 59 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index 589df83..2772572 100644 --- a/Readme.md +++ b/Readme.md @@ -90,6 +90,12 @@ await writableToken.transfer(accounts[7], 42.u256) Which transfers 42 tokens from account 3 to account 7 +And lastly, don't forget to close the provider when you're done: + +``` +await provider.close() +``` + Events ------ diff --git a/ethers/provider.nim b/ethers/provider.nim index 9b5a171..ce49ef9 100644 --- a/ethers/provider.nim +++ b/ethers/provider.nim @@ -208,3 +208,6 @@ proc confirm*(tx: Future[?TransactionResponse], ) return await txResp.confirm(wantedConfirms, timeoutInBlocks) + +method close*(provider: Provider) {.async, base.} = + discard diff --git a/ethers/providers/jsonrpc.nim b/ethers/providers/jsonrpc.nim index 559a4cb..406965a 100644 --- a/ethers/providers/jsonrpc.nim +++ b/ethers/providers/jsonrpc.nim @@ -177,6 +177,13 @@ method subscribe*(provider: JsonRpcProvider, let subscriptions = await provider.subscriptions return await subscriptions.subscribeBlocks(onBlock) +method close*(provider: JsonRpcProvider) {.async.} = + convertError: + let client = await provider.client + let subscriptions = await provider.subscriptions + await subscriptions.close() + await client.close() + # Signer method provider*(signer: JsonRpcSigner): Provider = diff --git a/ethers/providers/jsonrpc/subscriptions.nim b/ethers/providers/jsonrpc/subscriptions.nim index 0f33ea1..88cfe18 100644 --- a/ethers/providers/jsonrpc/subscriptions.nim +++ b/ethers/providers/jsonrpc/subscriptions.nim @@ -35,6 +35,11 @@ method unsubscribe(subscriptions: JsonRpcSubscriptions, {.async, base.} = raiseAssert "not implemented" +method close*(subscriptions: JsonRpcSubscriptions) {.async.} = + let ids = toSeq subscriptions.callbacks.keys + for id in ids: + await subscriptions.unsubscribe(id) + method unsubscribe(subscription: JsonRpcSubscription) {.async.} = let subscriptions = subscription.subscriptions let id = subscription.id diff --git a/testmodule/providers/jsonrpc/testJsonRpcProvider.nim b/testmodule/providers/jsonrpc/testJsonRpcProvider.nim index 5f1a483..106a43f 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcProvider.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcProvider.nim @@ -16,6 +16,10 @@ for url in ["ws://localhost:8545", "http://localhost:8545"]: setup: provider = JsonRpcProvider.new(url, pollingInterval = 100.millis) + + teardown: + await provider.close() + test "can be instantiated with a default URL": discard JsonRpcProvider.new() diff --git a/testmodule/providers/jsonrpc/testJsonRpcSigner.nim b/testmodule/providers/jsonrpc/testJsonRpcSigner.nim index 210e618..2789572 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSigner.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSigner.nim @@ -12,6 +12,9 @@ suite "JsonRpcSigner": provider = JsonRpcProvider.new() accounts = await provider.listAccounts() + teardown: + await provider.close() + test "is connected to the first account of the provider by default": let signer = provider.getSigner() check (await signer.getAddress()) == accounts[0] diff --git a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim index 7714328..2a053f4 100644 --- a/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim +++ b/testmodule/providers/jsonrpc/testJsonRpcSubscriptions.nim @@ -37,10 +37,23 @@ template subscriptionTests(subscriptions, client) = discard await client.call("evm_mine", newJArray()) check eventually count > 0 await subscription.unsubscribe() - let endcount = count + count = 0 discard await client.call("evm_mine", newJArray()) await sleepAsync(100.millis) - check count == endcount + check count == 0 + + test "stops listening to new blocks when provider is closed": + var count = 0 + proc callback(blck: Block) {.async.} = + inc count + let subscription = await subscriptions.subscribeBlocks(callback) + discard await client.call("evm_mine", newJArray()) + check eventually count > 0 + await subscriptions.close() + count = 0 + discard await client.call("evm_mine", newJArray()) + await sleepAsync(100.millis) + check count == 0 suite "Web socket subscriptions": @@ -52,6 +65,10 @@ suite "Web socket subscriptions": await client.connect("ws://localhost:8545") subscriptions = JsonRpcSubscriptions.new(client) + teardown: + await subscriptions.close() + await client.close() + subscriptionTests(subscriptions, client) suite "HTTP polling subscriptions": @@ -65,4 +82,8 @@ suite "HTTP polling subscriptions": subscriptions = JsonRpcSubscriptions.new(client, pollingInterval = 100.millis) + teardown: + await subscriptions.close() + await client.close() + subscriptionTests(subscriptions, client) diff --git a/testmodule/testContracts.nim b/testmodule/testContracts.nim index b406075..ab6bb8a 100644 --- a/testmodule/testContracts.nim +++ b/testmodule/testContracts.nim @@ -33,6 +33,7 @@ for url in ["ws://localhost:8545", "http://localhost:8545"]: teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "can call constant functions": check (await token.name()) == "TestToken" diff --git a/testmodule/testEnums.nim b/testmodule/testEnums.nim index 0731ceb..bc7ec42 100644 --- a/testmodule/testEnums.nim +++ b/testmodule/testEnums.nim @@ -22,6 +22,7 @@ suite "Contract enum parameters and return values": teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "handles enum parameter and return value": proc returnValue(contract: TestEnums, diff --git a/testmodule/testErc20.nim b/testmodule/testErc20.nim index 1e10690..8f21008 100644 --- a/testmodule/testErc20.nim +++ b/testmodule/testErc20.nim @@ -33,6 +33,7 @@ for url in ["ws://localhost:8545", "http://localhost:8545"]: teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "retrieves basic information": check (await token.name()) == "TestToken" diff --git a/testmodule/testReturns.nim b/testmodule/testReturns.nim index 77fbbee..5cdf03b 100644 --- a/testmodule/testReturns.nim +++ b/testmodule/testReturns.nim @@ -21,6 +21,7 @@ suite "Contract return values": teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "handles static size structs": proc getStatic(contract: TestReturns): Static {.contract, pure.} diff --git a/testmodule/testTesting.nim b/testmodule/testTesting.nim index 8c2f35f..1cc2720 100644 --- a/testmodule/testTesting.nim +++ b/testmodule/testTesting.nim @@ -88,6 +88,7 @@ suite "Testing helpers - provider": teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "revert works with provider": check await helpersContract.revertsWith(revertReason).reverts(revertReason) diff --git a/testmodule/testWallet.nim b/testmodule/testWallet.nim index e5c7c9f..14f4c73 100644 --- a/testmodule/testWallet.nim +++ b/testmodule/testWallet.nim @@ -20,9 +20,10 @@ suite "Wallet": setup: provider = JsonRpcProvider.new() snapshot = await provider.send("evm_snapshot") - + teardown: discard await provider.send("evm_revert", @[snapshot]) + await provider.close() test "Can create Wallet with private key": discard Wallet.new(pk1) @@ -114,7 +115,7 @@ suite "Wallet": gasLimit: some 22_000.u256) let testToken = Erc20.new(wallet.address, wallet) await testToken.transfer(wallet.address, 24.u256, overrides) - + test "Can call state-changing function automatically EIP1559": #TODO add actual token contract, not random address. Should work regardless let wallet = Wallet.new(pk_with_funds, provider)