mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-23 13:38:35 +00:00
core: sort results of Storage.Find and NEO.getRegisterValidators
Closes #909 We need to match elements order with C# implementation.
This commit is contained in:
parent
ad74cd7273
commit
8fb67615f8
3 changed files with 38 additions and 8 deletions
|
@ -1,10 +1,11 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"sort"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
|
||||||
|
@ -422,19 +423,20 @@ func storageFind(ic *interop.Context, v *vm.VM) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
prefix := string(v.Estack().Pop().Bytes())
|
prefix := v.Estack().Pop().Bytes()
|
||||||
siMap, err := ic.DAO.GetStorageItems(stc.ScriptHash)
|
siMap, err := ic.DAO.GetStorageItemsWithPrefix(stc.ScriptHash, prefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filteredMap := vm.NewMapItem()
|
filteredMap := vm.NewMapItem()
|
||||||
for k, v := range siMap {
|
for k, v := range siMap {
|
||||||
if strings.HasPrefix(k, prefix) {
|
filteredMap.Add(vm.NewByteArrayItem(append(prefix, []byte(k)...)), vm.NewByteArrayItem(v.Value))
|
||||||
filteredMap.Add(vm.NewByteArrayItem([]byte(k)),
|
|
||||||
vm.NewByteArrayItem(v.Value))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
sort.Slice(filteredMap.Value().([]vm.MapElement), func(i, j int) bool {
|
||||||
|
return bytes.Compare(filteredMap.Value().([]vm.MapElement)[i].Key.Value().([]byte),
|
||||||
|
filteredMap.Value().([]vm.MapElement)[j].Key.Value().([]byte)) == -1
|
||||||
|
})
|
||||||
|
|
||||||
item := vm.NewMapIterator(filteredMap)
|
item := vm.NewMapIterator(filteredMap)
|
||||||
v.Estack().PushVal(item)
|
v.Estack().PushVal(item)
|
||||||
|
|
|
@ -51,7 +51,7 @@ func TestStorageFind(t *testing.T) {
|
||||||
v, contractState, context, chain := createVMAndContractState(t)
|
v, contractState, context, chain := createVMAndContractState(t)
|
||||||
defer chain.Close()
|
defer chain.Close()
|
||||||
|
|
||||||
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}}
|
skeys := [][]byte{{0x01, 0x02}, {0x02, 0x01}, {0x01, 0x01}}
|
||||||
items := []*state.StorageItem{
|
items := []*state.StorageItem{
|
||||||
{
|
{
|
||||||
Value: []byte{0x01, 0x02, 0x03, 0x04},
|
Value: []byte{0x01, 0x02, 0x03, 0x04},
|
||||||
|
@ -59,6 +59,9 @@ func TestStorageFind(t *testing.T) {
|
||||||
{
|
{
|
||||||
Value: []byte{0x04, 0x03, 0x02, 0x01},
|
Value: []byte{0x04, 0x03, 0x02, 0x01},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Value: []byte{0x03, 0x04, 0x05, 0x06},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
require.NoError(t, context.DAO.PutContractState(contractState))
|
require.NoError(t, context.DAO.PutContractState(contractState))
|
||||||
|
@ -83,6 +86,18 @@ func TestStorageFind(t *testing.T) {
|
||||||
require.NoError(t, enumerator.Next(context, v))
|
require.NoError(t, enumerator.Next(context, v))
|
||||||
require.True(t, v.Estack().Pop().Bool())
|
require.True(t, v.Estack().Pop().Bool())
|
||||||
|
|
||||||
|
v.Estack().PushVal(iter)
|
||||||
|
require.NoError(t, iterator.Key(context, v))
|
||||||
|
require.Equal(t, []byte{0x01, 0x01}, v.Estack().Pop().Bytes())
|
||||||
|
|
||||||
|
v.Estack().PushVal(iter)
|
||||||
|
require.NoError(t, enumerator.Value(context, v))
|
||||||
|
require.Equal(t, []byte{0x03, 0x04, 0x05, 0x06}, v.Estack().Pop().Bytes())
|
||||||
|
|
||||||
|
v.Estack().PushVal(iter)
|
||||||
|
require.NoError(t, enumerator.Next(context, v))
|
||||||
|
require.True(t, v.Estack().Pop().Bool())
|
||||||
|
|
||||||
v.Estack().PushVal(iter)
|
v.Estack().PushVal(iter)
|
||||||
require.NoError(t, iterator.Key(context, v))
|
require.NoError(t, iterator.Key(context, v))
|
||||||
require.Equal(t, []byte{0x01, 0x02}, v.Estack().Pop().Bytes())
|
require.Equal(t, []byte{0x01, 0x02}, v.Estack().Pop().Bytes())
|
||||||
|
@ -96,6 +111,17 @@ func TestStorageFind(t *testing.T) {
|
||||||
require.False(t, v.Estack().Pop().Bool())
|
require.False(t, v.Estack().Pop().Bool())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("normal invocation, empty result", func(t *testing.T) {
|
||||||
|
v.Estack().PushVal([]byte{0x03})
|
||||||
|
v.Estack().PushVal(vm.NewInteropItem(&StorageContext{ScriptHash: scriptHash}))
|
||||||
|
|
||||||
|
err := storageFind(context, v)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NoError(t, enumerator.Next(context, v))
|
||||||
|
require.False(t, v.Estack().Pop().Bool())
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("invalid type for StorageContext", func(t *testing.T) {
|
t.Run("invalid type for StorageContext", func(t *testing.T) {
|
||||||
v.Estack().PushVal([]byte{0x01})
|
v.Estack().PushVal([]byte{0x01})
|
||||||
v.Estack().PushVal(vm.NewInteropItem(nil))
|
v.Estack().PushVal(vm.NewInteropItem(nil))
|
||||||
|
|
|
@ -3,6 +3,7 @@ package native
|
||||||
import (
|
import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
"github.com/nspcc-dev/neo-go/pkg/core/blockchainer"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
|
@ -344,6 +345,7 @@ func (n *NEO) getRegisteredValidators(d dao.DAO) ([]keyWithVotes, error) {
|
||||||
}
|
}
|
||||||
arr = append(arr, keyWithVotes{key, &votes.Balance})
|
arr = append(arr, keyWithVotes{key, &votes.Balance})
|
||||||
}
|
}
|
||||||
|
sort.Slice(arr, func(i, j int) bool { return strings.Compare(arr[i].Key, arr[j].Key) == -1 })
|
||||||
return arr, nil
|
return arr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue