*: use slices.Clone instead of make/copy

It's much easier this way.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
Roman Khimov 2024-08-24 00:07:41 +03:00
parent 7243754a0d
commit 9e112fc024
23 changed files with 82 additions and 114 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"os"
"os/signal"
"slices"
"syscall"
"time"
@ -36,10 +37,9 @@ import (
func NewCommands() []*cli.Command {
cfgFlags := []cli.Flag{options.Config, options.ConfigFile, options.RelativePath}
cfgFlags = append(cfgFlags, options.Network...)
var cfgWithCountFlags = make([]cli.Flag, len(cfgFlags))
copy(cfgWithCountFlags, cfgFlags)
cfgFlags = append(cfgFlags, options.Debug)
var cfgWithCountFlags = slices.Clone(cfgFlags)
cfgFlags = append(cfgFlags, options.Debug)
cfgWithCountFlags = append(cfgWithCountFlags,
&cli.UintFlag{
Name: "count",
@ -47,8 +47,7 @@ func NewCommands() []*cli.Command {
Usage: "Number of blocks to be processed (default or 0: all chain)",
},
)
var cfgCountOutFlags = make([]cli.Flag, len(cfgWithCountFlags))
copy(cfgCountOutFlags, cfgWithCountFlags)
var cfgCountOutFlags = slices.Clone(cfgWithCountFlags)
cfgCountOutFlags = append(cfgCountOutFlags,
&cli.UintFlag{
Name: "start",
@ -61,8 +60,7 @@ func NewCommands() []*cli.Command {
Usage: "Output file (stdout if not given)",
},
)
var cfgCountInFlags = make([]cli.Flag, len(cfgWithCountFlags))
copy(cfgCountInFlags, cfgWithCountFlags)
var cfgCountInFlags = slices.Clone(cfgWithCountFlags)
cfgCountInFlags = append(cfgCountInFlags,
&cli.StringFlag{
Name: "in",
@ -79,13 +77,12 @@ func NewCommands() []*cli.Command {
Usage: "Use if dump is incremental",
},
)
var cfgHeightFlags = make([]cli.Flag, len(cfgFlags)+1)
copy(cfgHeightFlags, cfgFlags)
cfgHeightFlags[len(cfgHeightFlags)-1] = &cli.UintFlag{
var cfgHeightFlags = slices.Clone(cfgFlags)
cfgHeightFlags = append(cfgHeightFlags, &cli.UintFlag{
Name: "height",
Usage: "Height of the state to reset DB to",
Required: true,
}
})
return []*cli.Command{
{
Name: "node",

View file

@ -4,6 +4,7 @@ import (
"encoding/hex"
"errors"
"fmt"
"slices"
"strconv"
"github.com/nspcc-dev/neo-go/cli/cmdargs"
@ -39,12 +40,11 @@ func newNEP11Commands() []*cli.Command {
Usage: "Hex-encoded token ID",
}
balanceFlags := make([]cli.Flag, len(baseBalanceFlags))
copy(balanceFlags, baseBalanceFlags)
balanceFlags := slices.Clone(baseBalanceFlags)
balanceFlags = append(balanceFlags, tokenID)
balanceFlags = append(balanceFlags, options.RPC...)
transferFlags := make([]cli.Flag, len(baseTransferFlags))
copy(transferFlags, baseTransferFlags)
transferFlags := slices.Clone(baseTransferFlags)
transferFlags = append(transferFlags, tokenID)
transferFlags = append(transferFlags, options.RPC...)
return []*cli.Command{

View file

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"math/big"
"slices"
"strings"
"github.com/nspcc-dev/neo-go/cli/cmdargs"
@ -91,11 +92,10 @@ var (
)
func newNEP17Commands() []*cli.Command {
balanceFlags := make([]cli.Flag, len(baseBalanceFlags))
copy(balanceFlags, baseBalanceFlags)
balanceFlags := slices.Clone(baseBalanceFlags)
balanceFlags = append(balanceFlags, options.RPC...)
transferFlags := make([]cli.Flag, len(baseTransferFlags))
copy(transferFlags, baseTransferFlags)
transferFlags := slices.Clone(baseTransferFlags)
transferFlags = append(transferFlags, options.RPC...)
return []*cli.Command{
{

View file

@ -5,6 +5,7 @@ import (
"go/ast"
"go/constant"
"go/types"
"slices"
"github.com/nspcc-dev/neo-go/pkg/core/interop/runtime"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/binding"
@ -56,8 +57,7 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
// while stored in the new.
oldScope := c.scope.vars.locals
c.scope.vars.newScope()
newScope := make([]map[string]varInfo, len(c.scope.vars.locals))
copy(newScope, c.scope.vars.locals)
newScope := slices.Clone(c.scope.vars.locals)
defer c.scope.vars.dropScope()
if f.decl.Recv != nil {

View file

@ -2,6 +2,7 @@ package config
import (
"fmt"
"slices"
"sort"
"strconv"
"strings"
@ -38,10 +39,8 @@ func (a *ApplicationConfiguration) EqualsButServices(o *ApplicationConfiguration
if len(a.P2P.Addresses) != len(o.P2P.Addresses) {
return false
}
aCp := make([]string, len(a.P2P.Addresses))
oCp := make([]string, len(o.P2P.Addresses))
copy(aCp, a.P2P.Addresses)
copy(oCp, o.P2P.Addresses)
aCp := slices.Clone(a.P2P.Addresses)
oCp := slices.Clone(o.P2P.Addresses)
sort.Strings(aCp)
sort.Strings(oCp)
for i := range aCp {

View file

@ -3,6 +3,7 @@ package consensus
import (
"errors"
"fmt"
"slices"
"sort"
"sync/atomic"
"time"
@ -788,9 +789,7 @@ func (s *service) newBlockFromContext(ctx *dbft.Context[util.Uint256]) dbft.Bloc
block.Block.PrimaryIndex = primaryIndex
// it's OK to have ctx.TransactionsHashes == nil here
hashes := make([]util.Uint256, len(ctx.TransactionHashes))
copy(hashes, ctx.TransactionHashes)
block.Block.MerkleRoot = hash.CalcMerkleRoot(hashes)
block.Block.MerkleRoot = hash.CalcMerkleRoot(slices.Clone(ctx.TransactionHashes))
return block
}

View file

@ -6,7 +6,9 @@ import (
"encoding/binary"
"errors"
"fmt"
"maps"
"math/big"
"slices"
"sort"
"strings"
@ -150,13 +152,8 @@ func copyNeoCache(src, dst *NeoCache) {
// Can't omit copying because gasPerBlock is append-only, thus to be able to
// discard cache changes in case of FAULTed transaction we need a separate
// container for updated gasPerBlock values.
dst.gasPerBlock = make(gasRecord, len(src.gasPerBlock))
copy(dst.gasPerBlock, src.gasPerBlock)
dst.gasPerVoteCache = make(map[string]big.Int)
for k, v := range src.gasPerVoteCache {
dst.gasPerVoteCache[k] = v
}
dst.gasPerBlock = slices.Clone(src.gasPerBlock)
dst.gasPerVoteCache = maps.Clone(src.gasPerVoteCache)
}
// makeValidatorKey creates a key from the account script hash.
@ -376,8 +373,7 @@ func (n *NEO) InitializeCache(blockHeight uint32, d *dao.Simple) error {
// nextValidators, committee and committee hash are filled in by this moment
// via n.updateCache call.
cache.newEpochNextValidators = cache.nextValidators.Copy()
cache.newEpochCommittee = make(keysWithVotes, len(cache.committee))
copy(cache.newEpochCommittee, cache.committee)
cache.newEpochCommittee = slices.Clone(cache.committee)
cache.newEpochCommitteeHash = cache.committeeHash
}

View file

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"slices"
"testing"
ojson "github.com/nspcc-dev/go-ordered-json"
@ -423,8 +424,7 @@ func TestManagement_ContractDeploy(t *testing.T) {
})
t.Run("bad methods in manifest 1", func(t *testing.T) {
badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods = slices.Clone(cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods[0].Offset = 100500 // out of bounds
manifB, err := json.Marshal(&badManifest)
require.NoError(t, err)
@ -433,8 +433,7 @@ func TestManagement_ContractDeploy(t *testing.T) {
})
t.Run("bad methods in manifest 2", func(t *testing.T) {
var badManifest = cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods = slices.Clone(cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods[0].Offset = len(cs1.NEF.Script) - 2 // Ends with `CALLT(X,X);RET`.
manifB, err := json.Marshal(badManifest)
@ -444,8 +443,7 @@ func TestManagement_ContractDeploy(t *testing.T) {
})
t.Run("duplicated methods in manifest 1", func(t *testing.T) {
badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods = slices.Clone(cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods[0] = badManifest.ABI.Methods[1] // duplicates
manifB, err := json.Marshal(&badManifest)
require.NoError(t, err)
@ -454,8 +452,7 @@ func TestManagement_ContractDeploy(t *testing.T) {
})
t.Run("duplicated events in manifest 1", func(t *testing.T) {
badManifest := cs1.Manifest
badManifest.ABI.Methods = make([]manifest.Method, len(cs1.Manifest.ABI.Methods))
copy(badManifest.ABI.Methods, cs1.Manifest.ABI.Methods)
badManifest.ABI.Methods = slices.Clone(cs1.Manifest.ABI.Methods)
badManifest.ABI.Events = []manifest.Event{{Name: "event"}, {Name: "event"}} // duplicates
manifB, err := json.Marshal(&badManifest)
require.NoError(t, err)

View file

@ -3,7 +3,9 @@ package native
import (
"encoding/hex"
"fmt"
"maps"
"math/big"
"slices"
"sort"
"github.com/nspcc-dev/neo-go/pkg/config"
@ -91,12 +93,8 @@ func (c *PolicyCache) Copy() dao.NativeContractCache {
func copyPolicyCache(src, dst *PolicyCache) {
*dst = *src
dst.attributeFee = make(map[transaction.AttrType]uint32, len(src.attributeFee))
for t, v := range src.attributeFee {
dst.attributeFee[t] = v
}
dst.blockedAccounts = make([]util.Uint160, len(src.blockedAccounts))
copy(dst.blockedAccounts, src.blockedAccounts)
dst.attributeFee = maps.Clone(src.attributeFee)
dst.blockedAccounts = slices.Clone(src.blockedAccounts)
}
// newPolicy returns Policy native contract.

View file

@ -2,6 +2,7 @@ package statesync
import (
"bytes"
"slices"
"sort"
"sync"
@ -38,9 +39,7 @@ func (mp *Pool) TryGet(hash util.Uint256) ([][]byte, bool) {
paths, ok := mp.hashes[hash]
// need to copy here, because we can modify existing array of paths inside the pool.
res := make([][]byte, len(paths))
copy(res, paths)
return res, ok
return slices.Clone(paths), ok
}
// GetAll returns all MPT nodes with the corresponding paths from the pool.

View file

@ -3,6 +3,7 @@ package transaction
import (
"errors"
"math/big"
"slices"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io"
@ -93,10 +94,7 @@ func (c *Signer) Copy() *Signer {
return nil
}
cp := *c
if c.AllowedContracts != nil {
cp.AllowedContracts = make([]util.Uint160, len(c.AllowedContracts))
copy(cp.AllowedContracts, c.AllowedContracts)
}
cp.AllowedContracts = slices.Clone(c.AllowedContracts)
cp.AllowedGroups = keys.PublicKeys(c.AllowedGroups).Copy()
if c.Rules != nil {
cp.Rules = make([]WitnessRule, len(c.Rules))

View file

@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"math/big"
"slices"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
lru "github.com/hashicorp/golang-lru/v2"
@ -81,12 +82,7 @@ func (keys PublicKeys) Contains(pKey *PublicKey) bool {
// Copy returns a shallow copy of the PublicKeys slice. It creates a new slice with the same elements,
// but does not perform a deep copy of the elements themselves.
func (keys PublicKeys) Copy() PublicKeys {
if keys == nil {
return nil
}
res := make(PublicKeys, len(keys))
copy(res, keys)
return res
return slices.Clone(keys)
}
// Unique returns a set of public keys.

View file

@ -5,6 +5,7 @@ import (
"encoding/hex"
"encoding/json"
"math/rand"
"slices"
"sort"
"testing"
@ -145,8 +146,7 @@ func TestSort(t *testing.T) {
pubs1[i] = priv.PublicKey()
}
pubs2 := make(PublicKeys, len(pubs1))
copy(pubs2, pubs1)
pubs2 := slices.Clone(pubs1)
sort.Sort(pubs1)

View file

@ -10,6 +10,7 @@ import (
mrand "math/rand"
"net"
"runtime"
"slices"
"sort"
"strconv"
"sync"
@ -1494,8 +1495,7 @@ func (s *Server) RequestTx(hashes ...util.Uint256) {
return
}
var sorted = make([]util.Uint256, len(hashes))
copy(sorted, hashes)
var sorted = slices.Clone(hashes)
sort.Slice(sorted, func(i, j int) bool {
return sorted[i].CompareTo(sorted[j]) < 0
})

View file

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"math"
"slices"
"strings"
ojson "github.com/nspcc-dev/go-ordered-json"
@ -100,8 +101,7 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error {
}
}
if len(m.SupportedStandards) > 1 {
names := make([]string, len(m.SupportedStandards))
copy(names, m.SupportedStandards)
names := slices.Clone(m.SupportedStandards)
if stringsHaveDups(names) {
return errors.New("duplicate supported standards")
}
@ -128,8 +128,7 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error {
return errors.New("invalid (null?) trusts")
}
if len(m.Trusts.Value) > 1 {
hashes := make([]PermissionDesc, len(m.Trusts.Value))
copy(hashes, m.Trusts.Value)
hashes := slices.Clone(m.Trusts.Value)
if permissionDescsHaveDups(hashes) {
return errors.New("duplicate trusted contracts")
}

View file

@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util"
@ -128,8 +129,7 @@ func (p *Permission) IsValid() error {
if len(p.Methods.Value) < 2 {
return nil
}
names := make([]string, len(p.Methods.Value))
copy(names, p.Methods.Value)
names := slices.Clone(p.Methods.Value)
if stringsHaveDups(names) {
return errors.New("duplicate method names")
}

View file

@ -9,6 +9,7 @@ import (
"fmt"
"math/big"
"os"
"slices"
"strings"
"unicode/utf8"
@ -349,10 +350,8 @@ func NewParameterFromValue(value any) (Parameter, error) {
result.Type = ArrayType
result.Value = arr
case []Parameter:
arr := make([]Parameter, len(v))
copy(arr, v)
result.Type = ArrayType
result.Value = arr
result.Value = slices.Clone(v)
case []*keys.PublicKey:
return NewParameterFromValue(keys.PublicKeys(v))
case keys.PublicKeys:

View file

@ -2,6 +2,7 @@ package rpcbinding
import (
"fmt"
"slices"
"sort"
"strings"
"text/template"
@ -390,8 +391,7 @@ func NewConfig() binding.Config {
func Generate(cfg binding.Config) error {
// Avoid changing *cfg.Manifest.
mfst := *cfg.Manifest
mfst.ABI.Methods = make([]manifest.Method, len(mfst.ABI.Methods))
copy(mfst.ABI.Methods, cfg.Manifest.ABI.Methods)
mfst.ABI.Methods = slices.Clone(mfst.ABI.Methods)
cfg.Manifest = &mfst
var imports = make(map[string]struct{})

View file

@ -5,6 +5,8 @@ providing only things used by neo-go.
*/
package bitfield
import "slices"
// Field is a bit field represented as a slice of uint64 values.
type Field []uint64
@ -32,9 +34,7 @@ func (f Field) IsSet(i int) bool {
// Copy makes a copy of the current Field.
func (f Field) Copy() Field {
fn := make(Field, len(f))
copy(fn, f)
return fn
return slices.Clone(f)
}
// And implements logical AND between f's and m's bits saving the result into f.

View file

@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"slices"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
@ -351,7 +352,5 @@ func DynamicOnUnload(v *VM, ctx *Context, commit bool) error {
// BreakPoints returns the current set of Context's breakpoints.
func (c *Context) BreakPoints() []int {
res := make([]int, len(c.sc.breakPoints))
copy(res, c.sc.breakPoints)
return res
return slices.Clone(c.sc.breakPoints)
}

View file

@ -2,6 +2,7 @@ package vm
import (
"encoding/binary"
"slices"
"testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -143,54 +144,48 @@ func TestIsScriptCorrect(t *testing.T) {
good := w.Bytes()
getScript := func() []byte {
s := make([]byte, len(good))
copy(s, good)
return s
}
t.Run("good", func(t *testing.T) {
require.NoError(t, IsScriptCorrect(good, nil))
})
t.Run("bad instruction", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[retOff] = 0xff
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds JMP 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmpOff+1] = 0x80 // -128
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds JMP 2", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmpOff+1] = 0x7f
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("bad JMP offset 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmpOff+1] = 0xff // into "something"
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("bad JMP offset 2", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmpOff+1] = byte(pushOff - jmpOff + 1)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds JMPL 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmplOff+1] = byte(-jmplOff - 1)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds JMPL 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmplOff+1] = byte(len(bad)-jmplOff) + 1
bad[jmplOff+2] = 0
bad[jmplOff+3] = 0
@ -206,25 +201,25 @@ func TestIsScriptCorrect(t *testing.T) {
})
t.Run("bad JMPL offset", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[jmplOff+1] = 0xfe // into JMP
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds TRY 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[tryOff+1] = byte(-tryOff - 1)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds TRY 2", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[tryOff+1] = byte(len(bad)-tryOff) + 1
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("out of bounds TRY 2", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[tryOff+2] = byte(len(bad)-tryOff) + 1
require.Error(t, IsScriptCorrect(bad, nil))
})
@ -239,31 +234,31 @@ func TestIsScriptCorrect(t *testing.T) {
})
t.Run("bad TRYL offset 1", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[trylOff+1] = byte(-(trylOff - jmpOff) - 1) // into "something"
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("bad TRYL offset 2", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[trylOff+5] = byte(len(bad) - trylOff - 1)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("bad ISTYPE type", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[istypeOff+1] = byte(0xff)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("bad ISTYPE type (Any)", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[istypeOff+1] = byte(stackitem.AnyT)
require.Error(t, IsScriptCorrect(bad, nil))
})
t.Run("good NEWARRAY_T type", func(t *testing.T) {
bad := getScript()
bad := slices.Clone(good)
bad[istypeOff] = byte(opcode.NEWARRAYT)
bad[istypeOff+1] = byte(stackitem.AnyT)
require.NoError(t, IsScriptCorrect(bad, nil))

View file

@ -57,5 +57,5 @@ func TestContext_BreakPoints(t *testing.T) {
// New context -> clean breakpoints.
v.loadScriptWithCallingHash(prog, nil, nil, util.Uint160{}, util.Uint160{}, callflag.All, 1, 3, nil)
require.Equal(t, []int{}, v.Context().BreakPoints())
require.Nil(t, v.Context().BreakPoints())
}

View file

@ -9,6 +9,7 @@ import (
"math"
"math/big"
"reflect"
"slices"
"unicode/utf8"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
@ -348,9 +349,7 @@ func (i *Struct) Convert(typ Type) (Item, error) {
case StructT:
return i, nil
case ArrayT:
arr := make([]Item, len(i.value))
copy(arr, i.value)
return NewArray(arr), nil
return NewArray(slices.Clone(i.value)), nil
case BooleanT:
return NewBool(true), nil
default:
@ -793,9 +792,7 @@ func (i *Array) Convert(typ Type) (Item, error) {
case ArrayT:
return i, nil
case StructT:
arr := make([]Item, len(i.value))
copy(arr, i.value)
return NewStruct(arr), nil
return NewStruct(slices.Clone(i.value)), nil
case BooleanT:
return NewBool(true), nil
default: