disallow .confirm(0)

reason: it didn't wait for any blocks to be mined,
not even the block that includes the transaction.
This commit is contained in:
Mark Spanbroek 2024-11-11 12:26:36 +01:00 committed by markspanbroek
parent c9275b1f6c
commit 5a9895b792
4 changed files with 19 additions and 14 deletions

View File

@ -230,22 +230,27 @@ proc confirm*(
{.async: (raises: [CancelledError, ProviderError, EthersError]).} =
## Waits for a transaction to be mined and for the specified number of blocks
## to pass since it was mined (confirmations).
## to pass since it was mined (confirmations). The number of confirmations
## includes the block in which the transaction was mined.
## A timeout, in blocks, can be specified that will raise an error if too many
## blocks have passed without the tx having been mined.
assert confirmations > 0
var blockNumber: UInt256
let blockEvent = newAsyncEvent()
proc onBlockNumber(number: UInt256) =
blockNumber = number
blockEvent.fire()
proc updateBlockNumber {.async: (raises: [ProviderError]).} =
let number = await tx.provider.getBlockNumber()
if number > blockNumber:
blockNumber = number
blockEvent.fire()
proc onBlock(blck: Block) =
if number =? blck.number:
onBlockNumber(number)
proc onBlock(_: Block) =
# ignore block parameter; hardhat may call this with pending blocks
asyncSpawn updateBlockNumber()
onBlockNumber(await tx.provider.getBlockNumber())
await updateBlockNumber()
let subscription = await tx.provider.subscribe(onBlock)
let finish = blockNumber + timeout.u256

View File

@ -68,13 +68,13 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]:
check UInt256.fromHex("0x" & txResp.hash.toHex) > 0
test "can wait for a transaction to be confirmed":
for confirmations in 0..3:
for confirmations in 1..3:
let signer = provider.getSigner()
let transaction = Transaction.example
let populated = await signer.populateTransaction(transaction)
let confirming = signer.sendTransaction(populated).confirm(confirmations)
await sleepAsync(100.millis) # wait for tx to be mined
await provider.mineBlocks(confirmations - 1)
await provider.mineBlocks(confirmations)
let receipt = await confirming
check receipt.blockNumber.isSome

View File

@ -305,11 +305,11 @@ for url in ["ws://" & providerUrl, "http://" & providerUrl]:
executeTx(),
executeTx()
)
let receipt1 = await futs[1].confirm(0)
let receipt2 = await futs[2].confirm(0)
let receipt1 = await futs[1].confirm(1)
let receipt2 = await futs[2].confirm(1)
check receipt1.status == TransactionStatus.Success
check receipt2.status == TransactionStatus.Success
let balanceAfter = await token.myBalance()
check balanceAfter == balanceBefore + 200.u256
check balanceAfter == balanceBefore + 200.u256

View File

@ -136,7 +136,7 @@ suite "Contract custom errors":
let contract = contract.connect(provider.getSigner())
try:
let future = contract.revertsTransaction(overrides = overrides).confirm(0)
let future = contract.revertsTransaction(overrides = overrides).confirm(1)
await sleepAsync(100.millis) # wait for transaction to be submitted
discard await provider.send("evm_mine", @[]) # mine the transaction
discard await future # wait for confirmation