Merge pull request #3563 from nspcc-dev/go-1.21

Go 1.21
This commit is contained in:
Anna Shaleva 2024-08-30 16:24:11 +05:00 committed by GitHub
commit ff979e7ad2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
138 changed files with 816 additions and 1139 deletions

View file

@ -53,7 +53,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.22' go-version: '1.23'
- name: Build CLI - name: Build CLI
run: make build run: make build
@ -135,7 +135,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.22' go-version: '1.23'
- name: Login to DockerHub - name: Login to DockerHub
if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') }} if: ${{ github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && github.event.inputs.push_image == 'true') }}

View file

@ -135,7 +135,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.22' go-version: '1.23'
cache: true cache: true
- name: Write coverage profile - name: Write coverage profile
@ -156,24 +156,24 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-22.04, windows-2022, macos-12, macos-14] os: [ubuntu-22.04, windows-2022, macos-12, macos-14]
go_versions: [ '1.20', '1.21', '1.22' ] go_versions: [ '1.21', '1.22', '1.23' ]
exclude: exclude:
# Only latest Go version for Windows and MacOS. # Only latest Go version for Windows and MacOS.
- os: windows-2022 - os: windows-2022
go_versions: '1.20' go_versions: '1.21'
- os: windows-2022 - os: windows-2022
go_versions: '1.21' go_versions: '1.22'
- os: macos-12
go_versions: '1.20'
- os: macos-12 - os: macos-12
go_versions: '1.21' go_versions: '1.21'
- os: macos-14 - os: macos-12
go_versions: '1.20' go_versions: '1.22'
- os: macos-14 - os: macos-14
go_versions: '1.21' go_versions: '1.21'
- os: macos-14
go_versions: '1.22'
# Exclude latest Go version for Ubuntu as Coverage uses it. # Exclude latest Go version for Ubuntu as Coverage uses it.
- os: ubuntu-22.04 - os: ubuntu-22.04
go_versions: '1.22' go_versions: '1.23'
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View file

@ -51,7 +51,7 @@ linters:
- decorder - decorder
- durationcheck - durationcheck
- errorlint - errorlint
- exportloopref - copyloopvar
- gofmt - gofmt
- misspell - misspell
- predeclared - predeclared

View file

@ -1,6 +1,6 @@
# Builder image # Builder image
# Keep go version in sync with Build GA job. # Keep go version in sync with Build GA job.
FROM golang:1.22-alpine as builder FROM golang:1.23-alpine as builder
# Display go version for information purposes. # Display go version for information purposes.
RUN go version RUN go version

View file

@ -1,6 +1,6 @@
# Builder image # Builder image
# Keep go version in sync with Build GA job. # Keep go version in sync with Build GA job.
FROM golang:1.22.0-windowsservercore-ltsc2022 as builder FROM golang:1.23.0-windowsservercore-ltsc2022 as builder
COPY . /neo-go COPY . /neo-go

View file

@ -3,7 +3,7 @@ REPONAME = "neo-go"
NETMODE ?= "privnet" NETMODE ?= "privnet"
BINARY=neo-go BINARY=neo-go
BINARY_PATH=./bin/$(BINARY)$(shell go env GOEXE) BINARY_PATH=./bin/$(BINARY)$(shell go env GOEXE)
GO_VERSION ?= 1.20 GO_VERSION ?= 1.23
DESTDIR = "" DESTDIR = ""
SYSCONFIGDIR = "/etc" SYSCONFIGDIR = "/etc"
BINDIR = "/usr/bin" BINDIR = "/usr/bin"

View file

@ -51,7 +51,7 @@ NeoGo, `:latest` points to the latest release) or build yourself.
### Building ### Building
Building NeoGo requires Go 1.20+ and `make`: Building NeoGo requires Go 1.21+ and `make`:
``` ```
make make

View file

@ -2,9 +2,10 @@ package query
import ( import (
"bytes" "bytes"
"cmp"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
@ -192,14 +193,18 @@ func queryCandidates(ctx *cli.Context) error {
return cli.Exit(err, 1) return cli.Exit(err, 1)
} }
sort.Slice(vals, func(i, j int) bool { slices.SortFunc(vals, func(a, b result.Candidate) int {
if vals[i].Active != vals[j].Active { if a.Active && !b.Active {
return vals[i].Active return 1
} }
if vals[i].Votes != vals[j].Votes { if !a.Active && b.Active {
return vals[i].Votes > vals[j].Votes return -1
} }
return vals[i].PublicKey.Cmp(&vals[j].PublicKey) == -1 res := cmp.Compare(a.Votes, b.Votes)
if res != 0 {
return res
}
return a.PublicKey.Cmp(&b.PublicKey)
}) })
var res []byte var res []byte
res = fmt.Appendf(res, "Key\tVotes\tCommittee\tConsensus\n") res = fmt.Appendf(res, "Key\tVotes\tCommittee\tConsensus\n")

View file

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

View file

@ -417,7 +417,7 @@ func initSmartContract(ctx *cli.Context) error {
gm := []byte("module " + contractName + ` gm := []byte("module " + contractName + `
go 1.20 go 1.21
require ( require (
github.com/nspcc-dev/neo-go/pkg/interop ` + ver + ` github.com/nspcc-dev/neo-go/pkg/interop ` + ver + `

View file

@ -64,8 +64,8 @@ func cancelTx(ctx *cli.Context) error {
if err != nil { if err != nil {
return err return err
} }
if mainTx != nil && t.NetworkFee < mainTx.NetworkFee+1 { if mainTx != nil {
t.NetworkFee = mainTx.NetworkFee + 1 t.NetworkFee = max(t.NetworkFee, mainTx.NetworkFee+1)
} }
t.NetworkFee += int64(flags.Fixed8FromContext(ctx, "gas")) t.NetworkFee += int64(flags.Fixed8FromContext(ctx, "gas"))
if mainTx != nil { if mainTx != nil {

View file

@ -12,6 +12,7 @@ import (
"io" "io"
"math/big" "math/big"
"os" "os"
"slices"
"strconv" "strconv"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
@ -41,7 +42,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef" "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/smartcontract/trigger"
"github.com/nspcc-dev/neo-go/pkg/util" "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"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/urfave/cli/v2" "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 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, "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 { if addr, err := address.StringToUint160(arg); err == nil {
buf = fmt.Appendf(buf, "Address to BE ScriptHash\t%s\n", addr) buf = fmt.Appendf(buf, "Address to BE ScriptHash\t%s\n", addr)

View file

@ -353,7 +353,7 @@ require (
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0 github.com/nspcc-dev/neo-go/pkg/interop v0.0.0
) )
replace github.com/nspcc-dev/neo-go/pkg/interop => ` + filepath.Join(wd, "../../pkg/interop") + ` replace github.com/nspcc-dev/neo-go/pkg/interop => ` + filepath.Join(wd, "../../pkg/interop") + `
go 1.20`) go 1.21`)
require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "go.mod"), goMod, os.ModePerm)) require.NoError(t, os.WriteFile(filepath.Join(tmpDir, "go.mod"), goMod, os.ModePerm))
return filename return filename
} }

View file

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

View file

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

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

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/engine module github.com/nspcc-dev/neo-go/examples/engine
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/events module github.com/nspcc-dev/neo-go/examples/events
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/iterator module github.com/nspcc-dev/neo-go/examples/iterator
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/nft module github.com/nspcc-dev/neo-go/examples/nft
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,6 +1,6 @@
module github.com/nspcc-dev/neo-go/examples/nft-nd-nns module github.com/nspcc-dev/neo-go/examples/nft-nd-nns
go 1.20 go 1.21
require ( require (
github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689 github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689

View file

@ -39,6 +39,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12 h1:npHgfD4Tl2WJS3AJaMUi5ynGDPUBfkg3U3fCzDyXZ+4= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12 h1:npHgfD4Tl2WJS3AJaMUi5ynGDPUBfkg3U3fCzDyXZ+4=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -55,6 +56,7 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@ -170,16 +172,19 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
@ -195,19 +200,25 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo= github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo=
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c/go.mod h1:kjBC9F8L25GR+kIHy/1KgG/KfcoGnVwIiyovgq1uszk=
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22 h1:n4ZaFCKt1pQJd7PXoMJabZWK9ejjbLOVrkl/lOUmshg= github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22 h1:n4ZaFCKt1pQJd7PXoMJabZWK9ejjbLOVrkl/lOUmshg=
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U= github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U=
github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y= github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689 h1:WnEdGAQwaW0C8wnNnQZ+rM/JfFKZDSTOqwm8cS0TOdk= github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689 h1:WnEdGAQwaW0C8wnNnQZ+rM/JfFKZDSTOqwm8cS0TOdk=
github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689/go.mod h1:x+wmcYqpZYJwLp1l/pHZrqNp3RSWlkMymWGDij3/OPo= github.com/nspcc-dev/neo-go v0.102.1-0.20231020181554-d89c8801d689/go.mod h1:x+wmcYqpZYJwLp1l/pHZrqNp3RSWlkMymWGDij3/OPo=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec h1:vDrbVXF2+2uP0RlkZmem3QYATcXCu9BzzGGCNsNcK7Q= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec h1:vDrbVXF2+2uP0RlkZmem3QYATcXCu9BzzGGCNsNcK7Q=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec/go.mod h1:/vrbWSHc7YS1KSYhVOyyeucXW/e+1DkVBOgnBEXUCeY= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec/go.mod h1:/vrbWSHc7YS1KSYhVOyyeucXW/e+1DkVBOgnBEXUCeY=
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 h1:jhuN8Ldqz7WApvUJRFY0bjRXE1R3iCkboMX5QVZhHVk= github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 h1:jhuN8Ldqz7WApvUJRFY0bjRXE1R3iCkboMX5QVZhHVk=
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM=
github.com/nspcc-dev/neofs-crypto v0.4.0 h1:5LlrUAM5O0k1+sH/sktBtrgfWtq1pgpDs09fZo+KYi4= github.com/nspcc-dev/neofs-crypto v0.4.0 h1:5LlrUAM5O0k1+sH/sktBtrgfWtq1pgpDs09fZo+KYi4=
github.com/nspcc-dev/neofs-crypto v0.4.0/go.mod h1:6XJ8kbXgOfevbI2WMruOtI+qUJXNwSGM/E9eClXxPHs=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11 h1:QOc8ZRN5DXlAeRPh5QG9u8rMLgoeRNiZF5/vL7QupWg= github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11 h1:QOc8ZRN5DXlAeRPh5QG9u8rMLgoeRNiZF5/vL7QupWg=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11/go.mod h1:W+ImTNRnSNMH8w43H1knCcIqwu7dLHePXtlJNZ7EFIs=
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE= github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
github.com/nspcc-dev/tzhash v1.7.0 h1:/+aL33NC7y5OIGnY2kYgjZt8mg7LVGFMdj/KAJLndnk= github.com/nspcc-dev/tzhash v1.7.0 h1:/+aL33NC7y5OIGnY2kYgjZt8mg7LVGFMdj/KAJLndnk=
github.com/nspcc-dev/tzhash v1.7.0/go.mod h1:Dnx9LUlOLr5paL2Rtc96x0PPs8D9eIkUtowt1n+KQus=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -218,6 +229,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -260,6 +272,7 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -288,6 +301,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
@ -311,6 +325,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -368,6 +383,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -562,6 +578,7 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -581,6 +598,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/nft-nd module github.com/nspcc-dev/neo-go/examples/nft-nd
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/oracle module github.com/nspcc-dev/neo-go/examples/oracle
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/runtime module github.com/nspcc-dev/neo-go/examples/runtime
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/storage module github.com/nspcc-dev/neo-go/examples/storage
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/timer module github.com/nspcc-dev/neo-go/examples/timer
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/token module github.com/nspcc-dev/neo-go/examples/token
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

View file

@ -1,10 +1,10 @@
module github.com/nspcc-dev/neo-go/examples/zkp/cubic module github.com/nspcc-dev/neo-go/examples/zkp/cubic
go 1.20 go 1.21
require ( require (
github.com/consensys/gnark v0.9.1 github.com/consensys/gnark v0.10.0
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e
github.com/nspcc-dev/neo-go v0.103.1 github.com/nspcc-dev/neo-go v0.103.1
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
) )
@ -27,6 +27,8 @@ require (
github.com/gorilla/websocket v1.4.2 // indirect github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect
github.com/holiman/uint256 v1.2.0 // indirect github.com/holiman/uint256 v1.2.0 // indirect
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 // indirect
github.com/ingonyama-zk/iciclegnark v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect

View file

@ -39,6 +39,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12 h1:npHgfD4Tl2WJS3AJaMUi5ynGDPUBfkg3U3fCzDyXZ+4= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12 h1:npHgfD4Tl2WJS3AJaMUi5ynGDPUBfkg3U3fCzDyXZ+4=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20221202181307-76fa05c21b12/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@ -57,15 +58,16 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark v0.9.1 h1:aTwBp5469MY/2jNrf4ABrqHRW3+JytfkADdw4ZBY7T0= github.com/consensys/gnark v0.10.0 h1:yhi6ThoeFP7WrH8zQDaO56WVXe9iJEBSkfrZ9PZxabw=
github.com/consensys/gnark v0.9.1/go.mod h1:udWvWGXnfBE7mn7BsNoGAvZDnUhcONBEtNijvVjfY80= github.com/consensys/gnark v0.10.0/go.mod h1:VJU5JrrhZorbfDH+EUjcuFWr2c5z19tHPh8D6KVQksU=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb h1:f0BMgIjhZy4lSRHCXFbQst85f5agZAjtDMixQqBWNpc= github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e h1:MKdOuCiy2DAX1tMp2YsmtNDaqdigpY6B5cZQDJ9BvEo=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@ -141,6 +143,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@ -169,6 +172,10 @@ github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM
github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 h1:YxI1RTPzpFJ3MBmxPl3Bo0F7ume7CmQEC1M9jL6CT94=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71/go.mod h1:kAK8/EoN7fUEmakzgZIYdWy1a2rBnpCaZLqSHwZWxEk=
github.com/ingonyama-zk/iciclegnark v0.1.0 h1:88MkEghzjQBMjrYRJFxZ9oR9CTIpB8NG2zLeCJSvXKQ=
github.com/ingonyama-zk/iciclegnark v0.1.0/go.mod h1:wz6+IpyHKs6UhMMoQpNqz1VY+ddfKqC/gRwR/64W6WU=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@ -179,16 +186,20 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -211,19 +222,25 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo= github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c h1:uyK5aLbAhrnZtnvobJLN24gGUrlxIJAAFqiWl+liZuo=
github.com/nspcc-dev/dbft v0.0.0-20230515113611-25db6ba61d5c/go.mod h1:kjBC9F8L25GR+kIHy/1KgG/KfcoGnVwIiyovgq1uszk=
github.com/nspcc-dev/go-ordered-json v0.0.0-20231123160306-3374ff1e7a3c h1:OOQeE613BH93ICPq3eke5N78gWNeMjcBWkmD2NKyXVg= github.com/nspcc-dev/go-ordered-json v0.0.0-20231123160306-3374ff1e7a3c h1:OOQeE613BH93ICPq3eke5N78gWNeMjcBWkmD2NKyXVg=
github.com/nspcc-dev/go-ordered-json v0.0.0-20231123160306-3374ff1e7a3c/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U= github.com/nspcc-dev/go-ordered-json v0.0.0-20231123160306-3374ff1e7a3c/go.mod h1:79bEUDEviBHJMFV6Iq6in57FEOCMcRhfQnfaf0ETA5U=
github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y= github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
github.com/nspcc-dev/neo-go v0.103.1 h1:BfRBceHUu8jSc1KQy7CzmQ/pa+xzAmgcyteGf0/IGgM= github.com/nspcc-dev/neo-go v0.103.1 h1:BfRBceHUu8jSc1KQy7CzmQ/pa+xzAmgcyteGf0/IGgM=
github.com/nspcc-dev/neo-go v0.103.1/go.mod h1:MD7MPiyshUwrE5n1/LzxeandbItaa/iLW/bJb6gNs/U= github.com/nspcc-dev/neo-go v0.103.1/go.mod h1:MD7MPiyshUwrE5n1/LzxeandbItaa/iLW/bJb6gNs/U=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec h1:vDrbVXF2+2uP0RlkZmem3QYATcXCu9BzzGGCNsNcK7Q= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec h1:vDrbVXF2+2uP0RlkZmem3QYATcXCu9BzzGGCNsNcK7Q=
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec/go.mod h1:/vrbWSHc7YS1KSYhVOyyeucXW/e+1DkVBOgnBEXUCeY= github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec/go.mod h1:/vrbWSHc7YS1KSYhVOyyeucXW/e+1DkVBOgnBEXUCeY=
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 h1:jhuN8Ldqz7WApvUJRFY0bjRXE1R3iCkboMX5QVZhHVk= github.com/nspcc-dev/neofs-api-go/v2 v2.14.0 h1:jhuN8Ldqz7WApvUJRFY0bjRXE1R3iCkboMX5QVZhHVk=
github.com/nspcc-dev/neofs-api-go/v2 v2.14.0/go.mod h1:DRIr0Ic1s+6QgdqmNFNLIqMqd7lNMJfYwkczlm1hDtM=
github.com/nspcc-dev/neofs-crypto v0.4.0 h1:5LlrUAM5O0k1+sH/sktBtrgfWtq1pgpDs09fZo+KYi4= github.com/nspcc-dev/neofs-crypto v0.4.0 h1:5LlrUAM5O0k1+sH/sktBtrgfWtq1pgpDs09fZo+KYi4=
github.com/nspcc-dev/neofs-crypto v0.4.0/go.mod h1:6XJ8kbXgOfevbI2WMruOtI+qUJXNwSGM/E9eClXxPHs=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11 h1:QOc8ZRN5DXlAeRPh5QG9u8rMLgoeRNiZF5/vL7QupWg= github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11 h1:QOc8ZRN5DXlAeRPh5QG9u8rMLgoeRNiZF5/vL7QupWg=
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.11/go.mod h1:W+ImTNRnSNMH8w43H1knCcIqwu7dLHePXtlJNZ7EFIs=
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE= github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso= github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
github.com/nspcc-dev/tzhash v1.7.0 h1:/+aL33NC7y5OIGnY2kYgjZt8mg7LVGFMdj/KAJLndnk= github.com/nspcc-dev/tzhash v1.7.0 h1:/+aL33NC7y5OIGnY2kYgjZt8mg7LVGFMdj/KAJLndnk=
github.com/nspcc-dev/tzhash v1.7.0/go.mod h1:Dnx9LUlOLr5paL2Rtc96x0PPs8D9eIkUtowt1n+KQus=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@ -234,6 +251,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@ -267,6 +285,7 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
@ -278,6 +297,7 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -308,6 +328,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
@ -331,6 +352,7 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -388,6 +410,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -586,6 +609,7 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -605,6 +629,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/examples/zkp/xor module github.com/nspcc-dev/neo-go/examples/zkp/xor
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

8
go.mod
View file

@ -1,11 +1,11 @@
module github.com/nspcc-dev/neo-go module github.com/nspcc-dev/neo-go
go 1.20 go 1.21
require ( require (
github.com/chzyer/readline v1.5.1 github.com/chzyer/readline v1.5.1
github.com/consensys/gnark v0.9.1 github.com/consensys/gnark v0.10.0
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
@ -48,6 +48,8 @@ require (
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.1 // indirect github.com/golang/snappy v0.0.1 // indirect
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 // indirect
github.com/ingonyama-zk/iciclegnark v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect

19
go.sum
View file

@ -16,10 +16,10 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark v0.9.1 h1:aTwBp5469MY/2jNrf4ABrqHRW3+JytfkADdw4ZBY7T0= github.com/consensys/gnark v0.10.0 h1:yhi6ThoeFP7WrH8zQDaO56WVXe9iJEBSkfrZ9PZxabw=
github.com/consensys/gnark v0.9.1/go.mod h1:udWvWGXnfBE7mn7BsNoGAvZDnUhcONBEtNijvVjfY80= github.com/consensys/gnark v0.10.0/go.mod h1:VJU5JrrhZorbfDH+EUjcuFWr2c5z19tHPh8D6KVQksU=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb h1:f0BMgIjhZy4lSRHCXFbQst85f5agZAjtDMixQqBWNpc= github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e h1:MKdOuCiy2DAX1tMp2YsmtNDaqdigpY6B5cZQDJ9BvEo=
github.com/consensys/gnark-crypto v0.12.2-0.20231013160410-1f65e75b6dfb/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/consensys/gnark-crypto v0.12.2-0.20240215234832-d72fcb379d3e/go.mod h1:wKqwsieaKPThcFkHe0d0zMsbHEUWFmZcG7KBCse210o=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@ -54,6 +54,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo= github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo=
github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
@ -66,6 +67,10 @@ github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyf
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71 h1:YxI1RTPzpFJ3MBmxPl3Bo0F7ume7CmQEC1M9jL6CT94=
github.com/ingonyama-zk/icicle v0.0.0-20230928131117-97f0079e5c71/go.mod h1:kAK8/EoN7fUEmakzgZIYdWy1a2rBnpCaZLqSHwZWxEk=
github.com/ingonyama-zk/iciclegnark v0.1.0 h1:88MkEghzjQBMjrYRJFxZ9oR9CTIpB8NG2zLeCJSvXKQ=
github.com/ingonyama-zk/iciclegnark v0.1.0/go.mod h1:wz6+IpyHKs6UhMMoQpNqz1VY+ddfKqC/gRwR/64W6WU=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@ -73,6 +78,7 @@ github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3x
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
@ -126,6 +132,7 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c=
github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w=
@ -146,6 +153,7 @@ github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQut
go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@ -166,6 +174,7 @@ golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -211,12 +220,14 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=

View file

@ -1,5 +1,5 @@
module github.com/nspcc-dev/neo-go/internal/examples/oracle module github.com/nspcc-dev/neo-go/internal/examples/oracle
go 1.20 go 1.21
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20240727093519-1a48f1ce43ec

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"
@ -118,9 +119,7 @@ func (c *codegen) traverseGlobals() bool {
var currMax int var currMax int
lastCnt, currMax = c.convertInitFuncs(f, pkg.Types, lastCnt) lastCnt, currMax = c.convertInitFuncs(f, pkg.Types, lastCnt)
if currMax > maxCnt { maxCnt = max(currMax, maxCnt)
maxCnt = currMax
}
} }
// because we reuse `convertFuncDecl` for init funcs, // because we reuse `convertFuncDecl` for init funcs,
// we need to clear scope, so that global variables // we need to clear scope, so that global variables
@ -128,9 +127,7 @@ func (c *codegen) traverseGlobals() bool {
c.scope = nil c.scope = nil
}) })
if c.globalInlineCount > maxCnt { maxCnt = max(c.globalInlineCount, maxCnt)
maxCnt = c.globalInlineCount
}
// Here we remove `INITSLOT` if no code was emitted for `init` function. // Here we remove `INITSLOT` if no code was emitted for `init` function.
// Note that the `INITSSLOT` must stay in place. // Note that the `INITSSLOT` must stay in place.
@ -701,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

@ -1,6 +1,7 @@
package compiler package compiler
import ( import (
"cmp"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
@ -10,7 +11,7 @@ import (
"go/types" "go/types"
"math" "math"
"math/big" "math/big"
"sort" "slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
@ -402,9 +403,7 @@ func (c *codegen) convertInitFuncs(f *ast.File, pkg *types.Package, lastCount in
f := c.convertFuncDecl(f, n, pkg) f := c.convertFuncDecl(f, n, pkg)
lastCount = f.vars.localsCnt lastCount = f.vars.localsCnt
if lastCount > maxCount { maxCount = max(lastCount, maxCount)
maxCount = lastCount
}
} }
case *ast.GenDecl: case *ast.GenDecl:
return false return false
@ -437,9 +436,7 @@ func (c *codegen) convertDeployFuncs() int {
f := c.convertFuncDecl(f, n, pkg) f := c.convertFuncDecl(f, n, pkg)
lastCount = f.vars.localsCnt lastCount = f.vars.localsCnt
if lastCount > maxCount { maxCount = max(lastCount, maxCount)
maxCount = lastCount
}
} }
case *ast.GenDecl: case *ast.GenDecl:
return false return false
@ -2257,7 +2254,7 @@ func (c *codegen) compile(info *buildInfo, pkg *packages.Package) error {
for _, p := range info.program { for _, p := range info.program {
keys = append(keys, p.Types) keys = append(keys, p.Types)
} }
sort.Slice(keys, func(i, j int) bool { return keys[i].Path() < keys[j].Path() }) slices.SortFunc(keys, func(a, b *types.Package) int { return cmp.Compare(a.Path(), b.Path()) })
// Generate the code for the program. // Generate the code for the program.
c.ForEachFile(func(f *ast.File, pkg *types.Package) { c.ForEachFile(func(f *ast.File, pkg *types.Package) {
@ -2539,9 +2536,7 @@ func removeNOPs(b []byte, nopOffsets []int, sequencePoints map[string][]DebugSeq
func calcOffsetCorrection(ip, target int, offsets []int) int { func calcOffsetCorrection(ip, target int, offsets []int) int {
cnt := 0 cnt := 0
start := sort.Search(len(offsets), func(i int) bool { start, _ := slices.BinarySearch(offsets, min(ip, target))
return offsets[i] >= ip || offsets[i] >= target
})
for i := start; i < len(offsets) && (offsets[i] < target || offsets[i] <= ip); i++ { for i := start; i < len(offsets) && (offsets[i] < target || offsets[i] <= ip); i++ {
ind := offsets[i] ind := offsets[i]
if ip <= ind && ind < target || target <= ind && ind < ip { if ip <= ind && ind < target || target <= ind && ind < ip {

View file

@ -11,7 +11,7 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"sort" "slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -362,7 +362,7 @@ func CompileAndSave(src string, o *Options) ([]byte, error) {
for k := range di.EmittedEvents { for k := range di.EmittedEvents {
keys = append(keys, k) keys = append(keys, k)
} }
sort.Strings(keys) slices.Sort(keys)
for _, eventName := range keys { for _, eventName := range keys {
var ( var (
eventUsages = di.EmittedEvents[eventName] eventUsages = di.EmittedEvents[eventName]

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/types" "go/types"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"unicode" "unicode"
@ -210,7 +210,7 @@ func (c *codegen) emitDebugInfo(contract []byte) *DebugInfo {
} }
fnames = append(fnames, name) fnames = append(fnames, name)
} }
sort.Strings(fnames) slices.Sort(fnames)
d.NamedTypes = make(map[string]binding.ExtendedType) d.NamedTypes = make(map[string]binding.ExtendedType)
for _, name := range fnames { for _, name := range fnames {
m := c.methodInfoFromScope(name, c.funcs[name], d.NamedTypes) m := c.methodInfoFromScope(name, c.funcs[name], d.NamedTypes)

View file

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

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

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

View file

@ -1,9 +1,11 @@
package config package config
import ( import (
"cmp"
"errors" "errors"
"fmt" "fmt"
"sort" "maps"
"slices"
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
@ -166,9 +168,7 @@ func (p *ProtocolConfiguration) Validate() error {
// sortCheckZero sorts heightNumber array and checks for zero height presence. // sortCheckZero sorts heightNumber array and checks for zero height presence.
func sortCheckZero(arr []heightNumber, field string) error { func sortCheckZero(arr []heightNumber, field string) error {
sort.Slice(arr, func(i, j int) bool { slices.SortFunc(arr, func(a, b heightNumber) int { return cmp.Compare(a.h, b.h) })
return arr[i].h < arr[j].h
})
if arr[0].h != 0 { if arr[0].h != 0 {
return fmt.Errorf("invalid %s: no height 0 specified", field) return fmt.Errorf("invalid %s: no height 0 specified", field)
} }
@ -231,40 +231,12 @@ func (p *ProtocolConfiguration) Equals(o *ProtocolConfiguration) bool {
p.TimePerBlock != o.TimePerBlock || p.TimePerBlock != o.TimePerBlock ||
p.ValidatorsCount != o.ValidatorsCount || p.ValidatorsCount != o.ValidatorsCount ||
p.VerifyTransactions != o.VerifyTransactions || p.VerifyTransactions != o.VerifyTransactions ||
len(p.CommitteeHistory) != len(o.CommitteeHistory) || !maps.Equal(p.CommitteeHistory, o.CommitteeHistory) ||
len(p.Hardforks) != len(o.Hardforks) || !maps.Equal(p.Hardforks, o.Hardforks) ||
len(p.SeedList) != len(o.SeedList) || !slices.Equal(p.SeedList, o.SeedList) ||
len(p.StandbyCommittee) != len(o.StandbyCommittee) || !slices.Equal(p.StandbyCommittee, o.StandbyCommittee) ||
len(p.ValidatorsHistory) != len(o.ValidatorsHistory) { !maps.Equal(p.ValidatorsHistory, o.ValidatorsHistory) {
return false return false
} }
for k, v := range p.CommitteeHistory {
vo, ok := o.CommitteeHistory[k]
if !ok || v != vo {
return false
}
}
for k, v := range p.Hardforks {
vo, ok := o.Hardforks[k]
if !ok || v != vo {
return false
}
}
for i := range p.SeedList {
if p.SeedList[i] != o.SeedList[i] {
return false
}
}
for i := range p.StandbyCommittee {
if p.StandbyCommittee[i] != o.StandbyCommittee[i] {
return false
}
}
for k, v := range p.ValidatorsHistory {
vo, ok := o.ValidatorsHistory[k]
if !ok || v != vo {
return false
}
}
return true return true
} }

View file

@ -3,7 +3,7 @@ package consensus
import ( import (
"errors" "errors"
"fmt" "fmt"
"sort" "slices"
"sync/atomic" "sync/atomic"
"time" "time"
@ -166,14 +166,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")
} }
@ -634,9 +629,7 @@ func (s *service) processBlock(b dbft.Block[util.Uint256]) {
} }
func (s *service) postBlock(b *coreb.Block) { func (s *service) postBlock(b *coreb.Block) {
if s.lastTimestamp < b.Timestamp { s.lastTimestamp = max(s.lastTimestamp, b.Timestamp)
s.lastTimestamp = b.Timestamp
}
s.lastProposal = nil s.lastProposal = nil
} }
@ -658,8 +651,6 @@ func (s *service) getBlockWitness(b *coreb.Block) *transaction.Witness {
return nil return nil
} }
sort.Sort(keys.PublicKeys(pubs))
buf := io.NewBufBinWriter() buf := io.NewBufBinWriter()
for i, j := 0, 0; i < len(pubs) && j < m; i++ { for i, j := 0, 0; i < len(pubs) && j < m; i++ {
if sig, ok := sigs[pubs[i]]; ok { if sig, ok := sigs[pubs[i]]; ok {
@ -790,9 +781,7 @@ func (s *service) newBlockFromContext(ctx *dbft.Context[util.Uint256]) dbft.Bloc
block.Block.PrimaryIndex = primaryIndex block.Block.PrimaryIndex = primaryIndex
// it's OK to have ctx.TransactionsHashes == nil here // it's OK to have ctx.TransactionsHashes == nil here
hashes := make([]util.Uint256, len(ctx.TransactionHashes)) block.Block.MerkleRoot = hash.CalcMerkleRoot(slices.Clone(ctx.TransactionHashes))
copy(hashes, ctx.TransactionHashes)
block.Block.MerkleRoot = hash.CalcMerkleRoot(hashes)
return block return block
} }

View file

@ -7,7 +7,7 @@ import (
"fmt" "fmt"
"math" "math"
"math/big" "math/big"
"sort" "slices"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -1115,9 +1115,7 @@ func (bc *Blockchain) Run() {
} }
nextSync = dur > persistInterval*2 nextSync = dur > persistInterval*2
interval := persistInterval - dur - gcDur interval := persistInterval - dur - gcDur
if interval <= 0 { interval = max(interval, time.Microsecond) // Reset doesn't work with zero or negative value.
interval = time.Microsecond // Reset doesn't work with zero value
}
persistTimer.Reset(interval) persistTimer.Reset(interval)
} }
} }
@ -1134,9 +1132,7 @@ func (bc *Blockchain) tryRunGC(oldHeight uint32) time.Duration {
syncP := newHeight / uint32(bc.config.StateSyncInterval) syncP := newHeight / uint32(bc.config.StateSyncInterval)
syncP-- syncP--
syncP *= uint32(bc.config.StateSyncInterval) syncP *= uint32(bc.config.StateSyncInterval)
if tgtBlock > int64(syncP) { tgtBlock = min(tgtBlock, int64(syncP))
tgtBlock = int64(syncP)
}
} }
// Always round to the GCP. // Always round to the GCP.
tgtBlock /= int64(bc.config.Ledger.GarbageCollectionPeriod) tgtBlock /= int64(bc.config.Ledger.GarbageCollectionPeriod)
@ -1619,9 +1615,7 @@ func (bc *Blockchain) storeBlock(block *block.Block, txpool *mempool.Pool) error
block.Index >= uint32(bc.config.StateSyncInterval)+bc.config.MaxTraceableBlocks && // check this in case if MaxTraceableBlocks>StateSyncInterval block.Index >= uint32(bc.config.StateSyncInterval)+bc.config.MaxTraceableBlocks && // check this in case if MaxTraceableBlocks>StateSyncInterval
int(block.Index)%bc.config.StateSyncInterval == 0 { int(block.Index)%bc.config.StateSyncInterval == 0 {
stop = block.Index - uint32(bc.config.StateSyncInterval) - bc.config.MaxTraceableBlocks stop = block.Index - uint32(bc.config.StateSyncInterval) - bc.config.MaxTraceableBlocks
if stop > uint32(bc.config.StateSyncInterval) { start = stop - min(stop, uint32(bc.config.StateSyncInterval))
start = stop - uint32(bc.config.StateSyncInterval)
}
} }
} else if block.Index > bc.config.MaxTraceableBlocks { } else if block.Index > bc.config.MaxTraceableBlocks {
start = block.Index - bc.config.MaxTraceableBlocks // is at least 1 start = block.Index - bc.config.MaxTraceableBlocks // is at least 1
@ -1844,9 +1838,7 @@ func (bc *Blockchain) updateExtensibleWhitelist(height uint32) error {
bc.updateExtensibleList(&newList, stateVals) bc.updateExtensibleList(&newList, stateVals)
} }
sort.Slice(newList, func(i, j int) bool { slices.SortFunc(newList, util.Uint160.Compare)
return newList[i].Less(newList[j])
})
bc.extensible.Store(newList) bc.extensible.Store(newList)
return nil return nil
} }
@ -1860,8 +1852,8 @@ func (bc *Blockchain) updateExtensibleList(s *[]util.Uint160, pubs keys.PublicKe
// IsExtensibleAllowed determines if script hash is allowed to send extensible payloads. // IsExtensibleAllowed determines if script hash is allowed to send extensible payloads.
func (bc *Blockchain) IsExtensibleAllowed(u util.Uint160) bool { func (bc *Blockchain) IsExtensibleAllowed(u util.Uint160) bool {
us := bc.extensible.Load().([]util.Uint160) us := bc.extensible.Load().([]util.Uint160)
n := sort.Search(len(us), func(i int) bool { return !us[i].Less(u) }) _, ok := slices.BinarySearchFunc(us, u, util.Uint160.Compare)
return n < len(us) return ok
} }
func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.Simple, trig trigger.Type, v *vm.VM) (*state.AppExecResult, *vm.VM, error) { func (bc *Blockchain) runPersist(script []byte, block *block.Block, cache *dao.Simple, trig trigger.Type, v *vm.VM) (*state.AppExecResult, *vm.VM, error) {
@ -2791,7 +2783,7 @@ func (bc *Blockchain) PoolTxWithData(t *transaction.Transaction, data any, mp *m
// GetCommittee returns the sorted list of public keys of nodes in committee. // GetCommittee returns the sorted list of public keys of nodes in committee.
func (bc *Blockchain) GetCommittee() (keys.PublicKeys, error) { func (bc *Blockchain) GetCommittee() (keys.PublicKeys, error) {
pubs := bc.contracts.NEO.GetCommitteeMembers(bc.dao) pubs := bc.contracts.NEO.GetCommitteeMembers(bc.dao)
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
return pubs, nil return pubs, nil
} }
@ -2954,10 +2946,7 @@ func (bc *Blockchain) VerifyWitness(h util.Uint160, c hash.Hashable, w *transact
// verifyHashAgainstScript verifies given hash against the given witness and returns the amount of GAS consumed. // verifyHashAgainstScript verifies given hash against the given witness and returns the amount of GAS consumed.
func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, gas int64) (int64, error) { func (bc *Blockchain) verifyHashAgainstScript(hash util.Uint160, witness *transaction.Witness, interopCtx *interop.Context, gas int64) (int64, error) {
gasPolicy := bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO) gas = min(gas, bc.contracts.Policy.GetMaxVerificationGas(interopCtx.DAO))
if gas > gasPolicy {
gas = gasPolicy
}
vm := interopCtx.SpawnVM() vm := interopCtx.SpawnVM()
vm.GasLimit = gas vm.GasLimit = gas

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"path/filepath" "path/filepath"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -334,7 +334,7 @@ func TestBlockchain_InitializeNeoCache_Bug3424(t *testing.T) {
standBySorted, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee) standBySorted, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee)
require.NoError(t, err) require.NoError(t, err)
standBySorted = standBySorted[:validatorsCount] standBySorted = standBySorted[:validatorsCount]
sort.Sort(standBySorted) slices.SortFunc(standBySorted, (*keys.PublicKey).Cmp)
pubs := e.Chain.ComputeNextBlockValidators() pubs := e.Chain.ComputeNextBlockValidators()
require.Equal(t, standBySorted, keys.PublicKeys(pubs)) require.Equal(t, standBySorted, keys.PublicKeys(pubs))
@ -384,7 +384,7 @@ func TestBlockchain_InitializeNeoCache_Bug3424(t *testing.T) {
for i := range candidates[:validatorsCount] { for i := range candidates[:validatorsCount] {
sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PublicKey() sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PublicKey()
} }
sort.Sort(sortedCandidates) slices.SortFunc(sortedCandidates, (*keys.PublicKey).Cmp)
require.EqualValues(t, sortedCandidates, keys.PublicKeys(pubs)) require.EqualValues(t, sortedCandidates, keys.PublicKeys(pubs))
// Move to the last block in the epoch and restart the node. // Move to the last block in the epoch and restart the node.

View file

@ -2,6 +2,7 @@ package core
import ( import (
"fmt" "fmt"
"slices"
"sync" "sync"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru/v2"
@ -85,7 +86,7 @@ func (h *HeaderHashes) init(dao *dao.Simple) error {
headers = append(headers, blk.Hash()) headers = append(headers, blk.Hash())
hash = blk.PrevHash hash = blk.PrevHash
} }
hashSliceReverse(headers) slices.Reverse(headers)
h.latest = append(h.latest, headers...) h.latest = append(h.latest, headers...)
} }
return nil return nil

View file

@ -1,11 +1,12 @@
package interop package interop
import ( import (
"cmp"
"context" "context"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"sort" "slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -361,16 +362,14 @@ func (c *ContractMD) AddMethod(md *MethodAndPrice, desc *manifest.Method) {
md.MD = desc md.MD = desc
desc.Safe = md.RequiredFlags&(callflag.All^callflag.ReadOnly) == 0 desc.Safe = md.RequiredFlags&(callflag.All^callflag.ReadOnly) == 0
index := sort.Search(len(c.methods), func(i int) bool { index, _ := slices.BinarySearchFunc(c.methods, *md, func(e, t MethodAndPrice) int {
md := c.methods[i].MD res := cmp.Compare(e.MD.Name, t.MD.Name)
if md.Name != desc.Name { if res != 0 {
return md.Name >= desc.Name return res
} }
return len(md.Parameters) > len(desc.Parameters) return cmp.Compare(len(e.MD.Parameters), len(t.MD.Parameters))
}) })
c.methods = append(c.methods, MethodAndPrice{}) c.methods = slices.Insert(c.methods, index, *md)
copy(c.methods[index+1:], c.methods[index:])
c.methods[index] = *md
if md.ActiveFrom != nil { if md.ActiveFrom != nil {
c.ActiveHFs[*md.ActiveFrom] = struct{}{} c.ActiveHFs[*md.ActiveFrom] = struct{}{}
@ -393,21 +392,18 @@ func (c *HFSpecificContractMD) GetMethodByOffset(offset int) (HFSpecificMethodAn
// GetMethod returns method `name` with the specified number of parameters. // GetMethod returns method `name` with the specified number of parameters.
func (c *HFSpecificContractMD) GetMethod(name string, paramCount int) (HFSpecificMethodAndPrice, bool) { func (c *HFSpecificContractMD) GetMethod(name string, paramCount int) (HFSpecificMethodAndPrice, bool) {
index := sort.Search(len(c.Methods), func(i int) bool { index, ok := slices.BinarySearchFunc(c.Methods, HFSpecificMethodAndPrice{}, func(a, _ HFSpecificMethodAndPrice) int {
md := c.Methods[i] res := strings.Compare(a.MD.Name, name)
res := strings.Compare(name, md.MD.Name) if res != 0 {
switch res { return res
case -1, 1:
return res == -1
default:
return paramCount <= len(md.MD.Parameters)
} }
return cmp.Compare(len(a.MD.Parameters), paramCount)
}) })
if index < len(c.Methods) { // Exact match is possible only for specific paramCount, but if we're
md := c.Methods[index] // searching for _some_ method with this name (-1) we're taking the
if md.MD.Name == name && (paramCount == -1 || len(md.MD.Parameters) == paramCount) { // first one.
return md, true if ok || (index < len(c.Methods) && c.Methods[index].MD.Name == name && paramCount == -1) {
} return c.Methods[index], true
} }
return HFSpecificMethodAndPrice{}, false return HFSpecificMethodAndPrice{}, false
} }
@ -426,7 +422,7 @@ func (c *ContractMD) AddEvent(md Event) {
// Sort sorts interop functions by id. // Sort sorts interop functions by id.
func Sort(fs []Function) { func Sort(fs []Function) {
sort.Slice(fs, func(i, j int) bool { return fs[i].ID < fs[j].ID }) slices.SortFunc(fs, func(a, b Function) int { return cmp.Compare(a.ID, b.ID) })
} }
// GetContract returns a contract by its hash in the current interop context. // GetContract returns a contract by its hash in the current interop context.
@ -436,13 +432,13 @@ func (ic *Context) GetContract(hash util.Uint160) (*state.Contract, error) {
// GetFunction returns metadata for interop with the specified id. // GetFunction returns metadata for interop with the specified id.
func (ic *Context) GetFunction(id uint32) *Function { func (ic *Context) GetFunction(id uint32) *Function {
n := sort.Search(len(ic.Functions), func(i int) bool { n, ok := slices.BinarySearchFunc(ic.Functions, Function{}, func(a, _ Function) int {
return ic.Functions[i].ID >= id return cmp.Compare(a.ID, id)
}) })
if n < len(ic.Functions) && ic.Functions[n].ID == id { if !ok {
return &ic.Functions[n]
}
return nil return nil
}
return &ic.Functions[n]
} }
// BaseExecFee represents factor to multiply syscall prices with. // BaseExecFee represents factor to multiply syscall prices with.

View file

@ -4,12 +4,12 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"math/big" "math/big"
"slices"
"github.com/nspcc-dev/neo-go/pkg/config" "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/interop"
"github.com/nspcc-dev/neo-go/pkg/core/state" "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/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/util"
"github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "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) { if !ic.VM.AddGas(ic.BaseExecFee() * price) {
return errors.New("gas limit exceeded") 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 return nil
} }

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

@ -0,0 +1,62 @@
package mempool
import (
"testing"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/util"
)
const (
poolSize = 10000
)
func BenchmarkPool(b *testing.B) {
fe := &FeerStub{
feePerByte: 1,
blockHeight: 1,
balance: 100_0000_0000,
}
txesSimple := make([]*transaction.Transaction, poolSize)
for i := range txesSimple {
txesSimple[i] = transaction.New([]byte{1, 2, 3}, 100500)
txesSimple[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}
}
txesIncFee := make([]*transaction.Transaction, poolSize)
for i := range txesIncFee {
txesIncFee[i] = transaction.New([]byte{1, 2, 3}, 100500)
txesIncFee[i].NetworkFee = 10 * int64(i)
txesIncFee[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3}}}
}
txesMulti := make([]*transaction.Transaction, poolSize)
for i := range txesMulti {
txesMulti[i] = transaction.New([]byte{1, 2, 3}, 100500)
txesMulti[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, byte(i % 256), byte(i / 256)}}}
}
txesMultiInc := make([]*transaction.Transaction, poolSize)
for i := range txesMultiInc {
txesMultiInc[i] = transaction.New([]byte{1, 2, 3}, 100500)
txesMultiInc[i].NetworkFee = 10 * int64(i)
txesMultiInc[i].Signers = []transaction.Signer{{Account: util.Uint160{1, 2, 3, byte(i % 256), byte(i / 256)}}}
}
senders := make(map[string][]*transaction.Transaction)
senders["one, same fee"] = txesSimple
senders["one, incr fee"] = txesIncFee
senders["many, same fee"] = txesMulti
senders["many, incr fee"] = txesMultiInc
for name, txes := range senders {
b.Run(name, func(b *testing.B) {
p := New(poolSize, 0, false, nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for j := range txes {
if p.Add(txes[j], fe) != nil {
b.Fail()
}
}
p.RemoveStale(func(*transaction.Transaction) bool { return false }, fe)
}
})
}
}

View file

@ -84,13 +84,13 @@ type Pool struct {
func (p items) Len() int { return len(p) } func (p items) Len() int { return len(p) }
func (p items) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p items) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p items) Less(i, j int) bool { return p[i].CompareTo(p[j]) < 0 } func (p items) Less(i, j int) bool { return p[i].Compare(p[j]) < 0 }
// CompareTo returns the difference between two items. // Compare returns the difference between two items.
// difference < 0 implies p < otherP. // difference < 0 implies p < otherP.
// difference = 0 implies p = otherP. // difference = 0 implies p = otherP.
// difference > 0 implies p > otherP. // difference > 0 implies p > otherP.
func (p item) CompareTo(otherP item) int { func (p item) Compare(otherP item) int {
pHigh := p.txn.HasAttribute(transaction.HighPriority) pHigh := p.txn.HasAttribute(transaction.HighPriority)
otherHigh := otherP.txn.HasAttribute(transaction.HighPriority) otherHigh := otherP.txn.HasAttribute(transaction.HighPriority)
if pHigh && !otherHigh { if pHigh && !otherHigh {
@ -238,8 +238,18 @@ func (mp *Pool) Add(t *transaction.Transaction, fee Feer, data ...any) error {
// transactions with the same priority and appending to the end of the // transactions with the same priority and appending to the end of the
// slice is always more efficient. // slice is always more efficient.
n := sort.Search(len(mp.verifiedTxes), func(n int) bool { n := sort.Search(len(mp.verifiedTxes), func(n int) bool {
return pItem.CompareTo(mp.verifiedTxes[n]) > 0 return pItem.Compare(mp.verifiedTxes[n]) > 0
}) })
// Changing sort.Search to slices.BinarySearchFunc() is not recommended
// above, as of Go 1.23 this results in
// cpu: AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics
// │ pool.current │ pool.new │
// │ sec/op │ sec/op vs base │
// Pool/one,_same_fee-16 1.742m ± 1% 1.799m ± 1% +3.29% (p=0.000 n=10)
// Pool/one,_incr_fee-16 12.51m ± 1% 12.63m ± 2% +0.92% (p=0.023 n=10)
// Pool/many,_same_fee-16 3.100m ± 1% 3.099m ± 1% ~ (p=0.631 n=10)
// Pool/many,_incr_fee-16 14.11m ± 1% 14.20m ± 1% ~ (p=0.315 n=10)
// geomean 5.556m 5.624m +1.22%
// We've reached our capacity already. // We've reached our capacity already.
if len(mp.verifiedTxes) == mp.capacity { if len(mp.verifiedTxes) == mp.capacity {
@ -255,6 +265,17 @@ func (mp *Pool) Add(t *transaction.Transaction, fee Feer, data ...any) error {
} else { } else {
mp.verifiedTxes = append(mp.verifiedTxes, pItem) mp.verifiedTxes = append(mp.verifiedTxes, pItem)
} }
// While we're obviously doing slices.Insert here (and above a bit),
// code simplification is not advised since slices.Insert works
// slightly slower as of Go 1.23:
// cpu: AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics
// │ pool.current │ pool.new2 │
// │ sec/op │ sec/op vs base │
// Pool/one,_same_fee-16 1.742m ± 1% 1.801m ± 2% +3.38% (p=0.000 n=10)
// Pool/one,_incr_fee-16 12.51m ± 1% 12.59m ± 2% ~ (p=0.218 n=10)
// Pool/many,_same_fee-16 3.100m ± 1% 3.134m ± 1% +1.11% (p=0.011 n=10)
// Pool/many,_incr_fee-16 14.11m ± 1% 14.09m ± 1% ~ (p=0.393 n=10)
// geomean 5.556m 5.626m +1.25%
if n != len(mp.verifiedTxes)-1 { if n != len(mp.verifiedTxes)-1 {
copy(mp.verifiedTxes[n+1:], mp.verifiedTxes[n:]) copy(mp.verifiedTxes[n+1:], mp.verifiedTxes[n:])
mp.verifiedTxes[n] = pItem mp.verifiedTxes[n] = pItem
@ -351,8 +372,8 @@ func (mp *Pool) RemoveStale(isOK func(*transaction.Transaction) bool, feer Feer)
// We can reuse already allocated slice // We can reuse already allocated slice
// because items are iterated one-by-one in increasing order. // because items are iterated one-by-one in increasing order.
newVerifiedTxes := mp.verifiedTxes[:0] newVerifiedTxes := mp.verifiedTxes[:0]
mp.fees = make(map[util.Uint160]utilityBalanceAndFees) // it'd be nice to reuse existing map, but we can't easily clear it clear(mp.fees)
mp.conflicts = make(map[util.Uint256][]util.Uint256) clear(mp.conflicts)
height := feer.BlockHeight() height := feer.BlockHeight()
var ( var (
staleItems []item staleItems []item
@ -466,14 +487,14 @@ func (mp *Pool) TryGetData(hash util.Uint256) (any, bool) {
if tx, ok := mp.verifiedMap[hash]; ok { if tx, ok := mp.verifiedMap[hash]; ok {
itm := item{txn: tx} itm := item{txn: tx}
n := sort.Search(len(mp.verifiedTxes), func(n int) bool { n := sort.Search(len(mp.verifiedTxes), func(n int) bool {
return itm.CompareTo(mp.verifiedTxes[n]) >= 0 return itm.Compare(mp.verifiedTxes[n]) >= 0
}) })
if n < len(mp.verifiedTxes) { if n < len(mp.verifiedTxes) {
for i := n; i < len(mp.verifiedTxes); i++ { // items may have equal priority, so `n` is the left bound of the items which are as prioritized as the desired `itm`. for i := n; i < len(mp.verifiedTxes); i++ { // items may have equal priority, so `n` is the left bound of the items which are as prioritized as the desired `itm`.
if mp.verifiedTxes[i].txn.Hash() == hash { if mp.verifiedTxes[i].txn.Hash() == hash {
return mp.verifiedTxes[i].data, ok return mp.verifiedTxes[i].data, ok
} }
if itm.CompareTo(mp.verifiedTxes[i]) != 0 { if itm.Compare(mp.verifiedTxes[i]) != 0 {
break break
} }
} }

View file

@ -3,7 +3,7 @@ package mempool
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"sort" "slices"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -116,6 +116,10 @@ func TestOverCapacity(t *testing.T) {
const mempoolSize = 10 const mempoolSize = 10
mp := New(mempoolSize, 0, false, nil) mp := New(mempoolSize, 0, false, nil)
var checkPoolIsSorted = func() {
require.True(t, slices.IsSortedFunc(mp.verifiedTxes, func(a, b item) int { return -a.Compare(b) }))
}
for i := 0; i < mempoolSize; i++ { for i := 0; i < mempoolSize; i++ {
tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0) tx := transaction.New([]byte{byte(opcode.PUSH1)}, 0)
tx.Nonce = uint32(i) tx.Nonce = uint32(i)
@ -124,7 +128,7 @@ func TestOverCapacity(t *testing.T) {
} }
txcnt := uint32(mempoolSize) txcnt := uint32(mempoolSize)
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
require.Equal(t, *uint256.NewInt(0), mp.fees[acc].feeSum) require.Equal(t, *uint256.NewInt(0), mp.fees[acc].feeSum)
bigScript := make([]byte, 64) bigScript := make([]byte, 64)
@ -140,7 +144,7 @@ func TestOverCapacity(t *testing.T) {
// size is ~90, networkFee is 10000 => feePerByte is 119 // size is ~90, networkFee is 10000 => feePerByte is 119
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
} }
require.Equal(t, *uint256.NewInt(10 * 10000), mp.fees[acc].feeSum) require.Equal(t, *uint256.NewInt(10 * 10000), mp.fees[acc].feeSum)
@ -155,7 +159,7 @@ func TestOverCapacity(t *testing.T) {
require.Equal(t, mempoolSize, len(mp.verifiedMap)) require.Equal(t, mempoolSize, len(mp.verifiedMap))
require.Equal(t, mempoolSize, len(mp.verifiedTxes)) require.Equal(t, mempoolSize, len(mp.verifiedTxes))
require.False(t, mp.containsKey(tx.Hash())) require.False(t, mp.containsKey(tx.Hash()))
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
require.Equal(t, *uint256.NewInt(100000), mp.fees[acc].feeSum) require.Equal(t, *uint256.NewInt(100000), mp.fees[acc].feeSum)
// Low net fee, but higher per-byte fee is still a better combination. // Low net fee, but higher per-byte fee is still a better combination.
@ -168,7 +172,7 @@ func TestOverCapacity(t *testing.T) {
// => feePerByte is 137 (>119) // => feePerByte is 137 (>119)
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
require.Equal(t, *uint256.NewInt(9*10000 + 7000), mp.fees[acc].feeSum) require.Equal(t, *uint256.NewInt(9*10000 + 7000), mp.fees[acc].feeSum)
// High priority always wins over low priority. // High priority always wins over low priority.
@ -180,7 +184,7 @@ func TestOverCapacity(t *testing.T) {
txcnt++ txcnt++
require.NoError(t, mp.Add(tx, fs)) require.NoError(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
} }
require.Equal(t, *uint256.NewInt(10 * 8000), mp.fees[acc].feeSum) require.Equal(t, *uint256.NewInt(10 * 8000), mp.fees[acc].feeSum)
// Good luck with low priority now. // Good luck with low priority now.
@ -190,7 +194,7 @@ func TestOverCapacity(t *testing.T) {
tx.Signers = []transaction.Signer{{Account: acc}} tx.Signers = []transaction.Signer{{Account: acc}}
require.Error(t, mp.Add(tx, fs)) require.Error(t, mp.Add(tx, fs))
require.Equal(t, mempoolSize, mp.Count()) require.Equal(t, mempoolSize, mp.Count())
require.Equal(t, true, sort.IsSorted(sort.Reverse(mp.verifiedTxes))) checkPoolIsSorted()
} }
func TestGetVerified(t *testing.T) { func TestGetVerified(t *testing.T) {
@ -343,18 +347,18 @@ func TestMempoolItemsOrder(t *testing.T) {
tx4.Signers = []transaction.Signer{{Account: sender0}} tx4.Signers = []transaction.Signer{{Account: sender0}}
item4 := item{txn: tx4} item4 := item{txn: tx4}
require.True(t, item1.CompareTo(item2) > 0) require.True(t, item1.Compare(item2) > 0)
require.True(t, item2.CompareTo(item1) < 0) require.True(t, item2.Compare(item1) < 0)
require.True(t, item1.CompareTo(item3) > 0) require.True(t, item1.Compare(item3) > 0)
require.True(t, item3.CompareTo(item1) < 0) require.True(t, item3.Compare(item1) < 0)
require.True(t, item1.CompareTo(item4) > 0) require.True(t, item1.Compare(item4) > 0)
require.True(t, item4.CompareTo(item1) < 0) require.True(t, item4.Compare(item1) < 0)
require.True(t, item2.CompareTo(item3) > 0) require.True(t, item2.Compare(item3) > 0)
require.True(t, item3.CompareTo(item2) < 0) require.True(t, item3.Compare(item2) < 0)
require.True(t, item2.CompareTo(item4) > 0) require.True(t, item2.Compare(item4) > 0)
require.True(t, item4.CompareTo(item2) < 0) require.True(t, item4.Compare(item2) < 0)
require.True(t, item3.CompareTo(item4) > 0) require.True(t, item3.Compare(item4) > 0)
require.True(t, item4.CompareTo(item3) < 0) require.True(t, item4.Compare(item3) < 0)
} }
func TestMempoolAddRemoveOracleResponse(t *testing.T) { func TestMempoolAddRemoveOracleResponse(t *testing.T) {

View file

@ -2,7 +2,7 @@ package mpt
import ( import (
"bytes" "bytes"
"sort" "slices"
) )
// Batch is a batch of storage changes. // Batch is a batch of storage changes.
@ -25,8 +25,8 @@ func MapToMPTBatch(m map[string][]byte) Batch {
for k, v := range m { for k, v := range m {
b.kv = append(b.kv, keyValue{strToNibbles(k), v}) // Strip storage prefix. b.kv = append(b.kv, keyValue{strToNibbles(k), v}) // Strip storage prefix.
} }
sort.Slice(b.kv, func(i, j int) bool { slices.SortFunc(b.kv, func(a, b keyValue) int {
return bytes.Compare(b.kv[i].key, b.kv[j].key) < 0 return bytes.Compare(a.key, b.key)
}) })
return b return b
} }

View file

@ -543,7 +543,7 @@ func (t *Trie) Collapse(depth int) {
panic("negative depth") panic("negative depth")
} }
t.root = collapse(depth, t.root) t.root = collapse(depth, t.root)
t.refcount = make(map[util.Uint256]*cachedNode) clear(t.refcount)
} }
func collapse(depth int, node Node) Node { func collapse(depth int, node Node) Node {

View file

@ -21,10 +21,6 @@ type TrieStore struct {
trie *Trie trie *Trie
} }
// ErrForbiddenTrieStoreOperation is returned when operation is not supposed to
// be performed over MPT-based Store.
var ErrForbiddenTrieStoreOperation = errors.New("operation is not allowed to be performed over TrieStore")
// NewTrieStore returns a new ready to use MPT-backed storage. // NewTrieStore returns a new ready to use MPT-backed storage.
func NewTrieStore(root util.Uint256, mode TrieMode, backed storage.Store) *TrieStore { func NewTrieStore(root util.Uint256, mode TrieMode, backed storage.Store) *TrieStore {
cache, ok := backed.(*storage.MemCachedStore) cache, ok := backed.(*storage.MemCachedStore)
@ -37,10 +33,11 @@ func NewTrieStore(root util.Uint256, mode TrieMode, backed storage.Store) *TrieS
} }
} }
// Get implements the Store interface. // Get implements the Store interface. It can return [errors.ErrUnsupported]
// for unsupported operations.
func (m *TrieStore) Get(key []byte) ([]byte, error) { func (m *TrieStore) Get(key []byte) ([]byte, error) {
if len(key) == 0 { if len(key) == 0 {
return nil, fmt.Errorf("%w: Get is supported only for contract storage items", ErrForbiddenTrieStoreOperation) return nil, fmt.Errorf("%w: Get is supported only for contract storage items", errors.ErrUnsupported)
} }
switch storage.KeyPrefix(key[0]) { switch storage.KeyPrefix(key[0]) {
case storage.STStorage, storage.STTempStorage: case storage.STStorage, storage.STTempStorage:
@ -51,22 +48,23 @@ func (m *TrieStore) Get(key []byte) ([]byte, error) {
} }
return res, err return res, err
default: default:
return nil, fmt.Errorf("%w: Get is supported only for contract storage items", ErrForbiddenTrieStoreOperation) return nil, fmt.Errorf("%w: Get is supported only for contract storage items", errors.ErrUnsupported)
} }
} }
// PutChangeSet implements the Store interface. // PutChangeSet implements the Store interface. It's not supported, so it
// always returns [errors.ErrUnsupported].
func (m *TrieStore) PutChangeSet(puts map[string][]byte, stor map[string][]byte) error { func (m *TrieStore) PutChangeSet(puts map[string][]byte, stor map[string][]byte) error {
// Only Get and Seek should be supported, as TrieStore is read-only and is always // Only Get and Seek should be supported, as TrieStore is read-only and is always
// should be wrapped by MemCachedStore to properly support put operations (if any). // should be wrapped by MemCachedStore to properly support put operations (if any).
return fmt.Errorf("%w: PutChangeSet is not supported", ErrForbiddenTrieStoreOperation) return fmt.Errorf("%w: PutChangeSet is not supported", errors.ErrUnsupported)
} }
// Seek implements the Store interface. // Seek implements the Store interface.
func (m *TrieStore) Seek(rng storage.SeekRange, f func(k, v []byte) bool) { func (m *TrieStore) Seek(rng storage.SeekRange, f func(k, v []byte) bool) {
prefix := storage.KeyPrefix(rng.Prefix[0]) prefix := storage.KeyPrefix(rng.Prefix[0])
if prefix != storage.STStorage && prefix != storage.STTempStorage { // Prefix is always non-empty. if prefix != storage.STStorage && prefix != storage.STTempStorage { // Prefix is always non-empty.
panic(fmt.Errorf("%w: Seek is supported only for contract storage items", ErrForbiddenTrieStoreOperation)) panic(fmt.Errorf("%w: Seek is supported only for contract storage items", errors.ErrUnsupported))
} }
prefixP := toNibbles(rng.Prefix[1:]) prefixP := toNibbles(rng.Prefix[1:])
fromP := []byte{} fromP := []byte{}
@ -113,9 +111,10 @@ func (m *TrieStore) Seek(rng storage.SeekRange, f func(k, v []byte) bool) {
} }
} }
// SeekGC implements the Store interface. // SeekGC implements the Store interface. It's not supported, so it always
// returns [errors.ErrUnsupported].
func (m *TrieStore) SeekGC(rng storage.SeekRange, keep func(k, v []byte) bool) error { func (m *TrieStore) SeekGC(rng storage.SeekRange, keep func(k, v []byte) bool) error {
return fmt.Errorf("%w: SeekGC is not supported", ErrForbiddenTrieStoreOperation) return fmt.Errorf("%w: SeekGC is not supported", errors.ErrUnsupported)
} }
// Close implements the Store interface. // Close implements the Store interface.

View file

@ -2,6 +2,7 @@ package mpt
import ( import (
"bytes" "bytes"
"errors"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/storage"
@ -15,10 +16,10 @@ func TestTrieStore_TestTrieOperations(t *testing.T) {
st := NewTrieStore(source.root.Hash(), ModeAll, backed) st := NewTrieStore(source.root.Hash(), ModeAll, backed)
t.Run("forbidden operations", func(t *testing.T) { t.Run("forbidden operations", func(t *testing.T) {
require.ErrorIs(t, st.SeekGC(storage.SeekRange{}, nil), ErrForbiddenTrieStoreOperation) require.ErrorIs(t, st.SeekGC(storage.SeekRange{}, nil), errors.ErrUnsupported)
_, err := st.Get([]byte{byte(storage.STTokenTransferInfo)}) _, err := st.Get([]byte{byte(storage.STTokenTransferInfo)})
require.ErrorIs(t, err, ErrForbiddenTrieStoreOperation) require.ErrorIs(t, err, errors.ErrUnsupported)
require.ErrorIs(t, st.PutChangeSet(nil, nil), ErrForbiddenTrieStoreOperation) require.ErrorIs(t, st.PutChangeSet(nil, nil), errors.ErrUnsupported)
}) })
t.Run("Get", func(t *testing.T) { t.Run("Get", func(t *testing.T) {

View file

@ -201,16 +201,16 @@ func curveHasherFromStackitem(si stackitem.Item, allowKeccak bool) (elliptic.Cur
return elliptic.P256(), hash.Sha256, nil return elliptic.P256(), hash.Sha256, nil
case int64(Secp256k1Keccak256): case int64(Secp256k1Keccak256):
if !allowKeccak { if !allowKeccak {
return nil, nil, errors.New("unsupported hash type") return nil, nil, fmt.Errorf("%w: keccak hash", errors.ErrUnsupported)
} }
return secp256k1.S256(), Keccak256, nil return secp256k1.S256(), Keccak256, nil
case int64(Secp256r1Keccak256): case int64(Secp256r1Keccak256):
if !allowKeccak { if !allowKeccak {
return nil, nil, errors.New("unsupported hash type") return nil, nil, fmt.Errorf("%w: keccak hash", errors.ErrUnsupported)
} }
return elliptic.P256(), Keccak256, nil return elliptic.P256(), Keccak256, nil
default: default:
return nil, nil, errors.New("unsupported curve/hash type") return nil, nil, fmt.Errorf("%w: unknown curve/hash", errors.ErrUnsupported)
} }
} }

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"math" "math"
"math/big" "math/big"
"sort" "slices"
"sync/atomic" "sync/atomic"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -397,7 +397,7 @@ func (s *Designate) DesignateAsRole(ic *interop.Context, r noderoles.Role, pubs
if si != nil { if si != nil {
return ErrAlreadyDesignated return ErrAlreadyDesignated
} }
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
nl := NodeList(pubs) nl := NodeList(pubs)
err := putConvertibleToDAO(s.ID, ic.DAO, key, &nl) err := putConvertibleToDAO(s.ID, ic.DAO, key, &nl)

View file

@ -6,8 +6,9 @@ import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt" "fmt"
"maps"
"math/big" "math/big"
"sort" "slices"
"strings" "strings"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -150,13 +151,8 @@ func copyNeoCache(src, dst *NeoCache) {
// Can't omit copying because gasPerBlock is append-only, thus to be able to // 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 // discard cache changes in case of FAULTed transaction we need a separate
// container for updated gasPerBlock values. // container for updated gasPerBlock values.
dst.gasPerBlock = make(gasRecord, len(src.gasPerBlock)) dst.gasPerBlock = slices.Clone(src.gasPerBlock)
copy(dst.gasPerBlock, src.gasPerBlock) dst.gasPerVoteCache = maps.Clone(src.gasPerVoteCache)
dst.gasPerVoteCache = make(map[string]big.Int)
for k, v := range src.gasPerVoteCache {
dst.gasPerVoteCache[k] = v
}
} }
// makeValidatorKey creates a key from the account script hash. // makeValidatorKey creates a key from the account script hash.
@ -376,8 +372,7 @@ func (n *NEO) InitializeCache(blockHeight uint32, d *dao.Simple) error {
// nextValidators, committee and committee hash are filled in by this moment // nextValidators, committee and committee hash are filled in by this moment
// via n.updateCache call. // via n.updateCache call.
cache.newEpochNextValidators = cache.nextValidators.Copy() cache.newEpochNextValidators = cache.nextValidators.Copy()
cache.newEpochCommittee = make(keysWithVotes, len(cache.committee)) cache.newEpochCommittee = slices.Clone(cache.committee)
copy(cache.newEpochCommittee, cache.committee)
cache.newEpochCommitteeHash = cache.committeeHash cache.newEpochCommitteeHash = cache.committeeHash
} }
@ -409,7 +404,7 @@ func (n *NEO) updateCache(cache *NeoCache, cvs keysWithVotes, blockHeight uint32
cache.committeeHash = hash.Hash160(script) cache.committeeHash = hash.Hash160(script)
nextVals := committee[:n.cfg.GetNumOfCNs(blockHeight+1)].Copy() nextVals := committee[:n.cfg.GetNumOfCNs(blockHeight+1)].Copy()
sort.Sort(nextVals) slices.SortFunc(nextVals, (*keys.PublicKey).Cmp)
cache.nextValidators = nextVals cache.nextValidators = nextVals
return nil return nil
} }
@ -434,7 +429,7 @@ func (n *NEO) updateCachedNewEpochValues(d *dao.Simple, cache *NeoCache, blockHe
cache.newEpochCommitteeHash = hash.Hash160(script) cache.newEpochCommitteeHash = hash.Hash160(script)
nextVals := committee[:numOfCNs].Copy() nextVals := committee[:numOfCNs].Copy()
sort.Sort(nextVals) slices.SortFunc(nextVals, (*keys.PublicKey).Cmp)
cache.newEpochNextValidators = nextVals cache.newEpochNextValidators = nextVals
return nil return nil
} }
@ -1032,23 +1027,23 @@ func (n *NEO) getCandidates(d *dao.Simple, sortByKey bool, maxNum int) ([]keyWit
// sortByKey assumes to sort by serialized key bytes (that's the way keys // sortByKey assumes to sort by serialized key bytes (that's the way keys
// are stored and retrieved from the storage by default). Otherwise, need // are stored and retrieved from the storage by default). Otherwise, need
// to sort using big.Int comparator. // to sort using big.Int comparator.
sort.Slice(arr, func(i, j int) bool { slices.SortFunc(arr, func(a, b keyWithVotes) int {
// The most-voted validators should end up in the front of the list. // The most-voted validators should end up in the front of the list.
cmp := arr[i].Votes.Cmp(arr[j].Votes) cmp := b.Votes.Cmp(a.Votes)
if cmp != 0 { if cmp != 0 {
return cmp > 0 return cmp
} }
// Ties are broken with deserialized public keys. // Ties are broken with deserialized public keys.
// Sort by ECPoint's (X, Y) components: compare X first, and then compare Y. // Sort by ECPoint's (X, Y) components: compare X first, and then compare Y.
cmpX := strings.Compare(arr[i].Key[1:], arr[j].Key[1:]) cmpX := strings.Compare(a.Key[1:], b.Key[1:])
if cmpX != 0 { if cmpX != 0 {
return cmpX == -1 return cmpX
} }
// The case when X components are the same is extremely rare, thus we perform // The case when X components are the same is extremely rare, thus we perform
// key deserialization only if needed. No error can occur. // key deserialization only if needed. No error can occur.
ki, _ := keys.NewPublicKeyFromBytes([]byte(arr[i].Key), elliptic.P256()) ka, _ := keys.NewPublicKeyFromBytes([]byte(a.Key), elliptic.P256())
kj, _ := keys.NewPublicKeyFromBytes([]byte(arr[j].Key), elliptic.P256()) kb, _ := keys.NewPublicKeyFromBytes([]byte(b.Key), elliptic.P256())
return ki.Y.Cmp(kj.Y) == -1 return ka.Y.Cmp(kb.Y)
}) })
} }
return arr, nil return arr, nil
@ -1176,7 +1171,7 @@ func (n *NEO) ComputeNextBlockValidators(d *dao.Simple) keys.PublicKeys {
func (n *NEO) getCommittee(ic *interop.Context, _ []stackitem.Item) stackitem.Item { func (n *NEO) getCommittee(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
pubs := n.GetCommitteeMembers(ic.DAO) pubs := n.GetCommitteeMembers(ic.DAO)
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
return pubsToArray(pubs) return pubsToArray(pubs)
} }

View file

@ -2,7 +2,7 @@ package native_test
import ( import (
"math/big" "math/big"
"sort" "slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames" "github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
@ -602,9 +602,7 @@ func TestCryptoLib_KoblitzMultisigVerificationScript(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
} }
// Sort private keys by their public keys. // Sort private keys by their public keys.
sort.Slice(pks, func(i, j int) bool { slices.SortFunc(pks, func(a, b *keys.PrivateKey) int { return a.PublicKey().Cmp(b.PublicKey()) })
return pks[i].PublicKey().Cmp(pks[j].PublicKey()) < 0
})
// Firstly, we need to build the N3 multisig account address based on the users' public keys. // Firstly, we need to build the N3 multisig account address based on the users' public keys.
// Pubs must be sorted, exactly like for the standard CheckMultisig. // Pubs must be sorted, exactly like for the standard CheckMultisig.

View file

@ -1,7 +1,7 @@
package native_test package native_test
import ( import (
"sort" "slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
@ -157,6 +157,6 @@ func TestDesignate_GenesisRolesExtension(t *testing.T) {
c := e.CommitteeInvoker(e.NativeHash(t, nativenames.Designation)) c := e.CommitteeInvoker(e.NativeHash(t, nativenames.Designation))
// Check designated node in a separate block. // Check designated node in a separate block.
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
checkNodeRoles(t, c, true, noderoles.StateValidator, e.Chain.BlockHeight()+1, pubs) checkNodeRoles(t, c, true, noderoles.StateValidator, e.Chain.BlockHeight()+1, pubs)
} }

View file

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

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"math" "math"
"math/big" "math/big"
"sort" "slices"
"strings" "strings"
"testing" "testing"
@ -204,7 +204,7 @@ func TestNEO_Vote(t *testing.T) {
standBySorted, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee) standBySorted, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee)
require.NoError(t, err) require.NoError(t, err)
standBySorted = standBySorted[:validatorsCount] standBySorted = standBySorted[:validatorsCount]
sort.Sort(standBySorted) slices.SortFunc(standBySorted, (*keys.PublicKey).Cmp)
pubs := e.Chain.ComputeNextBlockValidators() pubs := e.Chain.ComputeNextBlockValidators()
require.Equal(t, standBySorted, keys.PublicKeys(pubs)) require.Equal(t, standBySorted, keys.PublicKeys(pubs))
@ -269,7 +269,7 @@ func TestNEO_Vote(t *testing.T) {
for i := range candidates[:validatorsCount] { for i := range candidates[:validatorsCount] {
sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PublicKey() sortedCandidates[i] = candidates[i].(neotest.SingleSigner).Account().PublicKey()
} }
sort.Sort(sortedCandidates) slices.SortFunc(sortedCandidates, (*keys.PublicKey).Cmp)
require.EqualValues(t, sortedCandidates, keys.PublicKeys(pubs)) require.EqualValues(t, sortedCandidates, keys.PublicKeys(pubs))
pubs, err = neoCommitteeInvoker.Chain.GetNextBlockValidators() pubs, err = neoCommitteeInvoker.Chain.GetNextBlockValidators()
@ -403,7 +403,7 @@ func TestNEO_GetCommitteeAddress(t *testing.T) {
e := neoValidatorInvoker.Executor e := neoValidatorInvoker.Executor
standByCommitteePublicKeys, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee) standByCommitteePublicKeys, err := keys.NewPublicKeysFromStrings(e.Chain.GetConfig().StandbyCommittee)
require.NoError(t, err) require.NoError(t, err)
sort.Sort(standByCommitteePublicKeys) slices.SortFunc(standByCommitteePublicKeys, (*keys.PublicKey).Cmp)
expectedCommitteeAddress, err := smartcontract.CreateMajorityMultiSigRedeemScript(standByCommitteePublicKeys) expectedCommitteeAddress, err := smartcontract.CreateMajorityMultiSigRedeemScript(standByCommitteePublicKeys)
require.NoError(t, err) require.NoError(t, err)
stack, err := neoValidatorInvoker.TestInvoke(t, "getCommitteeAddress") stack, err := neoValidatorInvoker.TestInvoke(t, "getCommitteeAddress")
@ -811,8 +811,8 @@ func TestNEO_GetCandidates(t *testing.T) {
}) })
neoCommitteeInvoker.Invoke(t, v, "getCandidateVote", pub) neoCommitteeInvoker.Invoke(t, v, "getCandidateVote", pub)
} }
sort.Slice(expected, func(i, j int) bool { slices.SortFunc(expected, func(a, b stackitem.Item) int {
return bytes.Compare(expected[i].Value().([]stackitem.Item)[0].Value().([]byte), expected[j].Value().([]stackitem.Item)[0].Value().([]byte)) < 0 return bytes.Compare(a.Value().([]stackitem.Item)[0].Value().([]byte), b.Value().([]stackitem.Item)[0].Value().([]byte))
}) })
neoCommitteeInvoker.Invoke(t, stackitem.NewArray(expected), "getCandidates") neoCommitteeInvoker.Invoke(t, stackitem.NewArray(expected), "getCandidates")

View file

@ -3,8 +3,9 @@ package native
import ( import (
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"maps"
"math/big" "math/big"
"sort" "slices"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/core/dao" "github.com/nspcc-dev/neo-go/pkg/core/dao"
@ -91,12 +92,8 @@ func (c *PolicyCache) Copy() dao.NativeContractCache {
func copyPolicyCache(src, dst *PolicyCache) { func copyPolicyCache(src, dst *PolicyCache) {
*dst = *src *dst = *src
dst.attributeFee = make(map[transaction.AttrType]uint32, len(src.attributeFee)) dst.attributeFee = maps.Clone(src.attributeFee)
for t, v := range src.attributeFee { dst.blockedAccounts = slices.Clone(src.blockedAccounts)
dst.attributeFee[t] = v
}
dst.blockedAccounts = make([]util.Uint160, len(src.blockedAccounts))
copy(dst.blockedAccounts, src.blockedAccounts)
} }
// newPolicy returns Policy native contract. // newPolicy returns Policy native contract.
@ -329,14 +326,7 @@ func (p *Policy) IsBlocked(dao *dao.Simple, hash util.Uint160) bool {
// of the blocked account in the blocked accounts list (or the position it should be // of the blocked account in the blocked accounts list (or the position it should be
// put at). // put at).
func (p *Policy) isBlockedInternal(roCache *PolicyCache, hash util.Uint160) (int, bool) { func (p *Policy) isBlockedInternal(roCache *PolicyCache, hash util.Uint160) (int, bool) {
length := len(roCache.blockedAccounts) return slices.BinarySearchFunc(roCache.blockedAccounts, hash, util.Uint160.Compare)
i := sort.Search(length, func(i int) bool {
return !roCache.blockedAccounts[i].Less(hash)
})
if length != 0 && i != length && roCache.blockedAccounts[i].Equals(hash) {
return i, true
}
return i, false
} }
func (p *Policy) getStoragePrice(ic *interop.Context, _ []stackitem.Item) stackitem.Item { func (p *Policy) getStoragePrice(ic *interop.Context, _ []stackitem.Item) stackitem.Item {

View file

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

View file

@ -2,7 +2,7 @@ package statesync
import ( import (
"bytes" "bytes"
"sort" "slices"
"sync" "sync"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -38,9 +38,7 @@ func (mp *Pool) TryGet(hash util.Uint256) ([][]byte, bool) {
paths, ok := mp.hashes[hash] paths, ok := mp.hashes[hash]
// need to copy here, because we can modify existing array of paths inside the pool. // need to copy here, because we can modify existing array of paths inside the pool.
res := make([][]byte, len(paths)) return slices.Clone(paths), ok
copy(res, paths)
return res, ok
} }
// GetAll returns all MPT nodes with the corresponding paths from the pool. // GetAll returns all MPT nodes with the corresponding paths from the pool.
@ -95,11 +93,9 @@ func (mp *Pool) Update(remove map[util.Uint256][][]byte, add map[util.Uint256][]
for h, paths := range remove { for h, paths := range remove {
old := mp.hashes[h] old := mp.hashes[h]
for _, path := range paths { for _, path := range paths {
i := sort.Search(len(old), func(i int) bool { i, found := slices.BinarySearchFunc(old, path, bytes.Compare)
return bytes.Compare(old[i], path) >= 0 if found {
}) old = slices.Delete(old, i, i+1)
if i < len(old) && bytes.Equal(old[i], path) {
old = append(old[:i], old[i+1:]...)
} }
} }
if len(old) == 0 { if len(old) == 0 {
@ -117,18 +113,12 @@ func (mp *Pool) Update(remove map[util.Uint256][][]byte, add map[util.Uint256][]
func (mp *Pool) addPaths(nodeHash util.Uint256, paths [][]byte) { func (mp *Pool) addPaths(nodeHash util.Uint256, paths [][]byte) {
old := mp.hashes[nodeHash] old := mp.hashes[nodeHash]
for _, path := range paths { for _, path := range paths {
i := sort.Search(len(old), func(i int) bool { i, found := slices.BinarySearchFunc(old, path, bytes.Compare)
return bytes.Compare(old[i], path) >= 0 if found {
})
if i < len(old) && bytes.Equal(old[i], path) {
// then path is already added // then path is already added
continue continue
} }
old = append(old, path) old = slices.Insert(old, i, path)
if i != len(old)-1 {
copy(old[i+1:], old[i:])
old[i] = path
}
} }
mp.hashes[nodeHash] = old mp.hashes[nodeHash] = old
} }

View file

@ -3,7 +3,7 @@ package storage
import ( import (
"bytes" "bytes"
"context" "context"
"sort" "slices"
"strings" "strings"
"sync" "sync"
) )
@ -230,13 +230,11 @@ func (s *MemCachedStore) prepareSeekMemSnapshot(rng SeekRange) (Store, []KeyValu
// seeking from some point is supported with corresponding `rng` field set. // seeking from some point is supported with corresponding `rng` field set.
func performSeek(ctx context.Context, ps Store, memRes []KeyValueExists, rng SeekRange, cutPrefix bool, f func(k, v []byte) bool) { func performSeek(ctx context.Context, ps Store, memRes []KeyValueExists, rng SeekRange, cutPrefix bool, f func(k, v []byte) bool) {
lPrefix := len(string(rng.Prefix)) lPrefix := len(string(rng.Prefix))
less := func(k1, k2 []byte) bool { var cmpFunc = getCmpFunc(rng.Backwards)
res := bytes.Compare(k1, k2)
return res != 0 && rng.Backwards == (res > 0)
}
// Sort memRes items for further comparison with ps items. // Sort memRes items for further comparison with ps items.
sort.Slice(memRes, func(i, j int) bool { slices.SortFunc(memRes, func(a, b KeyValueExists) int {
return less(memRes[i].Key, memRes[j].Key) return cmpFunc(a.Key, b.Key)
}) })
var ( var (
@ -266,7 +264,7 @@ func performSeek(ctx context.Context, ps Store, memRes []KeyValueExists, rng See
done = true done = true
return false return false
default: default:
var isMem = haveMem && less(kvMem.Key, kvPs.Key) var isMem = haveMem && cmpFunc(kvMem.Key, kvPs.Key) < 0
if isMem { if isMem {
if kvMem.Exists { if kvMem.Exists {
if cutPrefix { if cutPrefix {

View file

@ -3,7 +3,7 @@ package storage
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"sort" "slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/internal/random" "github.com/nspcc-dev/neo-go/internal/random"
@ -424,8 +424,8 @@ func TestCachedSeekSorting(t *testing.T) {
}) })
assert.Equal(t, len(foundKVs), len(lowerKVs)+len(updatedKVs)) assert.Equal(t, len(foundKVs), len(lowerKVs)+len(updatedKVs))
expected := append(lowerKVs, updatedKVs...) expected := append(lowerKVs, updatedKVs...)
sort.Slice(expected, func(i, j int) bool { slices.SortFunc(expected, func(a, b KeyValue) int {
return bytes.Compare(expected[i].Key, expected[j].Key) < 0 return bytes.Compare(a.Key, b.Key)
}) })
require.Equal(t, expected, foundKVs) require.Equal(t, expected, foundKVs)
} }

View file

@ -2,7 +2,7 @@ package storage
import ( import (
"bytes" "bytes"
"sort" "slices"
"strings" "strings"
"sync" "sync"
) )
@ -107,10 +107,7 @@ func (s *MemoryStore) seek(rng SeekRange, f func(k, v []byte) bool, lock func(),
return strings.HasPrefix(key, sPrefix) && (lStart == 0 || strings.Compare(key[lPrefix:], sStart) <= 0) return strings.HasPrefix(key, sPrefix) && (lStart == 0 || strings.Compare(key[lPrefix:], sStart) <= 0)
} }
} }
less := func(k1, k2 []byte) bool { var cmpFunc = getCmpFunc(rng.Backwards)
res := bytes.Compare(k1, k2)
return res != 0 && rng.Backwards == (res > 0)
}
lock() lock()
m := s.chooseMap(rng.Prefix) m := s.chooseMap(rng.Prefix)
@ -123,8 +120,8 @@ func (s *MemoryStore) seek(rng SeekRange, f func(k, v []byte) bool, lock func(),
} }
} }
unlock() unlock()
sort.Slice(memList, func(i, j int) bool { slices.SortFunc(memList, func(a, b KeyValue) int {
return less(memList[i].Key, memList[j].Key) return cmpFunc(a.Key, b.Key)
}) })
for _, kv := range memList { for _, kv := range memList {
if !f(kv.Key, kv.Value) { if !f(kv.Key, kv.Value) {
@ -133,6 +130,13 @@ func (s *MemoryStore) seek(rng SeekRange, f func(k, v []byte) bool, lock func(),
} }
} }
func getCmpFunc(backwards bool) func(a, b []byte) int {
if !backwards {
return bytes.Compare
}
return func(a, b []byte) int { return -bytes.Compare(a, b) }
}
// Close implements Store interface and clears up memory. Never returns an // Close implements Store interface and clears up memory. Never returns an
// error. // error.
func (s *MemoryStore) Close() error { func (s *MemoryStore) Close() error {

View file

@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"reflect" "reflect"
"runtime" "runtime"
"sort" "slices"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -49,15 +49,10 @@ func testStoreSeek(t *testing.T, s Store) {
kvs := pushSeekDataSet(t, s) kvs := pushSeekDataSet(t, s)
check := func(t *testing.T, goodprefix, start []byte, goodkvs []KeyValue, backwards bool, cont func(k, v []byte) bool) { check := func(t *testing.T, goodprefix, start []byte, goodkvs []KeyValue, backwards bool, cont func(k, v []byte) bool) {
// Seek result expected to be sorted in an ascending (for forwards seeking) or descending (for backwards seeking) way. // Seek result expected to be sorted in an ascending (for forwards seeking) or descending (for backwards seeking) way.
cmpFunc := func(i, j int) bool { var cmpFunc = getCmpFunc(backwards)
return bytes.Compare(goodkvs[i].Key, goodkvs[j].Key) < 0 slices.SortFunc(goodkvs, func(a, b KeyValue) int {
} return cmpFunc(a.Key, b.Key)
if backwards { })
cmpFunc = func(i, j int) bool {
return bytes.Compare(goodkvs[i].Key, goodkvs[j].Key) > 0
}
}
sort.Slice(goodkvs, cmpFunc)
rng := SeekRange{ rng := SeekRange{
Prefix: goodprefix, Prefix: goodprefix,

View file

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

View file

@ -14,6 +14,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/bitfield"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
@ -428,14 +429,14 @@ func (t *Transaction) isValid() error {
} }
} }
} }
attrs := map[AttrType]bool{} var attrBits = bitfield.New(256)
for i := range t.Attributes { for i := range t.Attributes {
typ := t.Attributes[i].Type typ := t.Attributes[i].Type
if !typ.allowMultiple() { if !typ.allowMultiple() {
if attrs[typ] { if attrBits.IsSet(int(typ)) {
return fmt.Errorf("%w: multiple '%s' attributes", ErrInvalidAttribute, typ.String()) return fmt.Errorf("%w: multiple '%s' attributes", ErrInvalidAttribute, typ.String())
} }
attrs[typ] = true attrBits.Set(int(typ))
} }
} }
if len(t.Script) == 0 { if len(t.Script) == 0 {

View file

@ -115,10 +115,3 @@ func getCommitteeAddress(committee []*keys.PublicKey) (val util.Uint160, err err
} }
return hash.Hash160(raw), nil return hash.Hash160(raw), nil
} }
// hashSliceReverse reverses the given slice of util.Uint256.
func hashSliceReverse(dest []util.Uint256) {
for i, j := 0, len(dest)-1; i < j; i, j = i+1, j-1 {
dest[i], dest[j] = dest[j], dest[i]
}
}

View file

@ -7,7 +7,6 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/encoding/base58" "github.com/nspcc-dev/neo-go/pkg/encoding/base58"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"golang.org/x/crypto/scrypt" "golang.org/x/crypto/scrypt"
"golang.org/x/text/unicode/norm" "golang.org/x/text/unicode/norm"
) )
@ -53,32 +52,28 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string, params ScryptParams) (s st
if err != nil { if err != nil {
return s, err return s, err
} }
defer slice.Clean(derivedKey) defer clear(derivedKey)
derivedKey1 := derivedKey[:32] derivedKey1 := derivedKey[:32]
derivedKey2 := derivedKey[32:] derivedKey2 := derivedKey[32:]
privBytes := priv.Bytes() privBytes := priv.Bytes()
defer slice.Clean(privBytes) defer clear(privBytes)
xr := xor(privBytes, derivedKey1) xr := xor(privBytes, derivedKey1)
defer slice.Clean(xr) defer clear(xr)
encrypted, err := aesEncrypt(xr, derivedKey2) encrypted, err := aesEncrypt(xr, derivedKey2)
if err != nil { if err != nil {
return s, err return s, err
} }
buf := new(bytes.Buffer) var buf = make([]byte, 0, len(nepHeader)+1+len(addrHash)+len(encrypted))
buf.Write(nepHeader) buf = append(buf, nepHeader...)
buf.WriteByte(nepFlag) buf = append(buf, nepFlag)
buf.Write(addrHash) buf = append(buf, addrHash...)
buf.Write(encrypted) buf = append(buf, encrypted...)
if buf.Len() != 39 { return base58.CheckEncode(buf), nil
return s, fmt.Errorf("invalid buffer length: expecting 39 bytes got %d", buf.Len())
}
return base58.CheckEncode(buf.Bytes()), nil
} }
// NEP2Decrypt decrypts an encrypted key using the given passphrase // NEP2Decrypt decrypts an encrypted key using the given passphrase
@ -99,7 +94,7 @@ func NEP2Decrypt(key, passphrase string, params ScryptParams) (*PrivateKey, erro
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer slice.Clean(derivedKey) defer clear(derivedKey)
derivedKey1 := derivedKey[:32] derivedKey1 := derivedKey[:32]
derivedKey2 := derivedKey[32:] derivedKey2 := derivedKey[32:]
@ -109,10 +104,10 @@ func NEP2Decrypt(key, passphrase string, params ScryptParams) (*PrivateKey, erro
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer slice.Clean(decrypted) defer clear(decrypted)
privBytes := xor(decrypted, derivedKey1) privBytes := xor(decrypted, derivedKey1)
defer slice.Clean(privBytes) defer clear(privBytes)
// Rebuild the private key. // Rebuild the private key.
privKey, err := NewPrivateKeyFromBytes(privBytes) privKey, err := NewPrivateKeyFromBytes(privBytes)

View file

@ -13,7 +13,6 @@ import (
"github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/nspcc-dev/rfc6979" "github.com/nspcc-dev/rfc6979"
) )
@ -49,7 +48,7 @@ func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer slice.Clean(b) defer clear(b)
return NewPrivateKeyFromBytes(b) return NewPrivateKeyFromBytes(b)
} }
@ -111,7 +110,7 @@ func NewPrivateKeyFromWIF(wif string) (*PrivateKey, error) {
// https://en.bitcoin.it/wiki/Wallet_import_format // https://en.bitcoin.it/wiki/Wallet_import_format
func (p *PrivateKey) WIF() string { func (p *PrivateKey) WIF() string {
pb := p.Bytes() pb := p.Bytes()
defer slice.Clean(pb) defer clear(pb)
w, err := WIFEncode(pb, WIFVersion, true) w, err := WIFEncode(pb, WIFVersion, true)
// The only way WIFEncode() can fail is if we're to give it a key of // The only way WIFEncode() can fail is if we're to give it a key of
// wrong size, but we have a proper key here, aren't we? // wrong size, but we have a proper key here, aren't we?
@ -124,10 +123,7 @@ func (p *PrivateKey) WIF() string {
// Destroy wipes the contents of the private key from memory. Any operations // Destroy wipes the contents of the private key from memory. Any operations
// with the key after call to Destroy have undefined behavior. // with the key after call to Destroy have undefined behavior.
func (p *PrivateKey) Destroy() { func (p *PrivateKey) Destroy() {
bits := p.D.Bits() clear(p.D.Bits())
for i := range bits {
bits[i] = 0
}
} }
// Address derives the public NEO address that is coupled with the private key, and // Address derives the public NEO address that is coupled with the private key, and

View file

@ -9,6 +9,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
"slices"
"github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/decred/dcrd/dcrec/secp256k1/v4"
lru "github.com/hashicorp/golang-lru/v2" lru "github.com/hashicorp/golang-lru/v2"
@ -70,23 +71,13 @@ 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,
// but does not perform a deep copy of the elements themselves. // but does not perform a deep copy of the elements themselves.
func (keys PublicKeys) Copy() PublicKeys { func (keys PublicKeys) Copy() PublicKeys {
if keys == nil { return slices.Clone(keys)
return nil
}
res := make(PublicKeys, len(keys))
copy(res, keys)
return res
} }
// Unique returns a set of public keys. // Unique returns a set of public keys.
@ -161,7 +152,7 @@ func (p *PublicKey) getBytes(compressed bool) []byte {
if compressed { if compressed {
return elliptic.MarshalCompressed(p.Curve, p.X, p.Y) return elliptic.MarshalCompressed(p.Curve, p.X, p.Y)
} }
return elliptic.Marshal(p.Curve, p.X, p.Y) return elliptic.Marshal(p.Curve, p.X, p.Y) //nolint:staticcheck // We don't care about ECDH, but UncompressedBytes() should still work.
} }
// Bytes returns byte array representation of the public key in compressed // Bytes returns byte array representation of the public key in compressed

View file

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

View file

@ -1,11 +1,9 @@
package keys package keys
import ( import (
"bytes"
"fmt" "fmt"
"github.com/nspcc-dev/neo-go/pkg/encoding/base58" "github.com/nspcc-dev/neo-go/pkg/encoding/base58"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
) )
const ( const (
@ -37,14 +35,14 @@ func WIFEncode(key []byte, version byte, compressed bool) (s string, err error)
return s, fmt.Errorf("invalid private key length: %d", len(key)) return s, fmt.Errorf("invalid private key length: %d", len(key))
} }
buf := new(bytes.Buffer) var buf = make([]byte, 0, 1+len(key)+1)
buf.WriteByte(version) buf = append(buf, version)
buf.Write(key) buf = append(buf, key...)
if compressed { if compressed {
buf.WriteByte(0x01) buf = append(buf, 0x01)
} }
s = base58.CheckEncode(buf.Bytes()) s = base58.CheckEncode(buf)
return return
} }
@ -54,7 +52,7 @@ func WIFDecode(wif string, version byte) (*WIF, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer slice.Clean(b) defer clear(b)
if version == 0x00 { if version == 0x00 {
version = WIFVersion version = WIFVersion

View file

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

View file

@ -3,9 +3,9 @@ package bigint
import ( import (
"math" "math"
"math/big" "math/big"
"slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/util/slice"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "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) { func TestEquivalentRepresentations(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
buf := tc.buf buf := tc.buf
@ -210,7 +185,9 @@ func TestVeryBigInts(t *testing.T) {
num, ok := new(big.Int).SetString(tc.numStr, 10) num, ok := new(big.Int).SetString(tc.numStr, 10)
assert.True(t, ok) 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) assert.Equal(t, num, result, "error while converting %s from bytes", tc.numStr)
} }
} }

View file

@ -1,6 +1,7 @@
package fixedn package fixedn
import ( import (
"cmp"
"strconv" "strconv"
"strings" "strings"
@ -158,10 +159,10 @@ func (f Fixed8) Equal(g Fixed8) bool {
return f == g return f == g
} }
// CompareTo returns the difference between the f and g. // Compare performs three-way comparison between f and g.
// difference < 0 implies f < g. // - -1 implies f < g.
// difference = 0 implies f = g. // - 0 implies f = g.
// difference > 0 implies f > g. // - 1 implies f > g.
func (f Fixed8) CompareTo(g Fixed8) int { func (f Fixed8) Compare(g Fixed8) int {
return int(f - g) return cmp.Compare(f, g)
} }

View file

@ -164,8 +164,8 @@ func TestFixed8_Arith(t *testing.T) {
assert.True(t, u1.LessThan(u2)) assert.True(t, u1.LessThan(u2))
assert.True(t, u2.GreaterThan(u1)) assert.True(t, u2.GreaterThan(u1))
assert.True(t, u1.Equal(u1)) assert.True(t, u1.Equal(u1))
assert.NotZero(t, u1.CompareTo(u2)) assert.NotZero(t, u1.Compare(u2))
assert.Zero(t, u1.CompareTo(u1)) assert.Zero(t, u1.Compare(u1))
assert.EqualValues(t, Fixed8(2), u2.Div(3)) assert.EqualValues(t, Fixed8(2), u2.Div(3))
} }

View file

@ -1,3 +1,3 @@
module github.com/nspcc-dev/neo-go/pkg/interop module github.com/nspcc-dev/neo-go/pkg/interop
go 1.20 go 1.21

View file

@ -2,7 +2,7 @@ package chain
import ( import (
"encoding/hex" "encoding/hex"
"sort" "slices"
"testing" "testing"
"time" "time"
@ -103,12 +103,12 @@ func init() {
standByCommittee[5] = pubs[5].StringCompressed() standByCommittee[5] = pubs[5].StringCompressed()
multiValidatorAcc = make([]*wallet.Account, 4) multiValidatorAcc = make([]*wallet.Account, 4)
sort.Sort(pubs[:4]) slices.SortFunc(pubs[:4], (*keys.PublicKey).Cmp)
sort.Slice(accs[:4], func(i, j int) bool { slices.SortFunc(accs[:4], func(a, b *wallet.Account) int {
p1 := accs[i].PublicKey() pa := a.PublicKey()
p2 := accs[j].PublicKey() pb := b.PublicKey()
return p1.Cmp(p2) == -1 return pa.Cmp(pb)
}) })
for i := range multiValidatorAcc { for i := range multiValidatorAcc {
multiValidatorAcc[i] = wallet.NewAccountFromPrivateKey(accs[i].PrivateKey()) multiValidatorAcc[i] = wallet.NewAccountFromPrivateKey(accs[i].PrivateKey())
@ -119,12 +119,12 @@ func init() {
} }
multiCommitteeAcc = make([]*wallet.Account, len(committeeWIFs)) multiCommitteeAcc = make([]*wallet.Account, len(committeeWIFs))
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
sort.Slice(accs, func(i, j int) bool { slices.SortFunc(accs, func(a, b *wallet.Account) int {
p1 := accs[i].PublicKey() pa := a.PublicKey()
p2 := accs[j].PublicKey() pb := b.PublicKey()
return p1.Cmp(p2) == -1 return pa.Cmp(pb)
}) })
for i := range multiCommitteeAcc { for i := range multiCommitteeAcc {
multiCommitteeAcc[i] = wallet.NewAccountFromPrivateKey(accs[i].PrivateKey()) multiCommitteeAcc[i] = wallet.NewAccountFromPrivateKey(accs[i].PrivateKey())

View file

@ -3,7 +3,7 @@ package neotest
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"sort" "slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
@ -106,10 +106,10 @@ func NewMultiSigner(accs ...*wallet.Account) MultiSigner {
panic(fmt.Sprintf("verification script requires %d signatures, "+ panic(fmt.Sprintf("verification script requires %d signatures, "+
"but only %d accounts were provided", m, len(accs))) "but only %d accounts were provided", m, len(accs)))
} }
sort.Slice(accs, func(i, j int) bool { slices.SortFunc(accs, func(a, b *wallet.Account) int {
p1 := accs[i].PublicKey() pa := a.PublicKey()
p2 := accs[j].PublicKey() pb := b.PublicKey()
return p1.Cmp(p2) == -1 return pa.Cmp(pb)
}) })
for _, acc := range accs { for _, acc := range accs {
if !bytes.Equal(script, acc.Contract.Script) { if !bytes.Equal(script, acc.Contract.Script) {

View file

@ -1,7 +1,7 @@
package neotest package neotest
import ( import (
"sort" "slices"
"testing" "testing"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -31,7 +31,7 @@ func TestMultiSigner(t *testing.T) {
pubs[i] = a.PublicKey() pubs[i] = a.PublicKey()
} }
sort.Sort(pubs) slices.SortFunc(pubs, (*keys.PublicKey).Cmp)
m := smartcontract.GetDefaultHonestNodeCount(size) m := smartcontract.GetDefaultHonestNodeCount(size)
for i := range accs { for i := range accs {
require.NoError(t, accs[i].ConvertMultisig(m, pubs)) require.NoError(t, accs[i].ConvertMultisig(m, pubs))

View file

@ -3,7 +3,7 @@ package network
import ( import (
"errors" "errors"
"net" "net"
"sort" "slices"
"sync/atomic" "sync/atomic"
"testing" "testing"
"time" "time"
@ -91,7 +91,7 @@ func TestDefaultDiscoverer(t *testing.T) {
tryMaxWait = 1 // Don't waste time. tryMaxWait = 1 // Don't waste time.
var set1 = []string{"1.1.1.1:10333", "2.2.2.2:10333"} var set1 = []string{"1.1.1.1:10333", "2.2.2.2:10333"}
sort.Strings(set1) slices.Sort(set1)
// Added addresses should end up in the pool and in the unconnected set. // Added addresses should end up in the pool and in the unconnected set.
// Done twice to check re-adding unconnected addresses, which should be // Done twice to check re-adding unconnected addresses, which should be
@ -100,7 +100,7 @@ func TestDefaultDiscoverer(t *testing.T) {
d.BackFill(set1...) d.BackFill(set1...)
assert.Equal(t, len(set1), d.PoolCount()) assert.Equal(t, len(set1), d.PoolCount())
set1D := d.UnconnectedPeers() set1D := d.UnconnectedPeers()
sort.Strings(set1D) slices.Sort(set1D)
assert.Equal(t, 0, len(d.GoodPeers())) assert.Equal(t, 0, len(d.GoodPeers()))
assert.Equal(t, 0, len(d.BadPeers())) assert.Equal(t, 0, len(d.BadPeers()))
require.Equal(t, set1, set1D) require.Equal(t, set1, set1D)
@ -120,7 +120,7 @@ func TestDefaultDiscoverer(t *testing.T) {
} }
} }
require.Eventually(t, func() bool { return len(d.UnconnectedPeers()) == 0 }, 2*time.Second, 50*time.Millisecond) require.Eventually(t, func() bool { return len(d.UnconnectedPeers()) == 0 }, 2*time.Second, 50*time.Millisecond)
sort.Strings(dialled) slices.Sort(dialled)
assert.Equal(t, 0, d.PoolCount()) assert.Equal(t, 0, d.PoolCount())
assert.Equal(t, 0, len(d.BadPeers())) assert.Equal(t, 0, len(d.BadPeers()))
assert.Equal(t, 0, len(d.GoodPeers())) assert.Equal(t, 0, len(d.GoodPeers()))
@ -150,7 +150,7 @@ func TestDefaultDiscoverer(t *testing.T) {
}, addr.Capabilities) }, addr.Capabilities)
gAddrs[i] = addr.Address gAddrs[i] = addr.Address
} }
sort.Strings(gAddrs) slices.Sort(gAddrs)
assert.Equal(t, 0, d.PoolCount()) assert.Equal(t, 0, d.PoolCount())
assert.Equal(t, 0, len(d.UnconnectedPeers())) assert.Equal(t, 0, len(d.UnconnectedPeers()))
assert.Equal(t, 0, len(d.BadPeers())) assert.Equal(t, 0, len(d.BadPeers()))
@ -176,7 +176,7 @@ func TestDefaultDiscoverer(t *testing.T) {
ts.retFalse.Store(1) ts.retFalse.Store(1)
assert.Equal(t, len(set1), d.PoolCount()) assert.Equal(t, len(set1), d.PoolCount())
set1D := d.UnconnectedPeers() set1D := d.UnconnectedPeers()
sort.Strings(set1D) slices.Sort(set1D)
assert.Equal(t, 0, len(d.BadPeers())) assert.Equal(t, 0, len(d.BadPeers()))
require.Equal(t, set1, set1D) require.Equal(t, set1, set1D)
@ -193,7 +193,7 @@ func TestDefaultDiscoverer(t *testing.T) {
} }
} }
require.Eventually(t, func() bool { return d.PoolCount() == 0 }, 2*time.Second, 50*time.Millisecond) require.Eventually(t, func() bool { return d.PoolCount() == 0 }, 2*time.Second, 50*time.Millisecond)
sort.Strings(dialledBad) slices.Sort(dialledBad)
for i := 0; i < len(set1); i++ { for i := 0; i < len(set1); i++ {
for j := 0; j < connRetries; j++ { for j := 0; j < connRetries; j++ {
assert.Equal(t, set1[i], dialledBad[i*connRetries+j]) assert.Equal(t, set1[i], dialledBad[i*connRetries+j])
@ -216,7 +216,7 @@ func TestSeedDiscovery(t *testing.T) {
ts := &fakeTransp{} ts := &fakeTransp{}
ts.dialCh = make(chan string) ts.dialCh = make(chan string)
ts.retFalse.Store(1) // Fail all dial requests. ts.retFalse.Store(1) // Fail all dial requests.
sort.Strings(seeds) slices.Sort(seeds)
d := NewDefaultDiscovery(seeds, time.Second/10, ts) d := NewDefaultDiscovery(seeds, time.Second/10, ts)
tryMaxWait = 1 // Don't waste time. tryMaxWait = 1 // Don't waste time.

View file

@ -17,6 +17,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
Script: []byte{0, 1, 2}, Script: []byte{0, 1, 2},
ValidUntilBlock: 123, ValidUntilBlock: 123,
} }
emptySingleInvocation := append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...)
errorCases := map[string]*P2PNotaryRequest{ errorCases := map[string]*P2PNotaryRequest{
"main tx: missing NotaryAssisted attribute": {MainTransaction: &transaction.Transaction{}}, "main tx: missing NotaryAssisted attribute": {MainTransaction: &transaction.Transaction{}},
"main tx: zero NKeys": {MainTransaction: &transaction.Transaction{Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}}}}}, "main tx: zero NKeys": {MainTransaction: &transaction.Transaction{Attributes: []transaction.Attribute{{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}}}}},
@ -53,14 +54,14 @@ func TestNotaryRequestIsValid(t *testing.T) {
MainTransaction: mainTx, MainTransaction: mainTx,
FallbackTransaction: &transaction.Transaction{ FallbackTransaction: &transaction.Transaction{
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 1)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 1)}, {}},
}, },
}, },
"fallback tx: missing NotValidBefore attribute": { "fallback tx: missing NotValidBefore attribute": {
MainTransaction: mainTx, MainTransaction: mainTx,
FallbackTransaction: &transaction.Transaction{ FallbackTransaction: &transaction.Transaction{
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
"fallback tx: invalid number of Conflicts attributes": { "fallback tx: invalid number of Conflicts attributes": {
@ -68,7 +69,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
FallbackTransaction: &transaction.Transaction{ FallbackTransaction: &transaction.Transaction{
Attributes: []transaction.Attribute{{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}}}, Attributes: []transaction.Attribute{{Type: transaction.NotValidBeforeT, Value: &transaction.NotValidBefore{Height: 123}}},
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
"fallback tx: does not conflicts with main tx": { "fallback tx: does not conflicts with main tx": {
@ -79,7 +80,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: util.Uint256{}}}, {Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: util.Uint256{}}},
}, },
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
"fallback tx: missing NotaryAssisted attribute": { "fallback tx: missing NotaryAssisted attribute": {
@ -90,7 +91,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
{Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}}, {Type: transaction.ConflictsT, Value: &transaction.Conflicts{Hash: mainTx.Hash()}},
}, },
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
"fallback tx: non-zero NKeys": { "fallback tx: non-zero NKeys": {
@ -102,7 +103,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}}, {Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 1}},
}, },
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
"fallback tx: ValidUntilBlock mismatch": { "fallback tx: ValidUntilBlock mismatch": {
@ -115,7 +116,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}}, {Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
}, },
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
}, },
} }
@ -135,7 +136,7 @@ func TestNotaryRequestIsValid(t *testing.T) {
{Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}}, {Type: transaction.NotaryAssistedT, Value: &transaction.NotaryAssisted{NKeys: 0}},
}, },
Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}}, Signers: []transaction.Signer{{Account: random.Uint160()}, {Account: random.Uint160()}},
Scripts: []transaction.Witness{{InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...), VerificationScript: make([]byte, 0)}, {}}, Scripts: []transaction.Witness{{InvocationScript: emptySingleInvocation, VerificationScript: make([]byte, 0)}, {}},
}, },
} }
require.NoError(t, p.isValid()) require.NoError(t, p.isValid())

View file

@ -10,7 +10,7 @@ import (
mrand "math/rand" mrand "math/rand"
"net" "net"
"runtime" "runtime"
"sort" "slices"
"strconv" "strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -475,11 +475,7 @@ func (s *Server) run() {
} else if s.MinPeers > 0 && loopCnt%s.MinPeers == 0 && optimalN > peerN && optimalN < s.MaxPeers && optimalN < netSize { } else if s.MinPeers > 0 && loopCnt%s.MinPeers == 0 && optimalN > peerN && optimalN < s.MaxPeers && optimalN < netSize {
// Having some number of peers, but probably can get some more, the network is big. // Having some number of peers, but probably can get some more, the network is big.
// It also allows to start picking up new peers proactively, before we suddenly have <s.MinPeers of them. // It also allows to start picking up new peers proactively, before we suddenly have <s.MinPeers of them.
var connN = s.AttemptConnPeers s.discovery.RequestRemote(min(s.AttemptConnPeers, optimalN-peerN))
if connN > optimalN-peerN {
connN = optimalN - peerN
}
s.discovery.RequestRemote(connN)
} }
if addrCheckTimeout || s.discovery.PoolCount() < s.AttemptConnPeers { if addrCheckTimeout || s.discovery.PoolCount() < s.AttemptConnPeers {
@ -1173,10 +1169,8 @@ txloop:
var cbList = s.txCbList.Load() var cbList = s.txCbList.Load()
if cbList != nil { if cbList != nil {
var list = cbList.([]util.Uint256) var list = cbList.([]util.Uint256)
var i = sort.Search(len(list), func(i int) bool { _, found := slices.BinarySearchFunc(list, tx.Hash(), util.Uint256.Compare)
return list[i].CompareTo(tx.Hash()) >= 0 if found {
})
if i < len(list) && list[i].Equals(tx.Hash()) {
txCallback(tx) txCallback(tx)
} }
} }
@ -1443,25 +1437,16 @@ func (s *Server) tryInitStateSync() {
return return
} }
var peersNumber int
s.lock.RLock() s.lock.RLock()
heights := make([]uint32, 0) heights := make([]uint32, 0, len(s.peers))
for p := range s.peers { for p := range s.peers {
if p.Handshaked() { if p.Handshaked() {
peersNumber++ heights = append(heights, p.LastBlockIndex())
peerLastBlock := p.LastBlockIndex()
i := sort.Search(len(heights), func(i int) bool {
return heights[i] >= peerLastBlock
})
heights = append(heights, peerLastBlock)
if i != len(heights)-1 {
copy(heights[i+1:], heights[i:])
heights[i] = peerLastBlock
}
} }
} }
s.lock.RUnlock() s.lock.RUnlock()
if peersNumber >= s.MinPeers && len(heights) > 0 { slices.Sort(heights)
if len(heights) >= s.MinPeers && len(heights) > 0 {
// choose the height of the median peer as the current chain's height // choose the height of the median peer as the current chain's height
h := heights[len(heights)/2] h := heights[len(heights)/2]
err := s.stateSync.Init(h) err := s.stateSync.Init(h)
@ -1498,20 +1483,14 @@ func (s *Server) RequestTx(hashes ...util.Uint256) {
return return
} }
var sorted = make([]util.Uint256, len(hashes)) var sorted = slices.Clone(hashes)
copy(sorted, hashes) slices.SortFunc(sorted, util.Uint256.Compare)
sort.Slice(sorted, func(i, j int) bool {
return sorted[i].CompareTo(sorted[j]) < 0
})
s.txCbList.Store(sorted) s.txCbList.Store(sorted)
for i := 0; i <= len(hashes)/payload.MaxHashesCount; i++ { for i := 0; i <= len(hashes)/payload.MaxHashesCount; i++ {
start := i * payload.MaxHashesCount start := i * payload.MaxHashesCount
stop := (i + 1) * payload.MaxHashesCount stop := (i + 1) * payload.MaxHashesCount
if stop > len(hashes) { stop = min(stop, len(hashes))
stop = len(hashes)
}
if start == stop { if start == stop {
break break
} }
@ -1660,9 +1639,7 @@ func (s *Server) initStaleMemPools() {
threshold := 5 threshold := 5
// Not perfect, can change over time, but should be sufficient. // Not perfect, can change over time, but should be sufficient.
numOfCNs := s.config.GetNumOfCNs(s.chain.BlockHeight()) numOfCNs := s.config.GetNumOfCNs(s.chain.BlockHeight())
if numOfCNs*2 > threshold { threshold = max(threshold, numOfCNs*2)
threshold = numOfCNs * 2
}
s.mempool.SetResendThreshold(uint32(threshold), s.broadcastTX) s.mempool.SetResendThreshold(uint32(threshold), s.broadcastTX)
if s.chain.P2PSigExtensionsEnabled() { if s.chain.P2PSigExtensionsEnabled() {
@ -1769,12 +1746,5 @@ func (s *Server) Port(localAddr net.Addr) (uint16, error) {
func optimalNumOfThreads() int { func optimalNumOfThreads() int {
// Doing more won't help, mempool is still a contention point. // Doing more won't help, mempool is still a contention point.
const maxThreads = 16 const maxThreads = 16
var threads = runtime.GOMAXPROCS(0) return min(runtime.GOMAXPROCS(0), runtime.NumCPU(), maxThreads)
if threads > runtime.NumCPU() {
threads = runtime.NumCPU()
}
if threads > maxThreads {
threads = maxThreads
}
return threads
} }

View file

@ -229,9 +229,7 @@ func iterateNext(rpc RPCSessions, sessionID uuid.UUID, iterator *result.Iterator
if iterator.ID != nil { if iterator.ID != nil {
return rpc.TraverseIterator(sessionID, *iterator.ID, num) return rpc.TraverseIterator(sessionID, *iterator.ID, num)
} }
if num > len(iterator.Values) { num = min(num, len(iterator.Values))
num = len(iterator.Values)
}
items := iterator.Values[:num] items := iterator.Values[:num]
iterator.Values = iterator.Values[num:] iterator.Values = iterator.Values[num:]

View file

@ -1,11 +1,13 @@
package neo_test package neo_test
import ( import (
"cmp"
"context" "context"
"math/big" "math/big"
"sort" "slices"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
@ -76,7 +78,7 @@ func ExampleContract() {
cands, _ := neoToken.GetCandidates() cands, _ := neoToken.GetCandidates()
// Sort by votes. // Sort by votes.
sort.Slice(cands, func(i, j int) bool { return cands[i].Votes < cands[j].Votes }) slices.SortFunc(cands, func(a, b result.Validator) int { return cmp.Compare(a.Votes, b.Votes) })
// Get the extended NEO-specific balance data. // Get the extended NEO-specific balance data.
bNeo, _ := neoToken.GetAccountState(a.Sender()) bNeo, _ := neoToken.GetAccountState(a.Sender())

View file

@ -29,8 +29,8 @@ var (
// of transaction awaiting process and no result was received yet. // of transaction awaiting process and no result was received yet.
ErrContextDone = errors.New("waiter context done") ErrContextDone = errors.New("waiter context done")
// ErrAwaitingNotSupported is returned from Wait method if Waiter instance // ErrAwaitingNotSupported is returned from Wait method if Waiter instance
// doesn't support transaction awaiting. // doesn't support transaction awaiting. It's compatible with [errors.ErrUnsupported].
ErrAwaitingNotSupported = errors.New("awaiting not supported") ErrAwaitingNotSupported = fmt.Errorf("%w: awaiting", errors.ErrUnsupported)
// ErrMissedEvent is returned when RPCEventBased closes receiver channel // ErrMissedEvent is returned when RPCEventBased closes receiver channel
// which happens if missed event was received from the RPC server. // which happens if missed event was received from the RPC server.
ErrMissedEvent = errors.New("some event was missed") ErrMissedEvent = errors.New("some event was missed")

View file

@ -6,7 +6,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -866,7 +866,7 @@ func TestWSConcurrentAccess(t *testing.T) {
} }
ids.lock.RUnlock() ids.lock.RUnlock()
sort.Ints(idsList) slices.Sort(idsList)
require.Equal(t, 1, idsList[0]) require.Equal(t, 1, idsList[0])
require.Less(t, idsList[len(idsList)-1], require.Less(t, idsList[len(idsList)-1],
batchCount*3+1) // batchCount*requestsPerBatch+1 batchCount*3+1) // batchCount*requestsPerBatch+1

View file

@ -1,6 +1,8 @@
package notary package notary
import ( import (
"slices"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
@ -13,13 +15,9 @@ func (n *Notary) UpdateNotaryNodes(notaryNodes keys.PublicKeys) {
n.accMtx.Lock() n.accMtx.Lock()
defer n.accMtx.Unlock() defer n.accMtx.Unlock()
if n.currAccount != nil { if n.currAccount != nil && slices.ContainsFunc(notaryNodes, n.currAccount.PublicKey().Equal) {
for _, node := range notaryNodes {
if node.Equal(n.currAccount.PublicKey()) {
return return
} }
}
}
var acc *wallet.Account var acc *wallet.Account
for _, node := range notaryNodes { for _, node := range notaryNodes {

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,14 +257,12 @@ 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)
if nvbFallback < r.minNotValidBefore {
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
// keep the pooled tx valid. We will update its copy => the copy's size will be changed. // keep the pooled tx valid. We will update its copy => the copy's size will be changed.
@ -449,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

@ -449,9 +449,7 @@ func (p *pathParser) descendByRange(objs []any, start, end int) ([]any, bool) {
subEnd += len(arr) subEnd += len(arr)
} }
if subEnd > len(arr) { subEnd = min(subEnd, len(arr))
subEnd = len(arr)
}
if subEnd <= subStart { if subEnd <= subStart {
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

@ -1,6 +1,8 @@
package oracle package oracle
import ( import (
"slices"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -13,18 +15,9 @@ func (o *Oracle) UpdateOracleNodes(oracleNodes keys.PublicKeys) {
o.accMtx.Lock() o.accMtx.Lock()
defer o.accMtx.Unlock() defer o.accMtx.Unlock()
old := o.oracleNodes if slices.EqualFunc(o.oracleNodes, oracleNodes, (*keys.PublicKey).Equal) {
if isEqual := len(old) == len(oracleNodes); isEqual {
for i := range old {
if !old[i].Equal(oracleNodes[i]) {
isEqual = false
break
}
}
if isEqual {
return return
} }
}
var acc *wallet.Account var acc *wallet.Account
for i := range oracleNodes { for i := range oracleNodes {

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
} }

Some files were not shown because too many files have changed in this diff Show more