From f9d115ae75846d6bbe578ca14eb7e36f8c98917a Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 14 Apr 2025 12:51:54 +0200 Subject: [PATCH] Use pending block for gas estimations --- ethers/contracts/gas.nim | 11 +++++++--- testmodule/testGasEstimation.nim | 36 +++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ethers/contracts/gas.nim b/ethers/contracts/gas.nim index 7ef3ec3..703b1c5 100644 --- a/ethers/contracts/gas.nim +++ b/ethers/contracts/gas.nim @@ -5,6 +5,7 @@ import ../signer import ./contract import ./contractcall import ./transactions +import ./overrides import ./errors import ./syntax @@ -16,11 +17,15 @@ func estimateGas*[C: Contract](contract: C): ContractGasEstimations[C] = proc estimateGas( call: ContractCall ): Future[UInt256] {.async: (raises: [CancelledError, ProviderError, EthersError]).} = - var transaction = createTransaction(call) + let transaction = createTransaction(call) + var blockTag = BlockTag.pending + if call.overrides of CallOverrides: + if tag =? CallOverrides(call.overrides).blockTag: + blockTag = tag if signer =? call.contract.signer: - await signer.estimateGas(transaction) + await signer.estimateGas(transaction, blockTag) else: - await call.contract.provider.estimateGas(transaction) + await call.contract.provider.estimateGas(transaction, blockTag) func wrapFirstParameter(procedure: var NimNode) = let contractType = procedure.params[1][1] diff --git a/testmodule/testGasEstimation.nim b/testmodule/testGasEstimation.nim index 7efdd50..3b01a35 100644 --- a/testmodule/testGasEstimation.nim +++ b/testmodule/testGasEstimation.nim @@ -28,7 +28,7 @@ suite "gas estimation": discard await provider.send("evm_revert", @[snapshot]) await provider.close() - test "uses pending block for gas estimations": + test "contract function calls use pending block for gas estimations": let latest = CallOverrides(blockTag: some BlockTag.latest) let pending = CallOverrides(blockTag: some BlockTag.pending) @@ -41,3 +41,37 @@ suite "gas estimation": # fails with "Transaction ran out of gas" when gas estimation # is not done using the pending block await contract.checkTimeEquals(time) + + test "contract gas estimation uses pending block": + let latest = CallOverrides(blockTag: some BlockTag.latest) + let pending = CallOverrides(blockTag: some BlockTag.pending) + + # retrieve time of pending block + let time = await contract.getTime(overrides=pending) + + # ensure that time of latest block and pending block differ + check (await contract.getTime(overrides=latest)) != time + + # estimate gas + let gas = await contract.estimateGas.checkTimeEquals(time) + let overrides = TransactionOverrides(gasLimit: some gas) + + # fails with "Transaction ran out of gas" when gas estimation + # was not done using the pending block + await contract.checkTimeEquals(time, overrides) + + test "contract gas estimation honors a block tag override": + let latest = CallOverrides(blockTag: some BlockTag.latest) + let pending = CallOverrides(blockTag: some BlockTag.pending) + + # retrieve time of pending block + let time = await contract.getTime(overrides=pending) + + # ensure that time of latest block and pending block differ + check (await contract.getTime(overrides=latest)) != time + + # estimate gas + let gasLatest = await contract.estimateGas.checkTimeEquals(time, latest) + let gasPending = await contract.estimateGas.checkTimeEquals(time, pending) + + check gasLatest != gasPending