| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- package ethapi
- import (
- "context"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/rpc"
- "time"
- )
- type PublicEthereum2API struct {
- b Backend
- }
- func NewEthereum2API(b Backend) *PublicEthereum2API {
- return &PublicEthereum2API{b}
- }
- func (s *PublicEthereum2API) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (CallResult, error) {
- result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, vm.Config{}, 5*time.Second, s.b.RPCGasCap())
- if err != nil {
- return CallResult{Success: false, Msg: err.Error()}, err
- } else {
- if len(result.Revert()) > 0 {
- revertErr := newRevertError(result)
- return CallResult{Success: false, Data: revertErr.reason, Msg: revertErr.Error()}, nil
- }
- return CallResult{Success: true, Return: result.Return()}, nil
- }
- }
- // BatchCall executes a series of transactions on the state of a given block as base.
- // The base state can be overridden once before transactions are executed.
- //
- // Additionally, each call can override block context fields such as number.
- //
- // Note, this function doesn't make any changes in the state/blockchain and is
- // useful to execute and retrieve values.
- func (s *PublicEthereum2API) BatchCall(ctx context.Context, config BatchCallConfig) ([]CallResult, error) {
- state, header, err := s.b.StateAndHeaderByNumberOrHash(ctx, config.Block)
- if state == nil || err != nil {
- return nil, err
- }
- // State overrides are applied once before all calls
- if err := config.StateOverrides.Apply(state); err != nil {
- return nil, err
- }
- // Setup context so it may be cancelled before the calls completed
- // or, in case of unmetered gas, setup a context with a timeout.
- var (
- cancel context.CancelFunc
- //timeout = s.b.RPCEVMTimeout()
- timeout = time.Duration(5000000000)
- )
- 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 cancel()
- var (
- results []CallResult
- // Each tx and all the series of txes shouldn't consume more gas than cap
- globalGasCap = s.b.RPCGasCap()
- gp = new(core.GasPool).AddGas(globalGasCap)
- )
- for _, call := range config.Calls {
- blockContext := core.NewEVMBlockContext(header, NewChainContext(ctx, s.b), nil)
- if call.BlockOverrides != nil {
- call.BlockOverrides.Apply(&blockContext)
- }
- result, doCallErr := doCall(ctx, s.b, call.CallArgs, state, header, timeout, gp, &blockContext)
- if doCallErr != nil {
- results = append(results, CallResult{Success: false, Msg: doCallErr.Error()})
- } else {
- if len(result.Revert()) > 0 {
- revertErr := newRevertError(result)
- results = append(results, CallResult{Success: false, Return: result.Return(), Msg: revertErr.Error()})
- } else {
- results = append(results, CallResult{Success: true, Return: result.Return()})
- }
- }
- }
- return results, nil
- }
|