diff options
author | Martin Holst Swende <martin@swende.se> | 2019-04-08 19:49:52 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-04-08 19:49:52 +0800 |
commit | e2f3465e83a4c03b48977ed367e68b0d63ca2ed1 (patch) | |
tree | b8cb683600672789aa7b56ed349fbceaaa2ae4ae /internal | |
parent | ed97517ff4db1982251d8bf7dbeca565159e3604 (diff) | |
download | go-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.go | 20 | ||||
-rw-r--r-- | internal/ethapi/backend.go | 1 |
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) |