Skip to content

Commit 8296e0c

Browse files
committed
Apply block overrides in eth_estimateGas JSON-RPC endpoint
1 parent cdaa9b8 commit 8296e0c

4 files changed

Lines changed: 106 additions & 2 deletions

File tree

api/api.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ func (b *BlockChainAPI) EstimateGas(
693693
args ethTypes.TransactionArgs,
694694
blockNumberOrHash *rpc.BlockNumberOrHash,
695695
stateOverrides *ethTypes.StateOverride,
696+
blockOverrides *ethTypes.BlockOverrides,
696697
) (hexutil.Uint64, error) {
697698
l := b.logger.With().
698699
Str("endpoint", EthEstimateGas).
@@ -723,7 +724,13 @@ func (b *BlockChainAPI) EstimateGas(
723724
return handleError[hexutil.Uint64](err, l, b.collector)
724725
}
725726

726-
estimatedGas, err := b.evm.EstimateGas(args, from, height, stateOverrides)
727+
estimatedGas, err := b.evm.EstimateGas(
728+
args,
729+
from,
730+
height,
731+
stateOverrides,
732+
blockOverrides,
733+
)
727734
if err != nil {
728735
return handleError[hexutil.Uint64](err, l, b.collector)
729736
}

services/requester/requester.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ type Requester interface {
7878
from common.Address,
7979
height uint64,
8080
stateOverrides *ethTypes.StateOverride,
81+
blockOverrides *ethTypes.BlockOverrides,
8182
) (uint64, error)
8283

8384
// GetNonce gets nonce from the network at the given EVM block height.
@@ -320,14 +321,15 @@ func (e *EVM) EstimateGas(
320321
from common.Address,
321322
height uint64,
322323
stateOverrides *ethTypes.StateOverride,
324+
blockOverrides *ethTypes.BlockOverrides,
323325
) (uint64, error) {
324326
iterations := 0
325327

326328
dryRun := func(gasLimit uint64) (*evmTypes.Result, error) {
327329
gas := hexutil.Uint64(gasLimit)
328330
txArgs.Gas = &gas
329331
tx := txArgs.ToTransaction(types.LegacyTxType, blockGasLimit)
330-
result, err := e.dryRunTx(tx, from, height, stateOverrides, nil)
332+
result, err := e.dryRunTx(tx, from, height, stateOverrides, blockOverrides)
331333
iterations += 1
332334
return result, err
333335
}

tests/e2e_web3js_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ func TestWeb3_E2E(t *testing.T) {
4646
runWeb3Test(t, "contract_call_overrides_test")
4747
})
4848

49+
t.Run("test gas estimation block overrides", func(t *testing.T) {
50+
runWeb3Test(t, "estimate_gas_overrides_test")
51+
})
52+
4953
t.Run("test setup sanity check", func(t *testing.T) {
5054
runWeb3Test(t, "setup_test")
5155
})
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const { assert } = require('chai')
2+
const conf = require('./config')
3+
const helpers = require('./helpers')
4+
const web3 = conf.web3
5+
6+
let deployed = null
7+
let contractAddress = null
8+
9+
before(async () => {
10+
deployed = await helpers.deployContract('storage')
11+
contractAddress = deployed.receipt.contractAddress
12+
13+
assert.equal(deployed.receipt.status, conf.successStatus)
14+
})
15+
16+
it('should apply block overrides on eth_estimateGas', async () => {
17+
assert.equal(deployed.receipt.status, conf.successStatus)
18+
19+
let receipt = await web3.eth.getTransactionReceipt(deployed.receipt.transactionHash)
20+
assert.equal(receipt.contractAddress, contractAddress)
21+
22+
// Check the `block.number` value, without overrides
23+
let blockNumberSelector = deployed.contract.methods.blockNumber().encodeABI()
24+
let txArgs = {
25+
from: conf.eoa.address,
26+
to: contractAddress,
27+
gas: '0x75ab',
28+
gasPrice: web3.utils.toHex(conf.minGasPrice),
29+
value: '0x0',
30+
data: blockNumberSelector,
31+
}
32+
33+
let response = await helpers.callRPCMethod(
34+
'eth_estimateGas',
35+
[txArgs, 'latest', null, null]
36+
)
37+
assert.equal(response.status, 200)
38+
assert.isDefined(response.body)
39+
assert.equal(web3.utils.hexToNumber(response.body.result), 21651n)
40+
41+
// Override the `block.number` value to `2`.
42+
response = await helpers.callRPCMethod(
43+
'eth_estimateGas',
44+
[txArgs, 'latest', null, { number: '0x2' }]
45+
)
46+
assert.equal(response.status, 200)
47+
assert.isDefined(response.body)
48+
assert.equal(web3.utils.hexToNumber(response.body.result), 21651n)
49+
50+
// Check the `block.timestamp` value, without overrides
51+
let blockTimeSelector = deployed.contract.methods.blockTime().encodeABI()
52+
txArgs.data = blockTimeSelector
53+
54+
response = await helpers.callRPCMethod(
55+
'eth_estimateGas',
56+
[txArgs, 'latest', null, null]
57+
)
58+
assert.equal(response.status, 200)
59+
assert.isDefined(response.body)
60+
assert.equal(web3.utils.hexToNumber(response.body.result), 21607n)
61+
62+
// Override the `block.timestamp` value to `0x674DB1E1`.
63+
response = await helpers.callRPCMethod(
64+
'eth_estimateGas',
65+
[txArgs, 'latest', null, { time: '0x674DB1E1' }]
66+
)
67+
assert.equal(response.status, 200)
68+
assert.isDefined(response.body)
69+
assert.equal(web3.utils.hexToNumber(response.body.result), 21607n)
70+
71+
// Check the `block.prevrandao` value, without overrides
72+
let randomSelector = deployed.contract.methods.random().encodeABI()
73+
txArgs.data = randomSelector
74+
75+
response = await helpers.callRPCMethod(
76+
'eth_estimateGas',
77+
[txArgs, 'latest', null, null]
78+
)
79+
assert.equal(response.status, 200)
80+
assert.isDefined(response.body)
81+
82+
// Override the `block.prevrandao` value to `0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0`.
83+
let random = '0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0'
84+
response = await helpers.callRPCMethod(
85+
'eth_estimateGas',
86+
[txArgs, 'latest', null, { random: random }]
87+
)
88+
assert.equal(response.status, 200)
89+
assert.isDefined(response.body)
90+
assert.equal(web3.utils.hexToNumber(response.body.result), 21584n)
91+
})

0 commit comments

Comments
 (0)