*: drop pkg/util/slice, use slices.Reverse

This also removes bigint.FromBytesUnsigned(), it's not used very often and
it's somewhat misleading in the bigint package (which is supposed to use a
very specific enconding).

Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
Roman Khimov 2024-08-23 23:03:10 +03:00
parent 963e22ea95
commit c7b623cc38
11 changed files with 36 additions and 131 deletions

View file

@ -12,6 +12,7 @@ import (
"io"
"math/big"
"os"
"slices"
"strconv"
"strings"
"text/tabwriter"
@ -41,7 +42,6 @@ import (
"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/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/stackitem"
"github.com/urfave/cli/v2"
@ -1456,7 +1456,9 @@ func Parse(args []string) (string, error) {
}
buf = fmt.Appendf(buf, "Hex to String\t%s\n", fmt.Sprintf("%q", string(rawStr)))
buf = fmt.Appendf(buf, "Hex to Integer\t%s\n", bigint.FromBytes(rawStr))
buf = fmt.Appendf(buf, "Swap Endianness\t%s\n", hex.EncodeToString(slice.CopyReverse(rawStr)))
var clonedStr = slices.Clone(rawStr)
slices.Reverse(clonedStr)
buf = fmt.Appendf(buf, "Swap Endianness\t%s\n", hex.EncodeToString(clonedStr))
}
if addr, err := address.StringToUint160(arg); err == nil {
buf = fmt.Appendf(buf, "Address to BE ScriptHash\t%s\n", addr)

View file

@ -4,12 +4,12 @@ import (
"encoding/binary"
"errors"
"math/big"
"slices"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/encoding/bigint"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
@ -108,7 +108,9 @@ func GetRandom(ic *interop.Context) error {
if !ic.VM.AddGas(ic.BaseExecFee() * price) {
return errors.New("gas limit exceeded")
}
ic.VM.Estack().PushItem(stackitem.NewBigInteger(bigint.FromBytesUnsigned(res)))
// Resulting data is interpreted as an unsigned LE integer.
slices.Reverse(res)
ic.VM.Estack().PushItem(stackitem.NewBigInteger(new(big.Int).SetBytes(res)))
return nil
}

View file

@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"math/big"
"slices"
"strings"
"unicode/utf8"
@ -19,7 +20,6 @@ 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"
)
@ -241,7 +241,7 @@ func (s *Std) itoa(_ *interop.Context, args []stackitem.Item) stackitem.Item {
break
}
bs := bigint.ToBytes(num)
slice.Reverse(bs)
slices.Reverse(bs)
str = hex.EncodeToString(bs)
if pad := bs[0] & 0xF8; pad == 0 || pad == 0xF8 {
str = str[1:]
@ -288,7 +288,7 @@ func (s *Std) atoi(_ *interop.Context, args []stackitem.Item) stackitem.Item {
if changed && bs[0]&0x8 != 0 {
bs[0] |= 0xF0
}
slice.Reverse(bs)
slices.Reverse(bs)
bi = bigint.FromBytes(bs)
default:
panic(ErrInvalidBase)

View file

@ -4,8 +4,7 @@ import (
"math"
"math/big"
"math/bits"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"slices"
)
const (
@ -17,12 +16,6 @@ const (
var bigOne = big.NewInt(1)
// FromBytesUnsigned converts data in little-endian format to an unsigned integer.
func FromBytesUnsigned(data []byte) *big.Int {
bs := slice.CopyReverse(data)
return new(big.Int).SetBytes(bs)
}
// FromBytes converts data in little-endian format to
// an integer.
func FromBytes(data []byte) *big.Int {
@ -148,7 +141,7 @@ func ToPreallocatedBytes(n *big.Int, data []byte) []byte {
data = data[:lb]
}
_ = n.FillBytes(data)
slice.Reverse(data)
slices.Reverse(data)
if sign == -1 {
for i := range data {

View file

@ -3,9 +3,9 @@ package bigint
import (
"math"
"math/big"
"slices"
"testing"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -128,31 +128,6 @@ func TestBytesToInt(t *testing.T) {
})
}
var unsignedCases = []struct {
number int64
buf []byte
}{
{0xff00000000, []byte{0x00, 0x00, 0x00, 0x00, 0xff}},
{0xfd00000000, []byte{0x00, 0x00, 0x00, 0x00, 0xfd}},
{0x8000000000, []byte{0x00, 0x00, 0x00, 0x00, 0x80}},
{0xff0200000000, []byte{0x00, 0x00, 0x00, 0x00, 0x02, 0xff}},
{0xff0100000000, []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0xff}},
{0xff0100000000, []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00}},
}
func TestBytesToUnsigned(t *testing.T) {
for _, tc := range testCases {
if tc.number > 0 {
num := FromBytesUnsigned(tc.buf)
assert.Equal(t, tc.number, num.Int64(), "expected %x, got %x", tc.number, num.Int64())
}
}
for _, tc := range unsignedCases {
num := FromBytesUnsigned(tc.buf)
assert.Equal(t, tc.number, num.Int64(), "expected %x, got %x", tc.number, num.Int64())
}
}
func TestEquivalentRepresentations(t *testing.T) {
for _, tc := range testCases {
buf := tc.buf
@ -210,7 +185,9 @@ func TestVeryBigInts(t *testing.T) {
num, ok := new(big.Int).SetString(tc.numStr, 10)
assert.True(t, ok)
result := FromBytes(slice.CopyReverse(tc.buf))
revb := slices.Clone(tc.buf)
slices.Reverse(revb)
result := FromBytes(revb)
assert.Equal(t, num, result, "error while converting %s from bytes", tc.numStr)
}
}

View file

@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"io"
"slices"
"text/template"
"github.com/consensys/gnark-crypto/ecc"
@ -22,7 +23,6 @@ import (
curve "github.com/consensys/gnark/backend/groth16/bls12-381"
"github.com/consensys/gnark/backend/witness"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/binding"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
)
// Config represents a configuration for Verifier Go smart contract generator.
@ -320,7 +320,7 @@ func GetVerifyProofArgs(proof groth16.Proof, publicWitness witness.Witness) (*Ve
for i := range input { // firstly - public witnesses, after that - private ones (but they are missing from publicWitness anyway).
start := offset + i*fr.Bytes
end := start + fr.Bytes
slice.Reverse(publicWitnessBytes[start:end]) // gnark stores witnesses in the BE form, but native CryptoLib accepts LE-encoded fields elements (not a canonical form).
slices.Reverse(publicWitnessBytes[start:end]) // gnark stores witnesses in the BE form, but native CryptoLib accepts LE-encoded fields elements (not a canonical form).
input[i] = publicWitnessBytes[start:end]
}
return &VerifyProofArgs{

View file

@ -1,23 +0,0 @@
/*
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]
}
}

View file

@ -1,52 +0,0 @@
package slice
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
)
var testCases = []struct {
arr []byte
rev []byte
}{
{
arr: []byte{},
rev: []byte{},
},
{
arr: []byte{0x01},
rev: []byte{0x01},
},
{
arr: []byte{0x01, 0x02, 0x03, 0x04},
rev: []byte{0x04, 0x03, 0x02, 0x01},
},
{
arr: []byte{0x01, 0x02, 0x03, 0x04, 0x05},
rev: []byte{0x05, 0x04, 0x03, 0x02, 0x01},
},
}
func TestCopyReverse(t *testing.T) {
for _, tc := range testCases {
arg := bytes.Clone(tc.arr)
require.Equal(t, tc.arr, arg)
have := CopyReverse(arg)
require.Equal(t, tc.rev, have)
// test that argument was copied
for i := range have {
have[i] = ^have[i]
}
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)
}
}
}

View file

@ -4,10 +4,10 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"slices"
"strings"
"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.
@ -74,7 +74,8 @@ func (u Uint160) BytesBE() []byte {
// BytesLE returns a little-endian byte representation of u.
func (u Uint160) BytesLE() []byte {
return slice.CopyReverse(u.BytesBE())
slices.Reverse(u[:]) // u is a copy, can be changed.
return u[:]
}
// String implements the stringer interface.
@ -134,7 +135,7 @@ func (u Uint160) MarshalJSON() ([]byte, error) {
r := make([]byte, 3+Uint160Size*2+1)
copy(r, `"0x`)
r[len(r)-1] = '"'
slice.Reverse(u[:]) // u is a copy, so we can mangle it in any way.
slices.Reverse(u[:]) // u is a copy, so we can mangle it in any way.
hex.Encode(r[3:], u[:])
return r, nil
}

View file

@ -5,10 +5,10 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"slices"
"strings"
"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.
@ -26,7 +26,7 @@ func Uint256DecodeStringLE(s string) (u Uint256, err error) {
if err != nil {
return u, err
}
slice.Reverse(b)
slices.Reverse(b)
return Uint256DecodeBytesBE(b)
}
@ -55,8 +55,12 @@ func Uint256DecodeBytesBE(b []byte) (u Uint256, err error) {
// Uint256DecodeBytesLE attempts to decode the given string (in LE representation) into a Uint256.
func Uint256DecodeBytesLE(b []byte) (u Uint256, err error) {
b = slice.CopyReverse(b)
return Uint256DecodeBytesBE(b)
if len(b) != Uint256Size {
return u, fmt.Errorf("expected []byte of size %d got %d", Uint256Size, len(b))
}
u = Uint256(b)
slices.Reverse(u[:])
return u, nil
}
// BytesBE returns a byte slice representation of u.
@ -72,7 +76,8 @@ func (u Uint256) Reverse() Uint256 {
// BytesLE return a little-endian byte representation of u.
func (u Uint256) BytesLE() []byte {
return slice.CopyReverse(u.BytesBE())
slices.Reverse(u[:]) // u is a copy, can be changed.
return u[:]
}
// Equals returns true if both Uint256 values are the same.
@ -111,7 +116,7 @@ func (u Uint256) MarshalJSON() ([]byte, error) {
r := make([]byte, 3+Uint256Size*2+1)
copy(r, `"0x`)
r[len(r)-1] = '"'
slice.Reverse(u[:]) // u is a copy, so we can mangle it in any way.
slices.Reverse(u[:]) // u is a copy, so we can mangle it in any way.
hex.Encode(r[3:], u[:])
return r, nil
}

View file

@ -10,6 +10,7 @@ import (
"math"
"math/big"
"os"
"slices"
"text/tabwriter"
"unicode/utf8"
@ -22,7 +23,6 @@ import (
"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/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/nspcc-dev/neo-go/pkg/vm/invocations"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
@ -1358,7 +1358,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
}
case *stackitem.Buffer:
b := t.Value().([]byte)
slice.Reverse(b)
slices.Reverse(b)
default:
panic(fmt.Sprintf("invalid item type %s", t))
}