From d04b00074815e5ea385d7cdd2e67e9ba86ca8c50 Mon Sep 17 00:00:00 2001 From: Evgeniy Stratonikov Date: Tue, 12 Jan 2021 11:42:09 +0300 Subject: [PATCH] vm: remove iterator/enumerator Concat API Follow neo-project/neo#2170. --- pkg/compiler/syscall.go | 2 - pkg/core/interop/enumerator/interop.go | 5 --- pkg/core/interop/enumerator/interop_test.go | 5 +-- pkg/core/interop/interopnames/names.go | 4 -- pkg/core/interop/iterator/interop.go | 5 --- pkg/core/interop/iterator/interop_test.go | 5 +-- pkg/core/interops.go | 2 - pkg/interop/enumerator/enumerator.go | 9 ----- pkg/interop/iterator/iterator.go | 11 ------ pkg/vm/interop.go | 38 ------------------ pkg/vm/interop_iterators.go | 39 ------------------ pkg/vm/vm_test.go | 44 --------------------- 12 files changed, 2 insertions(+), 167 deletions(-) diff --git a/pkg/compiler/syscall.go b/pkg/compiler/syscall.go index c30617ab3..eacbe5c7f 100644 --- a/pkg/compiler/syscall.go +++ b/pkg/compiler/syscall.go @@ -36,13 +36,11 @@ var syscalls = map[string]map[string]string{ "SHA256": interopnames.NeoCryptoSHA256, }, "enumerator": { - "Concat": interopnames.SystemEnumeratorConcat, "Create": interopnames.SystemEnumeratorCreate, "Next": interopnames.SystemEnumeratorNext, "Value": interopnames.SystemEnumeratorValue, }, "iterator": { - "Concat": interopnames.SystemIteratorConcat, "Create": interopnames.SystemIteratorCreate, "Key": interopnames.SystemIteratorKey, "Keys": interopnames.SystemIteratorKeys, diff --git a/pkg/core/interop/enumerator/interop.go b/pkg/core/interop/enumerator/interop.go index 24cc85931..b75daff0c 100644 --- a/pkg/core/interop/enumerator/interop.go +++ b/pkg/core/interop/enumerator/interop.go @@ -5,11 +5,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/vm" ) -// Concat concatenates 2 enumerators into a single one. -func Concat(ic *interop.Context) error { - return vm.EnumeratorConcat(ic.VM) -} - // Create creates an enumerator from an array-like or bytearray-like stack item. func Create(ic *interop.Context) error { return vm.EnumeratorCreate(ic.VM) diff --git a/pkg/core/interop/enumerator/interop_test.go b/pkg/core/interop/enumerator/interop_test.go index 20149455d..a77a369a3 100644 --- a/pkg/core/interop/enumerator/interop_test.go +++ b/pkg/core/interop/enumerator/interop_test.go @@ -13,11 +13,8 @@ import ( func TestEnumerator(t *testing.T) { ic := &interop.Context{VM: vm.New()} full := []byte{4, 8, 15} - ic.VM.Estack().PushVal(full[2:]) + ic.VM.Estack().PushVal(full) require.NoError(t, Create(ic)) - ic.VM.Estack().PushVal(full[:2]) - require.NoError(t, Create(ic)) - require.NoError(t, Concat(ic)) res := ic.VM.Estack().Pop().Item() for i := range full { diff --git a/pkg/core/interop/interopnames/names.go b/pkg/core/interop/interopnames/names.go index 1d642cc9b..23b3fa3a4 100644 --- a/pkg/core/interop/interopnames/names.go +++ b/pkg/core/interop/interopnames/names.go @@ -26,11 +26,9 @@ const ( SystemContractGetCallFlags = "System.Contract.GetCallFlags" SystemContractNativeOnPersist = "System.Contract.NativeOnPersist" SystemContractNativePostPersist = "System.Contract.NativePostPersist" - SystemEnumeratorConcat = "System.Enumerator.Concat" SystemEnumeratorCreate = "System.Enumerator.Create" SystemEnumeratorNext = "System.Enumerator.Next" SystemEnumeratorValue = "System.Enumerator.Value" - SystemIteratorConcat = "System.Iterator.Concat" SystemIteratorCreate = "System.Iterator.Create" SystemIteratorKey = "System.Iterator.Key" SystemIteratorKeys = "System.Iterator.Keys" @@ -91,11 +89,9 @@ var names = []string{ SystemContractGetCallFlags, SystemContractNativeOnPersist, SystemContractNativePostPersist, - SystemEnumeratorConcat, SystemEnumeratorCreate, SystemEnumeratorNext, SystemEnumeratorValue, - SystemIteratorConcat, SystemIteratorCreate, SystemIteratorKey, SystemIteratorKeys, diff --git a/pkg/core/interop/iterator/interop.go b/pkg/core/interop/iterator/interop.go index 6bc161479..7692a8c2f 100644 --- a/pkg/core/interop/iterator/interop.go +++ b/pkg/core/interop/iterator/interop.go @@ -5,11 +5,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/vm" ) -// Concat concatenates 2 iterators into a single one. -func Concat(ic *interop.Context) error { - return vm.IteratorConcat(ic.VM) -} - // Create creates an iterator from array-like or map stack item. func Create(ic *interop.Context) error { return vm.IteratorCreate(ic.VM) diff --git a/pkg/core/interop/iterator/interop_test.go b/pkg/core/interop/iterator/interop_test.go index b220b5271..c8324b9ed 100644 --- a/pkg/core/interop/iterator/interop_test.go +++ b/pkg/core/interop/iterator/interop_test.go @@ -13,11 +13,8 @@ import ( func TestIterator(t *testing.T) { ic := &interop.Context{VM: vm.New()} full := []byte{4, 8, 15} - ic.VM.Estack().PushVal(full[2:]) + ic.VM.Estack().PushVal(full) require.NoError(t, Create(ic)) - ic.VM.Estack().PushVal(full[:2]) - require.NoError(t, Create(ic)) - require.NoError(t, Concat(ic)) res := ic.VM.Estack().Pop().Item() ic.VM.Estack().PushVal(res) diff --git a/pkg/core/interops.go b/pkg/core/interops.go index 41cbb1f25..eff9006ac 100644 --- a/pkg/core/interops.go +++ b/pkg/core/interops.go @@ -58,11 +58,9 @@ var systemInterops = []interop.Function{ {Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10}, {Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.WriteStates}, {Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, Price: 0, RequiredFlags: callflag.WriteStates}, - {Name: interopnames.SystemEnumeratorConcat, Func: enumerator.Concat, Price: 1 << 4, ParamCount: 2}, {Name: interopnames.SystemEnumeratorCreate, Func: enumerator.Create, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1 << 15, ParamCount: 1}, {Name: interopnames.SystemEnumeratorValue, Func: enumerator.Value, Price: 1 << 4, ParamCount: 1}, - {Name: interopnames.SystemIteratorConcat, Func: iterator.Concat, Price: 1 << 4, ParamCount: 2}, {Name: interopnames.SystemIteratorCreate, Func: iterator.Create, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemIteratorKey, Func: iterator.Key, Price: 1 << 4, ParamCount: 1}, {Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 1 << 4, ParamCount: 1}, diff --git a/pkg/interop/enumerator/enumerator.go b/pkg/interop/enumerator/enumerator.go index 5581538a8..740f270a3 100644 --- a/pkg/interop/enumerator/enumerator.go +++ b/pkg/interop/enumerator/enumerator.go @@ -30,12 +30,3 @@ func Next(e Enumerator) bool { func Value(e Enumerator) interface{} { return nil } - -// Concat concatenates two given enumerators returning one that will range on -// a first and then continue with b. Enumerator positions are not reset for a -// and b, so if any of them was already advanced by Next the resulting -// Enumerator will point at this new position and never go back to previous -// values. This function uses `System.Enumerator.Concat` syscall. -func Concat(a, b Enumerator) Enumerator { - return Enumerator{} -} diff --git a/pkg/interop/iterator/iterator.go b/pkg/interop/iterator/iterator.go index 80be62165..d99729518 100644 --- a/pkg/interop/iterator/iterator.go +++ b/pkg/interop/iterator/iterator.go @@ -19,17 +19,6 @@ func Create(items interface{}) Iterator { return Iterator{} } -// Concat concatenates two given iterators returning one that will range on -// a first and then continue with b. Iterator positions are not reset for a -// and b, so if any of them was already advanced by Next the resulting -// Iterator will point at this new position and never go back to previous -// key-value pairs. Concatenated iterators also remain completely independent -// in results they return, so if both contain the same key you'll receive this -// key twice when iterating. This function uses `System.Iterator.Concat` syscall. -func Concat(a, b Iterator) Iterator { - return Iterator{} -} - // Key returns iterator's key at current position. It's only valid to call after // successful Next call. This function uses `System.Iterator.Key` syscall. func Key(it Iterator) interface{} { diff --git a/pkg/vm/interop.go b/pkg/vm/interop.go index be45f3971..295d5f3cc 100644 --- a/pkg/vm/interop.go +++ b/pkg/vm/interop.go @@ -31,14 +31,10 @@ var defaultVMInterops = []interopIDFuncPrice{ Func: EnumeratorCreate, Price: 1 << 4}, {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorNext)), Func: EnumeratorNext, Price: 1 << 15}, - {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorConcat)), - Func: EnumeratorConcat, Price: 1 << 4}, {ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorValue)), Func: EnumeratorValue, Price: 1 << 4}, {ID: interopnames.ToID([]byte(interopnames.SystemIteratorCreate)), Func: IteratorCreate, Price: 1 << 4}, - {ID: interopnames.ToID([]byte(interopnames.SystemIteratorConcat)), - Func: IteratorConcat, Price: 1 << 4}, {ID: interopnames.ToID([]byte(interopnames.SystemIteratorKey)), Func: IteratorKey, Price: 1 << 4}, {ID: interopnames.ToID([]byte(interopnames.SystemIteratorKeys)), @@ -160,23 +156,6 @@ func EnumeratorValue(v *VM) error { return nil } -// EnumeratorConcat handles syscall System.Enumerator.Concat. -func EnumeratorConcat(v *VM) error { - iop1 := v.Estack().Pop().Interop() - arr1 := iop1.Value().(enumerator) - iop2 := v.Estack().Pop().Interop() - arr2 := iop2.Value().(enumerator) - - v.Estack().Push(&Element{ - value: stackitem.NewInterop(&concatEnum{ - current: arr1, - second: arr2, - }), - }) - - return nil -} - // IteratorCreate handles syscall System.Iterator.Create. func IteratorCreate(v *VM) error { data := v.Estack().Pop() @@ -212,23 +191,6 @@ func NewMapIterator(m *stackitem.Map) *stackitem.Interop { }) } -// IteratorConcat handles syscall System.Iterator.Concat. -func IteratorConcat(v *VM) error { - iop1 := v.Estack().Pop().Interop() - iter1 := iop1.Value().(iterator) - iop2 := v.Estack().Pop().Interop() - iter2 := iop2.Value().(iterator) - - v.Estack().Push(&Element{value: stackitem.NewInterop( - &concatIter{ - current: iter1, - second: iter2, - }, - )}) - - return nil -} - // IteratorKey handles syscall System.Iterator.Key. func IteratorKey(v *VM) error { iop := v.estack.Pop().Interop() diff --git a/pkg/vm/interop_iterators.go b/pkg/vm/interop_iterators.go index b29de47e3..d87396c96 100644 --- a/pkg/vm/interop_iterators.go +++ b/pkg/vm/interop_iterators.go @@ -22,10 +22,6 @@ type ( value []byte } - concatEnum struct { - current enumerator - second enumerator - } ) type ( @@ -39,11 +35,6 @@ type ( m []stackitem.MapElement } - concatIter struct { - current iterator - second iterator - } - keysWrapper struct { iter iterator } @@ -87,36 +78,6 @@ func (a *byteArrayWrapper) Key() stackitem.Item { return stackitem.Make(a.index) } -func (c *concatEnum) Next() bool { - if c.current.Next() { - return true - } - c.current = c.second - - return c.current.Next() -} - -func (c *concatEnum) Value() stackitem.Item { - return c.current.Value() -} - -func (i *concatIter) Next() bool { - if i.current.Next() { - return true - } - i.current = i.second - - return i.second.Next() -} - -func (i *concatIter) Value() stackitem.Item { - return i.current.Value() -} - -func (i *concatIter) Key() stackitem.Item { - return i.current.Key() -} - func (m *mapWrapper) Next() bool { if next := m.index + 1; next < len(m.m) { m.index = next diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 7a924c10d..be0c03103 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -545,50 +545,6 @@ func TestIteratorCreate(t *testing.T) { }) } -func testIterableConcat(t *testing.T, typ string) { - isIter := typ == "Iterator" - prog := getSyscallProg("System." + typ + ".Create") - prog = append(prog, byte(opcode.SWAP)) - prog = append(prog, getSyscallProg("System."+typ+".Create")...) - prog = append(prog, getSyscallProg("System."+typ+".Concat")...) - prog = append(prog, getEnumeratorProg(3, isIter)...) - vm := load(prog) - - arr := []stackitem.Item{ - stackitem.NewBool(false), - stackitem.NewBigInteger(big.NewInt(123)), - stackitem.NewMap(), - } - vm.estack.Push(&Element{value: stackitem.NewArray(arr[:1])}) - vm.estack.Push(&Element{value: stackitem.NewArray(arr[1:])}) - - runVM(t, vm) - - if isIter { - // Yes, this is how iterators are concatenated in reference VM - // https://github.com/neo-project/neo/blob/master-2.x/neo.UnitTests/UT_ConcatenatedIterator.cs#L54 - checkEnumeratorStack(t, vm, []stackitem.Item{ - stackitem.Make(1), arr[2], stackitem.NewBool(true), - stackitem.Make(0), arr[1], stackitem.NewBool(true), - stackitem.Make(0), arr[0], stackitem.NewBool(true), - }) - } else { - checkEnumeratorStack(t, vm, []stackitem.Item{ - arr[2], stackitem.NewBool(true), - arr[1], stackitem.NewBool(true), - arr[0], stackitem.NewBool(true), - }) - } -} - -func TestEnumeratorConcat(t *testing.T) { - testIterableConcat(t, "Enumerator") -} - -func TestIteratorConcat(t *testing.T) { - testIterableConcat(t, "Iterator") -} - func TestIteratorKeys(t *testing.T) { prog := getSyscallProg(interopnames.SystemIteratorCreate) prog = append(prog, getSyscallProg(interopnames.SystemIteratorKeys)...)