Use pending block for gas estimations

This commit is contained in:
Mark Spanbroek 2025-04-14 12:51:54 +02:00 committed by markspanbroek
parent a29e86bfc8
commit f9d115ae75
2 changed files with 43 additions and 4 deletions

View File

@ -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]

View File

@ -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