Skip to content

Commit 4edbc1f

Browse files
authored
internal/ethapi: cap txfee for SignTransaction and Resend (#21231)
1 parent 6cf6e1d commit 4edbc1f

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

internal/ethapi/api.go

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,10 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs
406406
if args.Nonce == nil {
407407
return nil, fmt.Errorf("nonce not specified")
408408
}
409+
// Before actually sign the transaction, ensure the transaction fee is reasonable.
410+
if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil {
411+
return nil, err
412+
}
409413
signed, err := s.signTransaction(ctx, &args, passwd)
410414
if err != nil {
411415
log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err)
@@ -1545,10 +1549,8 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
15451549
func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) {
15461550
// If the transaction fee cap is already specified, ensure the
15471551
// fee of the given transaction is _reasonable_.
1548-
feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))), new(big.Float).SetInt(big.NewInt(params.Ether)))
1549-
feeFloat, _ := feeEth.Float64()
1550-
if b.RPCTxFeeCap() != 0 && feeFloat > b.RPCTxFeeCap() {
1551-
return common.Hash{}, fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, b.RPCTxFeeCap())
1552+
if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil {
1553+
return common.Hash{}, err
15521554
}
15531555
if err := b.SendTx(ctx, tx); err != nil {
15541556
return common.Hash{}, err
@@ -1672,6 +1674,10 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen
16721674
if err := args.setDefaults(ctx, s.b); err != nil {
16731675
return nil, err
16741676
}
1677+
// Before actually sign the transaction, ensure the transaction fee is reasonable.
1678+
if err := checkTxFee(args.GasPrice.ToInt(), uint64(*args.Gas), s.b.RPCTxFeeCap()); err != nil {
1679+
return nil, err
1680+
}
16751681
tx, err := s.sign(args.From, args.toTransaction())
16761682
if err != nil {
16771683
return nil, err
@@ -1720,11 +1726,24 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
17201726
return common.Hash{}, err
17211727
}
17221728
matchTx := sendArgs.toTransaction()
1729+
1730+
// Before replacing the old transaction, ensure the _new_ transaction fee is reasonable.
1731+
var price = matchTx.GasPrice()
1732+
if gasPrice != nil {
1733+
price = gasPrice.ToInt()
1734+
}
1735+
var gas = matchTx.Gas()
1736+
if gasLimit != nil {
1737+
gas = uint64(*gasLimit)
1738+
}
1739+
if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil {
1740+
return common.Hash{}, err
1741+
}
1742+
// Iterate the pending list for replacement
17231743
pending, err := s.b.GetPoolTransactions()
17241744
if err != nil {
17251745
return common.Hash{}, err
17261746
}
1727-
17281747
for _, p := range pending {
17291748
var signer types.Signer = types.HomesteadSigner{}
17301749
if p.Protected() {
@@ -1901,3 +1920,18 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint {
19011920
func (s *PublicNetAPI) Version() string {
19021921
return fmt.Sprintf("%d", s.networkVersion)
19031922
}
1923+
1924+
// checkTxFee is an internal function used to check whether the fee of
1925+
// the given transaction is _reasonable_(under the cap).
1926+
func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
1927+
// Short circuit if there is no cap for transaction fee at all.
1928+
if cap == 0 {
1929+
return nil
1930+
}
1931+
feeEth := new(big.Float).Quo(new(big.Float).SetInt(new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(gas))), new(big.Float).SetInt(big.NewInt(params.Ether)))
1932+
feeFloat, _ := feeEth.Float64()
1933+
if feeFloat > cap {
1934+
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap)
1935+
}
1936+
return nil
1937+
}

0 commit comments

Comments
 (0)