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
parent 9bb9737c4a
commit 19cdaebbf1
No known key found for this signature in database
GPG Key ID: FBE3E9548D427C00
4 changed files with 19 additions and 14 deletions

View File

@ -230,22 +230,27 @@ proc confirm*(
{.async: (raises: [CancelledError, ProviderError, EthersError]).} = {.async: (raises: [CancelledError, ProviderError, EthersError]).} =
## Waits for a transaction to be mined and for the specified number of blocks ## 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 ## A timeout, in blocks, can be specified that will raise an error if too many
## blocks have passed without the tx having been mined. ## blocks have passed without the tx having been mined.
assert confirmations > 0
var blockNumber: UInt256 var blockNumber: UInt256
let blockEvent = newAsyncEvent() let blockEvent = newAsyncEvent()
proc onBlockNumber(number: UInt256) = proc updateBlockNumber {.async: (raises: [ProviderError]).} =
blockNumber = number let number = await tx.provider.getBlockNumber()
blockEvent.fire() if number > blockNumber:
blockNumber = number
blockEvent.fire()
proc onBlock(blck: Block) = proc onBlock(_: Block) =
if number =? blck.number: # ignore block parameter; hardhat may call this with pending blocks
onBlockNumber(number) asyncSpawn updateBlockNumber()
onBlockNumber(await tx.provider.getBlockNumber()) await updateBlockNumber()
let subscription = await tx.provider.subscribe(onBlock) let subscription = await tx.provider.subscribe(onBlock)
let finish = blockNumber + timeout.u256 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 check UInt256.fromHex("0x" & txResp.hash.toHex) > 0
test "can wait for a transaction to be confirmed": test "can wait for a transaction to be confirmed":
for confirmations in 0..3: for confirmations in 1..3:
let signer = provider.getSigner() let signer = provider.getSigner()
let transaction = Transaction.example let transaction = Transaction.example
let populated = await signer.populateTransaction(transaction) let populated = await signer.populateTransaction(transaction)
let confirming = signer.sendTransaction(populated).confirm(confirmations) let confirming = signer.sendTransaction(populated).confirm(confirmations)
await sleepAsync(100.millis) # wait for tx to be mined await sleepAsync(100.millis) # wait for tx to be mined
await provider.mineBlocks(confirmations - 1) await provider.mineBlocks(confirmations)
let receipt = await confirming let receipt = await confirming
check receipt.blockNumber.isSome check receipt.blockNumber.isSome

View File

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

View File

@ -136,7 +136,7 @@ suite "Contract custom errors":
let contract = contract.connect(provider.getSigner()) let contract = contract.connect(provider.getSigner())
try: 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 await sleepAsync(100.millis) # wait for transaction to be submitted
discard await provider.send("evm_mine", @[]) # mine the transaction discard await provider.send("evm_mine", @[]) # mine the transaction
discard await future # wait for confirmation discard await future # wait for confirmation