aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
authorMartin Holst Swende <martin@swende.se>2019-04-08 19:49:52 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-04-08 19:49:52 +0800
commite2f3465e83a4c03b48977ed367e68b0d63ca2ed1 (patch)
treeb8cb683600672789aa7b56ed349fbceaaa2ae4ae /internal
parented97517ff4db1982251d8bf7dbeca565159e3604 (diff)
downloadgo-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar.gz
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar.bz2
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar.lz
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar.xz
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.tar.zst
go-tangerine-e2f3465e83a4c03b48977ed367e68b0d63ca2ed1.zip
eth, les, geth: implement cli-configurable global gas cap for RPC calls (#19401)
* eth, les, geth: implement cli-configurable global gas cap for RPC calls * graphql, ethapi: place gas cap in DoCall * ethapi: reformat log message
Diffstat (limited to 'internal')
-rw-r--r--internal/ethapi/api.go20
-rw-r--r--internal/ethapi/backend.go1
2 files changed, 15 insertions, 6 deletions
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index e5a8124b1..ccd918be2 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -674,7 +674,7 @@ type CallArgs struct {
Data *hexutil.Bytes `json:"data"`
}
-func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error) {
+func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration, globalGasCap *big.Int) ([]byte, uint64, bool, error) {
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now())
state, header, err := b.StateAndHeaderByNumber(ctx, blockNr)
@@ -697,6 +697,10 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb
if args.Gas != nil {
gas = uint64(*args.Gas)
}
+ if globalGasCap != nil && globalGasCap.Uint64() < gas {
+ log.Warn("Caller gas above allowance, capping", "requested", gas, "cap", globalGasCap)
+ gas = globalGasCap.Uint64()
+ }
gasPrice := new(big.Int).SetUint64(defaultGasPrice)
if args.GasPrice != nil {
gasPrice = args.GasPrice.ToInt()
@@ -752,11 +756,11 @@ 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)
+ result, _, _, err := DoCall(ctx, s.b, args, blockNr, vm.Config{}, 5*time.Second, s.b.RPCGasCap())
return (hexutil.Bytes)(result), err
}
-func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Uint64, error) {
+func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumber, gasCap *big.Int) (hexutil.Uint64, error) {
// Binary search the gas requirement, as it may be higher than the amount used
var (
lo uint64 = params.TxGas - 1
@@ -773,13 +777,17 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
}
hi = block.GasLimit()
}
+ if gasCap != nil && hi > gasCap.Uint64() {
+ log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap)
+ hi = gasCap.Uint64()
+ }
cap = hi
// Create a helper to check if a gas allowance results in an executable transaction
executable := func(gas uint64) bool {
args.Gas = (*hexutil.Uint64)(&gas)
- _, _, failed, err := DoCall(ctx, b, args, rpc.PendingBlockNumber, vm.Config{}, 0)
+ _, _, failed, err := DoCall(ctx, b, args, rpc.PendingBlockNumber, vm.Config{}, 0, gasCap)
if err != nil || failed {
return false
}
@@ -797,7 +805,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,7 +814,7 @@ 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) {
- return DoEstimateGas(ctx, s.b, args, rpc.PendingBlockNumber)
+ return DoEstimateGas(ctx, s.b, args, rpc.PendingBlockNumber, s.b.RPCGasCap())
}
// ExecutionResult groups all structured logs emitted by the EVM
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index e88207f87..0c6c7eace 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -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)