Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ env:
- TEST="bash ./scripts/travis_go_checker.sh"
- TEST="bash ./scripts/travis_rpc_checker.sh"
- TEST="bash ./scripts/travis_pyhmy_checker.sh"
- TEST="bash ./scripts/travis_rosetta_checker.sh"

# We enable Travis on the main/dev branches.
# pull_request type includes both main repo/fork PR workflow
Expand Down
34 changes: 33 additions & 1 deletion hmy/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,39 @@ func (hmy *Harmony) traceTx(ctx context.Context, message core.Message, txctx *tr
if config == nil {
config = &tracers.TraceConfig{}
}
// Default tracer is the struct logger

//switch {
//case config.Tracer != nil:
// if *config.Tracer == "ParityBlockTracer" {
// tracer = &tracers.ParityBlockTracer{}
// break
// } else if *config.Tracer == "RosettaBlockTracer" {
// tracer = &tracers.RosettaBlockTracer{ParityBlockTracer: &tracers.ParityBlockTracer{}}
// break
// }
// // Define a meaningful timeout of a single transaction trace
// //timeout := defaultTraceTimeout
// //if config.Timeout != nil {
// // if timeout, err = time.ParseDuration(*config.Timeout); err != nil {
// // return nil, err
// // }
// //}
// //// Constuct the JavaScript tracer to execute with
// //if tracer, err = tracers.New(*config.Tracer); err != nil {
// // return nil, err
// //}
// //// Handle timeouts and RPC cancellations
// //deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
// //go func() {
// // <-deadlineCtx.Done()
// // tracer.(*tracers.Tracer).Stop(errors.New("execution timeout"))
// //}()
// //defer cancel()
//default:
// // Default tracer is the struct logger
// tracer = logger.NewStructLogger(config.Config)
//}

tracer = logger.NewStructLogger(config.Config)
if config.Tracer != nil {
tracer, err = tracers.New(*config.Tracer, txctx, config.TracerConfig)
Expand Down
36 changes: 29 additions & 7 deletions hmy/tracers/block_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@ type ParityBlockTracer struct {
tracers []*ParityTxTracer
}

func (jst *ParityBlockTracer) Stop(err error) {

}

func (jst *ParityBlockTracer) CaptureTxStart(gasLimit uint64) {

}
Expand Down Expand Up @@ -255,7 +259,11 @@ func (ptt *ParityTxTracer) len() int {
}

// CaptureStart implements the ParityBlockTracer interface to initialize the tracing operation.
func (jst *ParityBlockTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
func (jst *ParityBlockTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
jst.captureStart(env, from, to, create, input, gas, value)
}

func (jst *ParityBlockTracer) captureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
jst.cur = &ParityTxTracer{}
jst.cur.op = vm.CALL // vritual call
if create {
Expand All @@ -275,10 +283,14 @@ func (jst *ParityBlockTracer) CaptureStart(env *vm.EVM, from common.Address, to
return nil
}

func (jst *ParityBlockTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rdata []byte, depth int, err error) {
jst.captureState(env, pc, op, gas, cost, scope.Memory, scope.Stack, scope.Contract, depth, err)
}

// CaptureState implements the ParityBlockTracer interface to trace a single step of VM execution.
func (jst *ParityBlockTracer) 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) (vm.HookAfter, error) {
func (jst *ParityBlockTracer) 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) (vm.HookAfter, error) {
if err != nil {
return nil, jst.CaptureFault(env, pc, op, gas, cost, memory, stack, contract, depth, err)
return nil, jst.captureFault(env, pc, op, gas, cost, memory, stack, contract, depth, err)
}
var retErr error
stackPeek := func(n int) *uint256.Int {
Expand Down Expand Up @@ -393,9 +405,13 @@ func (jst *ParityBlockTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode,
return nil, retErr
}

func (jst *ParityBlockTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {
jst.captureFault(nil, pc, op, gas, cost, scope.Memory, scope.Stack, scope.Contract, depth, err)
}

// CaptureFault implements the ParityBlockTracer interface to trace an execution fault
// while running an opcode.
func (jst *ParityBlockTracer) CaptureFault(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 {
func (jst *ParityBlockTracer) captureFault(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.cur.last().err != nil {
return nil
}
Expand All @@ -417,7 +433,12 @@ func (jst *ParityBlockTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode,
}

// CaptureEnd is called after the call finishes to finalize the tracing.
func (jst *ParityBlockTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
func (jst *ParityBlockTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {
jst.captureEnd(output, gasUsed, t, err)
return
}

func (jst *ParityBlockTracer) captureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
jst.cur.output = output
jst.cur.gasUsed = gasUsed
if err != nil {
Expand Down Expand Up @@ -461,7 +482,7 @@ func (jst *ParityBlockTracer) GetStorage() *TraceBlockStorage {
}

// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error
func (jst *ParityBlockTracer) GetResult() ([]json.RawMessage, error) {
func (jst *ParityBlockTracer) GetResult() (json.RawMessage, error) {
var results []json.RawMessage
var err error
var headPiece string
Expand Down Expand Up @@ -501,5 +522,6 @@ func (jst *ParityBlockTracer) GetResult() ([]json.RawMessage, error) {
)
finalize(root, make([]int, 0))
}
return results, err
_ = err
return json.Marshal(results)
}
24 changes: 21 additions & 3 deletions hmy/tracers/rosetta_block_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,27 @@
package tracers

import (
"encoding/json"
"math/big"

"github.com/harmony-one/harmony/core/vm"
"github.com/pkg/errors"
)

// init registers itself this packages as a lookup for tracers.
func init() {
RegisterLookup(false, newPrestateTracer)
}

func newPrestateTracer(code string, ctx *Context, _ json.RawMessage) (Tracer, error) {
if code != "RosettaBlockTracer" {
return nil, errors.New("invalid code")
}
tracer := &RosettaBlockTracer{ParityBlockTracer: &ParityBlockTracer{}}
return tracer, nil
//return &prestateTracer{prestate: prestate{}}, nil
}

type RosettaLogItem struct {
IsSuccess bool
Reverted bool
Expand Down Expand Up @@ -67,11 +83,11 @@ func (rbt *RosettaBlockTracer) AddRosettaLog(op vm.OpCode, from, to *vm.RosettaL
})
}

func (rbt *RosettaBlockTracer) GetResult() ([]*RosettaLogItem, error) {
func (rbt *RosettaBlockTracer) GetResult() (json.RawMessage, error) {
root := &rbt.cur.action

var results = make([]*RosettaLogItem, 0)
var err error
//var err error
var finalize func(ac *action, parentErr error, traceAddress []int)
finalize = func(ac *action, parentErr error, traceAddress []int) {
results = append(results, rbt.formatAction(traceAddress, parentErr, ac))
Expand All @@ -90,5 +106,7 @@ func (rbt *RosettaBlockTracer) GetResult() ([]*RosettaLogItem, error) {
finalize(subAc, root.err, append(traceAddress[:], i))
}

return append(results, rbt.logs...), err
// TODO
return json.RawMessage{}, nil
//return append(results, rbt.logs...), err
}