vm: move InvocationTree into a package of its own
result.Invoke shouldn't depend on vm.
This commit is contained in:
parent
8cd7b93208
commit
1e62474514
7 changed files with 37 additions and 34 deletions
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ type RegisterIterator func(sessionID string, item stackitem.Item, id int, finali
|
||||||
|
|
||||||
// InvokeDiag is an additional diagnostic data for invocation.
|
// InvokeDiag is an additional diagnostic data for invocation.
|
||||||
type InvokeDiag struct {
|
type InvokeDiag struct {
|
||||||
Changes []storage.Operation `json:"storagechanges"`
|
Changes []storage.Operation `json:"storagechanges"`
|
||||||
Invocations []*vm.InvocationTree `json:"invokedcontracts"`
|
Invocations []*invocations.Tree `json:"invokedcontracts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInvoke returns a new Invoke structure with the given fields set.
|
// NewInvoke returns a new Invoke structure with the given fields set.
|
||||||
|
|
|
@ -41,8 +41,8 @@ import (
|
||||||
rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
|
rpc2 "github.com/nspcc-dev/neo-go/pkg/services/oracle/broadcaster"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||||
|
@ -962,12 +962,12 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
Notifications: []state.NotificationEvent{},
|
Notifications: []state.NotificationEvent{},
|
||||||
Diagnostics: &result.InvokeDiag{
|
Diagnostics: &result.InvokeDiag{
|
||||||
Changes: []storage.Operation{},
|
Changes: []storage.Operation{},
|
||||||
Invocations: []*vm.InvocationTree{{
|
Invocations: []*invocations.Tree{{
|
||||||
Current: hash.Hash160(script),
|
Current: hash.Hash160(script),
|
||||||
Calls: []*vm.InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: nnsHash,
|
Current: nnsHash,
|
||||||
Calls: []*vm.InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: stdHash,
|
Current: stdHash,
|
||||||
},
|
},
|
||||||
|
@ -1075,12 +1075,12 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
Notifications: []state.NotificationEvent{},
|
Notifications: []state.NotificationEvent{},
|
||||||
Diagnostics: &result.InvokeDiag{
|
Diagnostics: &result.InvokeDiag{
|
||||||
Changes: []storage.Operation{},
|
Changes: []storage.Operation{},
|
||||||
Invocations: []*vm.InvocationTree{{
|
Invocations: []*invocations.Tree{{
|
||||||
Current: hash.Hash160(script),
|
Current: hash.Hash160(script),
|
||||||
Calls: []*vm.InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: nnsHash,
|
Current: nnsHash,
|
||||||
Calls: []*vm.InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: stdHash,
|
Current: stdHash,
|
||||||
},
|
},
|
||||||
|
@ -1167,7 +1167,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
Notifications: []state.NotificationEvent{},
|
Notifications: []state.NotificationEvent{},
|
||||||
Diagnostics: &result.InvokeDiag{
|
Diagnostics: &result.InvokeDiag{
|
||||||
Changes: []storage.Operation{},
|
Changes: []storage.Operation{},
|
||||||
Invocations: []*vm.InvocationTree{{
|
Invocations: []*invocations.Tree{{
|
||||||
Current: hash.Hash160(script),
|
Current: hash.Hash160(script),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
@ -1278,7 +1278,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
||||||
Notifications: []state.NotificationEvent{},
|
Notifications: []state.NotificationEvent{},
|
||||||
Diagnostics: &result.InvokeDiag{
|
Diagnostics: &result.InvokeDiag{
|
||||||
Changes: []storage.Operation{},
|
Changes: []storage.Operation{},
|
||||||
Invocations: []*vm.InvocationTree{{
|
Invocations: []*invocations.Tree{{
|
||||||
Current: hash.Hash160(script),
|
Current: hash.Hash160(script),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
@ -53,7 +54,7 @@ type Context struct {
|
||||||
// NEF represents a NEF file for the current contract.
|
// NEF represents a NEF file for the current contract.
|
||||||
NEF *nef.File
|
NEF *nef.File
|
||||||
// invTree is an invocation tree (or branch of it) for this context.
|
// invTree is an invocation tree (or branch of it) for this context.
|
||||||
invTree *InvocationTree
|
invTree *invocations.Tree
|
||||||
// onUnload is a callback that should be called after current context unloading
|
// onUnload is a callback that should be called after current context unloading
|
||||||
// if no exception occurs.
|
// if no exception occurs.
|
||||||
onUnload ContextUnloadCallback
|
onUnload ContextUnloadCallback
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package vm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
// InvocationTree represents a tree with script hashes; when traversing it,
|
|
||||||
// you can see how contracts called each other.
|
|
||||||
type InvocationTree struct {
|
|
||||||
Current util.Uint160 `json:"hash"`
|
|
||||||
Calls []*InvocationTree `json:"call,omitempty"`
|
|
||||||
}
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -36,13 +37,13 @@ func TestInvocationTree(t *testing.T) {
|
||||||
topHash := v.Context().ScriptHash()
|
topHash := v.Context().ScriptHash()
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
|
|
||||||
res := &InvocationTree{
|
res := &invocations.Tree{
|
||||||
Calls: []*InvocationTree{{
|
Calls: []*invocations.Tree{{
|
||||||
Current: topHash,
|
Current: topHash,
|
||||||
Calls: []*InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: util.Uint160{1},
|
Current: util.Uint160{1},
|
||||||
Calls: []*InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: util.Uint160{2},
|
Current: util.Uint160{2},
|
||||||
},
|
},
|
||||||
|
@ -53,7 +54,7 @@ func TestInvocationTree(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Current: util.Uint160{4},
|
Current: util.Uint160{4},
|
||||||
Calls: []*InvocationTree{
|
Calls: []*invocations.Tree{
|
||||||
{
|
{
|
||||||
Current: util.Uint160{5},
|
Current: util.Uint160{5},
|
||||||
},
|
},
|
||||||
|
|
12
pkg/vm/invocations/invocation_tree.go
Normal file
12
pkg/vm/invocations/invocation_tree.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package invocations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Tree represents a tree with script hashes; when traversing it,
|
||||||
|
// you can see how contracts called each other.
|
||||||
|
type Tree struct {
|
||||||
|
Current util.Uint160 `json:"hash"`
|
||||||
|
Calls []*Tree `json:"call,omitempty"`
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||||
|
@ -87,7 +88,7 @@ type VM struct {
|
||||||
trigger trigger.Type
|
trigger trigger.Type
|
||||||
|
|
||||||
// invTree is a top-level invocation tree (if enabled).
|
// invTree is a top-level invocation tree (if enabled).
|
||||||
invTree *InvocationTree
|
invTree *invocations.Tree
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -271,11 +272,11 @@ func (v *VM) LoadFileWithFlags(path string, f callflag.CallFlag) error {
|
||||||
|
|
||||||
// CollectInvocationTree enables collecting invocation tree data.
|
// CollectInvocationTree enables collecting invocation tree data.
|
||||||
func (v *VM) EnableInvocationTree() {
|
func (v *VM) EnableInvocationTree() {
|
||||||
v.invTree = &InvocationTree{}
|
v.invTree = &invocations.Tree{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInvocationTree returns the current invocation tree structure.
|
// GetInvocationTree returns the current invocation tree structure.
|
||||||
func (v *VM) GetInvocationTree() *InvocationTree {
|
func (v *VM) GetInvocationTree() *invocations.Tree {
|
||||||
return v.invTree
|
return v.invTree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +357,7 @@ func (v *VM) loadScriptWithCallingHash(b []byte, exe *nef.File, caller util.Uint
|
||||||
if parent != nil {
|
if parent != nil {
|
||||||
curTree = parent.invTree
|
curTree = parent.invTree
|
||||||
}
|
}
|
||||||
newTree := &InvocationTree{Current: ctx.ScriptHash()}
|
newTree := &invocations.Tree{Current: ctx.ScriptHash()}
|
||||||
curTree.Calls = append(curTree.Calls, newTree)
|
curTree.Calls = append(curTree.Calls, newTree)
|
||||||
ctx.invTree = newTree
|
ctx.invTree = newTree
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue