|
|
|
@ -611,7 +611,7 @@ type CallArgs struct { |
|
|
|
|
Data hexutil.Bytes `json:"data"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, uint64, bool, error) { |
|
|
|
|
func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error) { |
|
|
|
|
defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) |
|
|
|
|
|
|
|
|
|
state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) |
|
|
|
@ -630,7 +630,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr |
|
|
|
|
// Set default gas & gas price if none were set
|
|
|
|
|
gas, gasPrice := uint64(args.Gas), args.GasPrice.ToInt() |
|
|
|
|
if gas == 0 { |
|
|
|
|
gas = 50000000 |
|
|
|
|
gas = math.MaxUint64 / 2 |
|
|
|
|
} |
|
|
|
|
if gasPrice.Sign() == 0 { |
|
|
|
|
gasPrice = new(big.Int).SetUint64(defaultGasPrice) |
|
|
|
@ -642,14 +642,14 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr |
|
|
|
|
// Setup context so it may be cancelled the call has completed
|
|
|
|
|
// or, in case of unmetered gas, setup a context with a timeout.
|
|
|
|
|
var cancel context.CancelFunc |
|
|
|
|
if vmCfg.DisableGasMetering { |
|
|
|
|
ctx, cancel = context.WithTimeout(ctx, time.Second*5) |
|
|
|
|
if timeout > 0 { |
|
|
|
|
ctx, cancel = context.WithTimeout(ctx, timeout) |
|
|
|
|
} else { |
|
|
|
|
ctx, cancel = context.WithCancel(ctx) |
|
|
|
|
} |
|
|
|
|
// Make sure the context is cancelled when the call has completed
|
|
|
|
|
// this makes sure resources are cleaned up.
|
|
|
|
|
defer func() { cancel() }() |
|
|
|
|
defer cancel() |
|
|
|
|
|
|
|
|
|
// Get a new instance of the EVM.
|
|
|
|
|
evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) |
|
|
|
@ -676,7 +676,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr |
|
|
|
|
// 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 := s.doCall(ctx, args, blockNr, vm.Config{DisableGasMetering: true}) |
|
|
|
|
result, _, _, err := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second) |
|
|
|
|
return (hexutil.Bytes)(result), err |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -705,7 +705,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (h |
|
|
|
|
executable := func(gas uint64) bool { |
|
|
|
|
args.Gas = hexutil.Uint64(gas) |
|
|
|
|
|
|
|
|
|
_, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}) |
|
|
|
|
_, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}, 0) |
|
|
|
|
if err != nil || failed { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|