Skip to content

Commit 42fac60

Browse files
committed
internal/ethapi: ethSendTransaction check baseFee (ethereum#27834)
1 parent 27ca506 commit 42fac60

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

internal/ethapi/transaction_args.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,27 +136,42 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b Backend) erro
136136
if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) {
137137
return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
138138
}
139-
// If the tx has completely specified a fee mechanism, no default is needed. This allows users
140-
// who are not yet synced past London to get defaults for other tx values. See
141-
// https://github.com/ethereum/go-ethereum/pull/23274 for more information.
139+
// If the tx has completely specified a fee mechanism, no default is needed.
140+
// This allows users who are not yet synced past London to get defaults for
141+
// other tx values. See https://github.com/ethereum/go-ethereum/pull/23274
142+
// for more information.
142143
eip1559ParamsSet := args.MaxFeePerGas != nil && args.MaxPriorityFeePerGas != nil
143-
if (args.GasPrice != nil && !eip1559ParamsSet) || (args.GasPrice == nil && eip1559ParamsSet) {
144-
// Sanity check the EIP-1559 fee parameters if present.
145-
if args.GasPrice == nil && args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
144+
145+
// Sanity check the EIP-1559 fee parameters if present.
146+
if args.GasPrice == nil && eip1559ParamsSet {
147+
if args.MaxFeePerGas.ToInt().Sign() == 0 {
148+
return errors.New("maxFeePerGas must be non-zero")
149+
}
150+
if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 {
146151
return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas)
147152
}
148-
return nil
153+
return nil // No need to set anything, user already set MaxFeePerGas and MaxPriorityFeePerGas
149154
}
150-
// Now attempt to fill in default value depending on whether London is active or not.
155+
// Sanity check the non-EIP-1559 fee parameters.
151156
head := b.CurrentHeader()
152-
if b.ChainConfig().IsEIP1559(head.Number) {
157+
isEIP1559 := b.ChainConfig().IsEIP1559(head.Number)
158+
if args.GasPrice != nil && !eip1559ParamsSet {
159+
// Zero gas-price is not allowed after London fork
160+
if args.GasPrice.ToInt().Sign() == 0 && isEIP1559 {
161+
return errors.New("gasPrice must be non-zero after EIP-1559 fork")
162+
}
163+
return nil // No need to set anything, user already set GasPrice
164+
}
165+
166+
// Now attempt to fill in default value depending on whether London is active or not.
167+
if isEIP1559 {
153168
// London is active, set maxPriorityFeePerGas and maxFeePerGas.
154169
if err := args.setLondonFeeDefaults(ctx, head, b); err != nil {
155170
return err
156171
}
157172
} else {
158173
if args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil {
159-
return fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active")
174+
return errors.New("maxFeePerGas and maxPriorityFeePerGas are not valid before EIP-1559 is active")
160175
}
161176
// London not active, set gas price.
162177
price, err := b.SuggestGasTipCap(ctx)

internal/ethapi/transaction_args_test.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package ethapi
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"math/big"
2324
"reflect"
@@ -57,6 +58,7 @@ func TestSetFeeDefaults(t *testing.T) {
5758

5859
var (
5960
b = newBackendMock()
61+
zero = (*hexutil.Big)(big.NewInt(0))
6062
fortytwo = (*hexutil.Big)(big.NewInt(42))
6163
maxFee = (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(b.current.BaseFee, big.NewInt(2)), fortytwo.ToInt()))
6264
al = &types.AccessList{types.AccessTuple{Address: common.Address{0xaa}, StorageKeys: []common.Hash{{0x01}}}}
@@ -71,13 +73,27 @@ func TestSetFeeDefaults(t *testing.T) {
7173
&TransactionArgs{GasPrice: fortytwo},
7274
nil,
7375
},
76+
{
77+
"legacy tx pre-London with zero price",
78+
false,
79+
&TransactionArgs{GasPrice: zero},
80+
&TransactionArgs{GasPrice: zero},
81+
nil,
82+
},
7483
{
7584
"legacy tx post-London, explicit gas price",
7685
true,
7786
&TransactionArgs{GasPrice: fortytwo},
7887
&TransactionArgs{GasPrice: fortytwo},
7988
nil,
8089
},
90+
{
91+
"legacy tx post-London with zero price",
92+
true,
93+
&TransactionArgs{GasPrice: zero},
94+
nil,
95+
errors.New("gasPrice must be non-zero after EIP-1559 fork"),
96+
},
8197

8298
// Access list txs
8399
{
@@ -143,14 +159,14 @@ func TestSetFeeDefaults(t *testing.T) {
143159
false,
144160
&TransactionArgs{MaxFeePerGas: maxFee},
145161
nil,
146-
fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active"),
162+
fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before EIP-1559 is active"),
147163
},
148164
{
149165
"dynamic fee tx pre-London, priorityFee set",
150166
false,
151167
&TransactionArgs{MaxPriorityFeePerGas: fortytwo},
152168
nil,
153-
fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before London is active"),
169+
fmt.Errorf("maxFeePerGas and maxPriorityFeePerGas are not valid before EIP-1559 is active"),
154170
},
155171
{
156172
"dynamic fee tx, maxFee < priorityFee",
@@ -166,6 +182,13 @@ func TestSetFeeDefaults(t *testing.T) {
166182
nil,
167183
fmt.Errorf("maxFeePerGas (0x7) < maxPriorityFeePerGas (0x2a)"),
168184
},
185+
{
186+
"dynamic fee tx post-London, explicit gas price",
187+
true,
188+
&TransactionArgs{MaxFeePerGas: zero, MaxPriorityFeePerGas: zero},
189+
nil,
190+
errors.New("maxFeePerGas must be non-zero"),
191+
},
169192

170193
// Misc
171194
{

0 commit comments

Comments
 (0)