diff --git a/cli/wallet/wallet.go b/cli/wallet/wallet.go index 17e46b8d8..2645f1722 100644 --- a/cli/wallet/wallet.go +++ b/cli/wallet/wallet.go @@ -8,6 +8,7 @@ import ( "io" "math/big" "os" + "slices" "strings" "github.com/nspcc-dev/neo-go/cli/cmdargs" @@ -512,16 +513,13 @@ func exportKeys(ctx *cli.Context) error { var wifs []string -loop: for _, a := range wall.Accounts { if addr != "" && a.Address != addr { continue } - for i := range wifs { - if a.EncryptedWIF == wifs[i] { - continue loop - } + if slices.Contains(wifs, a.EncryptedWIF) { + continue } wifs = append(wifs, a.EncryptedWIF) diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index 8c3daecf2..e9a0acc49 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -6,6 +6,7 @@ import ( "go/ast" "go/token" "go/types" + "slices" "strings" "github.com/nspcc-dev/neo-go/pkg/vm/emit" @@ -697,12 +698,7 @@ func (c *codegen) pickVarsFromNodes(nodes []nodeContext, markAsUsed func(name st } func isGoBuiltin(name string) bool { - for i := range goBuiltins { - if name == goBuiltins[i] { - return true - } - } - return false + return slices.Contains(goBuiltins, name) } func isPotentialCustomBuiltin(f *funcScope, expr ast.Expr) bool { diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index 75066b5bb..dfac38b02 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -3,6 +3,7 @@ package compiler import ( "go/ast" "go/types" + "slices" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" ) @@ -45,11 +46,7 @@ func (c *codegen) typeOf(e ast.Expr) types.Type { func isBasicTypeOfKind(typ types.Type, ks ...types.BasicKind) bool { if t, ok := typ.Underlying().(*types.Basic); ok { k := t.Kind() - for i := range ks { - if k == ks[i] { - return true - } - } + return slices.Contains(ks, k) } return false } diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 054438570..bfac4ea1b 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -167,14 +167,9 @@ func NewService(cfg Config) (Service, error) { } // Check that the wallet password is correct for at least one account. - var ok bool - for _, acc := range srv.wallet.Accounts { - err := acc.Decrypt(srv.Config.Wallet.Password, srv.wallet.Scrypt) - if err == nil { - ok = true - break - } - } + var ok = slices.ContainsFunc(srv.wallet.Accounts, func(acc *wallet.Account) bool { + return acc.Decrypt(srv.Config.Wallet.Password, srv.wallet.Scrypt) == nil + }) if !ok { return nil, errors.New("no account with provided password was found") } diff --git a/pkg/core/interop/runtime/witness.go b/pkg/core/interop/runtime/witness.go index 09c4335d4..783e12a71 100644 --- a/pkg/core/interop/runtime/witness.go +++ b/pkg/core/interop/runtime/witness.go @@ -4,6 +4,7 @@ import ( "crypto/elliptic" "errors" "fmt" + "slices" "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -79,10 +80,8 @@ func checkScope(ic *interop.Context, hash util.Uint160) (bool, error) { } if c.Scopes&transaction.CustomContracts != 0 { currentScriptHash := ic.VM.GetCurrentScriptHash() - for _, allowedContract := range c.AllowedContracts { - if allowedContract == currentScriptHash { - return true, nil - } + if slices.Contains(c.AllowedContracts, currentScriptHash) { + return true, nil } } if c.Scopes&transaction.CustomGroups != 0 { @@ -91,10 +90,8 @@ func checkScope(ic *interop.Context, hash util.Uint160) (bool, error) { return false, err } // check if the current group is the required one - for _, allowedGroup := range c.AllowedGroups { - if groups.Contains(allowedGroup) { - return true, nil - } + if slices.ContainsFunc(c.AllowedGroups, groups.Contains) { + return true, nil } } if c.Scopes&transaction.Rules != 0 { diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index 7965116de..e6c4835cc 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -71,12 +71,7 @@ func (keys *PublicKeys) Bytes() []byte { // Contains checks whether the passed param is contained in PublicKeys. func (keys PublicKeys) Contains(pKey *PublicKey) bool { - for _, key := range keys { - if key.Equal(pKey) { - return true - } - } - return false + return slices.ContainsFunc(keys, pKey.Equal) } // Copy returns a shallow copy of the PublicKeys slice. It creates a new slice with the same elements, diff --git a/pkg/services/notary/notary.go b/pkg/services/notary/notary.go index f326554d4..6639acbca 100644 --- a/pkg/services/notary/notary.go +++ b/pkg/services/notary/notary.go @@ -6,6 +6,7 @@ import ( "encoding/hex" "errors" "fmt" + "slices" "sync" "sync/atomic" @@ -131,18 +132,14 @@ func (r request) isMainCompleted() bool { // NewNotary returns a new Notary module. func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction func(tx *transaction.Transaction) error) (*Notary, error) { w := cfg.MainCfg.UnlockWallet - wallet, err := wallet.NewWalletFromFile(w.Path) + wall, err := wallet.NewWalletFromFile(w.Path) if err != nil { return nil, err } - haveAccount := false - for _, acc := range wallet.Accounts { - if err := acc.Decrypt(w.Password, wallet.Scrypt); err == nil { - haveAccount = true - break - } - } + var haveAccount = slices.ContainsFunc(wall.Accounts, func(acc *wallet.Account) bool { + return acc.Decrypt(w.Password, wall.Scrypt) == nil + }) if !haveAccount { return nil, errors.New("no wallet account could be unlocked") } @@ -151,7 +148,7 @@ func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction fu requests: make(map[util.Uint256]*request), Config: cfg, Network: net, - wallet: wallet, + wallet: wall, onTransaction: onTransaction, newTxs: make(chan txHashPair, defaultTxChannelCapacity), mp: mp, @@ -260,10 +257,10 @@ func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) { defer n.reqMtx.Unlock() r, exists := n.requests[payload.MainTransaction.Hash()] if exists { - for _, fb := range r.fallbacks { - if fb.Hash().Equals(payload.FallbackTransaction.Hash()) { - return // then we already have processed this request - } + if slices.ContainsFunc(r.fallbacks, func(fb *transaction.Transaction) bool { + return fb.Hash().Equals(payload.FallbackTransaction.Hash()) + }) { + return // then we already have processed this request } r.minNotValidBefore = min(r.minNotValidBefore, nvbFallback) } else { @@ -447,13 +444,9 @@ func (n *Notary) newTxCallbackLoop() { } if !isMain { // Ensure that fallback was not already completed. - var isPending bool - for _, fb := range r.fallbacks { - if fb.Hash() == tx.tx.Hash() { - isPending = true - break - } - } + var isPending = slices.ContainsFunc(r.fallbacks, func(fb *transaction.Transaction) bool { + return fb.Hash() == tx.tx.Hash() + }) if !isPending { n.reqMtx.Unlock() continue diff --git a/pkg/services/oracle/network.go b/pkg/services/oracle/network.go index 4af62d440..cafdbe414 100644 --- a/pkg/services/oracle/network.go +++ b/pkg/services/oracle/network.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "net/http" + "slices" "syscall" "github.com/nspcc-dev/neo-go/pkg/config" @@ -39,12 +40,9 @@ func isReserved(ip net.IP) bool { if !ip.IsGlobalUnicast() { return true } - for i := range privateNets { - if privateNets[i].Contains(ip) { - return true - } - } - return false + return slices.ContainsFunc(privateNets, func(pn net.IPNet) bool { + return pn.Contains(ip) + }) } func getDefaultClient(cfg config.OracleConfiguration) *http.Client { diff --git a/pkg/services/oracle/oracle.go b/pkg/services/oracle/oracle.go index 649677bea..e0c0c6906 100644 --- a/pkg/services/oracle/oracle.go +++ b/pkg/services/oracle/oracle.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "net/http" + "slices" "sync" "time" @@ -150,13 +151,9 @@ func NewOracle(cfg Config) (*Oracle, error) { return nil, err } - haveAccount := false - for _, acc := range o.wallet.Accounts { - if err := acc.Decrypt(w.Password, o.wallet.Scrypt); err == nil { - haveAccount = true - break - } - } + var haveAccount = slices.ContainsFunc(o.wallet.Accounts, func(acc *wallet.Account) bool { + return acc.Decrypt(w.Password, o.wallet.Scrypt) == nil + }) if !haveAccount { return nil, errors.New("no wallet account could be unlocked") } diff --git a/pkg/services/oracle/request.go b/pkg/services/oracle/request.go index 1607fa56a..25d9a9107 100644 --- a/pkg/services/oracle/request.go +++ b/pkg/services/oracle/request.go @@ -6,6 +6,7 @@ import ( "mime" "net/http" "net/url" + "slices" "time" "github.com/nspcc-dev/neo-go/pkg/core/state" @@ -284,10 +285,5 @@ func checkMediaType(hdr string, allowed []string) bool { return false } - for _, ct := range allowed { - if ct == typ { - return true - } - } - return false + return slices.Contains(allowed, typ) } diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index e7123e88c..43eb61f90 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -3,6 +3,7 @@ package stateroot import ( "errors" "fmt" + "slices" "sync" "sync/atomic" "time" @@ -112,13 +113,9 @@ func New(cfg config.StateRoot, sm *stateroot.Module, log *zap.Logger, bc Ledger, return nil, err } - haveAccount := false - for _, acc := range s.wallet.Accounts { - if err := acc.Decrypt(w.Password, s.wallet.Scrypt); err == nil { - haveAccount = true - break - } - } + var haveAccount = slices.ContainsFunc(s.wallet.Accounts, func(acc *wallet.Account) bool { + return acc.Decrypt(w.Password, s.wallet.Scrypt) == nil + }) if !haveAccount { return nil, errors.New("no wallet account could be unlocked") } diff --git a/pkg/smartcontract/context/context.go b/pkg/smartcontract/context/context.go index 2974e2675..2f842a239 100644 --- a/pkg/smartcontract/context/context.go +++ b/pkg/smartcontract/context/context.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "slices" "sort" "strings" @@ -111,13 +112,9 @@ func (c *ParameterContext) AddSignature(h util.Uint160, ctr *wallet.Contract, pu return errors.New("signature is already added") } pubBytes := pub.Bytes() - var contained bool - for i := range pubs { - if bytes.Equal(pubBytes, pubs[i]) { - contained = true - break - } - } + var contained = slices.ContainsFunc(pubs, func(p []byte) bool { + return bytes.Equal(pubBytes, p) + }) if !contained { return errors.New("public key is not present in script") } diff --git a/pkg/smartcontract/manifest/container.go b/pkg/smartcontract/manifest/container.go index 1e8adaeda..c65df8a59 100644 --- a/pkg/smartcontract/manifest/container.go +++ b/pkg/smartcontract/manifest/container.go @@ -7,6 +7,7 @@ package manifest import ( "bytes" "encoding/json" + "slices" ) // WildStrings represents a string set which can be a wildcard. @@ -25,12 +26,7 @@ func (c *WildStrings) Contains(v string) bool { if c.IsWildcard() { return true } - for _, s := range c.Value { - if v == s { - return true - } - } - return false + return slices.Contains(c.Value, v) } // Contains checks if v is in the container. @@ -38,12 +34,7 @@ func (c *WildPermissionDescs) Contains(v PermissionDesc) bool { if c.IsWildcard() { return true } - for _, u := range c.Value { - if u.Equals(v) { - return true - } - } - return false + return slices.ContainsFunc(c.Value, v.Equals) } // IsWildcard returns true iff the container is a wildcard. diff --git a/pkg/smartcontract/manifest/group.go b/pkg/smartcontract/manifest/group.go index 15485aa3c..d2473cbca 100644 --- a/pkg/smartcontract/manifest/group.go +++ b/pkg/smartcontract/manifest/group.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "errors" + "slices" "sort" "github.com/nspcc-dev/neo-go/pkg/crypto/hash" @@ -71,12 +72,9 @@ func (g Groups) AreValid(h util.Uint160) error { } func (g Groups) Contains(k *keys.PublicKey) bool { - for i := range g { - if k.Equal(g[i].PublicKey) { - return true - } - } - return false + return slices.ContainsFunc(g, func(gr Group) bool { + return k.Equal(gr.PublicKey) + }) } // MarshalJSON implements the json.Marshaler interface. diff --git a/pkg/smartcontract/manifest/manifest.go b/pkg/smartcontract/manifest/manifest.go index 03d0103f9..40cb168ce 100644 --- a/pkg/smartcontract/manifest/manifest.go +++ b/pkg/smartcontract/manifest/manifest.go @@ -77,12 +77,9 @@ func DefaultManifest(name string) *Manifest { // CanCall returns true if the current contract is allowed to call // the method of another contract with the specified hash. func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) bool { - for i := range m.Permissions { - if m.Permissions[i].IsAllowed(hash, toCall, method) { - return true - } - } - return false + return slices.ContainsFunc(m.Permissions, func(p Permission) bool { + return p.IsAllowed(hash, toCall, method) + }) } // IsValid checks manifest internal consistency and correctness, one of the @@ -95,10 +92,8 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error { return errors.New("no name") } - for i := range m.SupportedStandards { - if m.SupportedStandards[i] == "" { - return errors.New("invalid nameless supported standard") - } + if slices.Contains(m.SupportedStandards, "") { + return errors.New("invalid nameless supported standard") } if len(m.SupportedStandards) > 1 { names := slices.Clone(m.SupportedStandards) @@ -153,12 +148,7 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error { // IsStandardSupported denotes whether the specified standard is supported by the contract. func (m *Manifest) IsStandardSupported(standard string) bool { - for _, st := range m.SupportedStandards { - if st == standard { - return true - } - } - return false + return slices.Contains(m.SupportedStandards, standard) } // ToStackItem converts Manifest to stackitem.Item. diff --git a/pkg/smartcontract/manifest/permission.go b/pkg/smartcontract/manifest/permission.go index 08d788054..bf5657a08 100644 --- a/pkg/smartcontract/manifest/permission.go +++ b/pkg/smartcontract/manifest/permission.go @@ -121,10 +121,8 @@ func (d *PermissionDesc) Equals(v PermissionDesc) bool { // IsValid checks if Permission is correct. func (p *Permission) IsValid() error { - for i := range p.Methods.Value { - if p.Methods.Value[i] == "" { - return errors.New("empty method name") - } + if slices.Contains(p.Methods.Value, "") { + return errors.New("empty method name") } if len(p.Methods.Value) < 2 { return nil @@ -166,17 +164,10 @@ func (p *Permission) IsAllowed(hash util.Uint160, m *Manifest, method string) bo return false } case PermissionGroup: - has := false - g := p.Contract.Group() - for i := range m.Groups { - if g.Equal(m.Groups[i].PublicKey) { - has = true - break - } - } - if !has { - return false - } + contractG := p.Contract.Group() + return slices.ContainsFunc(m.Groups, func(manifestG Group) bool { + return contractG.Equal(manifestG.PublicKey) + }) default: panic(fmt.Sprintf("unexpected permission: %d", p.Contract.Type)) } diff --git a/pkg/vm/stackitem/item.go b/pkg/vm/stackitem/item.go index 2298eb20a..0b793d291 100644 --- a/pkg/vm/stackitem/item.go +++ b/pkg/vm/stackitem/item.go @@ -876,12 +876,9 @@ func (i *Map) String() string { // Index returns an index of the key in map. func (i *Map) Index(key Item) int { - for k := range i.value { - if i.value[k].Key.Equals(key) { - return k - } - } - return -1 + return slices.IndexFunc(i.value, func(e MapElement) bool { + return e.Key.Equals(key) + }) } // Has checks if the map has the specified key. diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 2c485139a..39ea54124 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -1873,7 +1873,10 @@ func (v *VM) ContractHasTryBlock() bool { // CheckMultisigPar checks if the sigs contains sufficient valid signatures. func CheckMultisigPar(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sigs [][]byte) bool { if len(sigs) == 1 { - return checkMultisig1(v, curve, h, pkeys, sigs[0]) + return slices.ContainsFunc(pkeys, func(keyb []byte) bool { + pkey := bytesToPublicKey(keyb, curve) + return pkey.Verify(sigs[0], h) + }) } k1, k2 := 0, len(pkeys)-1 @@ -1963,17 +1966,6 @@ loop: return sigok } -func checkMultisig1(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sig []byte) bool { - for i := range pkeys { - pkey := bytesToPublicKey(pkeys[i], curve) - if pkey.Verify(sig, h) { - return true - } - } - - return false -} - func cloneIfStruct(item stackitem.Item) stackitem.Item { switch it := item.(type) { case *stackitem.Struct: diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index 50a5d91f1..0702dc6e0 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -3,6 +3,7 @@ package wallet import ( "errors" "fmt" + "slices" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -111,24 +112,16 @@ func NewContractAccount(hash util.Uint160, args ...any) *Account { // SignTx signs transaction t and updates it's Witnesses. func (a *Account) SignTx(net netmode.Magic, t *transaction.Transaction) error { - var ( - haveAcc bool - pos int - ) if a.Locked { return errors.New("account is locked") } if a.Contract == nil { return errors.New("account has no contract") } - for i := range t.Signers { - if t.Signers[i].Account.Equals(a.ScriptHash()) { - haveAcc = true - pos = i - break - } - } - if !haveAcc { + var pos = slices.IndexFunc(t.Signers, func(s transaction.Signer) bool { + return s.Account.Equals(a.ScriptHash()) + }) + if pos == -1 { return errors.New("transaction is not signed by this account") } if len(t.Scripts) < pos { @@ -289,15 +282,7 @@ func (a *Account) ConvertMultisig(m int, pubs []*keys.PublicKey) error { // with m sufficient signatures. The encrypted private key is not modified and // remains the same. func (a *Account) ConvertMultisigEncrypted(accKey *keys.PublicKey, m int, pubs []*keys.PublicKey) error { - var found bool - for i := range pubs { - if accKey.Equal(pubs[i]) { - found = true - break - } - } - - if !found { + if !slices.ContainsFunc(pubs, accKey.Equal) { return errors.New("own public key was not found among multisig keys") }