aboutsummaryrefslogtreecommitdiffstats
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/ethapi/api.go61
-rw-r--r--internal/ethapi/backend.go2
-rw-r--r--internal/ethapi/tracer_test.go4
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")