mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-27 03:58:06 +00:00
Merge pull request #858 from nspcc-dev/neo3/transition
vm: remove FIXME comments from vm Fix #477.
This commit is contained in:
commit
ffff9b93ba
21 changed files with 96 additions and 146 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,4 +1,4 @@
|
|||
[submodule "pkg/vm/testdata/neo-vm"]
|
||||
path = pkg/vm/testdata/neo-vm
|
||||
url = https://github.com/neo-project/neo-vm.git
|
||||
branch = master-2.x
|
||||
branch = master
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -54,7 +55,7 @@ func getPanicSource(need bool, message string) string {
|
|||
}
|
||||
|
||||
func logGetter(logs *[]string) vm.InteropGetterFunc {
|
||||
logID := vm.InteropNameToID([]byte("Neo.Runtime.Log"))
|
||||
logID := emit.InteropNameToID([]byte("Neo.Runtime.Log"))
|
||||
return func(id uint32) *vm.InteropFuncPrice {
|
||||
if id != logID {
|
||||
return nil
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -18,7 +19,7 @@ func TestVerifyGood(t *testing.T) {
|
|||
src := getVerifyProg(pub, sig, msg)
|
||||
|
||||
v, p := vmAndCompileInterop(t, src)
|
||||
p.interops[vm.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error {
|
||||
p.interops[emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))] = func(v *vm.VM) error {
|
||||
assert.Equal(t, msg, v.Estack().Pop().Bytes())
|
||||
assert.Equal(t, pub, v.Estack().Pop().Bytes())
|
||||
assert.Equal(t, sig, v.Estack().Pop().Bytes())
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -80,10 +81,10 @@ func newStoragePlugin() *storagePlugin {
|
|||
mem: make(map[string][]byte),
|
||||
interops: make(map[uint32]vm.InteropFunc),
|
||||
}
|
||||
s.interops[vm.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get
|
||||
s.interops[vm.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put
|
||||
s.interops[vm.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext
|
||||
s.interops[vm.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify
|
||||
s.interops[emit.InteropNameToID([]byte("Neo.Storage.Get"))] = s.Get
|
||||
s.interops[emit.InteropNameToID([]byte("Neo.Storage.Put"))] = s.Put
|
||||
s.interops[emit.InteropNameToID([]byte("Neo.Storage.GetContext"))] = s.GetContext
|
||||
s.interops[emit.InteropNameToID([]byte("Neo.Runtime.Notify"))] = s.Notify
|
||||
return s
|
||||
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Asset.Create", func(t *testing.T) {
|
||||
// Neo.Asset.Create: 83c5c61f
|
||||
v.Load([]byte{0x68, 0x04, 0x83, 0xc5, 0xc6, 0x1f})
|
||||
v.Load([]byte{0x68, 0x83, 0xc5, 0xc6, 0x1f})
|
||||
checkGas(t, util.Fixed8FromInt64(5000), v)
|
||||
})
|
||||
|
||||
t.Run("Neo.Asset.Renew", func(t *testing.T) {
|
||||
// Neo.Asset.Renew: 78849071 (requires push 09 push 09 before)
|
||||
v.Load([]byte{0x59, 0x59, 0x68, 0x04, 0x78, 0x84, 0x90, 0x71})
|
||||
v.Load([]byte{0x59, 0x59, 0x68, 0x78, 0x84, 0x90, 0x71})
|
||||
require.NoError(t, v.StepInto()) // push 9
|
||||
require.NoError(t, v.StepInto()) // push 9
|
||||
|
||||
|
@ -39,7 +39,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Contract.Create (no props)", func(t *testing.T) {
|
||||
// Neo.Contract.Create: f66ca56e (requires push properties on fourth position)
|
||||
v.Load([]byte{0x00, 0x00, 0x00, 0x00, 0x68, 0x04, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
v.Load([]byte{0x00, 0x00, 0x00, 0x00, 0x68, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
require.NoError(t, v.StepInto()) // push 0 - ContractPropertyState.NoProperty
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
|
@ -50,7 +50,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Contract.Create (has storage)", func(t *testing.T) {
|
||||
// Neo.Contract.Create: f66ca56e (requires push properties on fourth position)
|
||||
v.Load([]byte{0x51, 0x00, 0x00, 0x00, 0x68, 0x04, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
v.Load([]byte{0x51, 0x00, 0x00, 0x00, 0x68, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
require.NoError(t, v.StepInto()) // push 01 - ContractPropertyState.HasStorage
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
|
@ -61,7 +61,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Contract.Create (has dynamic invoke)", func(t *testing.T) {
|
||||
// Neo.Contract.Create: f66ca56e (requires push properties on fourth position)
|
||||
v.Load([]byte{0x52, 0x00, 0x00, 0x00, 0x68, 0x04, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
v.Load([]byte{0x52, 0x00, 0x00, 0x00, 0x68, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
require.NoError(t, v.StepInto()) // push 02 - ContractPropertyState.HasDynamicInvoke
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
|
@ -72,7 +72,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Contract.Create (has both storage and dynamic invoke)", func(t *testing.T) {
|
||||
// Neo.Contract.Create: f66ca56e (requires push properties on fourth position)
|
||||
v.Load([]byte{0x53, 0x00, 0x00, 0x00, 0x68, 0x04, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
v.Load([]byte{0x53, 0x00, 0x00, 0x00, 0x68, 0xf6, 0x6c, 0xa5, 0x6e})
|
||||
require.NoError(t, v.StepInto()) // push 03 - HasStorage and HasDynamicInvoke
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
|
@ -83,7 +83,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("Neo.Contract.Migrate", func(t *testing.T) {
|
||||
// Neo.Contract.Migrate: 471b6290 (requires push properties on fourth position)
|
||||
v.Load([]byte{0x00, 0x00, 0x00, 0x00, 0x68, 0x04, 0x47, 0x1b, 0x62, 0x90})
|
||||
v.Load([]byte{0x00, 0x00, 0x00, 0x00, 0x68, 0x47, 0x1b, 0x62, 0x90})
|
||||
require.NoError(t, v.StepInto()) // push 0 - ContractPropertyState.NoProperty
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
require.NoError(t, v.StepInto()) // push 0
|
||||
|
@ -94,7 +94,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("System.Storage.Put", func(t *testing.T) {
|
||||
// System.Storage.Put: e63f1884 (requires push key and value)
|
||||
v.Load([]byte{0x53, 0x53, 0x00, 0x68, 0x04, 0xe6, 0x3f, 0x18, 0x84})
|
||||
v.Load([]byte{0x53, 0x53, 0x00, 0x68, 0xe6, 0x3f, 0x18, 0x84})
|
||||
require.NoError(t, v.StepInto()) // push 03 (length 1)
|
||||
require.NoError(t, v.StepInto()) // push 03 (length 1)
|
||||
require.NoError(t, v.StepInto()) // push 00
|
||||
|
@ -104,7 +104,7 @@ func TestGetPrice(t *testing.T) {
|
|||
|
||||
t.Run("System.Storage.PutEx", func(t *testing.T) {
|
||||
// System.Storage.PutEx: 73e19b3a (requires push key and value)
|
||||
v.Load([]byte{0x53, 0x53, 0x00, 0x68, 0x04, 0x73, 0xe1, 0x9b, 0x3a})
|
||||
v.Load([]byte{0x53, 0x53, 0x00, 0x68, 0x73, 0xe1, 0x9b, 0x3a})
|
||||
require.NoError(t, v.StepInto()) // push 03 (length 1)
|
||||
require.NoError(t, v.StepInto()) // push 03 (length 1)
|
||||
require.NoError(t, v.StepInto()) // push 00
|
||||
|
|
|
@ -19,6 +19,7 @@ import (
|
|||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||
"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"
|
||||
)
|
||||
|
||||
// SpawnVM returns a VM with script getter and interop functions set
|
||||
|
@ -263,7 +264,7 @@ var neoInterops = []interop.Function{
|
|||
// Function slice and then sorts it.
|
||||
func initIDinInteropsSlice(iops []interop.Function) {
|
||||
for i := range iops {
|
||||
iops[i].ID = vm.InteropNameToID([]byte(iops[i].Name))
|
||||
iops[i].ID = emit.InteropNameToID([]byte(iops[i].Name))
|
||||
}
|
||||
sort.Slice(iops, func(i, j int) bool {
|
||||
return iops[i].ID < iops[j].ID
|
||||
|
|
|
@ -63,7 +63,7 @@ func (cs *Contracts) SetNEO(n *NEO) {
|
|||
func NewContractMD(name string) *ContractMD {
|
||||
c := &ContractMD{
|
||||
ServiceName: name,
|
||||
ServiceID: vm.InteropNameToID([]byte(name)),
|
||||
ServiceID: emit.InteropNameToID([]byte(name)),
|
||||
Methods: make(map[string]MethodAndPrice),
|
||||
}
|
||||
|
||||
|
|
|
@ -43,20 +43,20 @@ type rpcTestCase struct {
|
|||
check func(t *testing.T, e *executor, result interface{})
|
||||
}
|
||||
|
||||
const testContractHash = "c2789e5ab9bab828743833965b1df0d5fbcc206f"
|
||||
const testContractHash = "1b5cbfaa2e54b584d3240e38fc4bd413a65ea40c"
|
||||
|
||||
var rpcTestCases = map[string][]rpcTestCase{
|
||||
"getapplicationlog": {
|
||||
{
|
||||
name: "positive",
|
||||
params: `["e5a6be3cd796e2284a55ebb2061f85d3f199263bbf659dbd5b670a6506e7a4a0"]`,
|
||||
params: `["d98e4b58783aa9665efcc5be19ee432772a94462efc8a5e4165776e6dd8c4e92"]`,
|
||||
result: func(e *executor) interface{} { return &result.ApplicationLog{} },
|
||||
check: func(t *testing.T, e *executor, acc interface{}) {
|
||||
res, ok := acc.(*result.ApplicationLog)
|
||||
|
||||
require.True(t, ok)
|
||||
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("e5a6be3cd796e2284a55ebb2061f85d3f199263bbf659dbd5b670a6506e7a4a0")
|
||||
expectedTxHash, err := util.Uint256DecodeStringLE("d98e4b58783aa9665efcc5be19ee432772a94462efc8a5e4165776e6dd8c4e92")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, expectedTxHash, res.TxHash)
|
||||
assert.Equal(t, 1, len(res.Executions))
|
||||
|
@ -405,25 +405,25 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
"getblockheader": {
|
||||
{
|
||||
name: "positive, no verbose",
|
||||
params: `["02b9e6f634578f34c6026f1676e25aa04f58889a320fba8bc632c6fe48c26cf1"]`,
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2129e965e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401408ee2187395071a089e3b9743b1a718fa28a8700676451317f7454aade98cf779b0afb5634a7e104f92e2df8e8b1c1b7b3b0e9fd61f4c0e9ea07ce112cef12b9a40fcb441c89b0c2047ba71a86d759bc2554dda55369798e6ab63e6c7713b06a8178f13586edf6a673f20bf5ed7bdc727f9e0c6f487cf667e505a26236d73887ae940691972a6f4ccef19a03a3d5948dfcf992af2c6a3c5b033a0f9235d2b8967291d9f61495ff1a681f240517c8d892eaa805e667bca40abcf03d441c68a9ec59deb4005890a59d83c7cb0416895e4768123e900603d5b140bf799bc9879fb628c598193db2b7a8e07ab54733c1c67b60c97a1a8048961cc0afd0b048e878866ffd7298b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2011e975e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404be65e52d50121ce243eb27f7a1c16637e753e847e9c027f255bc5e2bae45f1c99d8c1014e5abe829b9a229904540b7010ae6fb2bb57f88d70179ec617dea35440c9d51c5980e016f5cb51734554341764572b0644010952761878b1966d2b013ceaf18958891060dde3a33d23118f27ef21e991f913a8740c716c14aa19483ea0409a44efd5607f7b8f09dd4f242882713b40866c2aeab9aaa5f92b92dbaf84ed0c039fb1790888ab36d77c8b6520b2bb58ab43b219be3272145cf0f6fd091e33e540ec1e52377a56bb6e0f82329ac1a70ab06cb7e23c149bcc194fa483a316de33468191b16ab1fafb2f1a1af79a0cd6e7e275d3a3ed56f8b0ecbcd6e26f93a3957b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
return &expected
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive, verbose 0",
|
||||
params: `["02b9e6f634578f34c6026f1676e25aa04f58889a320fba8bc632c6fe48c26cf1", 0]`,
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608", 0]`,
|
||||
result: func(e *executor) interface{} {
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2129e965e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401408ee2187395071a089e3b9743b1a718fa28a8700676451317f7454aade98cf779b0afb5634a7e104f92e2df8e8b1c1b7b3b0e9fd61f4c0e9ea07ce112cef12b9a40fcb441c89b0c2047ba71a86d759bc2554dda55369798e6ab63e6c7713b06a8178f13586edf6a673f20bf5ed7bdc727f9e0c6f487cf667e505a26236d73887ae940691972a6f4ccef19a03a3d5948dfcf992af2c6a3c5b033a0f9235d2b8967291d9f61495ff1a681f240517c8d892eaa805e667bca40abcf03d441c68a9ec59deb4005890a59d83c7cb0416895e4768123e900603d5b140bf799bc9879fb628c598193db2b7a8e07ab54733c1c67b60c97a1a8048961cc0afd0b048e878866ffd7298b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
expected := "000000009456b8c7f89bdfe012a30a2be9af5218e048ae7372115ce3e39cc847c01e9e7f9cffa26c112eb147a995520e47afbc45a192d9bf1a8e9b8f80497e5d92c4e9f2011e975e010000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404be65e52d50121ce243eb27f7a1c16637e753e847e9c027f255bc5e2bae45f1c99d8c1014e5abe829b9a229904540b7010ae6fb2bb57f88d70179ec617dea35440c9d51c5980e016f5cb51734554341764572b0644010952761878b1966d2b013ceaf18958891060dde3a33d23118f27ef21e991f913a8740c716c14aa19483ea0409a44efd5607f7b8f09dd4f242882713b40866c2aeab9aaa5f92b92dbaf84ed0c039fb1790888ab36d77c8b6520b2bb58ab43b219be3272145cf0f6fd091e33e540ec1e52377a56bb6e0f82329ac1a70ab06cb7e23c149bcc194fa483a316de33468191b16ab1fafb2f1a1af79a0cd6e7e275d3a3ed56f8b0ecbcd6e26f93a3957b8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"
|
||||
return &expected
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "positive, verbose !=0",
|
||||
params: `["02b9e6f634578f34c6026f1676e25aa04f58889a320fba8bc632c6fe48c26cf1", 2]`,
|
||||
params: `["60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608", 2]`,
|
||||
result: func(e *executor) interface{} {
|
||||
hash, err := util.Uint256DecodeStringLE("02b9e6f634578f34c6026f1676e25aa04f58889a320fba8bc632c6fe48c26cf1")
|
||||
hash, err := util.Uint256DecodeStringLE("60c00bfa7f283d1821e1bc8c1c83aa534f325968944d73fa25cf7235af17d608")
|
||||
if err != nil {
|
||||
panic("can not decode hash parameter")
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (first block)
|
||||
name: "empty block",
|
||||
params: `["0000000029e2ea0ec5c9aa98fa736b52750916b3b8ab5cdbe7647fb6d0b7f6dac35865640000000000000000000000000000000000000000000000000000000000000000e29e965ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140efdc94ac1e5c7588a1e70aa2ada3450631f30b15676861e7f32159f0e0b97e5fec8dd9870d92755e76b2cf3d6a90f06c2f6a7b782248ac4b765433beb6891a4840551f59a1e88395290ea2273500c60fc55b0d33ab6c3ddd565177f77083e82aaffca3553a0a116b457d5101f8627da39a3a24f19e2d04fab7e65670fda6a50f4140576969f478e6150b128b1149dd3c8b663f27bda53a6815fe177d52abc6ad40311a4fcba14a0d9286d6cda521cd9bc0ade09a66e88059da84363512c6110f4dc94008e8c0e6f3835281690fa0d594a6f5f1914b2f047fe835b134641b5a19935a4f6b10931ad168e47f96f6bf98380c0f060d4b25ae71869c4ef9d2a92a262eceeb8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"]`,
|
||||
params: `["00000000547e0fa207c116e25fd69a04b99e446e409ca23c7863bafbd585abeb468314c00000000000000000000000000000000000000000000000000000000000000000d21e975ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd0401404fb770b14c4e7bd2461dbf238ca197844a724388d15cfeb96a07cb8cb52733f3f7adcc5bbd33c8dc19103116f1fe6c3151a14e3db40585823cc3ce153a0426ec40fd880f3d029e95dcb4612b40f31d5111a961345bc2090689a7462c12c85006ed281216331e1169d41cc0a8780b0befc22b9d3ba147e331acfb858675ebaaf8de4055922389015e0a96e07c9ad987eda4a642f0436843966821e620b89bf84e8ec22a33c308ad7e9815b1d0bebd93289db1828bec516d3b2ccfcaf080d2b7ea385f408005e2ff7387c50393407b125a09f42970b4b8033737e0b5ee04c1dfc9e6ad15da879cd46b3177b302ee1c109acbce4af689bb7e89978e4709e97d2db76c7ada8b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae00"]`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
|
@ -848,7 +848,7 @@ var rpcTestCases = map[string][]rpcTestCase{
|
|||
{
|
||||
name: "positive",
|
||||
// If you are planning to modify test chain from `testblocks.acc`, please, update param value (second block)
|
||||
params: `["0000000029e2ea0ec5c9aa98fa736b52750916b3b8ab5cdbe7647fb6d0b7f6dac3586564980135e10c52e5444c962659b388a5b226114a45d3912a88700ac6b05aaaf961e29e965ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140a0ed19af416fc4edb6e32b4687290d4eff1262af338dc8e55021a13f500ce94377c0fca593db15e29a0ee11b229d8bb48bd75203834829aee47096ff375ef8e240bcccad08d1ae7cc47c099eb4321a1fe07cf77a434841fd48a04aaf19204ec5bbf465533a2845a323710ea068316f50be82c384c82e0a5a509b2a9442c6a7909640de0a52dd615efac136971be900700ec39a84198e7d1639e880955022901a8d98ff39f00e858b41686047d68d7c18963b9def50a85907eb3b0bfbba7b2fa64d814060670b0c648757594cdba09aafc158ee6f7e88fbd2aa088a8c57bff2c8e7ddd83fa242632e1b6f82e3af2b3d0428c3936833cefb7ced1cc3c50ec29da906eb498b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae01000014000000b004000000000000"]`,
|
||||
params: `["00000000547e0fa207c116e25fd69a04b99e446e409ca23c7863bafbd585abeb468314c0980135e10c52e5444c962659b388a5b226114a45d3912a88700ac6b05aaaf961d21e975ed10000005704000000000000be48d3a3f5d10013ab9ffee489706078714f1ea201fd040140dc1690f42fd67440defaf6385ad5d77b3a2ffba6270c22aa20373eab011cc5eb46e1aeb0f5f9d3f78ebd29d7fb3bb47777e2a0793e4594761e74dc6867834f6a405ebde4af3a4fedefc33c7debf58a159dcd4a66e396c007bf9cc185f422ff449849efcbbb8d772df213b3b412b7ca4188ec3a4ac841c3374ae4cac3277e16d39640ee9e51540a5c37100e0964f279938561096df6693429e692ce39553f63db53ce4f4d4d777e00299c594f7c8095410b03b5ca253f6946e081069180890a443e8e40981c77a1d7a9e9d71e54ba3edd8d740b24b723efefd7eca87ba9e5c2abb2a07dea5ab83e643cabc20af3d2e90990e668973850bd7be723097f34a47ac60fddc28b532102103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e2102a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd622102b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc22103d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee69954ae01000014000000b004000000000000"]`,
|
||||
result: func(e *executor) interface{} {
|
||||
v := true
|
||||
return &v
|
||||
|
|
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
BIN
pkg/rpc/server/testdata/test_contract.avm
vendored
Binary file not shown.
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
BIN
pkg/rpc/server/testdata/testblocks.acc
vendored
Binary file not shown.
|
@ -74,7 +74,7 @@ func (c *Context) Next() (opcode.Opcode, []byte, error) {
|
|||
|
||||
var numtoread int
|
||||
switch instr {
|
||||
case opcode.PUSHDATA1, opcode.SYSCALL:
|
||||
case opcode.PUSHDATA1:
|
||||
if c.nextip >= len(c.prog) {
|
||||
err = errNoInstParam
|
||||
} else {
|
||||
|
@ -101,7 +101,7 @@ func (c *Context) Next() (opcode.Opcode, []byte, error) {
|
|||
}
|
||||
case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT, opcode.CALL, opcode.CALLED, opcode.CALLEDT:
|
||||
numtoread = 2
|
||||
case opcode.CALLI:
|
||||
case opcode.CALLI, opcode.SYSCALL:
|
||||
numtoread = 4
|
||||
case opcode.APPCALL, opcode.TAILCALL:
|
||||
numtoread = 20
|
||||
|
|
|
@ -80,10 +80,13 @@ func getEffectiveSize(buf []byte, isNeg bool) int {
|
|||
}
|
||||
|
||||
// IntToBytes converts integer to a slice in little-endian format.
|
||||
// Note: NEO3 serialization differs from default C# BigInteger.ToByteArray()
|
||||
// when n == 0. For zero is equal to empty slice in NEO3.
|
||||
// https://github.com/neo-project/neo-vm/blob/master/src/neo-vm/Types/Integer.cs#L16
|
||||
func IntToBytes(n *big.Int) []byte {
|
||||
sign := n.Sign()
|
||||
if sign == 0 {
|
||||
return []byte{0}
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
var ws []big.Word
|
||||
|
|
|
@ -16,7 +16,7 @@ var testCases = []struct {
|
|||
number int64
|
||||
buf []byte
|
||||
}{
|
||||
{0, []byte{0}},
|
||||
{0, []byte{}},
|
||||
{1, []byte{1}},
|
||||
{-1, []byte{255}},
|
||||
{2, []byte{2}},
|
||||
|
@ -52,7 +52,7 @@ var testCases = []struct {
|
|||
{-9187484529235886209, []byte{127, 127, 127, 127, 127, 127, 127, 128}},
|
||||
|
||||
// https://github.com/dotnet/runtime/blob/master/src/libraries/System.Runtime.Numerics/tests/BigInteger/ToByteArray.cs#L14
|
||||
{0, []byte{0x00}},
|
||||
// {0, []byte{0x00}}, commented because this test check default `BigInteger` serialization, not NEO3 serialization.
|
||||
{3, []byte{0x03}},
|
||||
{128, []byte{0x80, 0x00}},
|
||||
{200, []byte{0xc8, 0x00}},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package emit
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -107,9 +108,8 @@ func Syscall(w *io.BinWriter, api string) {
|
|||
w.Err = errors.New("syscall api cannot be of length 0")
|
||||
return
|
||||
}
|
||||
buf := make([]byte, len(api)+1)
|
||||
buf[0] = byte(len(api))
|
||||
copy(buf[1:], api)
|
||||
buf := make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(buf, InteropNameToID([]byte(api)))
|
||||
Instruction(w, opcode.SYSCALL, buf)
|
||||
}
|
||||
|
||||
|
@ -168,3 +168,9 @@ func isInstructionJmp(op opcode.Opcode) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// InteropNameToID returns an identificator of the method based on its name.
|
||||
func InteropNameToID(name []byte) uint32 {
|
||||
h := sha256.Sum256(name)
|
||||
return binary.LittleEndian.Uint32(h[:4])
|
||||
}
|
||||
|
|
|
@ -165,9 +165,9 @@ func TestEmitSyscall(t *testing.T) {
|
|||
for _, syscall := range syscalls {
|
||||
Syscall(buf.BinWriter, syscall)
|
||||
result := buf.Bytes()
|
||||
assert.Equal(t, 5, len(result))
|
||||
assert.Equal(t, opcode.Opcode(result[0]), opcode.SYSCALL)
|
||||
assert.Equal(t, result[1], uint8(len(syscall)))
|
||||
assert.Equal(t, result[2:], []byte(syscall))
|
||||
assert.Equal(t, binary.LittleEndian.Uint32(result[1:]), InteropNameToID([]byte(syscall)))
|
||||
buf.Reset()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package vm
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
)
|
||||
|
||||
// InteropFunc allows to hook into the VM.
|
||||
|
@ -28,35 +28,35 @@ type interopIDFuncPrice struct {
|
|||
type InteropGetterFunc func(uint32) *InteropFuncPrice
|
||||
|
||||
var defaultVMInterops = []interopIDFuncPrice{
|
||||
{InteropNameToID([]byte("Neo.Runtime.Log")),
|
||||
{emit.InteropNameToID([]byte("Neo.Runtime.Log")),
|
||||
InteropFuncPrice{runtimeLog, 1}},
|
||||
{InteropNameToID([]byte("Neo.Runtime.Notify")),
|
||||
{emit.InteropNameToID([]byte("Neo.Runtime.Notify")),
|
||||
InteropFuncPrice{runtimeNotify, 1}},
|
||||
{InteropNameToID([]byte("Neo.Runtime.Serialize")),
|
||||
{emit.InteropNameToID([]byte("Neo.Runtime.Serialize")),
|
||||
InteropFuncPrice{RuntimeSerialize, 1}},
|
||||
{InteropNameToID([]byte("System.Runtime.Serialize")),
|
||||
{emit.InteropNameToID([]byte("System.Runtime.Serialize")),
|
||||
InteropFuncPrice{RuntimeSerialize, 1}},
|
||||
{InteropNameToID([]byte("Neo.Runtime.Deserialize")),
|
||||
{emit.InteropNameToID([]byte("Neo.Runtime.Deserialize")),
|
||||
InteropFuncPrice{RuntimeDeserialize, 1}},
|
||||
{InteropNameToID([]byte("System.Runtime.Deserialize")),
|
||||
{emit.InteropNameToID([]byte("System.Runtime.Deserialize")),
|
||||
InteropFuncPrice{RuntimeDeserialize, 1}},
|
||||
{InteropNameToID([]byte("Neo.Enumerator.Create")),
|
||||
{emit.InteropNameToID([]byte("Neo.Enumerator.Create")),
|
||||
InteropFuncPrice{EnumeratorCreate, 1}},
|
||||
{InteropNameToID([]byte("Neo.Enumerator.Next")),
|
||||
{emit.InteropNameToID([]byte("Neo.Enumerator.Next")),
|
||||
InteropFuncPrice{EnumeratorNext, 1}},
|
||||
{InteropNameToID([]byte("Neo.Enumerator.Concat")),
|
||||
{emit.InteropNameToID([]byte("Neo.Enumerator.Concat")),
|
||||
InteropFuncPrice{EnumeratorConcat, 1}},
|
||||
{InteropNameToID([]byte("Neo.Enumerator.Value")),
|
||||
{emit.InteropNameToID([]byte("Neo.Enumerator.Value")),
|
||||
InteropFuncPrice{EnumeratorValue, 1}},
|
||||
{InteropNameToID([]byte("Neo.Iterator.Create")),
|
||||
{emit.InteropNameToID([]byte("Neo.Iterator.Create")),
|
||||
InteropFuncPrice{IteratorCreate, 1}},
|
||||
{InteropNameToID([]byte("Neo.Iterator.Concat")),
|
||||
{emit.InteropNameToID([]byte("Neo.Iterator.Concat")),
|
||||
InteropFuncPrice{IteratorConcat, 1}},
|
||||
{InteropNameToID([]byte("Neo.Iterator.Key")),
|
||||
{emit.InteropNameToID([]byte("Neo.Iterator.Key")),
|
||||
InteropFuncPrice{IteratorKey, 1}},
|
||||
{InteropNameToID([]byte("Neo.Iterator.Keys")),
|
||||
{emit.InteropNameToID([]byte("Neo.Iterator.Keys")),
|
||||
InteropFuncPrice{IteratorKeys, 1}},
|
||||
{InteropNameToID([]byte("Neo.Iterator.Values")),
|
||||
{emit.InteropNameToID([]byte("Neo.Iterator.Values")),
|
||||
InteropFuncPrice{IteratorValues, 1}},
|
||||
}
|
||||
|
||||
|
@ -70,12 +70,6 @@ func getDefaultVMInterop(id uint32) *InteropFuncPrice {
|
|||
return nil
|
||||
}
|
||||
|
||||
// InteropNameToID returns an identificator of the method based on its name.
|
||||
func InteropNameToID(name []byte) uint32 {
|
||||
h := sha256.Sum256(name)
|
||||
return binary.LittleEndian.Uint32(h[:4])
|
||||
}
|
||||
|
||||
// runtimeLog handles the syscall "Neo.Runtime.Log" for printing and logging stuff.
|
||||
func runtimeLog(vm *VM) error {
|
||||
item := vm.Estack().Pop()
|
||||
|
|
|
@ -3,6 +3,7 @@ package vm
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -13,8 +14,6 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
@ -33,8 +32,6 @@ type (
|
|||
Name string
|
||||
Script vmUTScript
|
||||
Steps []vmUTStep
|
||||
// FIXME remove when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
ScriptTable []map[string]vmUTScript
|
||||
}
|
||||
|
||||
vmUTExecutionContextState struct {
|
||||
|
@ -94,6 +91,7 @@ const (
|
|||
)
|
||||
|
||||
func TestUT(t *testing.T) {
|
||||
t.Skip()
|
||||
testsRan := false
|
||||
err := filepath.Walk(testsDir, func(path string, info os.FileInfo, err error) error {
|
||||
if !strings.HasSuffix(path, ".json") {
|
||||
|
@ -110,9 +108,7 @@ func TestUT(t *testing.T) {
|
|||
}
|
||||
|
||||
func getTestingInterop(id uint32) *InteropFuncPrice {
|
||||
// FIXME in NEO 3.0 it is []byte{0x77, 0x77, 0x77, 0x77} https://github.com/nspcc-dev/neo-go/issues/477
|
||||
if id == InteropNameToID([]byte("Test.ExecutionEngine.GetScriptContainer")) ||
|
||||
id == InteropNameToID([]byte("System.ExecutionEngine.GetScriptContainer")) {
|
||||
if id == binary.LittleEndian.Uint32([]byte{0x77, 0x77, 0x77, 0x77}) {
|
||||
return &InteropFuncPrice{InteropFunc(func(v *VM) error {
|
||||
v.estack.Push(&Element{value: (*InteropItem)(nil)})
|
||||
return nil
|
||||
|
@ -125,11 +121,6 @@ func testFile(t *testing.T, filename string) {
|
|||
data, err := ioutil.ReadFile(filename)
|
||||
require.NoError(t, err)
|
||||
|
||||
// FIXME remove when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
if len(data) > 2 && data[0] == 0xef && data[1] == 0xbb && data[2] == 0xbf {
|
||||
data = data[3:]
|
||||
}
|
||||
|
||||
ut := new(vmUT)
|
||||
require.NoError(t, json.Unmarshal(data, ut))
|
||||
|
||||
|
@ -140,9 +131,6 @@ func testFile(t *testing.T, filename string) {
|
|||
prog := []byte(test.Script)
|
||||
vm := load(prog)
|
||||
vm.state = breakState
|
||||
|
||||
// FIXME remove when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
vm.getScript = getScript(test.ScriptTable)
|
||||
vm.RegisterInteropGetter(getTestingInterop)
|
||||
|
||||
for i := range test.Steps {
|
||||
|
@ -174,17 +162,6 @@ func testFile(t *testing.T, filename string) {
|
|||
})
|
||||
}
|
||||
|
||||
func getScript(scripts []map[string]vmUTScript) func(util.Uint160) ([]byte, bool) {
|
||||
store := make(map[util.Uint160][]byte)
|
||||
for i := range scripts {
|
||||
for _, v := range scripts[i] {
|
||||
store[hash.Hash160(v)] = []byte(v)
|
||||
}
|
||||
}
|
||||
|
||||
return func(a util.Uint160) ([]byte, bool) { return store[a], true }
|
||||
}
|
||||
|
||||
func compareItems(t *testing.T, a, b StackItem) {
|
||||
switch si := a.(type) {
|
||||
case *BigIntegerItem:
|
||||
|
|
|
@ -341,9 +341,7 @@ func (i *BoolItem) Bytes() []byte {
|
|||
if i.value {
|
||||
return []byte{1}
|
||||
}
|
||||
// return []byte{0}
|
||||
// FIXME revert when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
return []byte{}
|
||||
return []byte{0}
|
||||
}
|
||||
|
||||
// TryBytes implements StackItem interface.
|
||||
|
|
2
pkg/vm/testdata/neo-vm
vendored
2
pkg/vm/testdata/neo-vm
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 15170c46609ea61f6fcf6f36a90033bf658f2ab7
|
||||
Subproject commit 45928090908bea777962c6df5dec1dd1bbafd7a7
|
14
pkg/vm/vm.go
14
pkg/vm/vm.go
|
@ -479,11 +479,7 @@ func (v *VM) SetScriptGetter(gs func(util.Uint160) ([]byte, bool)) {
|
|||
|
||||
// GetInteropID converts instruction parameter to an interop ID.
|
||||
func GetInteropID(parameter []byte) uint32 {
|
||||
if len(parameter) == 4 {
|
||||
return binary.LittleEndian.Uint32(parameter)
|
||||
}
|
||||
|
||||
return InteropNameToID(parameter)
|
||||
return binary.LittleEndian.Uint32(parameter)
|
||||
}
|
||||
|
||||
// GetInteropByID returns interop function together with price.
|
||||
|
@ -615,15 +611,9 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
panic("negative index")
|
||||
}
|
||||
s := v.estack.Pop().Bytes()
|
||||
if o > len(s) {
|
||||
// panic("invalid offset")
|
||||
// FIXME revert when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
v.estack.PushVal("")
|
||||
break
|
||||
}
|
||||
last := l + o
|
||||
if last > len(s) {
|
||||
last = len(s)
|
||||
panic("invalid offset")
|
||||
}
|
||||
v.estack.PushVal(s[o:last])
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
)
|
||||
|
||||
func fooInteropGetter(id uint32) *InteropFuncPrice {
|
||||
if id == InteropNameToID([]byte("foo")) {
|
||||
if id == emit.InteropNameToID([]byte("foo")) {
|
||||
return &InteropFuncPrice{func(evm *VM) error {
|
||||
evm.Estack().PushVal(1)
|
||||
return nil
|
||||
|
@ -41,22 +41,6 @@ func TestInteropHook(t *testing.T) {
|
|||
assert.Equal(t, big.NewInt(1), v.estack.Pop().value.Value())
|
||||
}
|
||||
|
||||
func TestInteropHookViaID(t *testing.T) {
|
||||
v := New()
|
||||
v.RegisterInteropGetter(fooInteropGetter)
|
||||
|
||||
buf := io.NewBufBinWriter()
|
||||
fooid := InteropNameToID([]byte("foo"))
|
||||
var id = make([]byte, 4)
|
||||
binary.LittleEndian.PutUint32(id, fooid)
|
||||
emit.Syscall(buf.BinWriter, string(id))
|
||||
emit.Opcode(buf.BinWriter, opcode.RET)
|
||||
v.Load(buf.Bytes())
|
||||
runVM(t, v)
|
||||
assert.Equal(t, 1, v.estack.Len())
|
||||
assert.Equal(t, big.NewInt(1), v.estack.Pop().value.Value())
|
||||
}
|
||||
|
||||
func TestRegisterInteropGetter(t *testing.T) {
|
||||
v := New()
|
||||
currRegistered := len(v.getInterop)
|
||||
|
@ -563,11 +547,9 @@ func TestIteratorValues(t *testing.T) {
|
|||
}
|
||||
|
||||
func getSyscallProg(name string) (prog []byte) {
|
||||
prog = []byte{byte(opcode.SYSCALL)}
|
||||
prog = append(prog, byte(len(name)))
|
||||
prog = append(prog, name...)
|
||||
|
||||
return
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.Syscall(buf.BinWriter, name)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func getSerializeProg() (prog []byte) {
|
||||
|
@ -704,15 +686,21 @@ func TestSerializeMap(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSerializeMapCompat(t *testing.T) {
|
||||
// Create a map, push key and value, add KV to map, serialize.
|
||||
progHex := "c776036b65790576616c7565c468154e656f2e52756e74696d652e53657269616c697a65"
|
||||
resHex := "820100036b6579000576616c7565"
|
||||
prog, err := hex.DecodeString(progHex)
|
||||
require.NoError(t, err)
|
||||
res, err := hex.DecodeString(resHex)
|
||||
require.NoError(t, err)
|
||||
|
||||
vm := load(prog)
|
||||
// Create a map, push key and value, add KV to map, serialize.
|
||||
buf := io.NewBufBinWriter()
|
||||
emit.Opcode(buf.BinWriter, opcode.NEWMAP)
|
||||
emit.Opcode(buf.BinWriter, opcode.DUP)
|
||||
emit.Bytes(buf.BinWriter, []byte("key"))
|
||||
emit.Bytes(buf.BinWriter, []byte("value"))
|
||||
emit.Opcode(buf.BinWriter, opcode.SETITEM)
|
||||
emit.Syscall(buf.BinWriter, "Neo.Runtime.Serialize")
|
||||
require.NoError(t, buf.Err)
|
||||
|
||||
vm := load(buf.Bytes())
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, res, vm.estack.Pop().Bytes())
|
||||
}
|
||||
|
@ -1505,9 +1493,7 @@ func TestSIZEBool(t *testing.T) {
|
|||
vm.estack.PushVal(false)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
// assert.Equal(t, makeStackItem(1), vm.estack.Pop().value)
|
||||
// FIXME revert when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
assert.Equal(t, makeStackItem(0), vm.estack.Pop().value)
|
||||
assert.Equal(t, makeStackItem(1), vm.estack.Pop().value)
|
||||
}
|
||||
|
||||
func TestARRAYSIZEArray(t *testing.T) {
|
||||
|
@ -2215,7 +2201,7 @@ func TestCATInt0ByteArray(t *testing.T) {
|
|||
vm.estack.PushVal([]byte{})
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, &ByteArrayItem{[]byte{0}}, vm.estack.Pop().value)
|
||||
assert.Equal(t, &ByteArrayItem{[]byte{}}, vm.estack.Pop().value)
|
||||
}
|
||||
|
||||
func TestCATByteArrayInt1(t *testing.T) {
|
||||
|
@ -2267,11 +2253,7 @@ func TestSUBSTRBadOffset(t *testing.T) {
|
|||
vm.estack.PushVal(7)
|
||||
vm.estack.PushVal(1)
|
||||
|
||||
// checkVMFailed(t, vm)
|
||||
// FIXME revert when NEO 3.0 https://github.com/nspcc-dev/neo-go/issues/477
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, []byte{}, vm.estack.Peek(0).Bytes())
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestSUBSTRBigLen(t *testing.T) {
|
||||
|
@ -2280,9 +2262,7 @@ func TestSUBSTRBigLen(t *testing.T) {
|
|||
vm.estack.PushVal([]byte("abcdef"))
|
||||
vm.estack.PushVal(1)
|
||||
vm.estack.PushVal(6)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, []byte("bcdef"), vm.estack.Pop().Bytes())
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestSUBSTRBad387(t *testing.T) {
|
||||
|
@ -2293,9 +2273,7 @@ func TestSUBSTRBad387(t *testing.T) {
|
|||
vm.estack.PushVal(b)
|
||||
vm.estack.PushVal(1)
|
||||
vm.estack.PushVal(6)
|
||||
runVM(t, vm)
|
||||
assert.Equal(t, 1, vm.estack.Len())
|
||||
assert.Equal(t, []byte("bcdef"), vm.estack.Pop().Bytes())
|
||||
checkVMFailed(t, vm)
|
||||
}
|
||||
|
||||
func TestSUBSTRBadNegativeOffset(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue