Merge pull request #2075 from nspcc-dev/small-refactoring

Array util refactoring and naming improvement
This commit is contained in:
Roman Khimov 2021-07-20 11:29:59 +03:00 committed by GitHub
commit c88ebaede9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 127 additions and 129 deletions

View file

@ -15,6 +15,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// HasTransaction errors.
@ -317,11 +318,9 @@ func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[strin
saveToMap := func(k, v []byte) {
// Cut prefix and hash.
// Must copy here, #1468.
key := make([]byte, len(k))
copy(key, k)
si := make(state.StorageItem, len(v))
copy(si, v)
siMap[string(key)] = si
key := slice.Copy(k)
val := slice.Copy(v)
siMap[string(key)] = state.StorageItem(val)
}
dao.Seek(id, prefix, saveToMap)
return siMap, nil

View file

@ -31,13 +31,6 @@ func lcpMany(kv []keyValue) []byte {
return p
}
// copySlice is a helper for copying slice if needed.
func copySlice(a []byte) []byte {
b := make([]byte, len(a))
copy(b, a)
return b
}
// toNibbles mangles path by splitting every byte into 2 containing low- and high- 4-byte part.
func toNibbles(path []byte) []byte {
result := make([]byte, len(path)*2)

View file

@ -6,6 +6,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// GetProof returns a proof that key belongs to t.
@ -25,11 +26,11 @@ func (t *Trie) getProof(curr Node, path []byte, proofs *[][]byte) (Node, error)
switch n := curr.(type) {
case *LeafNode:
if len(path) == 0 {
*proofs = append(*proofs, copySlice(n.Bytes()))
*proofs = append(*proofs, slice.Copy(n.Bytes()))
return n, nil
}
case *BranchNode:
*proofs = append(*proofs, copySlice(n.Bytes()))
*proofs = append(*proofs, slice.Copy(n.Bytes()))
i, path := splitPath(path)
r, err := t.getProof(n.Children[i], path, proofs)
if err != nil {
@ -39,7 +40,7 @@ func (t *Trie) getProof(curr Node, path []byte, proofs *[][]byte) (Node, error)
return n, nil
case *ExtensionNode:
if bytes.HasPrefix(path, n.key) {
*proofs = append(*proofs, copySlice(n.Bytes()))
*proofs = append(*proofs, slice.Copy(n.Bytes()))
r, err := t.getProof(n.next, path[len(n.key):], proofs)
if err != nil {
return nil, err

View file

@ -9,6 +9,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/core/storage"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// Trie is an MPT trie storing all key-value pairs.
@ -64,7 +65,7 @@ func (t *Trie) getWithPath(curr Node, path []byte) (Node, []byte, error) {
switch n := curr.(type) {
case *LeafNode:
if len(path) == 0 {
return curr, copySlice(n.value), nil
return curr, slice.Copy(n.value), nil
}
case *BranchNode:
i, path := splitPath(path)
@ -179,7 +180,7 @@ func (t *Trie) putIntoExtension(curr *ExtensionNode, path []byte, val Node) (Nod
t.addRef(b.Hash(), b.bytes)
if lp > 0 {
e := NewExtensionNode(copySlice(pref), b)
e := NewExtensionNode(slice.Copy(pref), b)
t.addRef(e.Hash(), e.bytes)
return e, nil
}

View file

@ -53,7 +53,7 @@ func newGAS() *GAS {
}
func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.StorageItem, amount *big.Int) error {
acc, err := state.NEP17BalanceStateFromBytes(*si)
acc, err := state.NEP17BalanceFromBytes(*si)
if err != nil {
return err
}
@ -72,7 +72,7 @@ func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.Stor
}
func (g *GAS) balanceFromBytes(si *state.StorageItem) (*big.Int, error) {
acc, err := state.NEP17BalanceStateFromBytes(*si)
acc, err := state.NEP17BalanceFromBytes(*si)
if err != nil {
return nil, err
}

View file

@ -392,7 +392,7 @@ func (n *NEO) getGASPerVote(d dao.DAO, key []byte, index ...uint32) []big.Int {
}
func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.StorageItem, amount *big.Int) error {
acc, err := state.NEOBalanceStateFromBytes(*si)
acc, err := state.NEOBalanceFromBytes(*si)
if err != nil {
return err
}
@ -424,14 +424,14 @@ func (n *NEO) increaseBalance(ic *interop.Context, h util.Uint160, si *state.Sto
}
func (n *NEO) balanceFromBytes(si *state.StorageItem) (*big.Int, error) {
acc, err := state.NEOBalanceStateFromBytes(*si)
acc, err := state.NEOBalanceFromBytes(*si)
if err != nil {
return nil, err
}
return &acc.Balance, err
}
func (n *NEO) distributeGas(ic *interop.Context, h util.Uint160, acc *state.NEOBalanceState) error {
func (n *NEO) distributeGas(ic *interop.Context, h util.Uint160, acc *state.NEOBalance) error {
if ic.Block == nil || ic.Block.Index == 0 {
return nil
}
@ -609,7 +609,7 @@ func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int,
if si == nil {
return nil, storage.ErrKeyNotFound
}
st, err := state.NEOBalanceStateFromBytes(si)
st, err := state.NEOBalanceFromBytes(si)
if err != nil {
return nil, err
}
@ -752,7 +752,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
if si == nil {
return errors.New("invalid account")
}
acc, err := state.NEOBalanceStateFromBytes(si)
acc, err := state.NEOBalanceFromBytes(si)
if err != nil {
return err
}
@ -802,7 +802,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
// ModifyAccountVotes modifies votes of the specified account by value (can be negative).
// typ specifies if this modify is occurring during transfer or vote (with old or new validator).
func (n *NEO) ModifyAccountVotes(acc *state.NEOBalanceState, d dao.DAO, value *big.Int, isNewVote bool) error {
func (n *NEO) ModifyAccountVotes(acc *state.NEOBalance, d dao.DAO, value *big.Int, isNewVote bool) error {
n.votesChanged.Store(true)
if acc.VoteTo != nil {
key := makeValidatorKey(acc.VoteTo)

View file

@ -27,6 +27,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
@ -135,9 +136,7 @@ func newOracle() *Oracle {
// GetOracleResponseScript returns script for transaction with oracle response.
func (o *Oracle) GetOracleResponseScript() []byte {
b := make([]byte, len(o.oracleScript))
copy(b, o.oracleScript)
return b
return slice.Copy(o.oracleScript)
}
// OnPersist implements Contract interface.

View file

@ -16,6 +16,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
@ -232,7 +233,7 @@ func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
break
}
bs := bigint.ToBytes(num)
reverse(bs)
slice.Reverse(bs)
str = hex.EncodeToString(bs)
if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 {
str = str[1:]
@ -280,7 +281,7 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
if changed && bs[0]&0x8 != 0 {
bs[0] |= 0xF0
}
reverse(bs)
slice.Reverse(bs)
bi = bigint.FromBytes(bs)
default:
panic(ErrInvalidBase)
@ -289,13 +290,6 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
return stackitem.NewBigInteger(bi)
}
func reverse(b []byte) {
l := len(b)
for i := 0; i < l/2; i++ {
b[i], b[l-i-1] = b[l-i-1], b[i]
}
}
func (s *Std) base64Encode(_ *interop.Context, args []stackitem.Item) stackitem.Item {
src := s.toLimitedBytes(args[0])
result := base64.StdEncoding.EncodeToString(src)

View file

@ -10,21 +10,21 @@ import (
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// NEP17BalanceState represents balance state of a NEP17-token.
type NEP17BalanceState struct {
// NEP17Balance represents balance state of a NEP17-token.
type NEP17Balance struct {
Balance big.Int
}
// NEOBalanceState represents balance state of a NEO-token.
type NEOBalanceState struct {
NEP17BalanceState
// NEOBalance represents balance state of a NEO-token.
type NEOBalance struct {
NEP17Balance
BalanceHeight uint32
VoteTo *keys.PublicKey
}
// NEP17BalanceStateFromBytes converts serialized NEP17BalanceState to structure.
func NEP17BalanceStateFromBytes(b []byte) (*NEP17BalanceState, error) {
balance := new(NEP17BalanceState)
// NEP17BalanceFromBytes converts serialized NEP17Balance to structure.
func NEP17BalanceFromBytes(b []byte) (*NEP17Balance, error) {
balance := new(NEP17Balance)
err := balanceFromBytes(b, balance)
if err != nil {
return nil, err
@ -32,8 +32,8 @@ func NEP17BalanceStateFromBytes(b []byte) (*NEP17BalanceState, error) {
return balance, nil
}
// Bytes returns serialized NEP17BalanceState.
func (s *NEP17BalanceState) Bytes() []byte {
// Bytes returns serialized NEP17Balance.
func (s *NEP17Balance) Bytes() []byte {
return balanceToBytes(s)
}
@ -53,12 +53,12 @@ func balanceToBytes(item stackitem.Convertible) []byte {
}
// ToStackItem implements stackitem.Convertible. It never returns an error.
func (s *NEP17BalanceState) ToStackItem() (stackitem.Item, error) {
func (s *NEP17Balance) ToStackItem() (stackitem.Item, error) {
return stackitem.NewStruct([]stackitem.Item{stackitem.NewBigInteger(&s.Balance)}), nil
}
// FromStackItem implements stackitem.Convertible.
func (s *NEP17BalanceState) FromStackItem(item stackitem.Item) error {
func (s *NEP17Balance) FromStackItem(item stackitem.Item) error {
items, ok := item.Value().([]stackitem.Item)
if !ok {
return errors.New("not a struct")
@ -74,9 +74,9 @@ func (s *NEP17BalanceState) FromStackItem(item stackitem.Item) error {
return nil
}
// NEOBalanceStateFromBytes converts serialized NEOBalanceState to structure.
func NEOBalanceStateFromBytes(b []byte) (*NEOBalanceState, error) {
balance := new(NEOBalanceState)
// NEOBalanceFromBytes converts serialized NEOBalance to structure.
func NEOBalanceFromBytes(b []byte) (*NEOBalance, error) {
balance := new(NEOBalance)
err := balanceFromBytes(b, balance)
if err != nil {
return nil, err
@ -84,14 +84,14 @@ func NEOBalanceStateFromBytes(b []byte) (*NEOBalanceState, error) {
return balance, nil
}
// Bytes returns serialized NEOBalanceState.
func (s *NEOBalanceState) Bytes() []byte {
// Bytes returns serialized NEOBalance.
func (s *NEOBalance) Bytes() []byte {
return balanceToBytes(s)
}
// ToStackItem implements stackitem.Convertible interface. It never returns an error.
func (s *NEOBalanceState) ToStackItem() (stackitem.Item, error) {
resItem, _ := s.NEP17BalanceState.ToStackItem()
func (s *NEOBalance) ToStackItem() (stackitem.Item, error) {
resItem, _ := s.NEP17Balance.ToStackItem()
result := resItem.(*stackitem.Struct)
result.Append(stackitem.NewBigInteger(big.NewInt(int64(s.BalanceHeight))))
if s.VoteTo != nil {
@ -102,8 +102,8 @@ func (s *NEOBalanceState) ToStackItem() (stackitem.Item, error) {
return result, nil
}
// FromStackItem converts stackitem.Item to NEOBalanceState.
func (s *NEOBalanceState) FromStackItem(item stackitem.Item) error {
// FromStackItem converts stackitem.Item to NEOBalance.
func (s *NEOBalance) FromStackItem(item stackitem.Item) error {
structItem, ok := item.Value().([]stackitem.Item)
if !ok || len(structItem) < 3 {
return errors.New("invalid stackitem length")

View file

@ -4,6 +4,7 @@ import (
"os"
"github.com/dgraph-io/badger/v2"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// BadgerDBOptions configuration for BadgerDB.
@ -32,10 +33,8 @@ func (b *BadgerDBBatch) Delete(key []byte) {
// Put implements the Batch interface.
func (b *BadgerDBBatch) Put(key, value []byte) {
keycopy := make([]byte, len(key))
copy(keycopy, key)
valuecopy := make([]byte, len(value))
copy(valuecopy, value)
keycopy := slice.Copy(key)
valuecopy := slice.Copy(value)
err := b.batch.Set(keycopy, valuecopy)
if err != nil {
panic(err)

View file

@ -6,6 +6,7 @@ import (
"os"
"github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/syndtr/goleveldb/leveldb/util"
"go.etcd.io/bbolt"
)
@ -63,9 +64,7 @@ func (s *BoltDBStore) Get(key []byte) (val []byte, err error) {
val = b.Get(key)
// Value from Get is only valid for the lifetime of transaction, #1482
if val != nil {
var valcopy = make([]byte, len(val))
copy(valcopy, val)
val = valcopy
val = slice.Copy(val)
}
return nil
})

View file

@ -3,6 +3,8 @@ package storage
import (
"strings"
"sync"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// MemoryStore is an in-memory implementation of a Store, mainly
@ -57,8 +59,7 @@ func (s *MemoryStore) put(key string, value []byte) {
// Put implements the Store interface. Never returns an error.
func (s *MemoryStore) Put(key, value []byte) error {
newKey := string(key)
vcopy := make([]byte, len(value))
copy(vcopy, value)
vcopy := slice.Copy(value)
s.mut.Lock()
s.put(newKey, vcopy)
s.mut.Unlock()

View file

@ -5,6 +5,7 @@ import (
"runtime"
"testing"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -55,10 +56,8 @@ func testStorePutBatch(t *testing.T, s Store) {
batch = s.Batch()
)
// Test that key and value are copied when batching.
keycopy := make([]byte, len(key))
copy(keycopy, key)
valuecopy := make([]byte, len(value))
copy(valuecopy, value)
keycopy := slice.Copy(key)
valuecopy := slice.Copy(value)
batch.Put(keycopy, valuecopy)
copy(valuecopy, key)