interop: strip full prefix in System.Storage.Find
This commit is contained in:
parent
933743ce87
commit
ffaae0f773
4 changed files with 34 additions and 24 deletions
|
@ -18,17 +18,19 @@ const (
|
|||
|
||||
// Iterator is an iterator state representation.
|
||||
type Iterator struct {
|
||||
m []stackitem.MapElement
|
||||
opts int64
|
||||
index int
|
||||
m []stackitem.MapElement
|
||||
opts int64
|
||||
index int
|
||||
prefixSize int
|
||||
}
|
||||
|
||||
// NewIterator creates a new Iterator with given options for a given map.
|
||||
func NewIterator(m *stackitem.Map, opts int64) *Iterator {
|
||||
func NewIterator(m *stackitem.Map, prefix int, opts int64) *Iterator {
|
||||
return &Iterator{
|
||||
m: m.Value().([]stackitem.MapElement),
|
||||
opts: opts,
|
||||
index: -1,
|
||||
m: m.Value().([]stackitem.MapElement),
|
||||
opts: opts,
|
||||
index: -1,
|
||||
prefixSize: prefix,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +48,7 @@ func (s *Iterator) Next() bool {
|
|||
func (s *Iterator) Value() stackitem.Item {
|
||||
key := s.m[s.index].Key.Value().([]byte)
|
||||
if s.opts&FindRemovePrefix != 0 {
|
||||
key = key[1:]
|
||||
key = key[s.prefixSize:]
|
||||
}
|
||||
if s.opts&FindKeysOnly != 0 {
|
||||
return stackitem.NewByteArray(key)
|
||||
|
|
|
@ -59,7 +59,7 @@ func storageFind(ic *interop.Context) error {
|
|||
filteredMap.Value().([]stackitem.MapElement)[j].Key.Value().([]byte)) == -1
|
||||
})
|
||||
|
||||
item := storage.NewIterator(filteredMap, opts)
|
||||
item := storage.NewIterator(filteredMap, len(prefix), opts)
|
||||
ic.VM.Estack().PushVal(stackitem.NewInterop(item))
|
||||
|
||||
return nil
|
||||
|
|
|
@ -49,7 +49,9 @@ func TestStorageFind(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01},
|
||||
{0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08}}
|
||||
{0x04, 0x00}, {0x05, 0x00}, {0x06}, {0x07}, {0x08},
|
||||
{0x09, 0x12, 0x34}, {0x09, 0x12, 0x56},
|
||||
}
|
||||
items := []state.StorageItem{
|
||||
[]byte{0x01, 0x02, 0x03, 0x04},
|
||||
[]byte{0x04, 0x03, 0x02, 0x01},
|
||||
|
@ -59,6 +61,8 @@ func TestStorageFind(t *testing.T) {
|
|||
rawArr,
|
||||
rawArr0,
|
||||
rawArr1,
|
||||
[]byte{111},
|
||||
[]byte{222},
|
||||
}
|
||||
|
||||
require.NoError(t, chain.contracts.Management.PutContractState(chain.dao, contractState))
|
||||
|
@ -70,9 +74,9 @@ func TestStorageFind(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
testFind := func(t *testing.T, prefix byte, opts int64, expected []stackitem.Item) {
|
||||
testFind := func(t *testing.T, prefix []byte, opts int64, expected []stackitem.Item) {
|
||||
v.Estack().PushVal(opts)
|
||||
v.Estack().PushVal([]byte{prefix})
|
||||
v.Estack().PushVal(prefix)
|
||||
v.Estack().PushVal(stackitem.NewInterop(&StorageContext{ID: id}))
|
||||
|
||||
err := storageFind(context)
|
||||
|
@ -101,7 +105,7 @@ func TestStorageFind(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("normal invocation", func(t *testing.T) {
|
||||
testFind(t, 0x01, istorage.FindDefault, []stackitem.Item{
|
||||
testFind(t, []byte{0x01}, istorage.FindDefault, []stackitem.Item{
|
||||
stackitem.NewStruct([]stackitem.Item{
|
||||
stackitem.NewByteArray(skeys[2]),
|
||||
stackitem.NewByteArray(items[2]),
|
||||
|
@ -114,25 +118,29 @@ func TestStorageFind(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("keys only", func(t *testing.T) {
|
||||
testFind(t, 0x01, istorage.FindKeysOnly, []stackitem.Item{
|
||||
testFind(t, []byte{0x01}, istorage.FindKeysOnly, []stackitem.Item{
|
||||
stackitem.NewByteArray(skeys[2]),
|
||||
stackitem.NewByteArray(skeys[0]),
|
||||
})
|
||||
})
|
||||
t.Run("remove prefix", func(t *testing.T) {
|
||||
testFind(t, 0x01, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
|
||||
testFind(t, []byte{0x01}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
|
||||
stackitem.NewByteArray(skeys[2][1:]),
|
||||
stackitem.NewByteArray(skeys[0][1:]),
|
||||
})
|
||||
testFind(t, []byte{0x09, 0x12}, istorage.FindKeysOnly|istorage.FindRemovePrefix, []stackitem.Item{
|
||||
stackitem.NewByteArray(skeys[8][2:]),
|
||||
stackitem.NewByteArray(skeys[9][2:]),
|
||||
})
|
||||
})
|
||||
t.Run("values only", func(t *testing.T) {
|
||||
testFind(t, 0x01, istorage.FindValuesOnly, []stackitem.Item{
|
||||
testFind(t, []byte{0x01}, istorage.FindValuesOnly, []stackitem.Item{
|
||||
stackitem.NewByteArray(items[2]),
|
||||
stackitem.NewByteArray(items[0]),
|
||||
})
|
||||
})
|
||||
t.Run("deserialize values", func(t *testing.T) {
|
||||
testFind(t, 0x04, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{
|
||||
testFind(t, []byte{0x04}, istorage.FindValuesOnly|istorage.FindDeserialize, []stackitem.Item{
|
||||
stackitem.NewByteArray(items[3][2:]),
|
||||
})
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
|
@ -153,21 +161,21 @@ func TestStorageFind(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("PickN", func(t *testing.T) {
|
||||
testFind(t, 0x06, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize, arr[:1])
|
||||
testFind(t, 0x06, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize, arr[1:2])
|
||||
testFind(t, []byte{0x06}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize, arr[:1])
|
||||
testFind(t, []byte{0x06}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize, arr[1:2])
|
||||
// Array with 0 elements.
|
||||
testFind(t, 0x07, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
testFind(t, []byte{0x07}, istorage.FindPick0|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
[]stackitem.Item{nil})
|
||||
// Array with 1 element.
|
||||
testFind(t, 0x08, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
testFind(t, []byte{0x08}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
[]stackitem.Item{nil})
|
||||
// Not an array, but serialized ByteArray.
|
||||
testFind(t, 0x04, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
testFind(t, []byte{0x04}, istorage.FindPick1|istorage.FindValuesOnly|istorage.FindDeserialize,
|
||||
[]stackitem.Item{nil})
|
||||
})
|
||||
|
||||
t.Run("normal invocation, empty result", func(t *testing.T) {
|
||||
testFind(t, 0x03, istorage.FindDefault, nil)
|
||||
testFind(t, []byte{0x03}, istorage.FindDefault, nil)
|
||||
})
|
||||
|
||||
t.Run("invalid options", func(t *testing.T) {
|
||||
|
|
|
@ -229,7 +229,7 @@ func (n *nonfungible) tokens(ic *interop.Context, args []stackitem.Item) stackit
|
|||
return bytes.Compare(filteredMap.Value().([]stackitem.MapElement)[i].Key.Value().([]byte),
|
||||
filteredMap.Value().([]stackitem.MapElement)[j].Key.Value().([]byte)) == -1
|
||||
})
|
||||
iter := istorage.NewIterator(filteredMap, istorage.FindValuesOnly|istorage.FindDeserialize|istorage.FindPick1)
|
||||
iter := istorage.NewIterator(filteredMap, 1, istorage.FindValuesOnly|istorage.FindDeserialize|istorage.FindPick1)
|
||||
return stackitem.NewInterop(iter)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue