forked from TrueCloudLab/neoneo-go
70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
|
package vm
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestInvocationTree(t *testing.T) {
|
||
|
script := []byte{
|
||
|
byte(opcode.PUSH3), byte(opcode.DEC),
|
||
|
byte(opcode.DUP), byte(opcode.PUSH0), byte(opcode.JMPEQ), (2 + 2 + 2 + 6 + 1),
|
||
|
byte(opcode.CALL), (2 + 2), // CALL shouldn't affect invocation tree.
|
||
|
byte(opcode.JMP), 0xf9, // DEC
|
||
|
byte(opcode.SYSCALL), 0, 0, 0, 0, byte(opcode.DROP),
|
||
|
byte(opcode.RET),
|
||
|
byte(opcode.RET),
|
||
|
byte(opcode.PUSHINT8), 0xff,
|
||
|
}
|
||
|
|
||
|
cnt := 0
|
||
|
v := newTestVM()
|
||
|
v.SyscallHandler = func(v *VM, _ uint32) error {
|
||
|
if v.Istack().Len() > 4 { // top -> call -> syscall -> call -> syscall -> ...
|
||
|
v.Estack().PushVal(1)
|
||
|
return nil
|
||
|
}
|
||
|
cnt++
|
||
|
v.LoadScriptWithHash(script, util.Uint160{byte(cnt)}, 0)
|
||
|
return nil
|
||
|
}
|
||
|
v.EnableInvocationTree()
|
||
|
v.LoadScript(script)
|
||
|
topHash := v.Context().ScriptHash()
|
||
|
require.NoError(t, v.Run())
|
||
|
|
||
|
res := &InvocationTree{
|
||
|
Calls: []*InvocationTree{{
|
||
|
Current: topHash,
|
||
|
Calls: []*InvocationTree{
|
||
|
{
|
||
|
Current: util.Uint160{1},
|
||
|
Calls: []*InvocationTree{
|
||
|
{
|
||
|
Current: util.Uint160{2},
|
||
|
},
|
||
|
{
|
||
|
Current: util.Uint160{3},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
{
|
||
|
Current: util.Uint160{4},
|
||
|
Calls: []*InvocationTree{
|
||
|
{
|
||
|
Current: util.Uint160{5},
|
||
|
},
|
||
|
{
|
||
|
Current: util.Uint160{6},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}},
|
||
|
}
|
||
|
require.Equal(t, res, v.GetInvocationTree())
|
||
|
}
|