|
|
|
@ -406,6 +406,10 @@ func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs |
|
|
|
|
if args.Nonce == nil { |
|
|
|
|
return nil, fmt.Errorf("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) |
|
|
|
@ -1545,10 +1549,8 @@ func (args *SendTxArgs) toTransaction() *types.Transaction { |
|
|
|
|
func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { |
|
|
|
|
// 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 |
|
|
|
@ -1672,6 +1674,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 |
|
|
|
@ -1720,11 +1726,24 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxAr |
|
|
|
|
return common.Hash{}, err |
|
|
|
|
} |
|
|
|
|
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 { |
|
|
|
|
return common.Hash{}, err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for _, p := range pending { |
|
|
|
|
var signer types.Signer = types.HomesteadSigner{} |
|
|
|
|
if p.Protected() { |
|
|
|
@ -1901,3 +1920,18 @@ func (s *PublicNetAPI) PeerCount() hexutil.Uint { |
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|