diff options
Diffstat (limited to 'internal')
-rw-r--r-- | internal/ethapi/api.go | 61 | ||||
-rw-r--r-- | internal/ethapi/backend.go | 2 | ||||
-rw-r--r-- | internal/ethapi/tracer_test.go | 4 |
3 files changed, 23 insertions, 44 deletions
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f49434e17..cf82cc866 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -48,8 +48,6 @@ import ( const defaultGas = 90000 -var emptyHex = "0x" - // PublicEthereumAPI provides an API to access Ethereum related information. // It offers only methods that operate on public data that is freely available to anyone. type PublicEthereumAPI struct { @@ -576,12 +574,12 @@ type CallArgs struct { Data hexutil.Bytes `json:"data"` } -func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config) ([]byte, *big.Int, error) { +func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, *big.Int, error) { defer func(start time.Time) { glog.V(logger.Debug).Infof("call took %v", time.Since(start)) }(time.Now()) state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) if state == nil || err != nil { - return nil, common.Big0, err + return "0x", common.Big0, err } // Set sender address or use a default if none specified addr := args.From @@ -591,59 +589,40 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr addr = accounts[0].Address } } + } else { + addr = args.From } // Set default gas & gas price if none were set gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt() - if gas.BitLen() == 0 { + if gas.Cmp(common.Big0) == 0 { gas = big.NewInt(50000000) } - if gasPrice.BitLen() == 0 { + if gasPrice.Cmp(common.Big0) == 0 { gasPrice = new(big.Int).Mul(big.NewInt(50), common.Shannon) } - // Create new call message msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false) - // 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) - } 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() }() - - // Get a new instance of the EVM. - evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) + // Execute the call and return + vmenv, vmError, err := s.b.GetVMEnv(ctx, msg, state, header) if err != nil { - return nil, common.Big0, err - } - // Wait for the context to be done and cancel the evm. Even if the - // EVM has finished, cancelling may be done (repeatedly) - go func() { - select { - case <-ctx.Done(): - evm.Cancel() - } - }() - - // Setup the gas pool (also for unmetered requests) - // and apply the message. + return "0x", common.Big0, err + } gp := new(core.GasPool).AddGas(common.MaxBig) - res, gas, err := core.ApplyMessage(evm, msg, gp) + res, gas, err := core.ApplyMessage(vmenv, msg, gp) if err := vmError(); err != nil { - return nil, common.Big0, err + return "0x", common.Big0, err + } + if len(res) == 0 { // backwards compatibility + return "0x", gas, err } - return res, gas, err + return common.ToHex(res), gas, err } // 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}) - return (hexutil.Bytes)(result), err +func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (string, error) { + result, _, err := s.doCall(ctx, args, blockNr) + return result, err } // EstimateGas returns an estimate of the amount of gas needed to execute the given transaction. @@ -665,7 +644,7 @@ func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (* mid := (hi + lo) / 2 (*big.Int)(&args.Gas).SetUint64(mid) - _, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}) + _, gas, err := s.doCall(ctx, args, rpc.PendingBlockNumber) // If the transaction became invalid or used all the gas (failed), raise the gas limit if err != nil || gas.Cmp((*big.Int)(&args.Gas)) == 0 { diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 214214f51..ebb14a5b5 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -51,7 +51,7 @@ type Backend interface { GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetTd(blockHash common.Hash) *big.Int - GetEVM(ctx context.Context, msg core.Message, state State, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) + GetVMEnv(ctx context.Context, msg core.Message, state State, header *types.Header) (*vm.EVM, func() error, error) // TxPool API SendTx(ctx context.Context, signedTx *types.Transaction) error RemoveTx(txHash common.Hash) diff --git a/internal/ethapi/tracer_test.go b/internal/ethapi/tracer_test.go index 693afe802..65a23f55e 100644 --- a/internal/ethapi/tracer_test.go +++ b/internal/ethapi/tracer_test.go @@ -45,7 +45,7 @@ func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} func runTrace(tracer *JavascriptTracer) (interface{}, error) { env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) - contract := vm.NewContract(account{}, account{}, big.NewInt(0), 10000) + contract := vm.NewContract(account{}, account{}, big.NewInt(0), big.NewInt(10000)) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} _, err := env.Interpreter().Run(contract, []byte{}) @@ -134,7 +134,7 @@ func TestHaltBetweenSteps(t *testing.T) { } env := vm.NewEVM(vm.Context{}, nil, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) - contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), 0) + contract := vm.NewContract(&account{}, &account{}, big.NewInt(0), big.NewInt(0)) tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil) timeout := errors.New("stahp") |