@@ -674,7 +674,7 @@ type CallArgs struct {
674
674
Data * hexutil.Bytes `json:"data"`
675
675
}
676
676
677
- func DoCall (ctx context.Context , b Backend , args CallArgs , blockNr rpc.BlockNumber , vmCfg vm.Config , timeout time.Duration ) ([]byte , uint64 , bool , error ) {
677
+ 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 ) {
678
678
defer func (start time.Time ) { log .Debug ("Executing EVM call finished" , "runtime" , time .Since (start )) }(time .Now ())
679
679
680
680
state , header , err := b .StateAndHeaderByNumber (ctx , blockNr )
@@ -697,6 +697,10 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb
697
697
if args .Gas != nil {
698
698
gas = uint64 (* args .Gas )
699
699
}
700
+ if globalGasCap != nil && globalGasCap .Uint64 () < gas {
701
+ log .Warn ("Caller gas above allowance, capping" , "requested" , gas , "cap" , globalGasCap )
702
+ gas = globalGasCap .Uint64 ()
703
+ }
700
704
gasPrice := new (big.Int ).SetUint64 (defaultGasPrice )
701
705
if args .GasPrice != nil {
702
706
gasPrice = args .GasPrice .ToInt ()
@@ -752,11 +756,11 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb
752
756
// Call executes the given transaction on the state for the given block number.
753
757
// It doesn't make and changes in the state/blockchain and is useful to execute and retrieve values.
754
758
func (s * PublicBlockChainAPI ) Call (ctx context.Context , args CallArgs , blockNr rpc.BlockNumber ) (hexutil.Bytes , error ) {
755
- result , _ , _ , err := DoCall (ctx , s .b , args , blockNr , vm.Config {}, 5 * time .Second )
759
+ result , _ , _ , err := DoCall (ctx , s .b , args , blockNr , vm.Config {}, 5 * time .Second , s . b . RPCGasCap () )
756
760
return (hexutil .Bytes )(result ), err
757
761
}
758
762
759
- func DoEstimateGas (ctx context.Context , b Backend , args CallArgs , blockNr rpc.BlockNumber ) (hexutil.Uint64 , error ) {
763
+ func DoEstimateGas (ctx context.Context , b Backend , args CallArgs , blockNr rpc.BlockNumber , gasCap * big. Int ) (hexutil.Uint64 , error ) {
760
764
// Binary search the gas requirement, as it may be higher than the amount used
761
765
var (
762
766
lo uint64 = params .TxGas - 1
@@ -773,13 +777,17 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
773
777
}
774
778
hi = block .GasLimit ()
775
779
}
780
+ if gasCap != nil && hi > gasCap .Uint64 () {
781
+ log .Warn ("Caller gas above allowance, capping" , "requested" , hi , "cap" , gasCap )
782
+ hi = gasCap .Uint64 ()
783
+ }
776
784
cap = hi
777
785
778
786
// Create a helper to check if a gas allowance results in an executable transaction
779
787
executable := func (gas uint64 ) bool {
780
788
args .Gas = (* hexutil .Uint64 )(& gas )
781
789
782
- _ , _ , failed , err := DoCall (ctx , b , args , rpc .PendingBlockNumber , vm.Config {}, 0 )
790
+ _ , _ , failed , err := DoCall (ctx , b , args , rpc .PendingBlockNumber , vm.Config {}, 0 , gasCap )
783
791
if err != nil || failed {
784
792
return false
785
793
}
@@ -797,7 +805,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
797
805
// Reject the transaction as invalid if it still fails at the highest allowance
798
806
if hi == cap {
799
807
if ! executable (hi ) {
800
- return 0 , fmt .Errorf ("gas required exceeds allowance or always failing transaction" )
808
+ return 0 , fmt .Errorf ("gas required exceeds allowance (%d) or always failing transaction" , cap )
801
809
}
802
810
}
803
811
return hexutil .Uint64 (hi ), nil
@@ -806,7 +814,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNr rpc.Bl
806
814
// EstimateGas returns an estimate of the amount of gas needed to execute the
807
815
// given transaction against the current pending block.
808
816
func (s * PublicBlockChainAPI ) EstimateGas (ctx context.Context , args CallArgs ) (hexutil.Uint64 , error ) {
809
- return DoEstimateGas (ctx , s .b , args , rpc .PendingBlockNumber )
817
+ return DoEstimateGas (ctx , s .b , args , rpc .PendingBlockNumber , s . b . RPCGasCap () )
810
818
}
811
819
812
820
// ExecutionResult groups all structured logs emitted by the EVM
0 commit comments