mirror of
https://github.com/status-im/nim-ethers.git
synced 2025-01-14 01:26:24 +00:00
b68bea9909
* fix: modify unsubscribe cleanup routine Ignore exceptions (other than CancelledError) if uninstallation of the filter fails. If it's the last step in the subscription cleanup, then filter changes for this filter will no longer be polled so if the filter continues to live on in geth for whatever reason, then it doesn't matter. This includes a number of fixes: - `CancelledError` is now caught inside of `getChanges`. This was causing conditions during `subscriptions.close`, where the `CancelledError` would get consumed by the `except CatchableError`, if there was an ongoing `poll` happening at the time of close. - After creating a new filter inside of `getChanges`, the new filter is polled for changes before returning. - `getChanges` also does not swallow `CatchableError` by returning an empty array, and instead re-raises the error if it is not `filter not found`. - The tests were simplified by accessing the private fields of `PollingSubscriptions`. That way, there wasn't a race condition for the `newFilterId` counter inside of the mock. - The `MockRpcHttpServer` was simplified by keeping track of the active filters only, and invalidation simply removes the filter. The tests then only needed to rely on the fact that the filter id changed in the mapping. - Because of the above changes, we no longer needed to sleep inside of the tests, so the sleeps were removed, and the polling interval could be changed to 1ms, which not only makes the tests faster, but would further highlight any race conditions if present. * docs: rpc custom port documentation --------- Co-authored-by: Adam Uhlíř <adam@uhlir.dev>
119 lines
4.0 KiB
Nim
119 lines
4.0 KiB
Nim
import std/os
|
|
import std/strformat
|
|
import pkg/asynctest
|
|
import pkg/chronos
|
|
import pkg/ethers
|
|
import pkg/ethers/testing
|
|
import pkg/serde
|
|
import ./helpers
|
|
|
|
suite "Testing helpers":
|
|
|
|
let revertReason = "revert reason"
|
|
let rpcResponse = "Error: VM Exception while processing transaction: " &
|
|
fmt"reverted with reason string '{revertReason}'"
|
|
|
|
test "checks that call reverts":
|
|
proc call() {.async.} =
|
|
raise newException(EstimateGasError, $rpcResponse)
|
|
|
|
check await call().reverts()
|
|
|
|
test "checks reason for revert":
|
|
proc call() {.async.} =
|
|
raise newException(EstimateGasError, $rpcResponse)
|
|
|
|
check await call().reverts(revertReason)
|
|
|
|
test "correctly indicates there was no revert":
|
|
proc call() {.async.} = discard
|
|
|
|
check not await call().reverts()
|
|
|
|
test "reverts only checks ProviderErrors, EstimateGasErrors":
|
|
proc callProviderError() {.async.} =
|
|
raise newException(ProviderError, "test")
|
|
proc callSignerError() {.async.} =
|
|
raise newException(SignerError, "test")
|
|
proc callEstimateGasError() {.async.} =
|
|
raise newException(EstimateGasError, "test")
|
|
proc callEthersError() {.async.} =
|
|
raise newException(EthersError, "test")
|
|
|
|
check await callProviderError().reverts()
|
|
check await callSignerError().reverts()
|
|
check await callEstimateGasError().reverts()
|
|
expect EthersError:
|
|
check await callEthersError().reverts()
|
|
|
|
test "reverts with reason only checks ProviderErrors, EstimateGasErrors":
|
|
proc callProviderError() {.async.} =
|
|
raise newException(ProviderError, revertReason)
|
|
proc callSignerError() {.async.} =
|
|
raise newException(SignerError, revertReason)
|
|
proc callEstimateGasError() {.async.} =
|
|
raise newException(EstimateGasError, revertReason)
|
|
proc callEthersError() {.async.} =
|
|
raise newException(EthersError, revertReason)
|
|
|
|
check await callProviderError().reverts(revertReason)
|
|
check await callSignerError().reverts(revertReason)
|
|
check await callEstimateGasError().reverts(revertReason)
|
|
expect EthersError:
|
|
check await callEthersError().reverts(revertReason)
|
|
|
|
test "reverts with reason is false when there is no revert":
|
|
proc call() {.async.} = discard
|
|
|
|
check not await call().reverts(revertReason)
|
|
|
|
test "reverts is false when the revert reason doesn't match":
|
|
proc call() {.async.} =
|
|
raise newException(EstimateGasError, "other reason")
|
|
|
|
check not await call().reverts(revertReason)
|
|
|
|
test "revert handles non-standard revert prefix":
|
|
let nonStdMsg = fmt"Provider VM Exception: reverted with {revertReason}"
|
|
proc call() {.async.} =
|
|
raise newException(EstimateGasError, nonStdMsg)
|
|
|
|
check await call().reverts(nonStdMsg)
|
|
|
|
test "works with functions that return a value":
|
|
proc call(): Future[int] {.async.} = return 42
|
|
check not await call().reverts()
|
|
check not await call().reverts(revertReason)
|
|
|
|
|
|
suite "Testing helpers - contracts":
|
|
|
|
var helpersContract: TestHelpers
|
|
var provider: JsonRpcProvider
|
|
var snapshot: JsonNode
|
|
var accounts: seq[Address]
|
|
let revertReason = "revert reason"
|
|
let providerUrl = getEnv("ETHERS_TEST_PROVIDER", "localhost:8545")
|
|
|
|
setup:
|
|
provider = JsonRpcProvider.new("ws://" & providerUrl)
|
|
snapshot = await provider.send("evm_snapshot")
|
|
accounts = await provider.listAccounts()
|
|
helpersContract = TestHelpers.new(provider.getSigner())
|
|
|
|
teardown:
|
|
discard await provider.send("evm_revert", @[snapshot])
|
|
await provider.close()
|
|
|
|
test "revert reason can be retrieved when transaction fails":
|
|
let txResp = helpersContract.doRevert(
|
|
revertReason,
|
|
# override gasLimit to skip estimating gas
|
|
TransactionOverrides(gasLimit: some 10000000.u256)
|
|
)
|
|
check await txResp.confirm(1).reverts(revertReason)
|
|
|
|
test "revert reason can be retrieved when estimate gas fails":
|
|
let txResp = helpersContract.doRevert(revertReason)
|
|
check await txResp.reverts(revertReason)
|