From 436d52338c86ba38d3c7c94c60ee1e2a82f69d50 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Thu, 13 Jun 2024 14:06:10 +0800 Subject: [PATCH] internal/ethapi: fix transaction APIs (#23179) --- internal/ethapi/api.go | 23 +++++++++++++---------- internal/ethapi/transaction_args.go | 5 ++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index df255596ed91..c14837c76248 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -460,14 +460,15 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args Transactio if args.Gas == nil { return nil, errors.New("gas not specified") } - if args.GasPrice == nil { - return nil, errors.New("gasPrice not specified") + if args.GasPrice == nil && (args.MaxFeePerGas == nil || args.MaxPriorityFeePerGas == nil) { + return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") } if args.Nonce == nil { return nil, errors.New("nonce not specified") } // Before actually sign the transaction, ensure the transaction fee is reasonable. - if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { + tx := args.toTransaction() + if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { return nil, err } signed, err := s.signTransaction(ctx, &args, passwd) @@ -2390,8 +2391,9 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Tra return SubmitTransaction(ctx, s.b, signed) } -// FillTransaction fills the defaults (nonce, gas, gasPrice) on a given unsigned transaction, -// and returns it to the caller for further processing (signing + broadcast) +// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields) +// on a given unsigned transaction, and returns it to the caller for further +// processing (signing + broadcast). func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { // Set some sanity defaults and terminate on failure if err := args.setDefaults(ctx, s.b); err != nil { @@ -3293,8 +3295,8 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Tra if args.Gas == nil { return nil, errors.New("gas not specified") } - if args.GasPrice == nil { - return nil, errors.New("gasPrice not specified") + if args.GasPrice == nil && (args.MaxPriorityFeePerGas == nil || args.MaxFeePerGas == nil) { + return nil, errors.New("missing gasPrice or maxFeePerGas/maxPriorityFeePerGas") } if args.Nonce == nil { return nil, errors.New("nonce not specified") @@ -3303,14 +3305,15 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Tra return nil, err } // Before actually sign the transaction, ensure the transaction fee is reasonable. - if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil { + tx := args.toTransaction() + if err := checkTxFee(tx.GasPrice(), tx.Gas(), s.b.RPCTxFeeCap()); err != nil { return nil, err } - tx, err := s.sign(args.from(), args.toTransaction()) + signed, err := s.sign(args.from(), tx) if err != nil { return nil, err } - data, err := tx.MarshalBinary() + data, err := signed.MarshalBinary() if err != nil { return nil, err } diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 926122df06f1..cacc5dc2e939 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -49,7 +49,7 @@ type TransactionArgs struct { Data *hexutil.Bytes `json:"data"` Input *hexutil.Bytes `json:"input"` - // For non-legacy transactions + // Introduced by AccessListTxType transaction. AccessList *types.AccessList `json:"accessList,omitempty"` ChainID *hexutil.Big `json:"chainId,omitempty"` } @@ -108,6 +108,9 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend) error { return err } if b.ChainConfig().IsEIP1559(head.Number) { + // The legacy tx gas price suggestion should not add 2x base fee + // because all fees are consumed, so it would result in a spiral + // upwards. price.Add(price, head.BaseFee) } args.GasPrice = (*hexutil.Big)(price)