Skip to content

Commit

Permalink
internal/ethapi: cap txfee for SignTransaction and Resend (ethereum#2…
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Jun 20, 2024
1 parent 56591d3 commit 341ca00
Showing 1 changed file with 38 additions and 19 deletions.
57 changes: 38 additions & 19 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs
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 {
return nil, err
}
signed, err := s.signTransaction(ctx, args, passwd)
if err != nil {
log.Warn("Failed transaction sign attempt", "from", args.From, "to", args.To, "value", args.Value.ToInt(), "err", err)
Expand Down Expand Up @@ -2375,10 +2379,8 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c

// If the transaction fee cap is already specified, ensure the
// fee of the given transaction is _reasonable_.
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)))
feeFloat, _ := feeEth.Float64()
if b.RPCTxFeeCap() != 0 && feeFloat > b.RPCTxFeeCap() {
return common.Hash{}, fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, b.RPCTxFeeCap())
if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil {
return common.Hash{}, err
}
if err := b.SendTx(ctx, tx); err != nil {
return common.Hash{}, err
Expand Down Expand Up @@ -3367,6 +3369,10 @@ func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args Sen
if err := args.setDefaults(ctx, s.b); err != nil {
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 {
return nil, err
}
tx, err := s.sign(args.From, args.toTransaction())
if err != nil {
return nil, err
Expand Down Expand Up @@ -3412,6 +3418,19 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr
}
matchTx := sendArgs.toTransaction()

// Before replacing the old transaction, ensure the _new_ transaction fee is reasonable.
var price = matchTx.GasPrice()
if gasPrice != nil {
price = gasPrice.ToInt()
}
var gas = matchTx.Gas()
if gasLimit != nil {
gas = uint64(*gasLimit)
}
if err := checkTxFee(price, gas, s.b.RPCTxFeeCap()); err != nil {
return common.Hash{}, err
}

// Iterate the pending list for replacement
pending, err := s.b.GetPoolTransactions()
if err != nil {
Expand Down Expand Up @@ -3561,6 +3580,21 @@ func (s *PublicNetAPI) Version() string {
return fmt.Sprintf("%d", s.networkVersion)
}

// checkTxFee is an internal function used to check whether the fee of
// the given transaction is _reasonable_(under the cap).
func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
// Short circuit if there is no cap for transaction fee at all.
if cap == 0 {
return nil
}
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)))
feeFloat, _ := feeEth.Float64()
if feeFloat > cap {
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap)
}
return nil
}

func GetSignersFromBlocks(b Backend, blockNumber uint64, blockHash common.Hash, masternodes []common.Address) ([]common.Address, error) {
var addrs []common.Address
mapMN := map[common.Address]bool{}
Expand Down Expand Up @@ -3661,18 +3695,3 @@ func (s *PublicBlockChainAPI) GetStakerROIMasternode(masternode common.Address)

return 100.0 / float64(totalCap.Div(totalCap, voterRewardAYear).Uint64())
}

// checkTxFee is an internal function used to check whether the fee of
// the given transaction is _reasonable_(under the cap).
func checkTxFee(gasPrice *big.Int, gas uint64, cap float64) error {
// Short circuit if there is no cap for transaction fee at all.
if cap == 0 {
return nil
}
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)))
feeFloat, _ := feeEth.Float64()
if feeFloat > cap {
return fmt.Errorf("tx fee (%.2f ether) exceeds the configured cap (%.2f ether)", feeFloat, cap)
}
return nil
}

0 comments on commit 341ca00

Please sign in to comment.