*: use slices.Index/slices.Contains where appropriate

This doesn't touch performance-sensitive parts, but simplifies a lot of code.

Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
Roman Khimov 2024-08-24 22:03:41 +03:00
parent 9cce148d83
commit a30792dbb6
19 changed files with 79 additions and 179 deletions

View file

@ -8,6 +8,7 @@ import (
"io" "io"
"math/big" "math/big"
"os" "os"
"slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/cli/cmdargs" "github.com/nspcc-dev/neo-go/cli/cmdargs"
@ -512,16 +513,13 @@ func exportKeys(ctx *cli.Context) error {
var wifs []string var wifs []string
loop:
for _, a := range wall.Accounts { for _, a := range wall.Accounts {
if addr != "" && a.Address != addr { if addr != "" && a.Address != addr {
continue continue
} }
for i := range wifs { if slices.Contains(wifs, a.EncryptedWIF) {
if a.EncryptedWIF == wifs[i] { continue
continue loop
}
} }
wifs = append(wifs, a.EncryptedWIF) wifs = append(wifs, a.EncryptedWIF)

View file

@ -6,6 +6,7 @@ import (
"go/ast" "go/ast"
"go/token" "go/token"
"go/types" "go/types"
"slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/vm/emit" "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 { func isGoBuiltin(name string) bool {
for i := range goBuiltins { return slices.Contains(goBuiltins, name)
if name == goBuiltins[i] {
return true
}
}
return false
} }
func isPotentialCustomBuiltin(f *funcScope, expr ast.Expr) bool { func isPotentialCustomBuiltin(f *funcScope, expr ast.Expr) bool {

View file

@ -3,6 +3,7 @@ package compiler
import ( import (
"go/ast" "go/ast"
"go/types" "go/types"
"slices"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "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 { func isBasicTypeOfKind(typ types.Type, ks ...types.BasicKind) bool {
if t, ok := typ.Underlying().(*types.Basic); ok { if t, ok := typ.Underlying().(*types.Basic); ok {
k := t.Kind() k := t.Kind()
for i := range ks { return slices.Contains(ks, k)
if k == ks[i] {
return true
}
}
} }
return false return false
} }

View file

@ -167,14 +167,9 @@ func NewService(cfg Config) (Service, error) {
} }
// Check that the wallet password is correct for at least one account. // Check that the wallet password is correct for at least one account.
var ok bool var ok = slices.ContainsFunc(srv.wallet.Accounts, func(acc *wallet.Account) bool {
for _, acc := range srv.wallet.Accounts { return acc.Decrypt(srv.Config.Wallet.Password, srv.wallet.Scrypt) == nil
err := acc.Decrypt(srv.Config.Wallet.Password, srv.wallet.Scrypt) })
if err == nil {
ok = true
break
}
}
if !ok { if !ok {
return nil, errors.New("no account with provided password was found") return nil, errors.New("no account with provided password was found")
} }

View file

@ -4,6 +4,7 @@ import (
"crypto/elliptic" "crypto/elliptic"
"errors" "errors"
"fmt" "fmt"
"slices"
"github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
@ -79,24 +80,20 @@ func checkScope(ic *interop.Context, hash util.Uint160) (bool, error) {
} }
if c.Scopes&transaction.CustomContracts != 0 { if c.Scopes&transaction.CustomContracts != 0 {
currentScriptHash := ic.VM.GetCurrentScriptHash() currentScriptHash := ic.VM.GetCurrentScriptHash()
for _, allowedContract := range c.AllowedContracts { if slices.Contains(c.AllowedContracts, currentScriptHash) {
if allowedContract == currentScriptHash {
return true, nil return true, nil
} }
} }
}
if c.Scopes&transaction.CustomGroups != 0 { if c.Scopes&transaction.CustomGroups != 0 {
groups, err := getContractGroups(ic.VM, ic, ic.VM.GetCurrentScriptHash()) groups, err := getContractGroups(ic.VM, ic, ic.VM.GetCurrentScriptHash())
if err != nil { if err != nil {
return false, err return false, err
} }
// check if the current group is the required one // check if the current group is the required one
for _, allowedGroup := range c.AllowedGroups { if slices.ContainsFunc(c.AllowedGroups, groups.Contains) {
if groups.Contains(allowedGroup) {
return true, nil return true, nil
} }
} }
}
if c.Scopes&transaction.Rules != 0 { if c.Scopes&transaction.Rules != 0 {
ctx := scopeContext{ic.VM, ic} ctx := scopeContext{ic.VM, ic}
for _, r := range c.Rules { for _, r := range c.Rules {

View file

@ -71,12 +71,7 @@ func (keys *PublicKeys) Bytes() []byte {
// Contains checks whether the passed param is contained in PublicKeys. // Contains checks whether the passed param is contained in PublicKeys.
func (keys PublicKeys) Contains(pKey *PublicKey) bool { func (keys PublicKeys) Contains(pKey *PublicKey) bool {
for _, key := range keys { return slices.ContainsFunc(keys, pKey.Equal)
if key.Equal(pKey) {
return true
}
}
return false
} }
// Copy returns a shallow copy of the PublicKeys slice. It creates a new slice with the same elements, // Copy returns a shallow copy of the PublicKeys slice. It creates a new slice with the same elements,

View file

@ -6,6 +6,7 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"slices"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -131,18 +132,14 @@ func (r request) isMainCompleted() bool {
// NewNotary returns a new Notary module. // NewNotary returns a new Notary module.
func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction func(tx *transaction.Transaction) error) (*Notary, error) { func NewNotary(cfg Config, net netmode.Magic, mp *mempool.Pool, onTransaction func(tx *transaction.Transaction) error) (*Notary, error) {
w := cfg.MainCfg.UnlockWallet w := cfg.MainCfg.UnlockWallet
wallet, err := wallet.NewWalletFromFile(w.Path) wall, err := wallet.NewWalletFromFile(w.Path)
if err != nil { if err != nil {
return nil, err return nil, err
} }
haveAccount := false var haveAccount = slices.ContainsFunc(wall.Accounts, func(acc *wallet.Account) bool {
for _, acc := range wallet.Accounts { return acc.Decrypt(w.Password, wall.Scrypt) == nil
if err := acc.Decrypt(w.Password, wallet.Scrypt); err == nil { })
haveAccount = true
break
}
}
if !haveAccount { if !haveAccount {
return nil, errors.New("no wallet account could be unlocked") 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), requests: make(map[util.Uint256]*request),
Config: cfg, Config: cfg,
Network: net, Network: net,
wallet: wallet, wallet: wall,
onTransaction: onTransaction, onTransaction: onTransaction,
newTxs: make(chan txHashPair, defaultTxChannelCapacity), newTxs: make(chan txHashPair, defaultTxChannelCapacity),
mp: mp, mp: mp,
@ -260,11 +257,11 @@ func (n *Notary) OnNewRequest(payload *payload.P2PNotaryRequest) {
defer n.reqMtx.Unlock() defer n.reqMtx.Unlock()
r, exists := n.requests[payload.MainTransaction.Hash()] r, exists := n.requests[payload.MainTransaction.Hash()]
if exists { if exists {
for _, fb := range r.fallbacks { if slices.ContainsFunc(r.fallbacks, func(fb *transaction.Transaction) bool {
if fb.Hash().Equals(payload.FallbackTransaction.Hash()) { return fb.Hash().Equals(payload.FallbackTransaction.Hash())
}) {
return // then we already have processed this request return // then we already have processed this request
} }
}
r.minNotValidBefore = min(r.minNotValidBefore, nvbFallback) r.minNotValidBefore = min(r.minNotValidBefore, nvbFallback)
} else { } else {
// Avoid changes in the main transaction witnesses got from the notary request pool to // Avoid changes in the main transaction witnesses got from the notary request pool to
@ -447,13 +444,9 @@ func (n *Notary) newTxCallbackLoop() {
} }
if !isMain { if !isMain {
// Ensure that fallback was not already completed. // Ensure that fallback was not already completed.
var isPending bool var isPending = slices.ContainsFunc(r.fallbacks, func(fb *transaction.Transaction) bool {
for _, fb := range r.fallbacks { return fb.Hash() == tx.tx.Hash()
if fb.Hash() == tx.tx.Hash() { })
isPending = true
break
}
}
if !isPending { if !isPending {
n.reqMtx.Unlock() n.reqMtx.Unlock()
continue continue

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"slices"
"syscall" "syscall"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -39,12 +40,9 @@ func isReserved(ip net.IP) bool {
if !ip.IsGlobalUnicast() { if !ip.IsGlobalUnicast() {
return true return true
} }
for i := range privateNets { return slices.ContainsFunc(privateNets, func(pn net.IPNet) bool {
if privateNets[i].Contains(ip) { return pn.Contains(ip)
return true })
}
}
return false
} }
func getDefaultClient(cfg config.OracleConfiguration) *http.Client { func getDefaultClient(cfg config.OracleConfiguration) *http.Client {

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"errors" "errors"
"net/http" "net/http"
"slices"
"sync" "sync"
"time" "time"
@ -150,13 +151,9 @@ func NewOracle(cfg Config) (*Oracle, error) {
return nil, err return nil, err
} }
haveAccount := false var haveAccount = slices.ContainsFunc(o.wallet.Accounts, func(acc *wallet.Account) bool {
for _, acc := range o.wallet.Accounts { return acc.Decrypt(w.Password, o.wallet.Scrypt) == nil
if err := acc.Decrypt(w.Password, o.wallet.Scrypt); err == nil { })
haveAccount = true
break
}
}
if !haveAccount { if !haveAccount {
return nil, errors.New("no wallet account could be unlocked") return nil, errors.New("no wallet account could be unlocked")
} }

View file

@ -6,6 +6,7 @@ import (
"mime" "mime"
"net/http" "net/http"
"net/url" "net/url"
"slices"
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
@ -284,10 +285,5 @@ func checkMediaType(hdr string, allowed []string) bool {
return false return false
} }
for _, ct := range allowed { return slices.Contains(allowed, typ)
if ct == typ {
return true
}
}
return false
} }

View file

@ -3,6 +3,7 @@ package stateroot
import ( import (
"errors" "errors"
"fmt" "fmt"
"slices"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -112,13 +113,9 @@ func New(cfg config.StateRoot, sm *stateroot.Module, log *zap.Logger, bc Ledger,
return nil, err return nil, err
} }
haveAccount := false var haveAccount = slices.ContainsFunc(s.wallet.Accounts, func(acc *wallet.Account) bool {
for _, acc := range s.wallet.Accounts { return acc.Decrypt(w.Password, s.wallet.Scrypt) == nil
if err := acc.Decrypt(w.Password, s.wallet.Scrypt); err == nil { })
haveAccount = true
break
}
}
if !haveAccount { if !haveAccount {
return nil, errors.New("no wallet account could be unlocked") return nil, errors.New("no wallet account could be unlocked")
} }

View file

@ -6,6 +6,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"slices"
"sort" "sort"
"strings" "strings"
@ -111,13 +112,9 @@ func (c *ParameterContext) AddSignature(h util.Uint160, ctr *wallet.Contract, pu
return errors.New("signature is already added") return errors.New("signature is already added")
} }
pubBytes := pub.Bytes() pubBytes := pub.Bytes()
var contained bool var contained = slices.ContainsFunc(pubs, func(p []byte) bool {
for i := range pubs { return bytes.Equal(pubBytes, p)
if bytes.Equal(pubBytes, pubs[i]) { })
contained = true
break
}
}
if !contained { if !contained {
return errors.New("public key is not present in script") return errors.New("public key is not present in script")
} }

View file

@ -7,6 +7,7 @@ package manifest
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"slices"
) )
// WildStrings represents a string set which can be a wildcard. // WildStrings represents a string set which can be a wildcard.
@ -25,12 +26,7 @@ func (c *WildStrings) Contains(v string) bool {
if c.IsWildcard() { if c.IsWildcard() {
return true return true
} }
for _, s := range c.Value { return slices.Contains(c.Value, v)
if v == s {
return true
}
}
return false
} }
// Contains checks if v is in the container. // Contains checks if v is in the container.
@ -38,12 +34,7 @@ func (c *WildPermissionDescs) Contains(v PermissionDesc) bool {
if c.IsWildcard() { if c.IsWildcard() {
return true return true
} }
for _, u := range c.Value { return slices.ContainsFunc(c.Value, v.Equals)
if u.Equals(v) {
return true
}
}
return false
} }
// IsWildcard returns true iff the container is a wildcard. // IsWildcard returns true iff the container is a wildcard.

View file

@ -5,6 +5,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"slices"
"sort" "sort"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "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 { func (g Groups) Contains(k *keys.PublicKey) bool {
for i := range g { return slices.ContainsFunc(g, func(gr Group) bool {
if k.Equal(g[i].PublicKey) { return k.Equal(gr.PublicKey)
return true })
}
}
return false
} }
// MarshalJSON implements the json.Marshaler interface. // MarshalJSON implements the json.Marshaler interface.

View file

@ -77,12 +77,9 @@ func DefaultManifest(name string) *Manifest {
// CanCall returns true if the current contract is allowed to call // CanCall returns true if the current contract is allowed to call
// the method of another contract with the specified hash. // the method of another contract with the specified hash.
func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) bool { func (m *Manifest) CanCall(hash util.Uint160, toCall *Manifest, method string) bool {
for i := range m.Permissions { return slices.ContainsFunc(m.Permissions, func(p Permission) bool {
if m.Permissions[i].IsAllowed(hash, toCall, method) { return p.IsAllowed(hash, toCall, method)
return true })
}
}
return false
} }
// IsValid checks manifest internal consistency and correctness, one of the // IsValid checks manifest internal consistency and correctness, one of the
@ -95,11 +92,9 @@ func (m *Manifest) IsValid(hash util.Uint160, checkSize bool) error {
return errors.New("no name") return errors.New("no name")
} }
for i := range m.SupportedStandards { if slices.Contains(m.SupportedStandards, "") {
if m.SupportedStandards[i] == "" {
return errors.New("invalid nameless supported standard") return errors.New("invalid nameless supported standard")
} }
}
if len(m.SupportedStandards) > 1 { if len(m.SupportedStandards) > 1 {
names := slices.Clone(m.SupportedStandards) names := slices.Clone(m.SupportedStandards)
if stringsHaveDups(names) { if stringsHaveDups(names) {
@ -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. // IsStandardSupported denotes whether the specified standard is supported by the contract.
func (m *Manifest) IsStandardSupported(standard string) bool { func (m *Manifest) IsStandardSupported(standard string) bool {
for _, st := range m.SupportedStandards { return slices.Contains(m.SupportedStandards, standard)
if st == standard {
return true
}
}
return false
} }
// ToStackItem converts Manifest to stackitem.Item. // ToStackItem converts Manifest to stackitem.Item.

View file

@ -121,11 +121,9 @@ func (d *PermissionDesc) Equals(v PermissionDesc) bool {
// IsValid checks if Permission is correct. // IsValid checks if Permission is correct.
func (p *Permission) IsValid() error { func (p *Permission) IsValid() error {
for i := range p.Methods.Value { if slices.Contains(p.Methods.Value, "") {
if p.Methods.Value[i] == "" {
return errors.New("empty method name") return errors.New("empty method name")
} }
}
if len(p.Methods.Value) < 2 { if len(p.Methods.Value) < 2 {
return nil return nil
} }
@ -166,17 +164,10 @@ func (p *Permission) IsAllowed(hash util.Uint160, m *Manifest, method string) bo
return false return false
} }
case PermissionGroup: case PermissionGroup:
has := false contractG := p.Contract.Group()
g := p.Contract.Group() return slices.ContainsFunc(m.Groups, func(manifestG Group) bool {
for i := range m.Groups { return contractG.Equal(manifestG.PublicKey)
if g.Equal(m.Groups[i].PublicKey) { })
has = true
break
}
}
if !has {
return false
}
default: default:
panic(fmt.Sprintf("unexpected permission: %d", p.Contract.Type)) panic(fmt.Sprintf("unexpected permission: %d", p.Contract.Type))
} }

View file

@ -876,12 +876,9 @@ func (i *Map) String() string {
// Index returns an index of the key in map. // Index returns an index of the key in map.
func (i *Map) Index(key Item) int { func (i *Map) Index(key Item) int {
for k := range i.value { return slices.IndexFunc(i.value, func(e MapElement) bool {
if i.value[k].Key.Equals(key) { return e.Key.Equals(key)
return k })
}
}
return -1
} }
// Has checks if the map has the specified key. // Has checks if the map has the specified key.

View file

@ -1873,7 +1873,10 @@ func (v *VM) ContractHasTryBlock() bool {
// CheckMultisigPar checks if the sigs contains sufficient valid signatures. // CheckMultisigPar checks if the sigs contains sufficient valid signatures.
func CheckMultisigPar(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sigs [][]byte) bool { func CheckMultisigPar(v *VM, curve elliptic.Curve, h []byte, pkeys [][]byte, sigs [][]byte) bool {
if len(sigs) == 1 { 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 k1, k2 := 0, len(pkeys)-1
@ -1963,17 +1966,6 @@ loop:
return sigok 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 { func cloneIfStruct(item stackitem.Item) stackitem.Item {
switch it := item.(type) { switch it := item.(type) {
case *stackitem.Struct: case *stackitem.Struct:

View file

@ -3,6 +3,7 @@ package wallet
import ( import (
"errors" "errors"
"fmt" "fmt"
"slices"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "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. // SignTx signs transaction t and updates it's Witnesses.
func (a *Account) SignTx(net netmode.Magic, t *transaction.Transaction) error { func (a *Account) SignTx(net netmode.Magic, t *transaction.Transaction) error {
var (
haveAcc bool
pos int
)
if a.Locked { if a.Locked {
return errors.New("account is locked") return errors.New("account is locked")
} }
if a.Contract == nil { if a.Contract == nil {
return errors.New("account has no contract") return errors.New("account has no contract")
} }
for i := range t.Signers { var pos = slices.IndexFunc(t.Signers, func(s transaction.Signer) bool {
if t.Signers[i].Account.Equals(a.ScriptHash()) { return s.Account.Equals(a.ScriptHash())
haveAcc = true })
pos = i if pos == -1 {
break
}
}
if !haveAcc {
return errors.New("transaction is not signed by this account") return errors.New("transaction is not signed by this account")
} }
if len(t.Scripts) < pos { 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 // with m sufficient signatures. The encrypted private key is not modified and
// remains the same. // remains the same.
func (a *Account) ConvertMultisigEncrypted(accKey *keys.PublicKey, m int, pubs []*keys.PublicKey) error { func (a *Account) ConvertMultisigEncrypted(accKey *keys.PublicKey, m int, pubs []*keys.PublicKey) error {
var found bool if !slices.ContainsFunc(pubs, accKey.Equal) {
for i := range pubs {
if accKey.Equal(pubs[i]) {
found = true
break
}
}
if !found {
return errors.New("own public key was not found among multisig keys") return errors.New("own public key was not found among multisig keys")
} }