initial exception types and effects fixes

This commit is contained in:
gmega 2023-12-15 11:35:07 -03:00
parent fd16d71ea5
commit ce4d8d0238
No known key found for this signature in database
GPG Key ID: FFD8DAF00660270F
5 changed files with 35 additions and 19 deletions

View File

@ -2,5 +2,5 @@ template untilCancelled*(body) =
try:
while true:
body
except CancelledError:
raise
except CancelledError as exc:
raise exc

View File

@ -14,6 +14,14 @@ type
callbacks: Table[JsonNode, SubscriptionCallback]
SubscriptionCallback = proc(id, arguments: JsonNode) {.gcsafe, raises:[].}
# FIXME Nim 1.6.XX seems to have issues tracking exception effects and will see
# ghost unlisted Exceptions with table operations. In a smaller example
# (https://forum.nim-lang.org/t/10749), using {.experimental:"strictEffects".}
# would fix it, but it doesn't work here for some reason I yet don't
# understand. For now, therefore, I'm simply using a mitigation which is to
# tell the compiler the truth.
template mitigateEffectsBug(body) = {.cast(raises: []).}: body
method subscribeBlocks*(subscriptions: JsonRpcSubscriptions,
onBlock: BlockHandler):
Future[JsonNode]
@ -70,7 +78,7 @@ method subscribeBlocks(subscriptions: WebSocketSubscriptions,
if blck =? Block.fromJson(arguments["result"]).catch:
onBlock(blck)
let id = await subscriptions.client.eth_subscribe("newHeads")
subscriptions.callbacks[id] = callback
mitigateEffectsBug: subscriptions.callbacks[id] = callback
return id
method subscribeLogs(subscriptions: WebSocketSubscriptions,
@ -82,13 +90,13 @@ method subscribeLogs(subscriptions: WebSocketSubscriptions,
if log =? Log.fromJson(arguments["result"]).catch:
onLog(log)
let id = await subscriptions.client.eth_subscribe("logs", filter)
subscriptions.callbacks[id] = callback
mitigateEffectsBug: subscriptions.callbacks[id] = callback
return id
method unsubscribe(subscriptions: WebSocketSubscriptions,
id: JsonNode)
{.async.} =
subscriptions.callbacks.del(id)
mitigateEffectsBug: subscriptions.callbacks.del(id)
discard await subscriptions.client.eth_unsubscribe(id)
# Polling
@ -144,7 +152,7 @@ method subscribeBlocks(subscriptions: PollingSubscriptions,
asyncSpawn getBlock(hash)
let id = await subscriptions.client.eth_newBlockFilter()
subscriptions.callbacks[id] = callback
mitigateEffectsBug: subscriptions.callbacks[id] = callback
return id
method subscribeLogs(subscriptions: PollingSubscriptions,
@ -158,11 +166,11 @@ method subscribeLogs(subscriptions: PollingSubscriptions,
onLog(log)
let id = await subscriptions.client.eth_newFilter(filter)
subscriptions.callbacks[id] = callback
mitigateEffectsBug: subscriptions.callbacks[id] = callback
return id
method unsubscribe(subscriptions: PollingSubscriptions,
id: JsonNode)
{.async.} =
subscriptions.callbacks.del(id)
mitigateEffectsBug: subscriptions.callbacks.del(id)
discard await subscriptions.client.eth_uninstallFilter(id)

View File

@ -26,10 +26,12 @@ proc raiseEstimateGasError(
parent: parent)
raise e
method provider*(signer: Signer): Provider {.base, gcsafe.} =
method provider*(signer: Signer):
Provider {.base, gcsafe, raises: [CatchableError].} =
doAssert false, "not implemented"
method getAddress*(signer: Signer): Future[Address] {.base, gcsafe.} =
method getAddress*(signer: Signer):
Future[Address] {.base, gcsafe, raises: [CatchableError].} =
doAssert false, "not implemented"
method signMessage*(signer: Signer,
@ -40,7 +42,8 @@ method sendTransaction*(signer: Signer,
transaction: Transaction): Future[TransactionResponse] {.base, async.} =
doAssert false, "not implemented"
method getGasPrice*(signer: Signer): Future[UInt256] {.base, gcsafe.} =
method getGasPrice*(signer: Signer):
Future[UInt256] {.base, gcsafe, raises: [CatchableError].} =
signer.provider.getGasPrice()
method getTransactionCount*(signer: Signer,
@ -59,7 +62,8 @@ method estimateGas*(signer: Signer,
except ProviderError as e:
raiseEstimateGasError transaction, e
method getChainId*(signer: Signer): Future[UInt256] {.base, gcsafe.} =
method getChainId*(signer: Signer):
Future[UInt256] {.base, gcsafe, raises: [CatchableError].} =
signer.provider.getChainId()
method getNonce(signer: Signer): Future[UInt256] {.base, gcsafe, async.} =
@ -74,7 +78,7 @@ method getNonce(signer: Signer): Future[UInt256] {.base, gcsafe, async.} =
method updateNonce*(
signer: Signer,
nonce: UInt256
) {.base, gcsafe.} =
) {.base, gcsafe, raises: [CatchableError].} =
without lastSeen =? signer.lastSeenNonce:
signer.lastSeenNonce = some nonce
@ -83,7 +87,7 @@ method updateNonce*(
if nonce > lastSeen:
signer.lastSeenNonce = some nonce
method decreaseNonce*(signer: Signer) {.base, gcsafe.} =
method decreaseNonce*(signer: Signer) {.base, gcsafe, raises: [CatchableError].} =
if lastSeen =? signer.lastSeenNonce and lastSeen > 0:
signer.lastSeenNonce = some lastSeen - 1
@ -119,10 +123,12 @@ method populateTransaction*(signer: Signer,
populated.nonce = some(await signer.getNonce())
try:
populated.gasLimit = some(await signer.estimateGas(populated))
except ProviderError, EstimateGasError:
let e = getCurrentException()
except ProviderError as exc:
signer.decreaseNonce()
raise e
raise exc
except EstimateGasError as exc:
signer.decreaseNonce()
raise exc
else:
if transaction.nonce.isNone:

View File

@ -54,7 +54,7 @@ proc createRandom*(_: type Wallet, provider: Provider): Wallet =
result.address = Address.init(result.publicKey.toCanonicalAddress())
result.provider = some provider
method provider*(wallet: Wallet): Provider =
method provider*(wallet: Wallet): Provider {.raises: [CatchableError].} =
without provider =? wallet.provider:
raiseWalletError "Wallet has no provider"
provider

View File

@ -1,10 +1,12 @@
import std/os
import std/json
import pkg/ethers/basics
type Deployment* = object
json: JsonNode
const defaultFile = "../testnode/deployment.json"
const defaultFile = currentSourcePath.parentDir.parentDir /
"testnode" / "deployment.json"
## Reads deployment information from a json file. It expects a file that has
## been exported with Hardhat deploy. See also: