mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
eth, les, geth: implement cli-configurable global gas cap for RPC calls
This commit is contained in:
parent
36f81118f6
commit
9e93063e16
8 changed files with 48 additions and 6 deletions
|
|
@ -57,7 +57,6 @@ var (
|
|||
utils.IdentityFlag,
|
||||
utils.UnlockedAccountFlag,
|
||||
utils.PasswordFileFlag,
|
||||
utils.InsecureUnlockAllowedFlag,
|
||||
utils.BootnodesFlag,
|
||||
utils.BootnodesV4Flag,
|
||||
utils.BootnodesV5Flag,
|
||||
|
|
@ -136,8 +135,6 @@ var (
|
|||
utils.VMEnableDebugFlag,
|
||||
utils.NetworkIdFlag,
|
||||
utils.ConstantinopleOverrideFlag,
|
||||
utils.RPCCORSDomainFlag,
|
||||
utils.RPCVirtualHostsFlag,
|
||||
utils.EthStatsURLFlag,
|
||||
utils.FakePoWFlag,
|
||||
utils.NoCompactionFlag,
|
||||
|
|
@ -152,6 +149,8 @@ var (
|
|||
utils.RPCEnabledFlag,
|
||||
utils.RPCListenAddrFlag,
|
||||
utils.RPCPortFlag,
|
||||
utils.RPCCORSDomainFlag,
|
||||
utils.RPCVirtualHostsFlag,
|
||||
utils.GraphQLEnabledFlag,
|
||||
utils.GraphQLListenAddrFlag,
|
||||
utils.GraphQLPortFlag,
|
||||
|
|
@ -165,6 +164,8 @@ var (
|
|||
utils.WSAllowedOriginsFlag,
|
||||
utils.IPCDisabledFlag,
|
||||
utils.IPCPathFlag,
|
||||
utils.InsecureUnlockAllowedFlag,
|
||||
utils.RPCGlobalGasCap,
|
||||
}
|
||||
|
||||
whisperFlags = []cli.Flag{
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ var AppHelpFlagGroups = []flagGroup{
|
|||
utils.RPCListenAddrFlag,
|
||||
utils.RPCPortFlag,
|
||||
utils.RPCApiFlag,
|
||||
utils.RPCGlobalGasCap,
|
||||
utils.WSEnabledFlag,
|
||||
utils.WSListenAddrFlag,
|
||||
utils.WSPortFlag,
|
||||
|
|
|
|||
|
|
@ -448,6 +448,10 @@ var (
|
|||
Name: "allow-insecure-unlock",
|
||||
Usage: "Allow insecure account unlocking when account-related RPCs are exposed by http",
|
||||
}
|
||||
RPCGlobalGasCap = cli.Uint64Flag{
|
||||
Name: "rpc.gascap",
|
||||
Usage: "Sets a cap on gas that can be used in eth_call/estimateGas",
|
||||
}
|
||||
// Logging and debug settings
|
||||
EthStatsURLFlag = cli.StringFlag{
|
||||
Name: "ethstats",
|
||||
|
|
@ -1400,6 +1404,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
|||
if ctx.GlobalIsSet(EVMInterpreterFlag.Name) {
|
||||
cfg.EVMInterpreter = ctx.GlobalString(EVMInterpreterFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(RPCGlobalGasCap.Name) {
|
||||
cfg.RPCGasCap = new(big.Int).SetUint64(ctx.GlobalUint64(RPCGlobalGasCap.Name))
|
||||
}
|
||||
|
||||
// Override any default configs for hard coded networks.
|
||||
switch {
|
||||
|
|
|
|||
|
|
@ -218,6 +218,10 @@ func (b *EthAPIBackend) ExtRPCEnabled() bool {
|
|||
return b.extRPCEnabled
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) RPCGasCap() *big.Int {
|
||||
return b.eth.config.RPCGasCap
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) BloomStatus() (uint64, uint64) {
|
||||
sections, _, _ := b.eth.bloomIndexer.Sections()
|
||||
return params.BloomBitsBlocks, sections
|
||||
|
|
|
|||
|
|
@ -151,6 +151,9 @@ type Config struct {
|
|||
|
||||
// Constantinople block override (TODO: remove after the fork)
|
||||
ConstantinopleOverride *big.Int
|
||||
|
||||
// RPCGasCap is the global gas cap for eth-call variants.
|
||||
RPCGasCap *big.Int `toml:",omitempty"`
|
||||
}
|
||||
|
||||
type configMarshaling struct {
|
||||
|
|
|
|||
|
|
@ -752,8 +752,22 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb
|
|||
// Call executes the given transaction on the state for the given block number.
|
||||
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
|
||||
func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) {
|
||||
result, _, _, err := DoCall(ctx, s.b, args, blockNr, vm.Config{}, 5*time.Second)
|
||||
return (hexutil.Bytes)(result), err
|
||||
if gasCap := s.b.RPCGasCap(); gasCap != nil {
|
||||
if new(big.Int).SetUint64(uint64(*args.Gas)).Cmp(gasCap) > 0 {
|
||||
log.Warn("Applying cap on gas, caller requested amount above limit", "cap", gasCap, "requested", args.Gas)
|
||||
newGas := hexutil.Uint64(gasCap.Uint64())
|
||||
*args.Gas = newGas
|
||||
}
|
||||
result, _, _, err := DoCall(ctx, s.b, args, blockNr, vm.Config{}, 5*time.Second)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%v (gas capped at: %d)", err, *args.Gas)
|
||||
}
|
||||
return (hexutil.Bytes)(result), err
|
||||
} else {
|
||||
result, _, _, err := DoCall(ctx, s.b, args, blockNr, vm.Config{}, 5*time.Second)
|
||||
return (hexutil.Bytes)(result), err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Uint64, error) {
|
||||
|
|
@ -797,7 +811,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
|
|||
// Reject the transaction as invalid if it still fails at the highest allowance
|
||||
if hi == cap {
|
||||
if !executable(hi) {
|
||||
return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction")
|
||||
return 0, fmt.Errorf("gas required exceeds allowance (%d) or always failing transaction", cap)
|
||||
}
|
||||
}
|
||||
return hexutil.Uint64(hi), nil
|
||||
|
|
@ -806,6 +820,13 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
|
|||
// EstimateGas returns an estimate of the amount of gas needed to execute the
|
||||
// given transaction against the current pending block.
|
||||
func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) {
|
||||
if gasCap := s.b.RPCGasCap(); gasCap != nil {
|
||||
if new(big.Int).SetUint64(uint64(*args.Gas)).Cmp(gasCap) > 0 {
|
||||
log.Warn("Applying cap on gas, caller requested amount above limit", "cap", gasCap, "requested", args.Gas)
|
||||
newGas := hexutil.Uint64(gasCap.Uint64())
|
||||
*args.Gas = newGas
|
||||
}
|
||||
}
|
||||
return DoEstimateGas(ctx, s.b, args, rpc.PendingBlockNumber)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ type Backend interface {
|
|||
EventMux() *event.TypeMux
|
||||
AccountManager() *accounts.Manager
|
||||
ExtRPCEnabled() bool
|
||||
RPCGasCap() *big.Int // global gas cap for eth_call over rpc: DoS protection
|
||||
|
||||
// BlockChain API
|
||||
SetHead(number uint64)
|
||||
|
|
|
|||
|
|
@ -192,6 +192,10 @@ func (b *LesApiBackend) ExtRPCEnabled() bool {
|
|||
return b.extRPCEnabled
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) RPCGasCap() *big.Int {
|
||||
return b.eth.config.RPCGasCap
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) BloomStatus() (uint64, uint64) {
|
||||
if b.eth.bloomIndexer == nil {
|
||||
return 0, 0
|
||||
|
|
|
|||
Loading…
Reference in a new issue