From 9e112fc024163579fa68224c10c2aebbffd3bafb Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Sat, 24 Aug 2024 00:07:41 +0300 Subject: [PATCH] *: use slices.Clone instead of make/copy It's much easier this way. Signed-off-by: Roman Khimov --- cli/server/server.go | 19 ++++----- cli/wallet/nep11.go | 8 ++-- cli/wallet/nep17.go | 8 ++-- pkg/compiler/inline.go | 4 +- pkg/config/application_config.go | 7 ++-- pkg/consensus/consensus.go | 5 +-- pkg/core/native/native_neo.go | 14 +++---- .../native/native_test/management_test.go | 13 +++---- pkg/core/native/policy.go | 10 ++--- pkg/core/statesync/mptpool.go | 5 +-- pkg/core/transaction/signer.go | 6 +-- pkg/crypto/keys/publickey.go | 8 +--- pkg/crypto/keys/publickey_test.go | 4 +- pkg/network/server.go | 4 +- pkg/smartcontract/manifest/manifest.go | 7 ++-- pkg/smartcontract/manifest/permission.go | 4 +- pkg/smartcontract/parameter.go | 5 +-- pkg/smartcontract/rpcbinding/binding.go | 4 +- pkg/util/bitfield/bitfield.go | 6 +-- pkg/vm/context.go | 5 +-- pkg/vm/contract_checks_test.go | 39 ++++++++----------- pkg/vm/debug_test.go | 2 +- pkg/vm/stackitem/item.go | 9 ++--- 23 files changed, 82 insertions(+), 114 deletions(-) diff --git a/cli/server/server.go b/cli/server/server.go index 67787ced9..ceab19586 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -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", diff --git a/cli/wallet/nep11.go b/cli/wallet/nep11.go index 7c4d97206..809e76c01 100644 --- a/cli/wallet/nep11.go +++ b/cli/wallet/nep11.go @@ -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{ diff --git a/cli/wallet/nep17.go b/cli/wallet/nep17.go index f8f6efe9c..462069b8b 100644 --- a/cli/wallet/nep17.go +++ b/cli/wallet/nep17.go @@ -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{ { diff --git a/pkg/compiler/inline.go b/pkg/compiler/inline.go index 9cf641c5a..e9e07320d 100644 --- a/pkg/compiler/inline.go +++ b/pkg/compiler/inline.go @@ -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 { diff --git a/pkg/config/application_config.go b/pkg/config/application_config.go index 2e94961d7..fb9ba2827 100644 --- a/pkg/config/application_config.go +++ b/pkg/config/application_config.go @@ -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 { diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 7a32c7615..054438570 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -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 } diff --git a/pkg/core/native/native_neo.go b/pkg/core/native/native_neo.go index 42871fc64..42313b5c1 100644 --- a/pkg/core/native/native_neo.go +++ b/pkg/core/native/native_neo.go @@ -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 } diff --git a/pkg/core/native/native_test/management_test.go b/pkg/core/native/native_test/management_test.go index 9870e81f0..546b7f923 100644 --- a/pkg/core/native/native_test/management_test.go +++ b/pkg/core/native/native_test/management_test.go @@ -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) diff --git a/pkg/core/native/policy.go b/pkg/core/native/policy.go index 0591fe7b4..1f82c0a0d 100644 --- a/pkg/core/native/policy.go +++ b/pkg/core/native/policy.go @@ -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. diff --git a/pkg/core/statesync/mptpool.go b/pkg/core/statesync/mptpool.go index 819188246..16a1aa4b8 100644 --- a/pkg/core/statesync/mptpool.go +++ b/pkg/core/statesync/mptpool.go @@ -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. diff --git a/pkg/core/transaction/signer.go b/pkg/core/transaction/signer.go index a4290b66b..be2781767 100644 --- a/pkg/core/transaction/signer.go +++ b/pkg/core/transaction/signer.go @@ -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)) diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index 774623456..7965116de 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -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. diff --git a/pkg/crypto/keys/publickey_test.go b/pkg/crypto/keys/publickey_test.go index 1f9e5bba9..6fa70fd54 100644 --- a/pkg/crypto/keys/publickey_test.go +++ b/pkg/crypto/keys/publickey_test.go @@ -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) diff --git a/pkg/network/server.go b/pkg/network/server.go index eea8e3159..4001e46eb 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -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 }) diff --git a/pkg/smartcontract/manifest/manifest.go b/pkg/smartcontract/manifest/manifest.go index 95a2f41d3..03d0103f9 100644 --- a/pkg/smartcontract/manifest/manifest.go +++ b/pkg/smartcontract/manifest/manifest.go @@ -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") } diff --git a/pkg/smartcontract/manifest/permission.go b/pkg/smartcontract/manifest/permission.go index 18b67dd7e..08d788054 100644 --- a/pkg/smartcontract/manifest/permission.go +++ b/pkg/smartcontract/manifest/permission.go @@ -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") } diff --git a/pkg/smartcontract/parameter.go b/pkg/smartcontract/parameter.go index 24577d854..c9f941a02 100644 --- a/pkg/smartcontract/parameter.go +++ b/pkg/smartcontract/parameter.go @@ -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: diff --git a/pkg/smartcontract/rpcbinding/binding.go b/pkg/smartcontract/rpcbinding/binding.go index 02f363496..30520420d 100644 --- a/pkg/smartcontract/rpcbinding/binding.go +++ b/pkg/smartcontract/rpcbinding/binding.go @@ -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{}) diff --git a/pkg/util/bitfield/bitfield.go b/pkg/util/bitfield/bitfield.go index 62f51c5da..1bd082a0d 100644 --- a/pkg/util/bitfield/bitfield.go +++ b/pkg/util/bitfield/bitfield.go @@ -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. diff --git a/pkg/vm/context.go b/pkg/vm/context.go index 9a5be2a1e..ca21d6d30 100644 --- a/pkg/vm/context.go +++ b/pkg/vm/context.go @@ -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) } diff --git a/pkg/vm/contract_checks_test.go b/pkg/vm/contract_checks_test.go index 7bb9ef08a..3a3007131 100644 --- a/pkg/vm/contract_checks_test.go +++ b/pkg/vm/contract_checks_test.go @@ -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)) diff --git a/pkg/vm/debug_test.go b/pkg/vm/debug_test.go index ca5df493a..5441d5de6 100644 --- a/pkg/vm/debug_test.go +++ b/pkg/vm/debug_test.go @@ -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()) } diff --git a/pkg/vm/stackitem/item.go b/pkg/vm/stackitem/item.go index b00f52ec4..e51ee92e0 100644 --- a/pkg/vm/stackitem/item.go +++ b/pkg/vm/stackitem/item.go @@ -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: