Skip to content

Commit 97aacd9

Browse files
core: fix pre-check for account balance under EIP-1559 (ethereum#23244)
When processing a transaction with London fork rules, EIP-1559 mandates checking that the sender must have sufficient balance to cover gas * gasFeeCap. In the EIP's pseudocode, this check happens after the value transferred by the transaction has already been deducted. However, in go-ethereum, the balance has not yet been updated when the check happens, and therefore needs to be added explicitly. Co-authored-by: Martin Holst Swende <[email protected]>
1 parent f05419f commit 97aacd9

File tree

7 files changed

+84
-2
lines changed

7 files changed

+84
-2
lines changed

cmd/evm/testdata/12/alloc.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
3+
"balance" : "84000000",
4+
"code" : "0x",
5+
"nonce" : "0x00",
6+
"storage" : {
7+
"0x00" : "0x00"
8+
}
9+
}
10+
}
11+

cmd/evm/testdata/12/env.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
3+
"currentDifficulty" : "0x020000",
4+
"currentNumber" : "0x01",
5+
"currentTimestamp" : "0x03e8",
6+
"previousHash" : "0xfda4419b3660e99f37e536dae1ab081c180136bb38c837a93e93d9aab58553b2",
7+
"currentGasLimit" : "0x0f4240",
8+
"currentBaseFee" : "0x20"
9+
}
10+

cmd/evm/testdata/12/readme.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Test 1559 balance + gasCap
2+
3+
This test contains an EIP-1559 consensus issue which happened on Ropsten, where
4+
`geth` did not properly account for the value transfer while doing the check on `max_fee_per_gas * gas_limit`.
5+
6+
Before the issue was fixed, this invocation allowed the transaction to pass into a block:
7+
```
8+
dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout
9+
```
10+
11+
With the fix applied, the result is:
12+
```
13+
dir=./testdata/12 && ./evm t8n --state.fork=London --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout --output.result=stdout
14+
INFO [07-21|19:03:50.276] rejected tx index=0 hash=ccc996..d83435 from=0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B error="insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
15+
INFO [07-21|19:03:50.276] Trie dumping started root=e05f81..6597a5
16+
INFO [07-21|19:03:50.276] Trie dumping complete accounts=1 elapsed="39.549µs"
17+
{
18+
"alloc": {
19+
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
20+
"balance": "0x501bd00"
21+
}
22+
},
23+
"result": {
24+
"stateRoot": "0xe05f81f8244a76503ceec6f88abfcd03047a612a1001217f37d30984536597a5",
25+
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
26+
"receiptRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
27+
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
28+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
29+
"receipts": [],
30+
"rejected": [
31+
{
32+
"index": 0,
33+
"error": "insufficient funds for gas * price + value: address 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B have 84000000 want 84000032"
34+
}
35+
]
36+
}
37+
}
38+
```
39+
40+
The transaction is rejected.

cmd/evm/testdata/12/txs.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[
2+
{
3+
"input" : "0x",
4+
"gas" : "0x5208",
5+
"nonce" : "0x0",
6+
"to" : "0x1111111111111111111111111111111111111111",
7+
"value" : "0x20",
8+
"v" : "0x0",
9+
"r" : "0x0",
10+
"s" : "0x0",
11+
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
12+
"chainId" : "0x1",
13+
"type" : "0x2",
14+
"maxFeePerGas" : "0xfa0",
15+
"maxPriorityFeePerGas" : "0x20",
16+
"accessList" : [
17+
]
18+
}
19+
]
20+

core/state_processor_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func TestStateProcessorErrors(t *testing.T) {
118118
txs: []*types.Transaction{
119119
makeTx(0, common.Address{}, big.NewInt(1000000000000000000), params.TxGas, big.NewInt(875000000), nil),
120120
},
121-
want: "could not apply tx 0 [0x98c796b470f7fcab40aaef5c965a602b0238e1034cce6fb73823042dd0638d74]: insufficient funds for transfer: address 0x71562b71999873DB5b286dF957af199Ec94617F7",
121+
want: "could not apply tx 0 [0x98c796b470f7fcab40aaef5c965a602b0238e1034cce6fb73823042dd0638d74]: insufficient funds for gas * price + value: address 0x71562b71999873DB5b286dF957af199Ec94617F7 have 1000000000000000000 want 1000018375000000000",
122122
},
123123
{ // ErrInsufficientFunds
124124
txs: []*types.Transaction{

core/state_transition.go

+1
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ func (st *StateTransition) buyGas() error {
193193
if st.gasFeeCap != nil {
194194
balanceCheck = new(big.Int).SetUint64(st.msg.Gas())
195195
balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap)
196+
balanceCheck.Add(balanceCheck, st.value)
196197
}
197198
if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 {
198199
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From().Hex(), have, want)

eth/tracers/api_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ func TestOverriddenTraceCall(t *testing.T) {
369369
config: &TraceCallConfig{
370370
Tracer: &tracer,
371371
},
372-
expectErr: core.ErrInsufficientFundsForTransfer,
372+
expectErr: core.ErrInsufficientFunds,
373373
expect: nil,
374374
},
375375
// Successful simple contract call

0 commit comments

Comments
 (0)