mirror of
https://github.com/status-im/nim-ethers.git
synced 2025-01-11 16:14:36 +00:00
Fix: ensure that gas estimations are done using the "pending" block
This commit is contained in:
parent
d46f5a10d3
commit
af5a0f5fb4
@ -88,7 +88,7 @@ method estimateGas*(
|
|||||||
|
|
||||||
transaction.sender = some(address)
|
transaction.sender = some(address)
|
||||||
try:
|
try:
|
||||||
return await signer.provider.estimateGas(transaction)
|
return await signer.provider.estimateGas(transaction, blockTag)
|
||||||
except ProviderError as e:
|
except ProviderError as e:
|
||||||
raiseEstimateGasError transaction, e
|
raiseEstimateGasError transaction, e
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ method populateTransaction*(
|
|||||||
# stuck transactions
|
# stuck transactions
|
||||||
populated.nonce = some(await signer.getNonce())
|
populated.nonce = some(await signer.getNonce())
|
||||||
try:
|
try:
|
||||||
populated.gasLimit = some(await signer.estimateGas(populated))
|
populated.gasLimit = some(await signer.estimateGas(populated, BlockTag.pending))
|
||||||
except EstimateGasError as e:
|
except EstimateGasError as e:
|
||||||
signer.decreaseNonce()
|
signer.decreaseNonce()
|
||||||
raise e
|
raise e
|
||||||
@ -173,7 +173,7 @@ method populateTransaction*(
|
|||||||
if transaction.nonce.isNone:
|
if transaction.nonce.isNone:
|
||||||
populated.nonce = some(await signer.getNonce())
|
populated.nonce = some(await signer.getNonce())
|
||||||
if transaction.gasLimit.isNone:
|
if transaction.gasLimit.isNone:
|
||||||
populated.gasLimit = some(await signer.estimateGas(populated))
|
populated.gasLimit = some(await signer.estimateGas(populated, BlockTag.pending))
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
signer.populateLock.release()
|
signer.populateLock.release()
|
||||||
|
@ -6,5 +6,6 @@ import ./testEvents
|
|||||||
import ./testWallet
|
import ./testWallet
|
||||||
import ./testTesting
|
import ./testTesting
|
||||||
import ./testErc20
|
import ./testErc20
|
||||||
|
import ./testGasEstimation
|
||||||
|
|
||||||
{.warning[UnusedImport]:off.}
|
{.warning[UnusedImport]:off.}
|
||||||
|
41
testmodule/testGasEstimation.nim
Normal file
41
testmodule/testGasEstimation.nim
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import pkg/asynctest
|
||||||
|
import pkg/ethers
|
||||||
|
import pkg/serde
|
||||||
|
import ./hardhat
|
||||||
|
|
||||||
|
type
|
||||||
|
TestGasEstimation = ref object of Contract
|
||||||
|
|
||||||
|
proc getTime(contract: TestGasEstimation): UInt256 {.contract, view.}
|
||||||
|
proc checkTimeEquals(contract: TestGasEstimation, expected: UInt256) {.contract.}
|
||||||
|
|
||||||
|
suite "gas estimation":
|
||||||
|
|
||||||
|
var contract: TestGasEstimation
|
||||||
|
var provider: JsonRpcProvider
|
||||||
|
var snapshot: JsonNode
|
||||||
|
|
||||||
|
setup:
|
||||||
|
provider = JsonRpcProvider.new()
|
||||||
|
snapshot = await provider.send("evm_snapshot")
|
||||||
|
let deployment = readDeployment()
|
||||||
|
let signer = provider.getSigner()
|
||||||
|
contract = TestGasEstimation.new(!deployment.address(TestGasEstimation), signer)
|
||||||
|
|
||||||
|
teardown:
|
||||||
|
discard await provider.send("evm_revert", @[snapshot])
|
||||||
|
await provider.close()
|
||||||
|
|
||||||
|
test "uses pending block for gas estimations":
|
||||||
|
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
|
||||||
|
|
||||||
|
# fails with "Transaction ran out of gas" when gas estimation
|
||||||
|
# is not done using the pending block
|
||||||
|
await contract.checkTimeEquals(time)
|
22
testnode/contracts/TestGasEstimation.sol
Normal file
22
testnode/contracts/TestGasEstimation.sol
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
contract TestGasEstimation {
|
||||||
|
|
||||||
|
uint lastCheckedTime;
|
||||||
|
|
||||||
|
// this function returns a different value depending on whether
|
||||||
|
// it is called on the latest block, or on the pending block
|
||||||
|
function getTime() public view returns (uint) {
|
||||||
|
return block.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function is designed to require a different amount of
|
||||||
|
// gas, depending on whether the parameter matches the block
|
||||||
|
// timestamp
|
||||||
|
function checkTimeEquals(uint expected) public {
|
||||||
|
if (expected == block.timestamp) {
|
||||||
|
lastCheckedTime = block.timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
testnode/deploy/testgasestimation.js
Normal file
6
testnode/deploy/testgasestimation.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = async ({ deployments, getNamedAccounts }) => {
|
||||||
|
const { deployer } = await getNamedAccounts();
|
||||||
|
await deployments.deploy("TestGasEstimation", { from: deployer });
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.tags = ["TestGasEstimation"];
|
Loading…
x
Reference in New Issue
Block a user