forked from TrueCloudLab/neoneo-go
parent
e36e71ffbd
commit
d04b000748
12 changed files with 2 additions and 167 deletions
|
@ -36,13 +36,11 @@ var syscalls = map[string]map[string]string{
|
||||||
"SHA256": interopnames.NeoCryptoSHA256,
|
"SHA256": interopnames.NeoCryptoSHA256,
|
||||||
},
|
},
|
||||||
"enumerator": {
|
"enumerator": {
|
||||||
"Concat": interopnames.SystemEnumeratorConcat,
|
|
||||||
"Create": interopnames.SystemEnumeratorCreate,
|
"Create": interopnames.SystemEnumeratorCreate,
|
||||||
"Next": interopnames.SystemEnumeratorNext,
|
"Next": interopnames.SystemEnumeratorNext,
|
||||||
"Value": interopnames.SystemEnumeratorValue,
|
"Value": interopnames.SystemEnumeratorValue,
|
||||||
},
|
},
|
||||||
"iterator": {
|
"iterator": {
|
||||||
"Concat": interopnames.SystemIteratorConcat,
|
|
||||||
"Create": interopnames.SystemIteratorCreate,
|
"Create": interopnames.SystemIteratorCreate,
|
||||||
"Key": interopnames.SystemIteratorKey,
|
"Key": interopnames.SystemIteratorKey,
|
||||||
"Keys": interopnames.SystemIteratorKeys,
|
"Keys": interopnames.SystemIteratorKeys,
|
||||||
|
|
|
@ -5,11 +5,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"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.
|
// Create creates an enumerator from an array-like or bytearray-like stack item.
|
||||||
func Create(ic *interop.Context) error {
|
func Create(ic *interop.Context) error {
|
||||||
return vm.EnumeratorCreate(ic.VM)
|
return vm.EnumeratorCreate(ic.VM)
|
||||||
|
|
|
@ -13,11 +13,8 @@ import (
|
||||||
func TestEnumerator(t *testing.T) {
|
func TestEnumerator(t *testing.T) {
|
||||||
ic := &interop.Context{VM: vm.New()}
|
ic := &interop.Context{VM: vm.New()}
|
||||||
full := []byte{4, 8, 15}
|
full := []byte{4, 8, 15}
|
||||||
ic.VM.Estack().PushVal(full[2:])
|
ic.VM.Estack().PushVal(full)
|
||||||
require.NoError(t, Create(ic))
|
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()
|
res := ic.VM.Estack().Pop().Item()
|
||||||
for i := range full {
|
for i := range full {
|
||||||
|
|
|
@ -26,11 +26,9 @@ const (
|
||||||
SystemContractGetCallFlags = "System.Contract.GetCallFlags"
|
SystemContractGetCallFlags = "System.Contract.GetCallFlags"
|
||||||
SystemContractNativeOnPersist = "System.Contract.NativeOnPersist"
|
SystemContractNativeOnPersist = "System.Contract.NativeOnPersist"
|
||||||
SystemContractNativePostPersist = "System.Contract.NativePostPersist"
|
SystemContractNativePostPersist = "System.Contract.NativePostPersist"
|
||||||
SystemEnumeratorConcat = "System.Enumerator.Concat"
|
|
||||||
SystemEnumeratorCreate = "System.Enumerator.Create"
|
SystemEnumeratorCreate = "System.Enumerator.Create"
|
||||||
SystemEnumeratorNext = "System.Enumerator.Next"
|
SystemEnumeratorNext = "System.Enumerator.Next"
|
||||||
SystemEnumeratorValue = "System.Enumerator.Value"
|
SystemEnumeratorValue = "System.Enumerator.Value"
|
||||||
SystemIteratorConcat = "System.Iterator.Concat"
|
|
||||||
SystemIteratorCreate = "System.Iterator.Create"
|
SystemIteratorCreate = "System.Iterator.Create"
|
||||||
SystemIteratorKey = "System.Iterator.Key"
|
SystemIteratorKey = "System.Iterator.Key"
|
||||||
SystemIteratorKeys = "System.Iterator.Keys"
|
SystemIteratorKeys = "System.Iterator.Keys"
|
||||||
|
@ -91,11 +89,9 @@ var names = []string{
|
||||||
SystemContractGetCallFlags,
|
SystemContractGetCallFlags,
|
||||||
SystemContractNativeOnPersist,
|
SystemContractNativeOnPersist,
|
||||||
SystemContractNativePostPersist,
|
SystemContractNativePostPersist,
|
||||||
SystemEnumeratorConcat,
|
|
||||||
SystemEnumeratorCreate,
|
SystemEnumeratorCreate,
|
||||||
SystemEnumeratorNext,
|
SystemEnumeratorNext,
|
||||||
SystemEnumeratorValue,
|
SystemEnumeratorValue,
|
||||||
SystemIteratorConcat,
|
|
||||||
SystemIteratorCreate,
|
SystemIteratorCreate,
|
||||||
SystemIteratorKey,
|
SystemIteratorKey,
|
||||||
SystemIteratorKeys,
|
SystemIteratorKeys,
|
||||||
|
|
|
@ -5,11 +5,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"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.
|
// Create creates an iterator from array-like or map stack item.
|
||||||
func Create(ic *interop.Context) error {
|
func Create(ic *interop.Context) error {
|
||||||
return vm.IteratorCreate(ic.VM)
|
return vm.IteratorCreate(ic.VM)
|
||||||
|
|
|
@ -13,11 +13,8 @@ import (
|
||||||
func TestIterator(t *testing.T) {
|
func TestIterator(t *testing.T) {
|
||||||
ic := &interop.Context{VM: vm.New()}
|
ic := &interop.Context{VM: vm.New()}
|
||||||
full := []byte{4, 8, 15}
|
full := []byte{4, 8, 15}
|
||||||
ic.VM.Estack().PushVal(full[2:])
|
ic.VM.Estack().PushVal(full)
|
||||||
require.NoError(t, Create(ic))
|
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()
|
res := ic.VM.Estack().Pop().Item()
|
||||||
ic.VM.Estack().PushVal(res)
|
ic.VM.Estack().PushVal(res)
|
||||||
|
|
|
@ -58,11 +58,9 @@ var systemInterops = []interop.Function{
|
||||||
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10},
|
{Name: interopnames.SystemContractGetCallFlags, Func: contractGetCallFlags, Price: 1 << 10},
|
||||||
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.WriteStates},
|
{Name: interopnames.SystemContractNativeOnPersist, Func: native.OnPersist, Price: 0, RequiredFlags: callflag.WriteStates},
|
||||||
{Name: interopnames.SystemContractNativePostPersist, Func: native.PostPersist, 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.SystemEnumeratorCreate, Func: enumerator.Create, Price: 1 << 4, ParamCount: 1},
|
||||||
{Name: interopnames.SystemEnumeratorNext, Func: enumerator.Next, Price: 1 << 15, 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.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.SystemIteratorCreate, Func: iterator.Create, Price: 1 << 4, ParamCount: 1},
|
||||||
{Name: interopnames.SystemIteratorKey, Func: iterator.Key, 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},
|
{Name: interopnames.SystemIteratorKeys, Func: iterator.Keys, Price: 1 << 4, ParamCount: 1},
|
||||||
|
|
|
@ -30,12 +30,3 @@ func Next(e Enumerator) bool {
|
||||||
func Value(e Enumerator) interface{} {
|
func Value(e Enumerator) interface{} {
|
||||||
return nil
|
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{}
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,17 +19,6 @@ func Create(items interface{}) Iterator {
|
||||||
return 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
|
// 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.
|
// successful Next call. This function uses `System.Iterator.Key` syscall.
|
||||||
func Key(it Iterator) interface{} {
|
func Key(it Iterator) interface{} {
|
||||||
|
|
|
@ -31,14 +31,10 @@ var defaultVMInterops = []interopIDFuncPrice{
|
||||||
Func: EnumeratorCreate, Price: 1 << 4},
|
Func: EnumeratorCreate, Price: 1 << 4},
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorNext)),
|
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorNext)),
|
||||||
Func: EnumeratorNext, Price: 1 << 15},
|
Func: EnumeratorNext, Price: 1 << 15},
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorConcat)),
|
|
||||||
Func: EnumeratorConcat, Price: 1 << 4},
|
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorValue)),
|
{ID: interopnames.ToID([]byte(interopnames.SystemEnumeratorValue)),
|
||||||
Func: EnumeratorValue, Price: 1 << 4},
|
Func: EnumeratorValue, Price: 1 << 4},
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorCreate)),
|
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorCreate)),
|
||||||
Func: IteratorCreate, Price: 1 << 4},
|
Func: IteratorCreate, Price: 1 << 4},
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorConcat)),
|
|
||||||
Func: IteratorConcat, Price: 1 << 4},
|
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorKey)),
|
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorKey)),
|
||||||
Func: IteratorKey, Price: 1 << 4},
|
Func: IteratorKey, Price: 1 << 4},
|
||||||
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorKeys)),
|
{ID: interopnames.ToID([]byte(interopnames.SystemIteratorKeys)),
|
||||||
|
@ -160,23 +156,6 @@ func EnumeratorValue(v *VM) error {
|
||||||
return nil
|
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.
|
// IteratorCreate handles syscall System.Iterator.Create.
|
||||||
func IteratorCreate(v *VM) error {
|
func IteratorCreate(v *VM) error {
|
||||||
data := v.Estack().Pop()
|
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.
|
// IteratorKey handles syscall System.Iterator.Key.
|
||||||
func IteratorKey(v *VM) error {
|
func IteratorKey(v *VM) error {
|
||||||
iop := v.estack.Pop().Interop()
|
iop := v.estack.Pop().Interop()
|
||||||
|
|
|
@ -22,10 +22,6 @@ type (
|
||||||
value []byte
|
value []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
concatEnum struct {
|
|
||||||
current enumerator
|
|
||||||
second enumerator
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -39,11 +35,6 @@ type (
|
||||||
m []stackitem.MapElement
|
m []stackitem.MapElement
|
||||||
}
|
}
|
||||||
|
|
||||||
concatIter struct {
|
|
||||||
current iterator
|
|
||||||
second iterator
|
|
||||||
}
|
|
||||||
|
|
||||||
keysWrapper struct {
|
keysWrapper struct {
|
||||||
iter iterator
|
iter iterator
|
||||||
}
|
}
|
||||||
|
@ -87,36 +78,6 @@ func (a *byteArrayWrapper) Key() stackitem.Item {
|
||||||
return stackitem.Make(a.index)
|
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 {
|
func (m *mapWrapper) Next() bool {
|
||||||
if next := m.index + 1; next < len(m.m) {
|
if next := m.index + 1; next < len(m.m) {
|
||||||
m.index = next
|
m.index = next
|
||||||
|
|
|
@ -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) {
|
func TestIteratorKeys(t *testing.T) {
|
||||||
prog := getSyscallProg(interopnames.SystemIteratorCreate)
|
prog := getSyscallProg(interopnames.SystemIteratorCreate)
|
||||||
prog = append(prog, getSyscallProg(interopnames.SystemIteratorKeys)...)
|
prog = append(prog, getSyscallProg(interopnames.SystemIteratorKeys)...)
|
||||||
|
|
Loading…
Reference in a new issue