forked from cerc-io/plugeth
rpc, internal/ethapi: default rpc gascap at 25M + better error message (#21229)
* rpc, internal/ethapi: default rpc gascap at 50M + better error message * eth,internal: make globalgascap uint64 * core/tests: fix compilation failure * eth/config: gascap at 25M + minor review concerns
This commit is contained in:
parent
af5c97aebe
commit
12867d152c
@ -476,7 +476,8 @@ var (
|
|||||||
}
|
}
|
||||||
RPCGlobalGasCap = cli.Uint64Flag{
|
RPCGlobalGasCap = cli.Uint64Flag{
|
||||||
Name: "rpc.gascap",
|
Name: "rpc.gascap",
|
||||||
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas",
|
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)",
|
||||||
|
Value: eth.DefaultConfig.RPCGasCap,
|
||||||
}
|
}
|
||||||
RPCGlobalTxFeeCap = cli.Float64Flag{
|
RPCGlobalTxFeeCap = cli.Float64Flag{
|
||||||
Name: "rpc.txfeecap",
|
Name: "rpc.txfeecap",
|
||||||
@ -1563,7 +1564,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
|||||||
cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
|
cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
|
||||||
}
|
}
|
||||||
if ctx.GlobalIsSet(RPCGlobalGasCap.Name) {
|
if ctx.GlobalIsSet(RPCGlobalGasCap.Name) {
|
||||||
cfg.RPCGasCap = new(big.Int).SetUint64(ctx.GlobalUint64(RPCGlobalGasCap.Name))
|
cfg.RPCGasCap = ctx.GlobalUint64(RPCGlobalGasCap.Name)
|
||||||
|
}
|
||||||
|
if cfg.RPCGasCap != 0 {
|
||||||
|
log.Info("Set global gas cap", "cap", cfg.RPCGasCap)
|
||||||
|
} else {
|
||||||
|
log.Info("Global gas cap disabled")
|
||||||
}
|
}
|
||||||
if ctx.GlobalIsSet(RPCGlobalTxFeeCap.Name) {
|
if ctx.GlobalIsSet(RPCGlobalTxFeeCap.Name) {
|
||||||
cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCap.Name)
|
cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCap.Name)
|
||||||
|
@ -18,6 +18,7 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -245,7 +246,7 @@ func TestInvalidTransactions(t *testing.T) {
|
|||||||
|
|
||||||
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()))
|
balance := new(big.Int).Add(tx.Value(), new(big.Int).Mul(new(big.Int).SetUint64(tx.Gas()), tx.GasPrice()))
|
||||||
pool.currentState.AddBalance(from, balance)
|
pool.currentState.AddBalance(from, balance)
|
||||||
if err := pool.AddRemote(tx); err != ErrIntrinsicGas {
|
if err := pool.AddRemote(tx); !errors.Is(err, ErrIntrinsicGas) {
|
||||||
t.Error("expected", ErrIntrinsicGas, "got", err)
|
t.Error("expected", ErrIntrinsicGas, "got", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ func (b *EthAPIBackend) ExtRPCEnabled() bool {
|
|||||||
return b.extRPCEnabled
|
return b.extRPCEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *EthAPIBackend) RPCGasCap() *big.Int {
|
func (b *EthAPIBackend) RPCGasCap() uint64 {
|
||||||
return b.eth.config.RPCGasCap
|
return b.eth.config.RPCGasCap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,8 @@ var DefaultConfig = Config{
|
|||||||
GasPrice: big.NewInt(params.GWei),
|
GasPrice: big.NewInt(params.GWei),
|
||||||
Recommit: 3 * time.Second,
|
Recommit: 3 * time.Second,
|
||||||
},
|
},
|
||||||
TxPool: core.DefaultTxPoolConfig,
|
TxPool: core.DefaultTxPoolConfig,
|
||||||
|
RPCGasCap: 25000000,
|
||||||
GPO: gasprice.Config{
|
GPO: gasprice.Config{
|
||||||
Blocks: 20,
|
Blocks: 20,
|
||||||
Percentile: 60,
|
Percentile: 60,
|
||||||
@ -158,7 +159,7 @@ type Config struct {
|
|||||||
EVMInterpreter string
|
EVMInterpreter string
|
||||||
|
|
||||||
// RPCGasCap is the global gas cap for eth-call variants.
|
// RPCGasCap is the global gas cap for eth-call variants.
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap uint64 `toml:",omitempty"`
|
||||||
|
|
||||||
// RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for
|
// RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for
|
||||||
// send-transction variants. The unit is ether.
|
// send-transction variants. The unit is ether.
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/big"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -49,7 +48,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
|||||||
DocRoot string `toml:"-"`
|
DocRoot string `toml:"-"`
|
||||||
EWASMInterpreter string
|
EWASMInterpreter string
|
||||||
EVMInterpreter string
|
EVMInterpreter string
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap uint64 `toml:",omitempty"`
|
||||||
RPCTxFeeCap float64 `toml:",omitempty"`
|
RPCTxFeeCap float64 `toml:",omitempty"`
|
||||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||||
@ -127,7 +126,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||||||
DocRoot *string `toml:"-"`
|
DocRoot *string `toml:"-"`
|
||||||
EWASMInterpreter *string
|
EWASMInterpreter *string
|
||||||
EVMInterpreter *string
|
EVMInterpreter *string
|
||||||
RPCGasCap *big.Int `toml:",omitempty"`
|
RPCGasCap *uint64 `toml:",omitempty"`
|
||||||
RPCTxFeeCap *float64 `toml:",omitempty"`
|
RPCTxFeeCap *float64 `toml:",omitempty"`
|
||||||
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
||||||
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
||||||
@ -230,7 +229,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
|||||||
c.EVMInterpreter = *dec.EVMInterpreter
|
c.EVMInterpreter = *dec.EVMInterpreter
|
||||||
}
|
}
|
||||||
if dec.RPCGasCap != nil {
|
if dec.RPCGasCap != nil {
|
||||||
c.RPCGasCap = dec.RPCGasCap
|
c.RPCGasCap = *dec.RPCGasCap
|
||||||
}
|
}
|
||||||
if dec.RPCTxFeeCap != nil {
|
if dec.RPCTxFeeCap != nil {
|
||||||
c.RPCTxFeeCap = *dec.RPCTxFeeCap
|
c.RPCTxFeeCap = *dec.RPCTxFeeCap
|
||||||
|
@ -741,7 +741,7 @@ type CallArgs struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToMessage converts CallArgs to the Message type used by the core evm
|
// ToMessage converts CallArgs to the Message type used by the core evm
|
||||||
func (args *CallArgs) ToMessage(globalGasCap *big.Int) types.Message {
|
func (args *CallArgs) ToMessage(globalGasCap uint64) types.Message {
|
||||||
// Set sender address or use zero address if none specified.
|
// Set sender address or use zero address if none specified.
|
||||||
var addr common.Address
|
var addr common.Address
|
||||||
if args.From != nil {
|
if args.From != nil {
|
||||||
@ -753,9 +753,9 @@ func (args *CallArgs) ToMessage(globalGasCap *big.Int) types.Message {
|
|||||||
if args.Gas != nil {
|
if args.Gas != nil {
|
||||||
gas = uint64(*args.Gas)
|
gas = uint64(*args.Gas)
|
||||||
}
|
}
|
||||||
if globalGasCap != nil && globalGasCap.Uint64() < gas {
|
if globalGasCap != 0 && globalGasCap < gas {
|
||||||
log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
|
log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
|
||||||
gas = globalGasCap.Uint64()
|
gas = globalGasCap
|
||||||
}
|
}
|
||||||
gasPrice := new(big.Int)
|
gasPrice := new(big.Int)
|
||||||
if args.GasPrice != nil {
|
if args.GasPrice != nil {
|
||||||
@ -790,7 +790,7 @@ type account struct {
|
|||||||
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
StateDiff *map[common.Hash]common.Hash `json:"stateDiff"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides map[common.Address]account, vmCfg vm.Config, timeout time.Duration, globalGasCap *big.Int) (*core.ExecutionResult, error) {
|
func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides map[common.Address]account, vmCfg vm.Config, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) {
|
||||||
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
|
||||||
|
|
||||||
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
|
||||||
@ -861,7 +861,10 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.Blo
|
|||||||
if evm.Cancelled() {
|
if evm.Cancelled() {
|
||||||
return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
|
return nil, fmt.Errorf("execution aborted (timeout = %v)", timeout)
|
||||||
}
|
}
|
||||||
return result, err
|
if err != nil {
|
||||||
|
return result, fmt.Errorf("err: %w (supplied gas %d)", err, msg.Gas())
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRevertError(result *core.ExecutionResult) *revertError {
|
func newRevertError(result *core.ExecutionResult) *revertError {
|
||||||
@ -916,7 +919,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOr
|
|||||||
return result.Return(), result.Err
|
return result.Return(), result.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap *big.Int) (hexutil.Uint64, error) {
|
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) {
|
||||||
// Binary search the gas requirement, as it may be higher than the amount used
|
// Binary search the gas requirement, as it may be higher than the amount used
|
||||||
var (
|
var (
|
||||||
lo uint64 = params.TxGas - 1
|
lo uint64 = params.TxGas - 1
|
||||||
@ -964,9 +967,9 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Recap the highest gas allowance with specified gascap.
|
// Recap the highest gas allowance with specified gascap.
|
||||||
if gasCap != nil && hi > gasCap.Uint64() {
|
if gasCap != 0 && hi > gasCap {
|
||||||
log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
|
log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
|
||||||
hi = gasCap.Uint64()
|
hi = gasCap
|
||||||
}
|
}
|
||||||
cap = hi
|
cap = hi
|
||||||
|
|
||||||
@ -976,7 +979,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||||||
|
|
||||||
result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap)
|
result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == core.ErrIntrinsicGas {
|
if errors.Is(err, core.ErrIntrinsicGas) {
|
||||||
return true, nil, nil // Special case, raise gas limit
|
return true, nil, nil // Special case, raise gas limit
|
||||||
}
|
}
|
||||||
return true, nil, err // Bail out
|
return true, nil, err // Bail out
|
||||||
|
@ -45,8 +45,8 @@ type Backend interface {
|
|||||||
ChainDb() ethdb.Database
|
ChainDb() ethdb.Database
|
||||||
AccountManager() *accounts.Manager
|
AccountManager() *accounts.Manager
|
||||||
ExtRPCEnabled() bool
|
ExtRPCEnabled() bool
|
||||||
RPCGasCap() *big.Int // global gas cap for eth_call over rpc: DoS protection
|
|
||||||
RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs
|
RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs
|
||||||
|
RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection
|
||||||
|
|
||||||
// Blockchain API
|
// Blockchain API
|
||||||
SetHead(number uint64)
|
SetHead(number uint64)
|
||||||
|
@ -258,7 +258,7 @@ func (b *LesApiBackend) ExtRPCEnabled() bool {
|
|||||||
return b.extRPCEnabled
|
return b.extRPCEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LesApiBackend) RPCGasCap() *big.Int {
|
func (b *LesApiBackend) RPCGasCap() uint64 {
|
||||||
return b.eth.config.RPCGasCap
|
return b.eth.config.RPCGasCap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user