Merge pull request #2075 from nspcc-dev/small-refactoring
Array util refactoring and naming improvement
This commit is contained in:
commit
c88ebaede9
26 changed files with 127 additions and 129 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,32 +36,27 @@ func TestParseMultisigContract(t *testing.T) {
|
||||||
testParseMultisigContract(t, s, 1, pub)
|
testParseMultisigContract(t, s, 1, pub)
|
||||||
})
|
})
|
||||||
t.Run("bad, no check multisig", func(t *testing.T) {
|
t.Run("bad, no check multisig", func(t *testing.T) {
|
||||||
sBad := make([]byte, len(s))
|
sBad := slice.Copy(s)
|
||||||
copy(sBad, s)
|
|
||||||
sBad[len(sBad)-1] ^= 0xFF
|
sBad[len(sBad)-1] ^= 0xFF
|
||||||
testParseMultisigContract(t, sBad, 0)
|
testParseMultisigContract(t, sBad, 0)
|
||||||
})
|
})
|
||||||
t.Run("bad, invalid number of keys", func(t *testing.T) {
|
t.Run("bad, invalid number of keys", func(t *testing.T) {
|
||||||
sBad := make([]byte, len(s))
|
sBad := slice.Copy(s)
|
||||||
copy(sBad, s)
|
|
||||||
sBad[len(sBad)-2] = opPush1 + 1
|
sBad[len(sBad)-2] = opPush1 + 1
|
||||||
testParseMultisigContract(t, sBad, 0)
|
testParseMultisigContract(t, sBad, 0)
|
||||||
})
|
})
|
||||||
t.Run("bad, invalid first instruction", func(t *testing.T) {
|
t.Run("bad, invalid first instruction", func(t *testing.T) {
|
||||||
sBad := make([]byte, len(s))
|
sBad := slice.Copy(s)
|
||||||
copy(sBad, s)
|
|
||||||
sBad[0] = 0xFF
|
sBad[0] = 0xFF
|
||||||
testParseMultisigContract(t, sBad, 0)
|
testParseMultisigContract(t, sBad, 0)
|
||||||
})
|
})
|
||||||
t.Run("bad, invalid public key", func(t *testing.T) {
|
t.Run("bad, invalid public key", func(t *testing.T) {
|
||||||
sBad := make([]byte, len(s))
|
sBad := slice.Copy(s)
|
||||||
copy(sBad, s)
|
|
||||||
sBad[2] = 0xFF
|
sBad[2] = 0xFF
|
||||||
testParseMultisigContract(t, sBad, 0)
|
testParseMultisigContract(t, sBad, 0)
|
||||||
})
|
})
|
||||||
t.Run("bad, many sigs", func(t *testing.T) {
|
t.Run("bad, many sigs", func(t *testing.T) {
|
||||||
sBad := make([]byte, len(s))
|
sBad := slice.Copy(s)
|
||||||
copy(sBad, s)
|
|
||||||
sBad[0] = opPush1 + 1
|
sBad[0] = opPush1 + 1
|
||||||
testParseMultisigContract(t, sBad, 0)
|
testParseMultisigContract(t, sBad, 0)
|
||||||
})
|
})
|
||||||
|
|
|
@ -252,7 +252,7 @@ func getAccountState(ctx *cli.Context) error {
|
||||||
if len(res.Stack) == 0 {
|
if len(res.Stack) == 0 {
|
||||||
return cli.NewExitError("result stack is empty", 1)
|
return cli.NewExitError("result stack is empty", 1)
|
||||||
}
|
}
|
||||||
st := new(state.NEOBalanceState)
|
st := new(state.NEOBalance)
|
||||||
err = st.FromStackItem(res.Stack[0])
|
err = st.FromStackItem(res.Stack[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli.NewExitError(fmt.Errorf("failed to convert account state from stackitem: %w", err), 1)
|
return cli.NewExitError(fmt.Errorf("failed to convert account state from stackitem: %w", err), 1)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"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"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HasTransaction errors.
|
// HasTransaction errors.
|
||||||
|
@ -317,11 +318,9 @@ func (dao *Simple) GetStorageItemsWithPrefix(id int32, prefix []byte) (map[strin
|
||||||
saveToMap := func(k, v []byte) {
|
saveToMap := func(k, v []byte) {
|
||||||
// Cut prefix and hash.
|
// Cut prefix and hash.
|
||||||
// Must copy here, #1468.
|
// Must copy here, #1468.
|
||||||
key := make([]byte, len(k))
|
key := slice.Copy(k)
|
||||||
copy(key, k)
|
val := slice.Copy(v)
|
||||||
si := make(state.StorageItem, len(v))
|
siMap[string(key)] = state.StorageItem(val)
|
||||||
copy(si, v)
|
|
||||||
siMap[string(key)] = si
|
|
||||||
}
|
}
|
||||||
dao.Seek(id, prefix, saveToMap)
|
dao.Seek(id, prefix, saveToMap)
|
||||||
return siMap, nil
|
return siMap, nil
|
||||||
|
|
|
@ -31,13 +31,6 @@ func lcpMany(kv []keyValue) []byte {
|
||||||
return p
|
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.
|
// toNibbles mangles path by splitting every byte into 2 containing low- and high- 4-byte part.
|
||||||
func toNibbles(path []byte) []byte {
|
func toNibbles(path []byte) []byte {
|
||||||
result := make([]byte, len(path)*2)
|
result := make([]byte, len(path)*2)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"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/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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.
|
// 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) {
|
switch n := curr.(type) {
|
||||||
case *LeafNode:
|
case *LeafNode:
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
*proofs = append(*proofs, copySlice(n.Bytes()))
|
*proofs = append(*proofs, slice.Copy(n.Bytes()))
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
case *BranchNode:
|
case *BranchNode:
|
||||||
*proofs = append(*proofs, copySlice(n.Bytes()))
|
*proofs = append(*proofs, slice.Copy(n.Bytes()))
|
||||||
i, path := splitPath(path)
|
i, path := splitPath(path)
|
||||||
r, err := t.getProof(n.Children[i], path, proofs)
|
r, err := t.getProof(n.Children[i], path, proofs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -39,7 +40,7 @@ func (t *Trie) getProof(curr Node, path []byte, proofs *[][]byte) (Node, error)
|
||||||
return n, nil
|
return n, nil
|
||||||
case *ExtensionNode:
|
case *ExtensionNode:
|
||||||
if bytes.HasPrefix(path, n.key) {
|
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)
|
r, err := t.getProof(n.next, path[len(n.key):], proofs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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.
|
// 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) {
|
switch n := curr.(type) {
|
||||||
case *LeafNode:
|
case *LeafNode:
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return curr, copySlice(n.value), nil
|
return curr, slice.Copy(n.value), nil
|
||||||
}
|
}
|
||||||
case *BranchNode:
|
case *BranchNode:
|
||||||
i, path := splitPath(path)
|
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)
|
t.addRef(b.Hash(), b.bytes)
|
||||||
if lp > 0 {
|
if lp > 0 {
|
||||||
e := NewExtensionNode(copySlice(pref), b)
|
e := NewExtensionNode(slice.Copy(pref), b)
|
||||||
t.addRef(e.Hash(), e.bytes)
|
t.addRef(e.Hash(), e.bytes)
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func newGAS() *GAS {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GAS) increaseBalance(_ *interop.Context, _ util.Uint160, si *state.StorageItem, amount *big.Int) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
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) {
|
func (g *GAS) balanceFromBytes(si *state.StorageItem) (*big.Int, error) {
|
||||||
acc, err := state.NEP17BalanceStateFromBytes(*si)
|
acc, err := state.NEP17BalanceFromBytes(*si)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
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 {
|
if err != nil {
|
||||||
return err
|
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) {
|
func (n *NEO) balanceFromBytes(si *state.StorageItem) (*big.Int, error) {
|
||||||
acc, err := state.NEOBalanceStateFromBytes(*si)
|
acc, err := state.NEOBalanceFromBytes(*si)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &acc.Balance, 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 {
|
if ic.Block == nil || ic.Block.Index == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ func (n *NEO) CalculateBonus(d dao.DAO, acc util.Uint160, end uint32) (*big.Int,
|
||||||
if si == nil {
|
if si == nil {
|
||||||
return nil, storage.ErrKeyNotFound
|
return nil, storage.ErrKeyNotFound
|
||||||
}
|
}
|
||||||
st, err := state.NEOBalanceStateFromBytes(si)
|
st, err := state.NEOBalanceFromBytes(si)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -752,7 +752,7 @@ func (n *NEO) VoteInternal(ic *interop.Context, h util.Uint160, pub *keys.Public
|
||||||
if si == nil {
|
if si == nil {
|
||||||
return errors.New("invalid account")
|
return errors.New("invalid account")
|
||||||
}
|
}
|
||||||
acc, err := state.NEOBalanceStateFromBytes(si)
|
acc, err := state.NEOBalanceFromBytes(si)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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).
|
// 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).
|
// 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)
|
n.votesChanged.Store(true)
|
||||||
if acc.VoteTo != nil {
|
if acc.VoteTo != nil {
|
||||||
key := makeValidatorKey(acc.VoteTo)
|
key := makeValidatorKey(acc.VoteTo)
|
||||||
|
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"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/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -135,9 +136,7 @@ func newOracle() *Oracle {
|
||||||
|
|
||||||
// GetOracleResponseScript returns script for transaction with oracle response.
|
// GetOracleResponseScript returns script for transaction with oracle response.
|
||||||
func (o *Oracle) GetOracleResponseScript() []byte {
|
func (o *Oracle) GetOracleResponseScript() []byte {
|
||||||
b := make([]byte, len(o.oracleScript))
|
return slice.Copy(o.oracleScript)
|
||||||
copy(b, o.oracleScript)
|
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnPersist implements Contract interface.
|
// OnPersist implements Contract interface.
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
"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/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"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"
|
"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
|
break
|
||||||
}
|
}
|
||||||
bs := bigint.ToBytes(num)
|
bs := bigint.ToBytes(num)
|
||||||
reverse(bs)
|
slice.Reverse(bs)
|
||||||
str = hex.EncodeToString(bs)
|
str = hex.EncodeToString(bs)
|
||||||
if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 {
|
if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 {
|
||||||
str = str[1:]
|
str = str[1:]
|
||||||
|
@ -280,7 +281,7 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
if changed && bs[0]&0x8 != 0 {
|
if changed && bs[0]&0x8 != 0 {
|
||||||
bs[0] |= 0xF0
|
bs[0] |= 0xF0
|
||||||
}
|
}
|
||||||
reverse(bs)
|
slice.Reverse(bs)
|
||||||
bi = bigint.FromBytes(bs)
|
bi = bigint.FromBytes(bs)
|
||||||
default:
|
default:
|
||||||
panic(ErrInvalidBase)
|
panic(ErrInvalidBase)
|
||||||
|
@ -289,13 +290,6 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
return stackitem.NewBigInteger(bi)
|
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 {
|
func (s *Std) base64Encode(_ *interop.Context, args []stackitem.Item) stackitem.Item {
|
||||||
src := s.toLimitedBytes(args[0])
|
src := s.toLimitedBytes(args[0])
|
||||||
result := base64.StdEncoding.EncodeToString(src)
|
result := base64.StdEncoding.EncodeToString(src)
|
||||||
|
|
|
@ -10,21 +10,21 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NEP17BalanceState represents balance state of a NEP17-token.
|
// NEP17Balance represents balance state of a NEP17-token.
|
||||||
type NEP17BalanceState struct {
|
type NEP17Balance struct {
|
||||||
Balance big.Int
|
Balance big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEOBalanceState represents balance state of a NEO-token.
|
// NEOBalance represents balance state of a NEO-token.
|
||||||
type NEOBalanceState struct {
|
type NEOBalance struct {
|
||||||
NEP17BalanceState
|
NEP17Balance
|
||||||
BalanceHeight uint32
|
BalanceHeight uint32
|
||||||
VoteTo *keys.PublicKey
|
VoteTo *keys.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEP17BalanceStateFromBytes converts serialized NEP17BalanceState to structure.
|
// NEP17BalanceFromBytes converts serialized NEP17Balance to structure.
|
||||||
func NEP17BalanceStateFromBytes(b []byte) (*NEP17BalanceState, error) {
|
func NEP17BalanceFromBytes(b []byte) (*NEP17Balance, error) {
|
||||||
balance := new(NEP17BalanceState)
|
balance := new(NEP17Balance)
|
||||||
err := balanceFromBytes(b, balance)
|
err := balanceFromBytes(b, balance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -32,8 +32,8 @@ func NEP17BalanceStateFromBytes(b []byte) (*NEP17BalanceState, error) {
|
||||||
return balance, nil
|
return balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns serialized NEP17BalanceState.
|
// Bytes returns serialized NEP17Balance.
|
||||||
func (s *NEP17BalanceState) Bytes() []byte {
|
func (s *NEP17Balance) Bytes() []byte {
|
||||||
return balanceToBytes(s)
|
return balanceToBytes(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,12 @@ func balanceToBytes(item stackitem.Convertible) []byte {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToStackItem implements stackitem.Convertible. It never returns an error.
|
// 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
|
return stackitem.NewStruct([]stackitem.Item{stackitem.NewBigInteger(&s.Balance)}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromStackItem implements stackitem.Convertible.
|
// 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)
|
items, ok := item.Value().([]stackitem.Item)
|
||||||
if !ok {
|
if !ok {
|
||||||
return errors.New("not a struct")
|
return errors.New("not a struct")
|
||||||
|
@ -74,9 +74,9 @@ func (s *NEP17BalanceState) FromStackItem(item stackitem.Item) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEOBalanceStateFromBytes converts serialized NEOBalanceState to structure.
|
// NEOBalanceFromBytes converts serialized NEOBalance to structure.
|
||||||
func NEOBalanceStateFromBytes(b []byte) (*NEOBalanceState, error) {
|
func NEOBalanceFromBytes(b []byte) (*NEOBalance, error) {
|
||||||
balance := new(NEOBalanceState)
|
balance := new(NEOBalance)
|
||||||
err := balanceFromBytes(b, balance)
|
err := balanceFromBytes(b, balance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -84,14 +84,14 @@ func NEOBalanceStateFromBytes(b []byte) (*NEOBalanceState, error) {
|
||||||
return balance, nil
|
return balance, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns serialized NEOBalanceState.
|
// Bytes returns serialized NEOBalance.
|
||||||
func (s *NEOBalanceState) Bytes() []byte {
|
func (s *NEOBalance) Bytes() []byte {
|
||||||
return balanceToBytes(s)
|
return balanceToBytes(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToStackItem implements stackitem.Convertible interface. It never returns an error.
|
// ToStackItem implements stackitem.Convertible interface. It never returns an error.
|
||||||
func (s *NEOBalanceState) ToStackItem() (stackitem.Item, error) {
|
func (s *NEOBalance) ToStackItem() (stackitem.Item, error) {
|
||||||
resItem, _ := s.NEP17BalanceState.ToStackItem()
|
resItem, _ := s.NEP17Balance.ToStackItem()
|
||||||
result := resItem.(*stackitem.Struct)
|
result := resItem.(*stackitem.Struct)
|
||||||
result.Append(stackitem.NewBigInteger(big.NewInt(int64(s.BalanceHeight))))
|
result.Append(stackitem.NewBigInteger(big.NewInt(int64(s.BalanceHeight))))
|
||||||
if s.VoteTo != nil {
|
if s.VoteTo != nil {
|
||||||
|
@ -102,8 +102,8 @@ func (s *NEOBalanceState) ToStackItem() (stackitem.Item, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromStackItem converts stackitem.Item to NEOBalanceState.
|
// FromStackItem converts stackitem.Item to NEOBalance.
|
||||||
func (s *NEOBalanceState) FromStackItem(item stackitem.Item) error {
|
func (s *NEOBalance) FromStackItem(item stackitem.Item) error {
|
||||||
structItem, ok := item.Value().([]stackitem.Item)
|
structItem, ok := item.Value().([]stackitem.Item)
|
||||||
if !ok || len(structItem) < 3 {
|
if !ok || len(structItem) < 3 {
|
||||||
return errors.New("invalid stackitem length")
|
return errors.New("invalid stackitem length")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/dgraph-io/badger/v2"
|
"github.com/dgraph-io/badger/v2"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BadgerDBOptions configuration for BadgerDB.
|
// BadgerDBOptions configuration for BadgerDB.
|
||||||
|
@ -32,10 +33,8 @@ func (b *BadgerDBBatch) Delete(key []byte) {
|
||||||
|
|
||||||
// Put implements the Batch interface.
|
// Put implements the Batch interface.
|
||||||
func (b *BadgerDBBatch) Put(key, value []byte) {
|
func (b *BadgerDBBatch) Put(key, value []byte) {
|
||||||
keycopy := make([]byte, len(key))
|
keycopy := slice.Copy(key)
|
||||||
copy(keycopy, key)
|
valuecopy := slice.Copy(value)
|
||||||
valuecopy := make([]byte, len(value))
|
|
||||||
copy(valuecopy, value)
|
|
||||||
err := b.batch.Set(keycopy, valuecopy)
|
err := b.batch.Set(keycopy, valuecopy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -63,9 +64,7 @@ func (s *BoltDBStore) Get(key []byte) (val []byte, err error) {
|
||||||
val = b.Get(key)
|
val = b.Get(key)
|
||||||
// Value from Get is only valid for the lifetime of transaction, #1482
|
// Value from Get is only valid for the lifetime of transaction, #1482
|
||||||
if val != nil {
|
if val != nil {
|
||||||
var valcopy = make([]byte, len(val))
|
val = slice.Copy(val)
|
||||||
copy(valcopy, val)
|
|
||||||
val = valcopy
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,6 +3,8 @@ package storage
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MemoryStore is an in-memory implementation of a Store, mainly
|
// 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.
|
// Put implements the Store interface. Never returns an error.
|
||||||
func (s *MemoryStore) Put(key, value []byte) error {
|
func (s *MemoryStore) Put(key, value []byte) error {
|
||||||
newKey := string(key)
|
newKey := string(key)
|
||||||
vcopy := make([]byte, len(value))
|
vcopy := slice.Copy(value)
|
||||||
copy(vcopy, value)
|
|
||||||
s.mut.Lock()
|
s.mut.Lock()
|
||||||
s.put(newKey, vcopy)
|
s.put(newKey, vcopy)
|
||||||
s.mut.Unlock()
|
s.mut.Unlock()
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -55,10 +56,8 @@ func testStorePutBatch(t *testing.T, s Store) {
|
||||||
batch = s.Batch()
|
batch = s.Batch()
|
||||||
)
|
)
|
||||||
// Test that key and value are copied when batching.
|
// Test that key and value are copied when batching.
|
||||||
keycopy := make([]byte, len(key))
|
keycopy := slice.Copy(key)
|
||||||
copy(keycopy, key)
|
valuecopy := slice.Copy(value)
|
||||||
valuecopy := make([]byte, len(value))
|
|
||||||
copy(valuecopy, value)
|
|
||||||
|
|
||||||
batch.Put(keycopy, valuecopy)
|
batch.Put(keycopy, valuecopy)
|
||||||
copy(valuecopy, key)
|
copy(valuecopy, key)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -17,7 +17,7 @@ const (
|
||||||
|
|
||||||
// FromBytesUnsigned converts data in little-endian format to an unsigned integer.
|
// FromBytesUnsigned converts data in little-endian format to an unsigned integer.
|
||||||
func FromBytesUnsigned(data []byte) *big.Int {
|
func FromBytesUnsigned(data []byte) *big.Int {
|
||||||
bs := util.ArrayReverse(data)
|
bs := slice.CopyReverse(data)
|
||||||
return new(big.Int).SetBytes(bs)
|
return new(big.Int).SetBytes(bs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -204,7 +204,7 @@ func TestVeryBigInts(t *testing.T) {
|
||||||
num, ok := new(big.Int).SetString(tc.numStr, 10)
|
num, ok := new(big.Int).SetString(tc.numStr, 10)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
result := FromBytes(util.ArrayReverse(tc.buf))
|
result := FromBytes(slice.CopyReverse(tc.buf))
|
||||||
assert.Equal(t, num, result, "error while converting %s from bytes", tc.numStr)
|
assert.Equal(t, num, result, "error while converting %s from bytes", tc.numStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -228,11 +229,8 @@ func (o *Oracle) Run() {
|
||||||
|
|
||||||
// UpdateNativeContract updates native oracle contract info for tx verification.
|
// UpdateNativeContract updates native oracle contract info for tx verification.
|
||||||
func (o *Oracle) UpdateNativeContract(script, resp []byte, h util.Uint160, verifyOffset int) {
|
func (o *Oracle) UpdateNativeContract(script, resp []byte, h util.Uint160, verifyOffset int) {
|
||||||
o.oracleScript = make([]byte, len(script))
|
o.oracleScript = slice.Copy(script)
|
||||||
copy(o.oracleScript, script)
|
o.oracleResponse = slice.Copy(resp)
|
||||||
|
|
||||||
o.oracleResponse = make([]byte, len(resp))
|
|
||||||
copy(o.oracleResponse, resp)
|
|
||||||
|
|
||||||
o.oracleHash = h
|
o.oracleHash = h
|
||||||
o.verifyOffset = verifyOffset
|
o.verifyOffset = verifyOffset
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package util
|
|
||||||
|
|
||||||
// ArrayReverse returns a reversed version of the given byte slice.
|
|
||||||
func ArrayReverse(b []byte) []byte {
|
|
||||||
dest := make([]byte, len(b))
|
|
||||||
for i, j := 0, len(b)-1; i <= j; i, j = i+1, j-1 {
|
|
||||||
dest[i], dest[j] = b[j], b[i]
|
|
||||||
}
|
|
||||||
return dest
|
|
||||||
}
|
|
30
pkg/util/slice/array.go
Normal file
30
pkg/util/slice/array.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Package slice contains byte slice helpers.
|
||||||
|
*/
|
||||||
|
package slice
|
||||||
|
|
||||||
|
// CopyReverse returns a new byte slice containing reversed version of the
|
||||||
|
// original.
|
||||||
|
func CopyReverse(b []byte) []byte {
|
||||||
|
dest := make([]byte, len(b))
|
||||||
|
reverse(dest, b)
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reverse does in-place reversing of byte slice.
|
||||||
|
func Reverse(b []byte) {
|
||||||
|
reverse(b, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func reverse(dst []byte, src []byte) {
|
||||||
|
for i, j := 0, len(src)-1; i <= j; i, j = i+1, j-1 {
|
||||||
|
dst[i], dst[j] = src[j], src[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy copies the byte slice into new slice (make/copy).
|
||||||
|
func Copy(b []byte) []byte {
|
||||||
|
d := make([]byte, len(b))
|
||||||
|
copy(d, b)
|
||||||
|
return d
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package util
|
package slice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -28,12 +28,12 @@ var testCases = []struct {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArrayReverse(t *testing.T) {
|
func TestCopyReverse(t *testing.T) {
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
arg := make([]byte, len(tc.arr))
|
arg := Copy(tc.arr)
|
||||||
copy(arg, tc.arr)
|
require.Equal(t, tc.arr, arg)
|
||||||
|
|
||||||
have := ArrayReverse(arg)
|
have := CopyReverse(arg)
|
||||||
require.Equal(t, tc.rev, have)
|
require.Equal(t, tc.rev, have)
|
||||||
|
|
||||||
// test that argument was copied
|
// test that argument was copied
|
||||||
|
@ -41,5 +41,11 @@ func TestArrayReverse(t *testing.T) {
|
||||||
have[i] = ^have[i]
|
have[i] = ^have[i]
|
||||||
}
|
}
|
||||||
require.Equal(t, tc.arr, arg)
|
require.Equal(t, tc.arr, arg)
|
||||||
|
|
||||||
|
Reverse(arg)
|
||||||
|
require.Equal(t, tc.rev, arg)
|
||||||
|
if len(tc.arr) > 1 {
|
||||||
|
require.NotEqual(t, tc.arr, arg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uint160Size is the size of Uint160 in bytes.
|
// Uint160Size is the size of Uint160 in bytes.
|
||||||
|
@ -74,7 +75,7 @@ func (u Uint160) BytesBE() []byte {
|
||||||
|
|
||||||
// BytesLE returns a little-endian byte representation of u.
|
// BytesLE returns a little-endian byte representation of u.
|
||||||
func (u Uint160) BytesLE() []byte {
|
func (u Uint160) BytesLE() []byte {
|
||||||
return ArrayReverse(u.BytesBE())
|
return slice.CopyReverse(u.BytesBE())
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the stringer interface.
|
// String implements the stringer interface.
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Uint256Size is the size of Uint256 in bytes.
|
// Uint256Size is the size of Uint256 in bytes.
|
||||||
|
@ -54,7 +55,7 @@ func Uint256DecodeBytesBE(b []byte) (u Uint256, err error) {
|
||||||
|
|
||||||
// Uint256DecodeBytesLE attempts to decode the given string (in LE representation) into an Uint256.
|
// Uint256DecodeBytesLE attempts to decode the given string (in LE representation) into an Uint256.
|
||||||
func Uint256DecodeBytesLE(b []byte) (u Uint256, err error) {
|
func Uint256DecodeBytesLE(b []byte) (u Uint256, err error) {
|
||||||
b = ArrayReverse(b)
|
b = slice.CopyReverse(b)
|
||||||
return Uint256DecodeBytesBE(b)
|
return Uint256DecodeBytesBE(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ func (u Uint256) Reverse() Uint256 {
|
||||||
|
|
||||||
// BytesLE return a little-endian byte representation of u.
|
// BytesLE return a little-endian byte representation of u.
|
||||||
func (u Uint256) BytesLE() []byte {
|
func (u Uint256) BytesLE() []byte {
|
||||||
return ArrayReverse(u.BytesBE())
|
return slice.CopyReverse(u.BytesBE())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equals returns true if both Uint256 values are the same.
|
// Equals returns true if both Uint256 values are the same.
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"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/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"gopkg.in/abiosoft/ishell.v2"
|
"gopkg.in/abiosoft/ishell.v2"
|
||||||
|
@ -565,7 +566,7 @@ func Parse(args []string) (string, error) {
|
||||||
}
|
}
|
||||||
buf.WriteString(fmt.Sprintf("Hex to String\t%s\n", fmt.Sprintf("%q", string(rawStr))))
|
buf.WriteString(fmt.Sprintf("Hex to String\t%s\n", fmt.Sprintf("%q", string(rawStr))))
|
||||||
buf.WriteString(fmt.Sprintf("Hex to Integer\t%s\n", bigint.FromBytes(rawStr)))
|
buf.WriteString(fmt.Sprintf("Hex to Integer\t%s\n", bigint.FromBytes(rawStr)))
|
||||||
buf.WriteString(fmt.Sprintf("Swap Endianness\t%s\n", hex.EncodeToString(util.ArrayReverse(rawStr))))
|
buf.WriteString(fmt.Sprintf("Swap Endianness\t%s\n", hex.EncodeToString(slice.CopyReverse(rawStr))))
|
||||||
}
|
}
|
||||||
if addr, err := address.StringToUint160(arg); err == nil {
|
if addr, err := address.StringToUint160(arg); err == nil {
|
||||||
buf.WriteString(fmt.Sprintf("Address to BE ScriptHash\t%s\n", addr))
|
buf.WriteString(fmt.Sprintf("Address to BE ScriptHash\t%s\n", addr))
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -188,9 +189,7 @@ func convertPrimitive(item Item, typ Type) (Item, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if typ == BufferT {
|
if typ == BufferT {
|
||||||
newb := make([]byte, len(b))
|
return NewBuffer(slice.Copy(b)), nil
|
||||||
copy(newb, b)
|
|
||||||
return NewBuffer(newb), nil
|
|
||||||
}
|
}
|
||||||
// ByteArray can't really be changed, so it's OK to reuse `b`.
|
// ByteArray can't really be changed, so it's OK to reuse `b`.
|
||||||
return NewByteArray(b), nil
|
return NewByteArray(b), nil
|
||||||
|
@ -633,9 +632,7 @@ func (i *ByteArray) Equals(s Item) bool {
|
||||||
|
|
||||||
// Dup implements Item interface.
|
// Dup implements Item interface.
|
||||||
func (i *ByteArray) Dup() Item {
|
func (i *ByteArray) Dup() Item {
|
||||||
a := make([]byte, len(i.value))
|
return &ByteArray{slice.Copy(i.value)}
|
||||||
copy(a, i.value)
|
|
||||||
return &ByteArray{a}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type implements Item interface.
|
// Type implements Item interface.
|
||||||
|
@ -1110,9 +1107,7 @@ func (i *Buffer) Convert(typ Type) (Item, error) {
|
||||||
case BufferT:
|
case BufferT:
|
||||||
return i, nil
|
return i, nil
|
||||||
case ByteArrayT:
|
case ByteArrayT:
|
||||||
val := make([]byte, len(i.value))
|
return NewByteArray(slice.Copy(i.value)), nil
|
||||||
copy(val, i.value)
|
|
||||||
return NewByteArray(val), nil
|
|
||||||
case IntegerT:
|
case IntegerT:
|
||||||
if len(i.value) > MaxBigIntegerSizeBits/8 {
|
if len(i.value) > MaxBigIntegerSizeBits/8 {
|
||||||
return nil, errTooBigInteger
|
return nil, errTooBigInteger
|
||||||
|
@ -1173,13 +1168,9 @@ func deepCopy(item Item, seen map[Item]Item) Item {
|
||||||
}
|
}
|
||||||
return NewBigInteger(bi)
|
return NewBigInteger(bi)
|
||||||
case *ByteArray:
|
case *ByteArray:
|
||||||
val := make([]byte, len(it.value))
|
return NewByteArray(slice.Copy(it.value))
|
||||||
copy(val, it.value)
|
|
||||||
return NewByteArray(val)
|
|
||||||
case *Buffer:
|
case *Buffer:
|
||||||
val := make([]byte, len(it.value))
|
return NewBuffer(slice.Copy(it.value))
|
||||||
copy(val, it.value)
|
|
||||||
return NewBuffer(val)
|
|
||||||
case *Bool:
|
case *Bool:
|
||||||
return NewBool(it.value)
|
return NewBool(it.value)
|
||||||
case *Pointer:
|
case *Pointer:
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"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"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
)
|
)
|
||||||
|
@ -1167,10 +1168,8 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
||||||
a[i], a[j] = a[j], a[i]
|
a[i], a[j] = a[j], a[i]
|
||||||
}
|
}
|
||||||
case *stackitem.Buffer:
|
case *stackitem.Buffer:
|
||||||
slice := t.Value().([]byte)
|
b := t.Value().([]byte)
|
||||||
for i, j := 0, t.Len()-1; i < j; i, j = i+1, j-1 {
|
slice.Reverse(b)
|
||||||
slice[i], slice[j] = slice[j], slice[i]
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("invalid item type %s", t))
|
panic(fmt.Sprintf("invalid item type %s", t))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue