diff options
Diffstat (limited to 'internal/ethapi')
-rw-r--r-- | internal/ethapi/api.go | 10 | ||||
-rw-r--r-- | internal/ethapi/backend.go | 4 | ||||
-rw-r--r-- | internal/ethapi/tracer.go | 90 | ||||
-rw-r--r-- | internal/ethapi/tracer_test.go | 4 |
4 files changed, 74 insertions, 34 deletions
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c8374fe18..987e14419 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -18,6 +18,7 @@ package ethapi import ( "bytes" + "context" "encoding/hex" "errors" "fmt" @@ -30,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -38,12 +40,10 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/util" - "golang.org/x/net/context" ) const ( @@ -695,8 +695,8 @@ type ExecutionResult struct { type StructLogRes struct { Pc uint64 `json:"pc"` Op string `json:"op"` - Gas *big.Int `json:"gas"` - GasCost *big.Int `json:"gasCost"` + Gas uint64 `json:"gas"` + GasCost uint64 `json:"gasCost"` Depth int `json:"depth"` Error error `json:"error"` Stack []string `json:"stack"` @@ -1378,7 +1378,7 @@ func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, if block == nil { return "", fmt.Errorf("block #%d not found", number) } - return fmt.Sprintf("0x%x", pow.EthashSeedHash(number)), nil + return fmt.Sprintf("0x%x", ethash.SeedHash(number)), nil } // PrivateDebugAPI is the collection of Etheruem APIs exposed over the private diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index e10fb14ff..42bf26613 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -18,6 +18,7 @@ package ethapi import ( + "context" "math/big" "github.com/ethereum/go-ethereum/accounts" @@ -30,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" - "golang.org/x/net/context" ) // Backend interface provides the common API services (that are provided by @@ -72,7 +72,7 @@ type State interface { GetNonce(ctx context.Context, addr common.Address) (uint64, error) } -func GetAPIs(apiBackend Backend, solcPath string) []rpc.API { +func GetAPIs(apiBackend Backend) []rpc.API { return []rpc.API{ { Namespace: "eth", diff --git a/internal/ethapi/tracer.go b/internal/ethapi/tracer.go index ef107fc42..d34363564 100644 --- a/internal/ethapi/tracer.go +++ b/internal/ethapi/tracer.go @@ -23,6 +23,7 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" "github.com/robertkrimen/otto" ) @@ -164,20 +165,53 @@ func (dw *dbWrapper) toValue(vm *otto.Otto) otto.Value { return value } +// contractWrapper provides a JS wrapper around vm.Contract +type contractWrapper struct { + contract *vm.Contract +} + +func (c *contractWrapper) caller() common.Address { + return c.contract.Caller() +} + +func (c *contractWrapper) address() common.Address { + return c.contract.Address() +} + +func (c *contractWrapper) value() *big.Int { + return c.contract.Value() +} + +func (c *contractWrapper) calldata() []byte { + return c.contract.Input +} + +func (c *contractWrapper) toValue(vm *otto.Otto) otto.Value { + value, _ := vm.ToValue(c) + obj := value.Object() + obj.Set("caller", c.caller) + obj.Set("address", c.address) + obj.Set("value", c.value) + obj.Set("calldata", c.calldata) + return value +} + // JavascriptTracer provides an implementation of Tracer that evaluates a // Javascript function for each VM execution step. type JavascriptTracer struct { - vm *otto.Otto // Javascript VM instance - traceobj *otto.Object // User-supplied object to call - log map[string]interface{} // (Reusable) map for the `log` arg to `step` - logvalue otto.Value // JS view of `log` - memory *memoryWrapper // Wrapper around the VM memory - memvalue otto.Value // JS view of `memory` - stack *stackWrapper // Wrapper around the VM stack - stackvalue otto.Value // JS view of `stack` - db *dbWrapper // Wrapper around the VM environment - dbvalue otto.Value // JS view of `db` - err error // Error, if one has occurred + vm *otto.Otto // Javascript VM instance + traceobj *otto.Object // User-supplied object to call + log map[string]interface{} // (Reusable) map for the `log` arg to `step` + logvalue otto.Value // JS view of `log` + memory *memoryWrapper // Wrapper around the VM memory + memvalue otto.Value // JS view of `memory` + stack *stackWrapper // Wrapper around the VM stack + stackvalue otto.Value // JS view of `stack` + db *dbWrapper // Wrapper around the VM environment + dbvalue otto.Value // JS view of `db` + contract *contractWrapper // Wrapper around the contract object + contractvalue otto.Value // JS view of `contract` + err error // Error, if one has occurred } // NewJavascriptTracer instantiates a new JavascriptTracer instance. @@ -189,6 +223,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) { // Set up builtins for this environment vm.Set("big", &fakeBig{}) + vm.Set("toHex", hexutil.Encode) jstracer, err := vm.Object("(" + code + ")") if err != nil { @@ -220,19 +255,22 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) { mem := &memoryWrapper{} stack := &stackWrapper{} db := &dbWrapper{} + contract := &contractWrapper{} return &JavascriptTracer{ - vm: vm, - traceobj: jstracer, - log: log, - logvalue: logvalue, - memory: mem, - memvalue: mem.toValue(vm), - stack: stack, - stackvalue: stack.toValue(vm), - db: db, - dbvalue: db.toValue(vm), - err: nil, + vm: vm, + traceobj: jstracer, + log: log, + logvalue: logvalue, + memory: mem, + memvalue: mem.toValue(vm), + stack: stack, + stackvalue: stack.toValue(vm), + db: db, + dbvalue: db.toValue(vm), + contract: contract, + contractvalue: contract.toValue(vm), + err: nil, }, nil } @@ -278,20 +316,22 @@ func wrapError(context string, err error) error { } // CaptureState implements the Tracer interface to trace a single step of VM execution -func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { +func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if jst.err == nil { jst.memory.memory = memory jst.stack.stack = stack jst.db.db = env.StateDB + jst.contract.contract = contract ocw := &opCodeWrapper{op} jst.log["pc"] = pc jst.log["op"] = ocw.toValue(jst.vm) - jst.log["gas"] = gas.Int64() - jst.log["gasPrice"] = cost.Int64() + jst.log["gas"] = gas + jst.log["gasPrice"] = cost jst.log["memory"] = jst.memvalue jst.log["stack"] = jst.stackvalue + jst.log["contract"] = jst.contractvalue jst.log["depth"] = depth jst.log["account"] = contract.Address() jst.log["err"] = err diff --git a/internal/ethapi/tracer_test.go b/internal/ethapi/tracer_test.go index 693afe802..0ef450ce3 100644 --- a/internal/ethapi/tracer_test.go +++ b/internal/ethapi/tracer_test.go @@ -136,10 +136,10 @@ 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) - tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil) + tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) timeout := errors.New("stahp") tracer.Stop(timeout) - tracer.CaptureState(env, 0, 0, big.NewInt(0), big.NewInt(0), nil, nil, contract, 0, nil) + tracer.CaptureState(env, 0, 0, 0, 0, nil, nil, contract, 0, nil) if _, err := tracer.GetResult(); err.Error() != "stahp in server-side tracer function 'step'" { t.Errorf("Expected timeout error, got %v", err) |