From 8fc733ff9596987b2710c78447b7a817e1501d53 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:56:32 +0100 Subject: [PATCH 001/111] feat: socket client uses pririority queue to determine processing order --- abci/client/client.go | 33 +++++++++++++++++++++++++++++++++ abci/client/socket_client.go | 25 ++++++++++++++++++++----- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index c5afa771e2..bfcd929ccb 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -55,6 +55,39 @@ type requestAndResponse struct { signal chan struct{} } +// priority of this request type; higher number means more important +func (reqResp *requestAndResponse) priority() (priority int8) { + if reqResp == nil || reqResp.Request == nil || reqResp.Request.Value == nil { + // Error + return -128 + } + // consensus-related requests are more important + switch reqResp.Request.Value.(type) { + case *types.Request_InitChain: + priority = 110 + case *types.Request_PrepareProposal: + priority = 100 + case *types.Request_ProcessProposal: + priority = 100 + case *types.Request_FinalizeBlock: + priority = 100 + case *types.Request_ExtendVote: + priority = 100 + case *types.Request_VerifyVoteExtension: + priority = 100 + case *types.Request_Info: + priority = 90 + case *types.Request_CheckTx: + priority = -10 + case *types.Request_Query: + priority = -20 + default: + priority = 0 + } + + return priority +} + func makeReqRes(req *types.Request) *requestAndResponse { return &requestAndResponse{ Request: req, diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 26adc2318f..24ba8ffff3 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -10,6 +10,7 @@ import ( "net" "time" + "github.com/ethereum/go-ethereum/common/prque" sync "github.com/sasha-s/go-deadlock" "github.com/dashpay/tenderdash/abci/types" @@ -28,7 +29,10 @@ type socketClient struct { mustConnect bool conn net.Conn - reqQueue chan *requestAndResponse + // Requests queue + reqQueue *prque.Prque[int8, *requestAndResponse] + // Signal emitted when new request is added to the queue. + reqSignal chan struct{} mtx sync.Mutex err error @@ -42,8 +46,10 @@ var _ Client = (*socketClient)(nil) // if it fails to connect. func NewSocketClient(logger log.Logger, addr string, mustConnect bool) Client { cli := &socketClient{ - logger: logger, - reqQueue: make(chan *requestAndResponse), + logger: logger, + reqQueue: prque.New[int8, *requestAndResponse](nil), + reqSignal: make(chan struct{}), + mustConnect: mustConnect, addr: addr, reqSent: list.New(), @@ -114,7 +120,11 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer select { case <-ctx.Done(): return - case reqres := <-cli.reqQueue: + case <-cli.reqSignal: + cli.mtx.Lock() + reqres := cli.reqQueue.PopItem() + cli.mtx.Unlock() + // N.B. We must enqueue before sending out the request, otherwise the // server may reply before we do it, and the receiver will fail for an // unsolicited reply. @@ -203,8 +213,12 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty reqres := makeReqRes(req) + cli.mtx.Lock() + cli.reqQueue.Push(reqres, reqres.priority()) + cli.mtx.Unlock() + select { - case cli.reqQueue <- reqres: + case cli.reqSignal <- struct{}{}: case <-ctx.Done(): return nil, fmt.Errorf("can't queue req: %w", ctx.Err()) } @@ -227,6 +241,7 @@ func (cli *socketClient) drainQueue() { cli.mtx.Lock() defer cli.mtx.Unlock() + cli.reqQueue.Reset() // mark all in-flight messages as resolved (they will get cli.Error()) for req := cli.reqSent.Front(); req != nil; req = req.Next() { reqres := req.Value.(*requestAndResponse) From 7311bdee00710963790617dc668f9abc76406d58 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:58:13 +0100 Subject: [PATCH 002/111] chore(consensus): add timing debug to makeProposal --- internal/consensus/state_proposaler.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 48848927b7..523d68a712 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -65,6 +65,13 @@ func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cst } rs.Proposal = proposal rs.ProposalReceiveTime = receivedAt + + // if rand.Intn(5) != 0 && !rs.Validators.Proposer.ProTxHash.Equal(p.privVal.ProTxHash) { + // p.logger.Debug("waiting for proposal to get outdated as a test") + // sleepTime := p.blockExec.committedState.ConsensusParams.Synchrony.MessageDelay + p.blockExec.committedState.ConsensusParams.Synchrony.Precision + // rs.ProposalReceiveTime = rs.ProposalReceiveTime.Add(sleepTime) + // } + p.proposalTimestampDifferenceMetric(*rs) // We don't update cs.ProposalBlockParts if it is already set. // This happens if we're already in cstypes.RoundStepApplyCommit or if there is a valid block in the current round. @@ -94,8 +101,13 @@ func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs * logger := p.logger.With( "height", height, "round", round) + + p.logger.Trace("before makeProposal") + start := time.Now() // Make proposal proposal := makeProposal(height, round, rs.ValidRound, block, blockParts) + p.logger.Info("makeProposal executed successfully", "duration", time.Since(start)) + // Sign proposal err := p.signProposal(ctx, height, proposal) if err != nil { From 4ef183319537d1f825faf443435015533e3659cf Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:20:01 +0100 Subject: [PATCH 003/111] build: update go.mod/go.sum --- go.mod | 209 ++++++++-------- go.sum | 741 +++++++++++++++++++++++++-------------------------------- 2 files changed, 433 insertions(+), 517 deletions(-) diff --git a/go.mod b/go.mod index 881c98ec28..3b24448362 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/dashpay/tenderdash go 1.21 require ( - github.com/BurntSushi/toml v1.2.0 + github.com/BurntSushi/toml v1.3.2 github.com/adlio/schema v1.3.3 github.com/btcsuite/btcd v0.22.1 github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce @@ -16,17 +16,17 @@ require ( github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-kit/kit v0.12.0 github.com/gogo/protobuf v1.3.2 - github.com/golang/protobuf v1.5.2 - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/protobuf v1.5.3 + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/golangci/golangci-lint v1.55.0 github.com/google/btree v1.1.2 // indirect github.com/google/gopacket v1.1.19 github.com/google/orderedcode v0.0.1 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/gorilla/websocket v1.5.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 - github.com/lib/pq v1.10.6 + github.com/lib/pq v1.10.9 github.com/libp2p/go-buffer-pool v0.1.0 github.com/mroth/weightedrand v0.4.1 github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae @@ -35,13 +35,13 @@ require ( github.com/rs/cors v1.8.2 github.com/rs/zerolog v1.29.0 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa - github.com/spf13/cobra v1.6.1 + github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.15.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 github.com/tendermint/tm-db v0.6.6 - golang.org/x/crypto v0.1.0 - golang.org/x/net v0.8.0 - golang.org/x/sync v0.1.0 + golang.org/x/crypto v0.17.0 + golang.org/x/net v0.18.0 + golang.org/x/sync v0.5.0 google.golang.org/grpc v1.52.0 pgregory.net/rapid v0.4.8 ) @@ -57,73 +57,96 @@ require ( ) require ( + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + github.com/4meepo/tagalign v1.3.3 // indirect + github.com/Abirdcfly/dupword v0.0.13 // indirect + github.com/Antonboom/testifylint v0.2.3 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.1.0 // indirect + github.com/alecthomas/go-check-sumtype v0.1.3 // indirect + github.com/alexkohler/nakedret/v2 v2.0.2 // indirect github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect github.com/bufbuild/connect-go v0.2.0 // indirect + github.com/butuzov/mirror v1.1.0 // indirect + github.com/catenacyber/perfsprint v0.2.0 // indirect + github.com/ccojocar/zxcvbn-go v1.0.1 // indirect github.com/chigopher/pathlib v0.15.0 // indirect github.com/containerd/containerd v1.6.6 // indirect github.com/containerd/typeurl v1.0.2 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/dashpay/dashd-go/btcutil v1.2.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/didip/tollbooth/v6 v6.0.1 // indirect github.com/didip/tollbooth_chi v0.0.0-20200524181329-8b84cd7183d9 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker v20.10.17+incompatible // indirect + github.com/ghostiam/protogetter v0.2.3 // indirect github.com/go-chi/chi/v5 v5.0.7 // indirect github.com/go-chi/render v1.0.1 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-pkgz/expirable-cache v0.0.3 // indirect github.com/go-pkgz/rest v1.5.0 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/iancoleman/strcase v0.2.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect + github.com/kkHAIKE/contextcheck v1.1.4 // indirect + github.com/macabu/inamedparam v0.1.2 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect github.com/moby/buildkit v0.10.3 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/nunnatsa/ginkgolinter v0.14.0 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect - github.com/sashamelentyev/usestdlibvars v1.8.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/sashamelentyev/interfacebloat v1.1.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.24.0 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/tendermint v0.34.21 // indirect + github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/xen0n/gosmopolitan v1.2.2 // indirect + github.com/ykadowak/zerologlint v0.1.3 // indirect + go-simpler.org/sloglint v0.1.2 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.33.0 // indirect go.opentelemetry.io/otel v1.8.0 // indirect go.opentelemetry.io/otel/trace v1.8.0 // indirect - golang.org/x/time v0.1.0 // indirect + go.tmz.dev/musttag v0.7.2 // indirect + golang.org/x/time v0.3.0 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect ) require ( - 4d63.com/gochecknoglobals v0.1.0 // indirect - github.com/Antonboom/errname v0.1.7 // indirect - github.com/Antonboom/nilnil v0.1.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + github.com/Antonboom/errname v0.1.12 // indirect + github.com/Antonboom/nilnil v0.1.7 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/DataDog/zstd v1.4.1 // indirect + github.com/DataDog/zstd v1.4.5 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect - github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.2 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/Microsoft/go-winio v0.5.2 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/OpenPeeDeeP/depguard v1.1.0 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect - github.com/ashanbrown/forbidigo v1.3.0 // indirect + github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/bkielbasa/cyclop v1.2.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect - github.com/bombsimon/wsl/v3 v3.3.0 // indirect - github.com/breml/bidichk v0.2.3 // indirect - github.com/breml/errchkjson v0.3.0 // indirect - github.com/butuzov/ireturn v0.1.1 // indirect + github.com/bombsimon/wsl/v3 v3.4.0 // indirect + github.com/breml/bidichk v0.2.7 // indirect + github.com/breml/errchkjson v0.3.6 // indirect + github.com/butuzov/ireturn v0.2.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/charithe/durationcheck v0.0.9 // indirect - github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/charithe/durationcheck v0.0.10 // indirect + github.com/chavacava/garif v0.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/daixiang0/gci v0.6.2 // indirect + github.com/daixiang0/gci v0.11.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/dgraph-io/badger/v2 v2.2007.2 // indirect @@ -134,20 +157,20 @@ require ( github.com/dustin/go-humanize v1.0.0 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-critic/go-critic v0.6.3 // indirect - github.com/go-toolsmith/astcast v1.0.0 // indirect - github.com/go-toolsmith/astcopy v1.0.0 // indirect - github.com/go-toolsmith/astequal v1.0.1 // indirect - github.com/go-toolsmith/astfmt v1.0.0 // indirect - github.com/go-toolsmith/astp v1.0.0 // indirect - github.com/go-toolsmith/strparse v1.0.0 // indirect - github.com/go-toolsmith/typep v1.0.2 // indirect - github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/go-critic/go-critic v0.9.0 // indirect + github.com/go-toolsmith/astcast v1.1.0 // indirect + github.com/go-toolsmith/astcopy v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.1.0 // indirect + github.com/go-toolsmith/astfmt v1.1.0 // indirect + github.com/go-toolsmith/astp v1.1.0 // indirect + github.com/go-toolsmith/strparse v1.1.0 // indirect + github.com/go-toolsmith/typep v1.1.0 // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.2.0+incompatible // indirect @@ -155,13 +178,13 @@ require ( github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect - github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect + github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.3.5 // indirect - github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect + github.com/golangci/misspell v0.4.1 // indirect + github.com/golangci/revgrep v0.5.0 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -173,69 +196,67 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect - github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jgautheron/goconst v1.6.0 // indirect github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f // indirect github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.2 // indirect + github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.15.10 // indirect + github.com/klauspost/compress v1.15.15 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/kulti/thelper v0.6.3 // indirect - github.com/kunwardeep/paralleltest v1.0.6 // indirect - github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/kunwardeep/paralleltest v1.0.8 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.3.1 // indirect - github.com/leonklingele/grouper v1.1.0 // indirect + github.com/ldez/tagliatelle v0.5.0 // indirect + github.com/leonklingele/grouper v1.1.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/maratori/testpackage v1.1.0 // indirect - github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/maratori/testpackage v1.1.1 // indirect + github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.1 // indirect + github.com/mgechev/revive v1.3.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moricho/tparallel v0.2.1 // indirect + github.com/moricho/tparallel v0.3.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect - github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.8.1 // indirect + github.com/nishanths/exhaustive v0.11.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect github.com/opencontainers/runc v1.1.3 // indirect - github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/profile v1.6.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.0.0 // indirect - github.com/prometheus/client_model v0.2.0 + github.com/polyfloyd/go-errorlint v1.4.5 // indirect + github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a github.com/prometheus/common v0.37.0 github.com/prometheus/procfs v0.8.0 // indirect - github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect - github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect - github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/quasilyte/go-ruleguard v0.4.0 // indirect + github.com/quasilyte/gogrep v0.5.0 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/ryancurrah/gomodguard v1.2.4 // indirect - github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect - github.com/securego/gosec/v2 v2.12.0 // indirect + github.com/ryancurrah/gomodguard v1.3.0 // indirect + github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect + github.com/securego/gosec/v2 v2.18.1 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect - github.com/sirupsen/logrus v1.9.0 // indirect - github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/sivchari/tenv v1.7.0 // indirect - github.com/sonatard/noctx v0.0.1 // indirect - github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/sivchari/tenv v1.7.1 // indirect + github.com/sonatard/noctx v0.0.2 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -244,48 +265,48 @@ require ( github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/sylvia7788/contextcheck v1.0.4 // indirect - github.com/tdakkota/asciicheck v0.1.1 // indirect - github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect - github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect - github.com/ultraware/funlen v0.0.3 // indirect + github.com/tdakkota/asciicheck v0.2.0 // indirect + github.com/tetafro/godot v1.4.15 // indirect + github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/ultraware/funlen v0.1.0 // indirect github.com/ultraware/whitespace v0.0.5 // indirect - github.com/uudashr/gocognit v1.0.6 // indirect + github.com/uudashr/gocognit v1.1.2 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect - gitlab.com/bosi/decorder v0.2.3 // indirect + gitlab.com/bosi/decorder v0.4.1 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect - golang.org/x/mod v0.9.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 - golang.org/x/text v0.8.0 // indirect - golang.org/x/tools v0.7.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.15.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.3.3 // indirect - mvdan.cc/gofumpt v0.3.1 // indirect + honnef.co/go/tools v0.4.6 // indirect + mvdan.cc/gofumpt v0.5.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect ) require ( github.com/creachadair/tomledit v0.0.23 + github.com/ethereum/go-ethereum v1.13.8 github.com/jonboulle/clockwork v0.3.0 github.com/oasisprotocol/oasis-core/go v0.2202.5 github.com/sasha-s/go-deadlock v0.3.1 - github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tendermint/go-amino v0.16.0 github.com/tyler-smith/go-bip39 v1.1.0 - golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa ) diff --git a/go.sum b/go.sum index 535782197a..0414e8cfb8 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ -4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= -4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= -bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -15,7 +16,6 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6 cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= @@ -29,99 +29,106 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w= -cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= -github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= -github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= -github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/4meepo/tagalign v1.3.3 h1:ZsOxcwGD/jP4U/aw7qeWu58i7dwYemfy5Y+IF1ACoNw= +github.com/4meepo/tagalign v1.3.3/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= +github.com/Abirdcfly/dupword v0.0.13 h1:SMS17YXypwP000fA7Lr+kfyBQyW14tTT+nRv9ASwUUo= +github.com/Abirdcfly/dupword v0.0.13/go.mod h1:Ut6Ue2KgF/kCOawpW4LnExT+xZLQviJPE4klBPMK/5Y= +github.com/Antonboom/errname v0.1.12 h1:oh9ak2zUtsLp5oaEd/erjB4GPu9w19NyoIskZClDcQY= +github.com/Antonboom/errname v0.1.12/go.mod h1:bK7todrzvlaZoQagP1orKzWXv59X/x0W0Io2XT1Ssro= +github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTow= +github.com/Antonboom/nilnil v0.1.7/go.mod h1:TP+ScQWVEq0eSIxqU8CbdT5DFWoHp0MbP+KMUO1BKYQ= +github.com/Antonboom/testifylint v0.2.3 h1:MFq9zyL+rIVpsvLX4vDPLojgN7qODzWsrnftNX2Qh60= +github.com/Antonboom/testifylint v0.2.3/go.mod h1:IYaXaOX9NbfAyO+Y04nfjGI8wDemC1rUyM/cYolz018= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.2 h1:DGdS4FlsdM6OkluXOhgkvwx05ZjD3Idm9WqtYnOmSuY= -github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.2/go.mod h1:xj0D2jwLdp6tOKLheyZCsfL0nz8DaicmJxSwj3VcHtY= -github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= -github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0 h1:3ZBs7LAezy8gh0uECsA6CGU43FF3zsx5f4eah5FxTMA= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.1.0/go.mod h1:rZLTje5A9kFBe0pzhpe2TdhRniBF++PRHQuRpR8esVc= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= -github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= -github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0 h1:aQl70G173h/GZYhWf36aE5H0KaujXfVMnn/f1kSDVYY= +github.com/OpenPeeDeeP/depguard/v2 v2.1.0/go.mod h1:PUBgk35fX4i7JDmwzlJwJ+GMe6NfO1723wmJMgPThNQ= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/go-check-sumtype v0.1.3 h1:M+tqMxB68hcgccRXBMVCPI4UJ+QUfdSx0xdbypKCqA8= +github.com/alecthomas/go-check-sumtype v0.1.3/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/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/alexkohler/nakedret/v2 v2.0.2 h1:qnXuZNvv3/AxkAb22q/sEsEpcA99YxLFACDtEw9TPxE= +github.com/alexkohler/nakedret/v2 v2.0.2/go.mod h1:2b8Gkk0GsOrqQv/gPWjNLDSKwG8I5moSXG1K4VIBcTQ= github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= -github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= -github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= +github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= -github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.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 v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= -github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= +github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= -github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= -github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= -github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= -github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= -github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= -github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/bombsimon/wsl/v3 v3.4.0 h1:RkSxjT3tmlptwfgEgTgU+KYKLI35p/tviNXNXiL2aNU= +github.com/bombsimon/wsl/v3 v3.4.0/go.mod h1:KkIB+TXkqy6MvK9BDZVbZxKNYsE1/oLRJbIFtf14qqo= +github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= +github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= +github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= +github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= @@ -138,21 +145,29 @@ github.com/bufbuild/buf v1.7.0 h1:uWRjhIXcrWkzIkA5TqXGyJbF51VW54QJsQZ3nwaes5Q= github.com/bufbuild/buf v1.7.0/go.mod h1:Go40fMAF46PnPLC7jJgTQhAI95pmC0+VtxFKVC0qLq0= github.com/bufbuild/connect-go v0.2.0 h1:WuMI/jLiJIhysHWvLWlxRozV67mGjCOUuDSl/lkDVic= github.com/bufbuild/connect-go v0.2.0/go.mod h1:4efZ2eXFENwd4p7tuLaL9m0qtTsCOzuBvrohvRGevDM= -github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= -github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/butuzov/ireturn v0.2.1 h1:w5Ks4tnfeFDZskGJ2x1GAkx5gaQV+kdU3NKNr3NEBzY= +github.com/butuzov/ireturn v0.2.1/go.mod h1:RfGHUvvAuFFxoHKf4Z8Yxuh6OjlCw1KvR2zM1NFHeBk= +github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= +github.com/butuzov/mirror v1.1.0/go.mod h1:8Q0BdQU6rC6WILDiBM60DBfvV78OLJmMmixe7GF45AE= +github.com/catenacyber/perfsprint v0.2.0 h1:azOocHLscPjqXVJ7Mf14Zjlkn4uNua0+Hcg1wTR6vUo= +github.com/catenacyber/perfsprint v0.2.0/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= +github.com/ccojocar/zxcvbn-go v1.0.1 h1:+sxrANSCj6CdadkcMnvde/GWU1vZiiXRbqYSCalV4/4= +github.com/ccojocar/zxcvbn-go v1.0.1/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= -github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= -github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 h1:tFXjAxje9thrTF4h57Ckik+scJjTWdwAtZqZPtOT48M= -github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4/go.mod h1:W8EnPSQ8Nv4fUjc/v1/8tHFqhuOJXnRub0dTfuAQktU= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= +github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= +github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= +github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chigopher/pathlib v0.15.0 h1:1pg96WL3iC1/YyWV4UJSl3E0GBf4B+h5amBtsbAAieY= github.com/chigopher/pathlib v0.15.0/go.mod h1:3+YPPV21mU9vyw8Mjp+F33CyCfE6iOzinpiqBcccv7I= @@ -168,7 +183,6 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0= github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= @@ -179,16 +193,10 @@ github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcD github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 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/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/atomicfile v0.2.6 h1:FgYxYvGcqREApTY8Nxg8msM6P/KVKK3ob5h9FaRUTNg= @@ -197,13 +205,13 @@ github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6V github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creachadair/tomledit v0.0.23 h1:ohYJjMsxwzj4dDzKaBWFbWH5J+3LO/8CYnlVY+baBWA= github.com/creachadair/tomledit v0.0.23/go.mod h1:cIu/4x5L855oSRejIqr+WRFh+mv9g4fWLiUFaApYn/Y= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/daixiang0/gci v0.6.2 h1:TXCP5RqjE/UupXO+p33MEhqdv7QxjKGw5MVkt9ATiMs= -github.com/daixiang0/gci v0.6.2/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.11.2 h1:Oji+oPsp3bQ6bNNgX30NBAVT18P4uBH4sRZnlOlTj7Y= +github.com/daixiang0/gci v0.11.2/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= github.com/dashpay/bls-signatures/go-bindings v0.0.0-20230207105415-06df92693ac8 h1:v4K3CiDoFY1gjcWL/scRcwzyjBwh8TVG3ek8cWolK1g= github.com/dashpay/bls-signatures/go-bindings v0.0.0-20230207105415-06df92693ac8/go.mod h1:auvGS60NBZ+a21aCCQh366PdsjDvHinsCvl28VrYPu4= github.com/dashpay/dashd-go v0.24.1 h1:w+F5pDt+fqud4QQM/O9sAJihbQ3oswO8DKOmDS/pcNw= @@ -212,23 +220,23 @@ github.com/dashpay/dashd-go/btcec/v2 v2.1.0 h1:fXwlLf5H+TtgHxjGMU74NesKzk6NisjKM github.com/dashpay/dashd-go/btcec/v2 v2.1.0/go.mod h1:1i8XtxdOmvK6mYEUCneVXTzFbrCUw3wq1u91j8gvsns= github.com/dashpay/dashd-go/btcutil v1.2.0 h1:YMq7L0V0au5bbphIhpsBBc+nfOZqU+gJ4pkgRZB7Eiw= github.com/dashpay/dashd-go/btcutil v1.2.0/go.mod h1:7UHoqUh3LY3OI4mEcogx0CnL3rtzDQyoqvsOCZZtvzE= -github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k= github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/didip/tollbooth/v6 v6.0.1 h1:QvLvRpB1G2bzKvkRze0muMUBlGN9H1z7tJ4DH4ypWOU= @@ -236,6 +244,7 @@ github.com/didip/tollbooth/v6 v6.0.1/go.mod h1:j2pKs+JQ5PvU/K4jFnrnwntrmfUbYLJE5 github.com/didip/tollbooth_chi v0.0.0-20200524181329-8b84cd7183d9 h1:gTh8fKuI/yLqQtZEPlDX3ZGsiTPZIe0ADHsxXSbwO1I= github.com/didip/tollbooth_chi v0.0.0-20200524181329-8b84cd7183d9/go.mod h1:YWyIfq3y4ArRfWZ9XksmuusP+7Mad+T0iFZ0kv0XG/M= github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M= +github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= @@ -245,7 +254,6 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -255,19 +263,21 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= +github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= +github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= +github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= +github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= @@ -276,16 +286,18 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghostiam/protogetter v0.2.3 h1:qdv2pzo3BpLqezwqfGDLZ+nHEYmc5bUpIdsMbBVwMjw= +github.com/ghostiam/protogetter v0.2.3/go.mod h1:KmNLOsy1v04hKbvZs8EfGI1fk39AgTdRDxWNYPfXVc4= github.com/go-chi/chi v4.1.1+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= @@ -293,8 +305,8 @@ github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8= github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns= -github.com/go-critic/go-critic v0.6.3 h1:abibh5XYBTASawfTQ0rA7dVtQT+6KzpGqb/J+DxRDaw= -github.com/go-critic/go-critic v0.6.3/go.mod h1:c6b3ZP1MQ7o6lPR7Rv3lEf7pYQUmAcx8ABHgdZCQt/k= +github.com/go-critic/go-critic v0.9.0 h1:Pmys9qvU3pSML/3GEQ2Xd9RZ/ip+aXHKILuxczKGV/U= +github.com/go-critic/go-critic v0.9.0/go.mod h1:5P8tdXL7m/6qnyG6oRAlYLORvoXH0WDypYgAEmagT40= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -309,8 +321,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-pkgz/expirable-cache v0.0.3 h1:rTh6qNPp78z0bQE6HDhXBHUwqnV9i09Vm6dksJLXQDc= @@ -319,31 +331,31 @@ github.com/go-pkgz/jrpc v0.2.0 h1:CLy/eZyekjraVrxZV18N2R1mYLMJ/nWrgdfyIOGPY/E= github.com/go-pkgz/jrpc v0.2.0/go.mod h1:wd8vtQ4CgtCnuqua6x2b1SKIgv0VSOh5Dn0uUITbiUE= github.com/go-pkgz/rest v1.5.0 h1:C8SxXcXza4GiUUAn/95iCkvoIrGbS30qpwK19iqlrWQ= github.com/go-pkgz/rest v1.5.0/go.mod h1:nQaM3RhSTUAmbBZWY4hfe4buyeC9VckvhoCktiQXJxI= -github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= -github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.1 h1:JbSszi42Jiqu36Gnf363HWS9MTEAz67vTQLponh3Moc= -github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= -github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= -github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= -github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= -github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o= -github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= -github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= +github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= +github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astequal v1.1.0 h1:kHKm1AWqClYn15R0K1KKE4RG614D46n+nqUQ06E1dTw= +github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= +github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= +github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= +github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= +github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= +github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= -github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= -github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= +github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= +github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= +github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -353,16 +365,14 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -375,7 +385,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -392,37 +401,37 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.48.0 h1:hRiBNk9iRqdAKMa06ntfEiLyza1/3IE9rHLNJaek4a8= -github.com/golangci/golangci-lint v1.48.0/go.mod h1:5N+oxduCho+7yuccW69upg/O7cxjfR/d+IQeiNxGmKM= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= +github.com/golangci/golangci-lint v1.55.0 h1:ePpc6YhM1ZV8kHU8dwmHDHAdeedZHdK8cmTXlkkRdi8= +github.com/golangci/golangci-lint v1.55.0/go.mod h1:Z/OawFQ4yqFo2/plDYlIjoZlJeVYkRcqS9dW55p0FXg= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= -github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= +github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g= +github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI= +github.com/golangci/revgrep v0.5.0 h1:GGBqHFtFOeHiSUQtFVZXPJtVZYOGB4iVlAjaoFRBQvY= +github.com/golangci/revgrep v0.5.0/go.mod h1:bjAMA+Sh/QUfTDcHzxfyHxr4xKvllVr/0sCv2e7jJHA= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg= -github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -435,11 +444,13 @@ github.com/google/go-cmp v0.5.3/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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 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 v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -453,40 +464,27 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw= -github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM= -github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601 h1:mrEEilTAUmaAORhssPPkxj84TsHrPMLBGW2Z4SoTxm8= +github.com/gordonklaus/ineffassign v0.0.0-20230610083614-0e73809eb601/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= -github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= -github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= @@ -496,16 +494,13 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3 github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= -github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= @@ -517,36 +512,30 @@ github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mO github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= -github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4= github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= -github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jgautheron/goconst v1.6.0 h1:gbMLWKRMkzAc6kYsQL6/TxaoBUg3Jm9LSF/Ih1ADWGA= +github.com/jgautheron/goconst v1.6.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI= github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ= github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f h1:BNuUg9k2EiJmlMwjoef3e8vZLHplbVw6DrjGFjLL+Yo= github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q= -github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E= github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b h1:izTof8BKh/nE1wrKOrloNA5q4odOarjf+Xpe+4qow98= github.com/jhump/protoreflect v1.12.1-0.20220721211354-060cc04fc18b/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= @@ -556,128 +545,101 @@ github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg= github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= 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/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= -github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= +github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= +github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.15.10 h1:Ai8UzuomSCDw90e1qNMtb15msBXsNpH6gzkkENQNcJo= -github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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.2/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/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +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/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/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= -github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= -github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= -github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vguyjbE558= +github.com/kunwardeep/paralleltest v1.0.8/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= -github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= -github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= -github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= +github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= +github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= +github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/macabu/inamedparam v0.1.2 h1:RR5cnayM6Q7cDhQol32DE2BGAPGMnffJ31LFE+UklaU= +github.com/macabu/inamedparam v0.1.2/go.mod h1:Xg25QvY7IBRl1KLPV9Rbml8JOMZtF/iAkNkmV7eQgjw= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= -github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= -github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= -github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 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/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg= -github.com/mgechev/revive v1.2.1 h1:GjFml7ZsoR0IrQ2E2YIvWFNS5GPDV7xNwvA5GM1HZC4= -github.com/mgechev/revive v1.2.1/go.mod h1:+Ro3wqY4vakcYNtkBWdZC7dBg1xSB6sp054wWwmeFm0= -github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mgechev/revive v1.3.4 h1:k/tO3XTaWY4DEHal9tWBkkUMJYO/dLDVyMmAQxmIMDc= +github.com/mgechev/revive v1.3.4/go.mod h1:W+pZCMu9qj8Uhfs1iJMQsEFLRozUfvwFwqVvRbSNLVw= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU= github.com/moby/buildkit v0.10.3/go.mod h1:jxeOuly98l9gWHai0Ojrbnczrk/rf+o9/JqNhY+UCSo= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= @@ -688,31 +650,25 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= -github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= +github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8= -github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s= github.com/mroth/weightedrand v0.4.1 h1:rHcbUBopmi/3x4nnrvwGJBhX9d0vk+KgoLUZeDP6YyI= github.com/mroth/weightedrand v0.4.1/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= 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-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo= -github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= -github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo= -github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= -github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= +github.com/nishanths/exhaustive v0.11.0 h1:T3I8nUGhl/Cwu5Z2hfc92l0e04D2GEW6e0l8pzda2l0= +github.com/nishanths/exhaustive v0.11.0/go.mod h1:RqwDsZ1xY0dNdqHho2z6X+bgzizwbLYOWnZbbl2wLB4= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.14.0 h1:XQPNmw+kZz5cC/HbFK3mQutpjzAQv1dHregRA+4CGGg= +github.com/nunnatsa/ginkgolinter v0.14.0/go.mod h1:cm2xaqCUCRd7qcP4DqbVvpcyEMkuLM9CF0wY6VASohk= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -720,27 +676,21 @@ github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae h1:Fa github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oasisprotocol/oasis-core/go v0.2202.5 h1:SwT3XIKz4W5gYZd9I2fe+4qGPYaVvqG0kF8jsancd4E= github.com/oasisprotocol/oasis-core/go v0.2202.5/go.mod h1:hKUgtuPPq371HokUQL5ashT5MZLZxK/VkWNKRLb9m+w= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.28.0 h1:i2rg/p9n/UqIDAMFUJ6qIUUMcsqOuUHgbpbu235Vr1c= +github.com/onsi/gomega v1.28.0/go.mod h1:A1H2JE76sI14WIP57LMKj7FVfCHx3g3BcZVjJG8bjX8= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec= @@ -753,8 +703,10 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY= -github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= +github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/copy v1.11.0 h1:OKBD80J/mLBrwnzXqGtFCzprFSGioo30JcmR4APsNwc= +github.com/otiai10/copy v1.11.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= @@ -762,11 +714,8 @@ github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -776,11 +725,10 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.0.0 h1:pDrQG0lrh68e602Wfp68BlUTRFoHn8PZYAjLgt2LFsM= -github.com/polyfloyd/go-errorlint v1.0.0/go.mod h1:KZy4xxPJyy88/gldCe5OdW6OQRtNO3EZE7hXzmnebgA= +github.com/polyfloyd/go-errorlint v1.4.5 h1:70YWmMy4FgRHehGNOUask3HtSFSOLKgmDn7ryNe7LqI= +github.com/polyfloyd/go-errorlint v1.4.5/go.mod h1:sIZEbFoDOCnTYYZoVkjc4hTnM459tuWA9H/EkdXwsKk= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -791,8 +739,9 @@ github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= @@ -806,26 +755,20 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA= -github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q= -github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= -github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a h1:sWFavxtIctGrVs5SYZ5Ml1CvrDAs8Kf5kx2PI3C41dA= -github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a/go.mod h1:VMX+OnnSw4LicdiEGtRSD/1X8kW7GuEscjYNr4cOIT4= -github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/dsl v0.3.16/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= -github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= -github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/go-ruleguard v0.4.0 h1:DyM6r+TKL+xbKB4Nm7Afd1IQh9kEUKQs2pboWGKtvQo= +github.com/quasilyte/go-ruleguard v0.4.0/go.mod h1:Eu76Z/R8IXtViWUIHkE3p8gdH3/PKk1eh3YGfaEof10= +github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= +github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -835,20 +778,21 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= -github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= -github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= -github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= -github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= +github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= +github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= +github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sashamelentyev/usestdlibvars v1.8.0 h1:QnWP9IOEuRyYKH+IG0LlQIjuJlc0rfdo4K3/Zh3WRMw= -github.com/sashamelentyev/usestdlibvars v1.8.0/go.mod h1:BFt7b5mSVHaaa26ZupiNRV2ODViQBxZZVhtAxAJRrjs= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.24.0 h1:MKNzmXtGh5N0y74Z/CIaJh4GlB364l0K1RUT08WSWAc= +github.com/sashamelentyev/usestdlibvars v1.24.0/go.mod h1:9cYkq+gYJ+a5W2RPdhfaSCnTVUC1OQP/bSiiBhq3OZE= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/securego/gosec/v2 v2.12.0 h1:CQWdW7ATFpvLSohMVsajscfyHJ5rsGmEXmsNcsDNmAg= -github.com/securego/gosec/v2 v2.12.0/go.mod h1:iTpT+eKTw59bSgklBHlSnH5O2tNygHMDxfvMubA4i7I= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/securego/gosec/v2 v2.18.1 h1:xnnehWg7dIW8qrRPGm8ykY21zp2MueKyC99Vlcuj96I= +github.com/securego/gosec/v2 v2.18.1/go.mod h1:ZUTcKD9gAFip1lLGHWCjkoBQJyaEzePTNzjwlL2HHoE= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -857,23 +801,21 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 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.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= -github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= +github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= -github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= -github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= -github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -883,14 +825,12 @@ github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -906,29 +846,26 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/sylvia7788/contextcheck v1.0.4 h1:MsiVqROAdr0efZc/fOCt0c235qm9XJqHtWwM+2h2B04= -github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= -github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= +github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= @@ -941,63 +878,62 @@ github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= -github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= -github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= -github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= -github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= -github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= -github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tetafro/godot v1.4.15 h1:QzdIs+XB8q+U1WmQEWKHQbKmCw06QuQM7gLx/dky2RM= +github.com/tetafro/godot v1.4.15/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tomarrell/wrapcheck/v2 v2.8.1 h1:HxSqDSN0sAt0yJYsrcYVoEeyM4aI9yAm3KQpIXDJRhQ= +github.com/tomarrell/wrapcheck/v2 v2.8.1/go.mod h1:/n2Q3NZ4XFT50ho6Hbxg+RV1uyo2Uow/Vdm9NQcl5SE= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= -github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= +github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= -github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= +github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= github.com/vektra/mockery/v2 v2.33.2 h1:znIUwQ3FxnA5jvPy8irYBoiIqMZhuOJhoPOJYNoTJqU= github.com/vektra/mockery/v2 v2.33.2/go.mod h1:9lREs4VEeQiUS3rizYQx1saxHu2JiIhThP0q9+fDegM= -github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= +github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/ykadowak/zerologlint v0.1.3 h1:TLy1dTW3Nuc+YE3bYRPToG1Q9Ej78b5UUN6bjbGdxPE= +github.com/ykadowak/zerologlint v0.1.3/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= -gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +gitlab.com/bosi/decorder v0.4.1 h1:VdsdfxhstabyhZovHafFw+9eJ6eU0d2CkFNJcZz/NU4= +gitlab.com/bosi/decorder v0.4.1/go.mod h1:jecSqWUew6Yle1pCr2eLWTensJMmsxHsBwt+PVbkAqA= +go-simpler.org/assert v0.6.0 h1:QxSrXa4oRuo/1eHMXSBFHKvJIpWABayzKldqZyugG7E= +go-simpler.org/assert v0.6.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= +go-simpler.org/sloglint v0.1.2 h1:IjdhF8NPxyn0Ckn2+fuIof7ntSnVUAqBFcQRrnG9AiM= +go-simpler.org/sloglint v0.1.2/go.mod h1:2LL+QImPfTslD5muNPydAEYmpXIj6o/WYcqnJjLi4o4= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k= -go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1013,25 +949,21 @@ go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRM go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.tmz.dev/musttag v0.7.2 h1:1J6S9ipDbalBSODNT5jCep8dhZyMr4ttnjQagmGYR5s= +go.tmz.dev/musttag v0.7.2/go.mod h1:m6q5NiiSKMnQYokefa2xGoyoXnrswCbJ0AWYzf4Zs28= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 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/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1040,13 +972,12 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1057,11 +988,12 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 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-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= -golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833 h1:jWGQJV4niP+CCmFW9ekjA9Zx8vYORzOUH2/Nl5WPuLQ= +golang.org/x/exp/typeparams v0.0.0-20230307190834-24139beb5833/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1075,7 +1007,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1090,13 +1021,15 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= -golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1108,9 +1041,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1118,7 +1048,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -1135,14 +1064,17 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= 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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1155,11 +1087,11 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1167,16 +1099,16 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1187,12 +1119,9 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1200,7 +1129,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1208,7 +1136,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1224,7 +1151,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1245,19 +1171,26 @@ golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1266,28 +1199,24 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1298,22 +1227,16 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1326,35 +1249,22 @@ golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1363,12 +1273,16 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= -golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1377,7 +1291,6 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= @@ -1397,15 +1310,12 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1413,7 +1323,6 @@ google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= @@ -1434,8 +1343,6 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -1448,19 +1355,15 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY= google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 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= @@ -1494,27 +1397,19 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= 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/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= 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/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/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= @@ -1527,6 +1422,7 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1534,19 +1430,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= -honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= -mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= +honnef.co/go/tools v0.4.6 h1:oFEHCKeID7to/3autwsWfnuv69j3NsfcXbvJKuIcep8= +honnef.co/go/tools v0.4.6/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= +mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E= +mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= pgregory.net/rapid v0.4.8 h1:d+5SGZWUbJPbl3ss6tmPFqnNeQR6VDOFly+eTjwPiEw= pgregory.net/rapid v0.4.8/go.mod h1:Z5PbWqjvWR1I3UGjvboUuan4fe4ZYEYNLNQLExzCoUs= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= From ea83b4f291b000c7bfa6d09e8c010359571bd58c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:33:37 +0100 Subject: [PATCH 004/111] chore: socket client debug --- abci/client/socket_client.go | 5 +++++ internal/consensus/state_proposaler.go | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 24ba8ffff3..9051dbd076 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -215,8 +215,13 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty cli.mtx.Lock() cli.reqQueue.Push(reqres, reqres.priority()) + size := cli.reqQueue.Size() cli.mtx.Unlock() + if size > 0 && size%1000 == 0 { + cli.logger.Error("suspicious abci.socketClient queue size", "size", size) + } + select { case cli.reqSignal <- struct{}{}: case <-ctx.Done(): diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 523d68a712..ff0ea61400 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -93,7 +93,10 @@ func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs * // Create on block if !p.checkValidBlock(rs) { var err error + start := time.Now() block, blockParts, err = p.createProposalBlock(ctx, round, rs) + p.logger.Debug("createProposalBlock executed", "took", time.Since(start).String()) + if err != nil { return err } @@ -102,11 +105,8 @@ func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs * "height", height, "round", round) - p.logger.Trace("before makeProposal") - start := time.Now() // Make proposal proposal := makeProposal(height, round, rs.ValidRound, block, blockParts) - p.logger.Info("makeProposal executed successfully", "duration", time.Since(start)) // Sign proposal err := p.signProposal(ctx, height, proposal) From 98025f6697a8b0ed7726078e638f578477d92468 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 10:53:30 +0100 Subject: [PATCH 005/111] chore: change abci client priorities --- abci/client/client.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index bfcd929ccb..141d431653 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -71,12 +71,14 @@ func (reqResp *requestAndResponse) priority() (priority int8) { priority = 100 case *types.Request_FinalizeBlock: priority = 100 + case *types.Request_Flush: + priority = 100 case *types.Request_ExtendVote: priority = 100 case *types.Request_VerifyVoteExtension: - priority = 100 - case *types.Request_Info: priority = 90 + case *types.Request_Info: + priority = 120 case *types.Request_CheckTx: priority = -10 case *types.Request_Query: From 0bbe9bde3e2e8f853a1bb17094397516070f599c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:59:18 +0100 Subject: [PATCH 006/111] feat: abci client prometheus support --- abci/client/client.go | 4 +- abci/client/metrics.gen.go | 44 +++++++++++++++++ abci/client/metrics.go | 72 ++++++++++++++++++++++++++++ abci/client/socket_client.go | 10 +++- abci/cmd/abci-cli/abci-cli.go | 2 +- abci/example/example_test.go | 2 +- abci/example/kvstore/kvstore_test.go | 2 +- abci/tests/client_server_test.go | 2 +- internal/consensus/replay_file.go | 6 ++- internal/proxy/client.go | 4 +- internal/proxy/client_test.go | 6 +-- node/node.go | 27 +++++++++-- node/public.go | 3 +- rpc/test/helpers.go | 2 +- test/e2e/node/main.go | 2 +- 15 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 abci/client/metrics.gen.go create mode 100644 abci/client/metrics.go diff --git a/abci/client/client.go b/abci/client/client.go index 141d431653..19c6a7bf61 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -36,10 +36,10 @@ type Client interface { // NewClient returns a new ABCI client of the specified transport type. // It returns an error if the transport is not "socket" or "grpc" -func NewClient(logger log.Logger, addr, transport string, mustConnect bool) (Client, error) { +func NewClient(logger log.Logger, addr, transport string, mustConnect bool, metrics *Metrics) (Client, error) { switch transport { case "socket": - return NewSocketClient(logger, addr, mustConnect), nil + return NewSocketClient(logger, addr, mustConnect, metrics), nil case "grpc": return NewGRPCClient(logger, addr, mustConnect), nil default: diff --git a/abci/client/metrics.gen.go b/abci/client/metrics.gen.go new file mode 100644 index 0000000000..941aaf3f39 --- /dev/null +++ b/abci/client/metrics.gen.go @@ -0,0 +1,44 @@ +// Code generated by metricsgen. DO NOT EDIT. + +package abciclient + +import ( + "github.com/go-kit/kit/metrics/discard" + prometheus "github.com/go-kit/kit/metrics/prometheus" + stdprometheus "github.com/prometheus/client_golang/prometheus" +) + +func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { + labels := []string{} + for i := 0; i < len(labelsAndValues); i += 2 { + labels = append(labels, labelsAndValues[i]) + } + return &Metrics{ + PendingSendMessages: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "pending_send_messages", + Help: "Number of messages in ABCI Socket queue", + }, append(labels, "message_type")).With(labelsAndValues...), + SocketReceiveMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "socket_receive_messages_total", + Help: "Number of messages received from ABCI Socket", + }, append(labels, "message_type")).With(labelsAndValues...), + SocketSendMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "socket_send_messages_total", + Help: "Number of messages sent to ABCI Socket", + }, append(labels, "message_type")).With(labelsAndValues...), + } +} + +func NopMetrics() *Metrics { + return &Metrics{ + PendingSendMessages: discard.NewGauge(), + SocketReceiveMessagesTotal: discard.NewCounter(), + SocketSendMessagesTotal: discard.NewCounter(), + } +} diff --git a/abci/client/metrics.go b/abci/client/metrics.go new file mode 100644 index 0000000000..09296ae500 --- /dev/null +++ b/abci/client/metrics.go @@ -0,0 +1,72 @@ +package abciclient + +import ( + "fmt" + "reflect" + "regexp" + + sync "github.com/sasha-s/go-deadlock" + + "github.com/go-kit/kit/metrics" +) + +const ( + // MetricsSubsystem is a subsystem shared by all metrics exposed by this + // package. + MetricsSubsystem = "abciclient" +) + +var ( + // valueToLabelRegexp is used to find the golang package name and type name + // so that the name can be turned into a prometheus label where the characters + // in the label do not include prometheus special characters such as '*' and '.'. + valueToLabelRegexp = regexp.MustCompile(`\*?(\w+)\.(.*)`) +) + +//go:generate go run ../../scripts/metricsgen -struct=Metrics + +// Metrics contains metrics exposed by this package. +type Metrics struct { + // Number of messages in ABCI Socket queue + PendingSendMessages metrics.Gauge `metrics_labels:"message_type"` + + // Number of messages received from ABCI Socket + SocketReceiveMessagesTotal metrics.Counter `metrics_labels:"message_type"` + // Number of messages sent to ABCI Socket + SocketSendMessagesTotal metrics.Counter `metrics_labels:"message_type"` +} + +type metricsLabelCache struct { + mtx *sync.RWMutex + messageLabelNames map[reflect.Type]string +} + +// ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang +// type that is passed in. +// This method uses a map on the Metrics struct so that each label name only needs +// to be produced once to prevent expensive string operations. +func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string { + t := reflect.TypeOf(i) + m.mtx.RLock() + + if s, ok := m.messageLabelNames[t]; ok { + m.mtx.RUnlock() + return s + } + m.mtx.RUnlock() + + s := t.String() + ss := valueToLabelRegexp.FindStringSubmatch(s) + l := fmt.Sprintf("%s_%s", ss[1], ss[2]) + m.mtx.Lock() + defer m.mtx.Unlock() + m.messageLabelNames[t] = l + return l +} + +func newMetricsLabelCache() *metricsLabelCache { + return &metricsLabelCache{ + mtx: &sync.RWMutex{}, + messageLabelNames: map[reflect.Type]string{}, + } +} diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 9051dbd076..99c2d045ad 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -37,6 +37,8 @@ type socketClient struct { mtx sync.Mutex err error reqSent *list.List // list of requests sent, waiting for response + + metrics *Metrics } var _ Client = (*socketClient)(nil) @@ -44,7 +46,11 @@ var _ Client = (*socketClient)(nil) // NewSocketClient creates a new socket client, which connects to a given // address. If mustConnect is true, the client will return an error upon start // if it fails to connect. -func NewSocketClient(logger log.Logger, addr string, mustConnect bool) Client { +func NewSocketClient(logger log.Logger, addr string, mustConnect bool, metrics *Metrics) Client { + if metrics == nil { + metrics = NopMetrics() + } + cli := &socketClient{ logger: logger, reqQueue: prque.New[int8, *requestAndResponse](nil), @@ -53,6 +59,8 @@ func NewSocketClient(logger log.Logger, addr string, mustConnect bool) Client { mustConnect: mustConnect, addr: addr, reqSent: list.New(), + + metrics: metrics, } cli.BaseService = *service.NewBaseService(logger, "socketClient", cli) return cli diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index f30bfe40e3..fb842ca1ae 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -63,7 +63,7 @@ func RootCmmand(logger log.Logger) *cobra.Command { if client == nil { var err error - client, err = abciclient.NewClient(logger.With("module", "abci-client"), flagAddress, flagAbci, false) + client, err = abciclient.NewClient(logger.With("module", "abci-client"), flagAddress, flagAbci, false, nil) if err != nil { return err } diff --git a/abci/example/example_test.go b/abci/example/example_test.go index d1f38df68d..3ca1e6ccb5 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -71,7 +71,7 @@ func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Ap require.NoError(t, err) // Connect to the socket - client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false) + client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false, nil) t.Cleanup(client.Wait) err = client.Start(ctx) diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 0041c0e4ff..b42bbf708b 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -322,7 +322,7 @@ func makeSocketClientServer( } // Connect to the socket - client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false) + client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false, nil) if err := client.Start(ctx); err != nil { cancel() return nil, nil, err diff --git a/abci/tests/client_server_test.go b/abci/tests/client_server_test.go index f95c124e5b..a4d8ddf363 100644 --- a/abci/tests/client_server_test.go +++ b/abci/tests/client_server_test.go @@ -34,7 +34,7 @@ func TestClientServerNoAddrPrefix(t *testing.T) { assert.NoError(t, err, "expected no error on server.Start") t.Cleanup(server.Wait) - client, err := abciclientent.NewClient(logger, addr, transport, true) + client, err := abciclientent.NewClient(logger, addr, transport, true, nil) assert.NoError(t, err, "expected no error on NewClient") err = client.Start(ctx) assert.NoError(t, err, "expected no error on client.Start") diff --git a/internal/consensus/replay_file.go b/internal/consensus/replay_file.go index 0c13b4dd27..692dbfa3f7 100644 --- a/internal/consensus/replay_file.go +++ b/internal/consensus/replay_file.go @@ -12,6 +12,7 @@ import ( dbm "github.com/tendermint/tm-db" + abciclient "github.com/dashpay/tenderdash/abci/client" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/internal/eventbus" "github.com/dashpay/tenderdash/internal/proxy" @@ -38,7 +39,7 @@ func RunReplayFile( csConfig *config.ConsensusConfig, console bool, ) error { - consensusState, err := newConsensusStateForReplay(ctx, cfg, logger, csConfig) + consensusState, err := newConsensusStateForReplay(ctx, cfg, logger, csConfig, nil) if err != nil { return err } @@ -301,6 +302,7 @@ func newConsensusStateForReplay( cfg config.BaseConfig, logger log.Logger, csConfig *config.ConsensusConfig, + clientMetrics *abciclient.Metrics, ) (*State, error) { dbType := dbm.BackendType(cfg.DBBackend) // Get BlockStore @@ -327,7 +329,7 @@ func newConsensusStateForReplay( return nil, err } - client, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir()) + client, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir(), clientMetrics) if err != nil { return nil, err } diff --git a/internal/proxy/client.go b/internal/proxy/client.go index 4ed8395759..c1265beecd 100644 --- a/internal/proxy/client.go +++ b/internal/proxy/client.go @@ -23,7 +23,7 @@ import ( // // The Closer is a noop except for persistent_kvstore applications, // which will clean up the store. -func ClientFactory(logger log.Logger, addr, transport, dbDir string) (abciclient.Client, io.Closer, error) { +func ClientFactory(logger log.Logger, addr, transport, dbDir string, clientMetrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { switch addr { case "kvstore": app, err := kvstore.NewMemoryApp( @@ -52,7 +52,7 @@ func ClientFactory(logger log.Logger, addr, transport, dbDir string) (abciclient return abciclient.NewLocalClient(logger, types.NewBaseApplication()), noopCloser{}, nil default: const mustConnect = false // loop retrying - client, err := abciclient.NewClient(logger, addr, transport, mustConnect) + client, err := abciclient.NewClient(logger, addr, transport, mustConnect, clientMetrics) if err != nil { return nil, noopCloser{}, err } diff --git a/internal/proxy/client_test.go b/internal/proxy/client_test.go index 700ee47a65..ffa7be03a4 100644 --- a/internal/proxy/client_test.go +++ b/internal/proxy/client_test.go @@ -60,7 +60,7 @@ var SOCKET = "socket" func TestEcho(t *testing.T) { sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", t.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) if err != nil { t.Fatal(err) } @@ -104,7 +104,7 @@ func BenchmarkEcho(b *testing.B) { b.StopTimer() // Initialize sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", b.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) if err != nil { b.Fatal(err) } @@ -155,7 +155,7 @@ func TestInfo(t *testing.T) { sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", t.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) require.NoError(t, err) // Start server diff --git a/node/node.go b/node/node.go index b46ec76b08..7a71e38c9a 100644 --- a/node/node.go +++ b/node/node.go @@ -3,6 +3,7 @@ package node import ( "context" "fmt" + "io" "net" "net/http" "strconv" @@ -34,6 +35,7 @@ import ( "github.com/dashpay/tenderdash/internal/store" tmbytes "github.com/dashpay/tenderdash/libs/bytes" "github.com/dashpay/tenderdash/libs/log" + "github.com/dashpay/tenderdash/libs/os" "github.com/dashpay/tenderdash/libs/service" tmtime "github.com/dashpay/tenderdash/libs/time" "github.com/dashpay/tenderdash/privval" @@ -44,6 +46,15 @@ import ( _ "github.com/lib/pq" // provide the psql db driver ) +// Function that creates new abciclient.Client +type ClientCreatorFunc func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) + +func MakeClientCreator(client abciclient.Client) ClientCreatorFunc { + return func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { + return client, os.NoopCloser{}, nil + } +} + // nodeImpl is the highest level interface to a full Tendermint node. // It includes all configuration information and running services. type nodeImpl struct { @@ -101,9 +112,8 @@ func newDefaultNode( ) } - appClient, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir()) - if err != nil { - return nil, err + appClient := func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { + return proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir(), metrics) } return makeNode( @@ -122,7 +132,7 @@ func makeNode( ctx context.Context, cfg *config.Config, nodeKey types.NodeKey, - client abciclient.Client, + createClientFunc ClientCreatorFunc, genesisDocProvider genesisDocProvider, dbProvider config.DBProvider, logger log.Logger, @@ -156,6 +166,12 @@ func makeNode( nodeMetrics := defaultMetricsProvider(cfg.Instrumentation)(genDoc.ChainID) + client, closer, err := createClientFunc(nodeMetrics.abci) + if err != nil { + return nil, err + } + defer closer.Close() + proxyApp := proxy.New(client, logger.With("module", "proxy"), nodeMetrics.proxy) eventBus := eventbus.NewDefault(logger.With("module", "events")) @@ -669,6 +685,7 @@ type nodeMetrics struct { state *sm.Metrics statesync *statesync.Metrics evidence *evidence.Metrics + abci *abciclient.Metrics } // metricsProvider returns consensus, p2p, mempool, state, statesync Metrics. @@ -689,6 +706,7 @@ func defaultMetricsProvider(cfg *config.InstrumentationConfig) metricsProvider { state: sm.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), statesync: statesync.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), evidence: evidence.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), + abci: abciclient.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), } } return &nodeMetrics{ @@ -700,6 +718,7 @@ func defaultMetricsProvider(cfg *config.InstrumentationConfig) metricsProvider { state: sm.NopMetrics(), statesync: statesync.NopMetrics(), evidence: evidence.NopMetrics(), + abci: abciclient.NopMetrics(), } } } diff --git a/node/public.go b/node/public.go index db1b80530a..e16f9009e9 100644 --- a/node/public.go +++ b/node/public.go @@ -5,7 +5,6 @@ import ( "context" "fmt" - abciclient "github.com/dashpay/tenderdash/abci/client" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/libs/service" @@ -34,7 +33,7 @@ func New( ctx context.Context, conf *config.Config, logger log.Logger, - cf abciclient.Client, + cf ClientCreatorFunc, gen *types.GenesisDoc, ) (service.Service, error) { nodeKey, err := types.LoadOrGenNodeKey(conf.NodeKeyFile()) diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index e2e64deabc..8b13ea3abf 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -98,7 +98,7 @@ func StartTendermint( } } papp := abciclient.NewLocalClient(logger, app) - tmNode, err := node.New(ctx, conf, logger, papp, nil) + tmNode, err := node.New(ctx, conf, logger, node.MakeClientCreator(papp), nil) if err != nil { return nil, func(_ context.Context) error { cancel(); return nil }, err } diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index caf90c2ac4..4a53c5b964 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -204,7 +204,7 @@ func startNode(ctx context.Context, cfg *Config) error { ctx, tmcfg, nodeLogger, - abciclient.NewLocalClient(nodeLogger, app), + node.MakeClientCreator(abciclient.NewLocalClient(nodeLogger, app)), nil, ) if err != nil { From 91aa568be1baca3639324a5ea9e6fcdc25f57c67 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:59:42 +0100 Subject: [PATCH 007/111] fix(e2e): panic when no key provided in e2e test --- test/e2e/app/app.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index 027577b30a..ebecb7b04b 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -249,6 +249,10 @@ func prepareTxs(req abci.RequestPrepareProposal) ([]*abci.TxRecord, error) { func verifyTx(tx types.Tx, _ abci.CheckTxType) (abci.ResponseCheckTx, error) { split := bytes.SplitN(tx, []byte{'='}, 2) + if len(split) != 2 { + return abci.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}, nil + } + k, v := split[0], split[1] if string(k) == VoteExtensionKey { From 056872368f1941912904a88378bb9f96aeaad8e1 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:00:20 +0100 Subject: [PATCH 008/111] chore: fix typo --- types/proposal_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/proposal_test.go b/types/proposal_test.go index a7f9d5ab9a..1635ff901b 100644 --- a/types/proposal_test.go +++ b/types/proposal_test.go @@ -238,7 +238,7 @@ func TestProposalProtoBuf(t *testing.T) { expPass bool }{ {"success", proposal, true}, - {"success", proposal2, false}, // blcokID cannot be empty + {"success", proposal2, false}, // blockID cannot be empty {"empty proposal failure validatebasic", &Proposal{}, false}, {"nil proposal", nil, false}, } From 73f5c57f52925c7e69a6e6866f9993bede77b911 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:03:20 +0100 Subject: [PATCH 009/111] chore: add missing NoopCloser --- internal/proxy/client.go | 17 +++++++---------- libs/os/os.go | 5 +++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/internal/proxy/client.go b/internal/proxy/client.go index c1265beecd..b7d4283510 100644 --- a/internal/proxy/client.go +++ b/internal/proxy/client.go @@ -13,6 +13,7 @@ import ( "github.com/dashpay/tenderdash/abci/example/kvstore" "github.com/dashpay/tenderdash/abci/types" "github.com/dashpay/tenderdash/libs/log" + tmos "github.com/dashpay/tenderdash/libs/os" "github.com/dashpay/tenderdash/libs/service" e2e "github.com/dashpay/tenderdash/test/e2e/app" ) @@ -32,7 +33,7 @@ func ClientFactory(logger log.Logger, addr, transport, dbDir string, clientMetri if err != nil { return nil, nil, err } - return abciclient.NewLocalClient(logger, app), noopCloser{}, nil + return abciclient.NewLocalClient(logger, app), tmos.NoopCloser{}, nil case "persistent_kvstore": app, err := kvstore.NewPersistentApp( kvstore.DefaultConfig(dbDir), @@ -45,26 +46,22 @@ func ClientFactory(logger log.Logger, addr, transport, dbDir string, clientMetri case "e2e": app, err := e2e.NewApplication(kvstore.DefaultConfig(dbDir)) if err != nil { - return nil, noopCloser{}, err + return nil, tmos.NoopCloser{}, err } - return abciclient.NewLocalClient(logger, app), noopCloser{}, nil + return abciclient.NewLocalClient(logger, app), tmos.NoopCloser{}, nil case "noop": - return abciclient.NewLocalClient(logger, types.NewBaseApplication()), noopCloser{}, nil + return abciclient.NewLocalClient(logger, types.NewBaseApplication()), tmos.NoopCloser{}, nil default: const mustConnect = false // loop retrying client, err := abciclient.NewClient(logger, addr, transport, mustConnect, clientMetrics) if err != nil { - return nil, noopCloser{}, err + return nil, tmos.NoopCloser{}, err } - return client, noopCloser{}, nil + return client, tmos.NoopCloser{}, nil } } -type noopCloser struct{} - -func (noopCloser) Close() error { return nil } - // proxyClient provides the application connection. type proxyClient struct { service.BaseService diff --git a/libs/os/os.go b/libs/os/os.go index 3d74c22082..fda66fc9ab 100644 --- a/libs/os/os.go +++ b/libs/os/os.go @@ -48,3 +48,8 @@ func CopyFile(src, dst string) error { _, err = io.Copy(dstfile, srcfile) return err } + +// NoopCloser is a no-op io.Closer. +type NoopCloser struct{} + +func (NoopCloser) Close() error { return nil } From e86d67bf5abc3f9b1eb67f02eac39ff51c500e78 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:44:51 +0100 Subject: [PATCH 010/111] chore: abciclient metrics --- abci/client/metrics.gen.go | 23 ++++++--------- abci/client/metrics.go | 55 ++++++++++++++++++++++++++++-------- abci/client/socket_client.go | 38 ++++++++++++++++--------- scripts/txs/random.sh | 1 + 4 files changed, 76 insertions(+), 41 deletions(-) mode change 100644 => 100755 scripts/txs/random.sh diff --git a/abci/client/metrics.gen.go b/abci/client/metrics.gen.go index 941aaf3f39..c620689993 100644 --- a/abci/client/metrics.gen.go +++ b/abci/client/metrics.gen.go @@ -14,31 +14,24 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { labels = append(labels, labelsAndValues[i]) } return &Metrics{ - PendingSendMessages: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ + QueuedMessages: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "pending_send_messages", + Name: "queued_messages", Help: "Number of messages in ABCI Socket queue", - }, append(labels, "message_type")).With(labelsAndValues...), - SocketReceiveMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + }, append(labels, "type", "priority")).With(labelsAndValues...), + SentMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "socket_receive_messages_total", + Name: "sent_messages_total", Help: "Number of messages received from ABCI Socket", - }, append(labels, "message_type")).With(labelsAndValues...), - SocketSendMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ - Namespace: namespace, - Subsystem: MetricsSubsystem, - Name: "socket_send_messages_total", - Help: "Number of messages sent to ABCI Socket", - }, append(labels, "message_type")).With(labelsAndValues...), + }, append(labels, "type", "priority")).With(labelsAndValues...), } } func NopMetrics() *Metrics { return &Metrics{ - PendingSendMessages: discard.NewGauge(), - SocketReceiveMessagesTotal: discard.NewCounter(), - SocketSendMessagesTotal: discard.NewCounter(), + QueuedMessages: discard.NewGauge(), + SentMessagesTotal: discard.NewCounter(), } } diff --git a/abci/client/metrics.go b/abci/client/metrics.go index 09296ae500..c03f8562cc 100644 --- a/abci/client/metrics.go +++ b/abci/client/metrics.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" "regexp" + "strconv" sync "github.com/sasha-s/go-deadlock" @@ -28,24 +29,61 @@ var ( // Metrics contains metrics exposed by this package. type Metrics struct { // Number of messages in ABCI Socket queue - PendingSendMessages metrics.Gauge `metrics_labels:"message_type"` + QueuedMessages metrics.Gauge `metrics_labels:"type, priority"` // Number of messages received from ABCI Socket - SocketReceiveMessagesTotal metrics.Counter `metrics_labels:"message_type"` - // Number of messages sent to ABCI Socket - SocketSendMessagesTotal metrics.Counter `metrics_labels:"message_type"` + SentMessagesTotal metrics.Counter `metrics_labels:"type, priority"` + + // labels cache + labels metricsLabelCache } type metricsLabelCache struct { - mtx *sync.RWMutex + mtx sync.RWMutex messageLabelNames map[reflect.Type]string } +func (m *Metrics) EnqueuedMessage(reqres *requestAndResponse) { + priority := strconv.Itoa(int(reqres.priority())) + typ := "nil" + if reqres != nil && reqres.Request != nil { + typ = m.labels.ValueToMetricLabel(reqres.Request.Value) + } + + m.QueuedMessages.With("type", typ, "priority", priority).Add(1) +} + +func (m *Metrics) DequeuedMessage(reqres *requestAndResponse) { + priority := strconv.Itoa(int(reqres.priority())) + typ := "nil" + if reqres != nil && reqres.Request != nil { + typ = m.labels.ValueToMetricLabel(reqres.Request.Value) + } + + m.QueuedMessages.With("type", typ, "priority", priority).Add(-1) +} + +func (m *Metrics) SentMessage(reqres *requestAndResponse) { + priority := strconv.Itoa(int(reqres.priority())) + typ := "nil" + if reqres != nil && reqres.Request != nil { + typ = m.labels.ValueToMetricLabel(reqres.Request.Value) + } + + m.SentMessagesTotal.With("type", typ, "priority", priority).Add(1) +} + // ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang // type that is passed in. // This method uses a map on the Metrics struct so that each label name only needs // to be produced once to prevent expensive string operations. func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string { + if m.messageLabelNames == nil { + m.mtx.Lock() + m.messageLabelNames = map[reflect.Type]string{} + m.mtx.Unlock() + } + t := reflect.TypeOf(i) m.mtx.RLock() @@ -63,10 +101,3 @@ func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string { m.messageLabelNames[t] = l return l } - -func newMetricsLabelCache() *metricsLabelCache { - return &metricsLabelCache{ - mtx: &sync.RWMutex{}, - messageLabelNames: map[reflect.Type]string{}, - } -} diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 99c2d045ad..2780ba4ab5 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -120,7 +120,26 @@ func (cli *socketClient) Error() error { return cli.err } -//---------------------------------------- +// Add the request to the pending messages queue. +// +// Note that you still need to wake up sendRequestsRoutine writing to `cli.reqSignal` +func (cli *socketClient) enqueue(reqres *requestAndResponse) { + cli.mtx.Lock() + cli.reqQueue.Push(reqres, reqres.priority()) + cli.mtx.Unlock() + + cli.metrics.EnqueuedMessage(reqres) +} + +// Remove the first request from the queue and return it. +func (cli *socketClient) dequeue() *requestAndResponse { + cli.mtx.Lock() + reqres := cli.reqQueue.PopItem() + cli.mtx.Unlock() + + cli.metrics.DequeuedMessage(reqres) + return reqres +} func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer) { bw := bufio.NewWriter(conn) @@ -129,11 +148,9 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer case <-ctx.Done(): return case <-cli.reqSignal: - cli.mtx.Lock() - reqres := cli.reqQueue.PopItem() - cli.mtx.Unlock() + reqres := cli.dequeue() - // N.B. We must enqueue before sending out the request, otherwise the + // N.B. We must track request before sending it out, otherwise the // server may reply before we do it, and the receiver will fail for an // unsolicited reply. cli.trackRequest(reqres) @@ -142,6 +159,7 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer cli.stopForError(fmt.Errorf("write to buffer: %w", err)) return } + cli.metrics.SentMessage(reqres) if err := bw.Flush(); err != nil { cli.stopForError(fmt.Errorf("flush buffer: %w", err)) @@ -220,15 +238,7 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty } reqres := makeReqRes(req) - - cli.mtx.Lock() - cli.reqQueue.Push(reqres, reqres.priority()) - size := cli.reqQueue.Size() - cli.mtx.Unlock() - - if size > 0 && size%1000 == 0 { - cli.logger.Error("suspicious abci.socketClient queue size", "size", size) - } + cli.enqueue(reqres) select { case cli.reqSignal <- struct{}{}: diff --git a/scripts/txs/random.sh b/scripts/txs/random.sh old mode 100644 new mode 100755 index 231fabcfea..60c74f1a9c --- a/scripts/txs/random.sh +++ b/scripts/txs/random.sh @@ -14,6 +14,7 @@ for i in `seq 1 $N`; do VALUE="$i" echo $(toHex $KEY=$VALUE) curl 127.0.0.1:$PORT/broadcast_tx_sync?tx=0x$(toHex $KEY=$VALUE) + echo done From f61dfd562a098d7cb01e00f37b418cbf1d8d70a0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:22:16 +0100 Subject: [PATCH 011/111] chore: abci metrics remove SentMessagesTotal which is a duplicate --- abci/client/metrics.gen.go | 8 +------- abci/client/metrics.go | 15 +-------------- abci/client/socket_client.go | 1 - 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/abci/client/metrics.gen.go b/abci/client/metrics.gen.go index c620689993..62847a1958 100644 --- a/abci/client/metrics.gen.go +++ b/abci/client/metrics.gen.go @@ -20,18 +20,12 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Name: "queued_messages", Help: "Number of messages in ABCI Socket queue", }, append(labels, "type", "priority")).With(labelsAndValues...), - SentMessagesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ - Namespace: namespace, - Subsystem: MetricsSubsystem, - Name: "sent_messages_total", - Help: "Number of messages received from ABCI Socket", - }, append(labels, "type", "priority")).With(labelsAndValues...), + } } func NopMetrics() *Metrics { return &Metrics{ QueuedMessages: discard.NewGauge(), - SentMessagesTotal: discard.NewCounter(), } } diff --git a/abci/client/metrics.go b/abci/client/metrics.go index c03f8562cc..26cdc92504 100644 --- a/abci/client/metrics.go +++ b/abci/client/metrics.go @@ -14,7 +14,7 @@ import ( const ( // MetricsSubsystem is a subsystem shared by all metrics exposed by this // package. - MetricsSubsystem = "abciclient" + MetricsSubsystem = "abci" ) var ( @@ -31,9 +31,6 @@ type Metrics struct { // Number of messages in ABCI Socket queue QueuedMessages metrics.Gauge `metrics_labels:"type, priority"` - // Number of messages received from ABCI Socket - SentMessagesTotal metrics.Counter `metrics_labels:"type, priority"` - // labels cache labels metricsLabelCache } @@ -63,16 +60,6 @@ func (m *Metrics) DequeuedMessage(reqres *requestAndResponse) { m.QueuedMessages.With("type", typ, "priority", priority).Add(-1) } -func (m *Metrics) SentMessage(reqres *requestAndResponse) { - priority := strconv.Itoa(int(reqres.priority())) - typ := "nil" - if reqres != nil && reqres.Request != nil { - typ = m.labels.ValueToMetricLabel(reqres.Request.Value) - } - - m.SentMessagesTotal.With("type", typ, "priority", priority).Add(1) -} - // ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang // type that is passed in. // This method uses a map on the Metrics struct so that each label name only needs diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 2780ba4ab5..a96fe7977d 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -159,7 +159,6 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer cli.stopForError(fmt.Errorf("write to buffer: %w", err)) return } - cli.metrics.SentMessage(reqres) if err := bw.Flush(); err != nil { cli.stopForError(fmt.Errorf("flush buffer: %w", err)) From ff8c2f3e6ddfbe2ec664ed68f85407f59ed4094b Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:26:18 +0100 Subject: [PATCH 012/111] refactor!: remove consensus params commit timeout --- internal/consensus/reactor_test.go | 1 - internal/consensus/state.go | 5 +- internal/consensus/state_add_commit.go | 7 +- internal/consensus/state_add_vote.go | 10 +- internal/consensus/state_data.go | 23 +-- internal/consensus/state_test.go | 2 - internal/test/factory/params.go | 10 +- proto/tendermint/types/params.pb.go | 233 ++++++------------------- proto/tendermint/types/params.proto | 12 -- types/params.go | 52 ++---- types/params_test.go | 72 +++----- version/version.go | 2 +- 12 files changed, 116 insertions(+), 313 deletions(-) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index fde234c87a..6b54be08dc 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -556,7 +556,6 @@ func TestReactorValidatorSetChanges(t *testing.T) { validatorUpdates: updates, consensusParams: factory.ConsensusParams(func(cp *types.ConsensusParams) { cp.Timeout.Propose = 2 * time.Second - cp.Timeout.Commit = 1 * time.Second cp.Timeout.Vote = 1 * time.Second }), } diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 91af6fac30..edf21edf12 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -512,8 +512,9 @@ func (cs *State) OnStop() { if cs.GetRoundState().Step == cstypes.RoundStepApplyCommit { select { case <-cs.getOnStopCh(): - case <-time.After(stateData.state.ConsensusParams.Timeout.Commit): - cs.logger.Error("OnStop: timeout waiting for commit to finish", "time", stateData.state.ConsensusParams.Timeout.Commit) + case <-time.After(stateData.state.ConsensusParams.Timeout.Vote): + // we wait vote timeout, just in case + cs.logger.Error("OnStop: timeout waiting for commit to finish", "time", stateData.state.ConsensusParams.Timeout.Vote) } } diff --git a/internal/consensus/state_add_commit.go b/internal/consensus/state_add_commit.go index 17981f909f..3cfcfe70d4 100644 --- a/internal/consensus/state_add_commit.go +++ b/internal/consensus/state_add_commit.go @@ -47,9 +47,10 @@ func (c *AddCommitAction) Execute(ctx context.Context, stateEvent StateEvent) er if err != nil { return fmt.Errorf("error adding commit: %w", err) } - if stateData.bypassCommitTimeout() { - _ = stateEvent.Ctrl.Dispatch(ctx, &EnterNewRoundEvent{Height: stateData.Height}, stateData) - } + + // We go to next round, as in Tenderdash we don't need to wait for new commits + _ = stateEvent.Ctrl.Dispatch(ctx, &EnterNewRoundEvent{Height: stateData.Height}, stateData) + _ = c.statsQueue.send(ctx, msgInfoFromCtx(ctx)) return nil } diff --git a/internal/consensus/state_add_vote.go b/internal/consensus/state_add_vote.go index 0644beb518..781c692e86 100644 --- a/internal/consensus/state_add_vote.go +++ b/internal/consensus/state_add_vote.go @@ -129,10 +129,10 @@ func addVoteToLastPrecommitMw(ep *EventPublisher, ctrl *Controller) AddVoteMiddl return added, err } - // if we can skip timeoutCommit and have all the votes now, - if stateData.bypassCommitTimeout() && stateData.LastPrecommits.HasAll() { - // go straight to new round (skip timeout commit) - // c.scheduleTimeout(time.Duration(0), c.Height, 0, cstypes.RoundStepNewHeight) + // if we have reached majority, we can go straight to new round. + // No need to wait, as we don't save all the precommits anyway + if stateData.LastPrecommits.HasTwoThirdsMajority() { + // go straight to new round _ = ctrl.Dispatch(ctx, &EnterNewRoundEvent{Height: stateData.Height}, stateData) } return added, err @@ -250,7 +250,7 @@ func addVoteDispatchPrecommitMw(ctrl *Controller) AddVoteMiddlewareFunc { return added, err } _ = ctrl.Dispatch(ctx, &EnterCommitEvent{Height: height, CommitRound: vote.Round}, stateData) - if stateData.bypassCommitTimeout() && precommits.HasAll() { + if precommits.HasTwoThirdsMajority() { _ = ctrl.Dispatch(ctx, &EnterNewRoundEvent{Height: stateData.Height}, stateData) } return added, err diff --git a/internal/consensus/state_data.go b/internal/consensus/state_data.go index 519d60175a..0262a3a89c 100644 --- a/internal/consensus/state_data.go +++ b/internal/consensus/state_data.go @@ -266,13 +266,9 @@ func (s *StateData) updateToState(state sm.State, commit *types.Commit) { if s.CommitTime.IsZero() { // "Now" makes it easier to sync up dev nodes. - // We add timeoutCommit to allow transactions - // to be gathered for the first block. - // And alternative solution that relies on clocks: - // cs.StartTime = state.LastBlockTime.Add(timeoutCommit) - s.StartTime = s.commitTime(tmtime.Now()) + s.StartTime = tmtime.Now() } else { - s.StartTime = s.commitTime(s.CommitTime) + s.StartTime = s.CommitTime } if s.Validators == nil || !bytes.Equal(s.Validators.QuorumHash, validators.QuorumHash) { @@ -314,14 +310,6 @@ func (s *StateData) HeightVoteSet() (int64, *cstypes.HeightVoteSet) { return s.Height, s.Votes } -func (s *StateData) commitTime(t time.Time) time.Time { - c := s.state.ConsensusParams.Timeout.Commit - if s.config.UnsafeCommitTimeoutOverride != 0 { - c = s.config.UnsafeProposeTimeoutOverride - } - return t.Add(c) -} - func (s *StateData) proposalIsTimely() bool { if s.Height == s.state.InitialHeight { // by definition, initial block must have genesis time @@ -459,13 +447,6 @@ func (s *StateData) voteTimeout(round int32) time.Duration { ) * time.Nanosecond } -func (s *StateData) bypassCommitTimeout() bool { - if s.config.UnsafeBypassCommitTimeoutOverride != nil { - return *s.config.UnsafeBypassCommitTimeoutOverride - } - return s.state.ConsensusParams.Timeout.BypassCommitTimeout -} - func (s *StateData) isValidForPrevote() error { // Check that a proposed block was not received within this round (and thus executing this from a timeout). if s.ProposalBlock == nil { diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 2c3587b114..b9759f2389 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -2728,7 +2728,6 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { cs1, vss := makeState(ctx, t, makeStateArgs{config: config}) stateData := cs1.GetStateData() - stateData.state.ConsensusParams.Timeout.BypassCommitTimeout = false err := stateData.Save() require.NoError(t, err) cs1.txNotifier = &fakeTxNotifier{ch: make(chan struct{})} @@ -2793,7 +2792,6 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { cs1, vss := makeState(ctx, t, makeStateArgs{config: config}) stateData := cs1.GetStateData() - stateData.state.ConsensusParams.Timeout.BypassCommitTimeout = false err := stateData.Save() require.NoError(t, err) diff --git a/internal/test/factory/params.go b/internal/test/factory/params.go index dcbe137a2e..b4d73727c4 100644 --- a/internal/test/factory/params.go +++ b/internal/test/factory/params.go @@ -11,12 +11,10 @@ import ( func ConsensusParams(opts ...func(*types.ConsensusParams)) *types.ConsensusParams { c := types.DefaultConsensusParams() c.Timeout = types.TimeoutParams{ - Commit: 10 * time.Millisecond, - Propose: 40 * time.Millisecond, - ProposeDelta: 1 * time.Millisecond, - Vote: 10 * time.Millisecond, - VoteDelta: 1 * time.Millisecond, - BypassCommitTimeout: true, + Propose: 40 * time.Millisecond, + ProposeDelta: 1 * time.Millisecond, + Vote: 10 * time.Millisecond, + VoteDelta: 1 * time.Millisecond, } for _, opt := range opts { opt(c) diff --git a/proto/tendermint/types/params.pb.go b/proto/tendermint/types/params.pb.go index 1d48708289..2b2c4813c0 100644 --- a/proto/tendermint/types/params.pb.go +++ b/proto/tendermint/types/params.pb.go @@ -487,16 +487,6 @@ type TimeoutParams struct { // to the next step immediately. Vote *time.Duration `protobuf:"bytes,3,opt,name=vote,proto3,stdduration" json:"vote,omitempty"` VoteDelta *time.Duration `protobuf:"bytes,4,opt,name=vote_delta,json=voteDelta,proto3,stdduration" json:"vote_delta,omitempty"` - // commit configures how long Tendermint will wait after receiving a quorum of - // precommits before beginning consensus for the next height. This can be - // used to allow slow precommits to arrive for inclusion in the next height before progressing. - Commit *time.Duration `protobuf:"bytes,5,opt,name=commit,proto3,stdduration" json:"commit,omitempty"` - // bypass_commit_timeout configures the node to proceed immediately to - // the next height once the node has received all precommits for a block, forgoing - // the remaining commit timeout. - // Setting bypass_commit_timeout false (the default) causes Tendermint to wait - // for the full commit timeout. - BypassCommitTimeout bool `protobuf:"varint,6,opt,name=bypass_commit_timeout,json=bypassCommitTimeout,proto3" json:"bypass_commit_timeout,omitempty"` } func (m *TimeoutParams) Reset() { *m = TimeoutParams{} } @@ -560,20 +550,6 @@ func (m *TimeoutParams) GetVoteDelta() *time.Duration { return nil } -func (m *TimeoutParams) GetCommit() *time.Duration { - if m != nil { - return m.Commit - } - return nil -} - -func (m *TimeoutParams) GetBypassCommitTimeout() bool { - if m != nil { - return m.BypassCommitTimeout - } - return false -} - // ABCIParams configure functionality specific to the Application Blockchain Interface. type ABCIParams struct { // Indicates if CheckTx should be called on all the transactions @@ -636,53 +612,51 @@ func init() { func init() { proto.RegisterFile("tendermint/types/params.proto", fileDescriptor_e12598271a686f57) } var fileDescriptor_e12598271a686f57 = []byte{ - // 731 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0xcf, 0x6e, 0xd3, 0x4a, - 0x14, 0xc6, 0xe3, 0x26, 0x4d, 0x93, 0x93, 0xa6, 0xa9, 0xe6, 0xde, 0xab, 0xeb, 0xdb, 0x4b, 0x9d, - 0xe2, 0x05, 0xaa, 0x54, 0xc9, 0xae, 0x5a, 0x10, 0x42, 0xe2, 0x8f, 0x9a, 0x04, 0x01, 0x42, 0x45, - 0xc8, 0x54, 0x2c, 0xba, 0xb1, 0xc6, 0xce, 0xe0, 0x58, 0x8d, 0x3d, 0x96, 0xc7, 0x8e, 0xe2, 0xb7, - 0x60, 0x85, 0x78, 0x04, 0xd8, 0xf0, 0x1c, 0x5d, 0x76, 0xc9, 0x0a, 0x50, 0xfa, 0x06, 0x3c, 0x01, - 0x9a, 0xf1, 0xb8, 0x69, 0x52, 0x4a, 0xb3, 0x8a, 0x3d, 0xe7, 0xfb, 0xf9, 0xf3, 0x7c, 0xe7, 0x78, - 0x02, 0x9b, 0x09, 0x09, 0xfb, 0x24, 0x0e, 0xfc, 0x30, 0x31, 0x93, 0x2c, 0x22, 0xcc, 0x8c, 0x70, - 0x8c, 0x03, 0x66, 0x44, 0x31, 0x4d, 0x28, 0x5a, 0x9f, 0x96, 0x0d, 0x51, 0xde, 0xf8, 0xdb, 0xa3, - 0x1e, 0x15, 0x45, 0x93, 0x5f, 0xe5, 0xba, 0x0d, 0xcd, 0xa3, 0xd4, 0x1b, 0x12, 0x53, 0xdc, 0x39, - 0xe9, 0x3b, 0xb3, 0x9f, 0xc6, 0x38, 0xf1, 0x69, 0x98, 0xd7, 0xf5, 0x2f, 0x65, 0x68, 0x75, 0x69, - 0xc8, 0x48, 0xc8, 0x52, 0xf6, 0x5a, 0x38, 0xa0, 0x7d, 0x58, 0x76, 0x86, 0xd4, 0x3d, 0x51, 0x95, - 0x2d, 0x65, 0xbb, 0xb1, 0xb7, 0x69, 0xcc, 0x7b, 0x19, 0x1d, 0x5e, 0xce, 0xd5, 0x56, 0xae, 0x45, - 0x0f, 0xa1, 0x46, 0x46, 0x7e, 0x9f, 0x84, 0x2e, 0x51, 0x97, 0x04, 0xb7, 0x75, 0x95, 0x7b, 0x2a, - 0x15, 0x12, 0xbd, 0x20, 0xd0, 0x13, 0xa8, 0x8f, 0xf0, 0xd0, 0xef, 0xe3, 0x84, 0xc6, 0x6a, 0x59, - 0xe0, 0xb7, 0xaf, 0xe2, 0x6f, 0x0b, 0x89, 0xe4, 0xa7, 0x0c, 0x7a, 0x00, 0x2b, 0x23, 0x12, 0x33, - 0x9f, 0x86, 0x6a, 0x45, 0xe0, 0xed, 0xdf, 0xe0, 0xb9, 0x40, 0xc2, 0x85, 0x9e, 0x7b, 0xb3, 0x2c, - 0x74, 0x07, 0x31, 0x0d, 0x33, 0x75, 0xf9, 0x3a, 0xef, 0x37, 0x85, 0xa4, 0xf0, 0xbe, 0x60, 0xb8, - 0x77, 0xe2, 0x07, 0x84, 0xa6, 0x89, 0x5a, 0xbd, 0xce, 0xfb, 0x28, 0x17, 0x14, 0xde, 0x52, 0x8f, - 0x76, 0xa1, 0x82, 0x1d, 0xd7, 0x57, 0x57, 0x04, 0x77, 0xeb, 0x2a, 0x77, 0xd0, 0xe9, 0xbe, 0x90, - 0x90, 0x50, 0xea, 0x5d, 0x68, 0x5c, 0x4a, 0x1f, 0xfd, 0x0f, 0xf5, 0x00, 0x8f, 0x6d, 0x27, 0x4b, - 0x08, 0x13, 0xfd, 0x2a, 0x5b, 0xb5, 0x00, 0x8f, 0x3b, 0xfc, 0x1e, 0xfd, 0x0b, 0x2b, 0xbc, 0xe8, - 0x61, 0x26, 0x5a, 0x52, 0xb6, 0xaa, 0x01, 0x1e, 0x3f, 0xc3, 0x4c, 0xff, 0xac, 0xc0, 0xda, 0x6c, - 0x2f, 0xd0, 0x0e, 0x20, 0xae, 0xc5, 0x1e, 0xb1, 0xc3, 0x34, 0xb0, 0x45, 0x53, 0x8b, 0x27, 0xb6, - 0x02, 0x3c, 0x3e, 0xf0, 0xc8, 0xab, 0x34, 0x10, 0xd6, 0x0c, 0x1d, 0xc2, 0x7a, 0x21, 0x2e, 0xe6, - 0x49, 0x36, 0xfd, 0x3f, 0x23, 0x1f, 0x38, 0xa3, 0x18, 0x38, 0xa3, 0x27, 0x05, 0x9d, 0xda, 0xe9, - 0xb7, 0x76, 0xe9, 0xe3, 0xf7, 0xb6, 0x62, 0xad, 0xe5, 0xcf, 0x2b, 0x2a, 0xb3, 0x9b, 0x28, 0xcf, - 0x6e, 0x42, 0xbf, 0x07, 0xad, 0xb9, 0xbe, 0x23, 0x1d, 0x9a, 0x51, 0xea, 0xd8, 0x27, 0x24, 0xb3, - 0x45, 0x4a, 0xaa, 0xb2, 0x55, 0xde, 0xae, 0x5b, 0x8d, 0x28, 0x75, 0x5e, 0x92, 0xec, 0x88, 0x2f, - 0xe9, 0xbb, 0xd0, 0x9c, 0xe9, 0x37, 0x6a, 0x43, 0x03, 0x47, 0x91, 0x5d, 0x4c, 0x09, 0xdf, 0x59, - 0xc5, 0x02, 0x1c, 0x45, 0x52, 0xa6, 0x1f, 0xc3, 0xea, 0x73, 0xcc, 0x06, 0xa4, 0x2f, 0x81, 0x3b, - 0xd0, 0x12, 0x29, 0xd8, 0xf3, 0x01, 0x37, 0xc5, 0xf2, 0x61, 0x91, 0xb2, 0x0e, 0xcd, 0xa9, 0x6e, - 0x9a, 0x75, 0xa3, 0x50, 0xf1, 0xc0, 0x3f, 0x28, 0xd0, 0x9a, 0x9b, 0x20, 0xd4, 0x83, 0x66, 0x40, - 0x18, 0x13, 0x21, 0x92, 0x21, 0xce, 0xe4, 0xe7, 0xf6, 0x87, 0x04, 0x2b, 0x22, 0xbd, 0x55, 0x49, - 0xf5, 0x38, 0x84, 0x1e, 0x41, 0x3d, 0x8a, 0x89, 0xeb, 0xb3, 0x85, 0x7a, 0x90, 0x3f, 0x61, 0x4a, - 0xe8, 0x3f, 0x97, 0xa0, 0x39, 0x33, 0x9b, 0x7c, 0x9a, 0xa3, 0x98, 0x46, 0x94, 0x91, 0x45, 0x5f, - 0xa8, 0xd0, 0xf3, 0x1d, 0xc9, 0x4b, 0xbe, 0xa3, 0x04, 0x2f, 0xfa, 0x3e, 0xab, 0x92, 0xea, 0x71, - 0x08, 0xed, 0x43, 0x65, 0x44, 0x13, 0x22, 0x8f, 0x81, 0x1b, 0x61, 0x21, 0x46, 0x8f, 0x01, 0xf8, - 0xaf, 0xf4, 0xad, 0x2c, 0x98, 0x03, 0x47, 0x72, 0xd3, 0xfb, 0x50, 0x75, 0x69, 0x10, 0xf8, 0x89, - 0x3c, 0x01, 0x6e, 0x64, 0xa5, 0x1c, 0xed, 0xc1, 0x3f, 0x4e, 0x16, 0x61, 0xc6, 0xec, 0x7c, 0xc1, - 0xbe, 0x7c, 0x14, 0xd4, 0xac, 0xbf, 0xf2, 0x62, 0x57, 0xd4, 0x64, 0xd0, 0xfa, 0x0e, 0xc0, 0xf4, - 0xbb, 0x46, 0x9b, 0x00, 0x31, 0x71, 0x07, 0xc4, 0x3d, 0xb1, 0x93, 0xb1, 0xc8, 0xbc, 0x66, 0xd5, - 0xe5, 0xca, 0xd1, 0xb8, 0x63, 0x7d, 0x9a, 0x68, 0xca, 0xe9, 0x44, 0x53, 0xce, 0x26, 0x9a, 0xf2, - 0x63, 0xa2, 0x29, 0xef, 0xcf, 0xb5, 0xd2, 0xd9, 0xb9, 0x56, 0xfa, 0x7a, 0xae, 0x95, 0x8e, 0xef, - 0x7a, 0x7e, 0x32, 0x48, 0x1d, 0xc3, 0xa5, 0x81, 0xd9, 0xc7, 0x6c, 0x10, 0xe1, 0xcc, 0xcc, 0x0f, - 0x11, 0x7e, 0x97, 0x1f, 0xfb, 0xe6, 0xfc, 0x5f, 0x89, 0x53, 0x15, 0xeb, 0xfb, 0xbf, 0x02, 0x00, - 0x00, 0xff, 0xff, 0xaa, 0x0f, 0x78, 0xde, 0x65, 0x06, 0x00, 0x00, + // 692 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xcf, 0x6e, 0xd3, 0x4c, + 0x14, 0xc5, 0xe3, 0x26, 0x6d, 0x93, 0x9b, 0xa6, 0xa9, 0x46, 0x9f, 0xf4, 0x99, 0x42, 0x9d, 0xe2, + 0x05, 0xaa, 0x54, 0xc9, 0xae, 0x28, 0x2c, 0x90, 0xf8, 0xa3, 0xa6, 0x41, 0x80, 0x50, 0x11, 0x32, + 0x15, 0x8b, 0x6e, 0xac, 0xb1, 0x33, 0x38, 0x56, 0x63, 0x8f, 0xe5, 0xb1, 0xa3, 0xf8, 0x01, 0xd8, + 0xb3, 0x42, 0x3c, 0x02, 0x6c, 0x78, 0x8e, 0x2e, 0xbb, 0x64, 0x05, 0x28, 0x7d, 0x11, 0x34, 0xe3, + 0x99, 0x86, 0xa4, 0x14, 0xb2, 0x4a, 0x3c, 0xf7, 0xfc, 0x7c, 0x3c, 0xe7, 0xde, 0x19, 0xd8, 0xca, + 0x48, 0xdc, 0x27, 0x69, 0x14, 0xc6, 0x99, 0x9d, 0x15, 0x09, 0x61, 0x76, 0x82, 0x53, 0x1c, 0x31, + 0x2b, 0x49, 0x69, 0x46, 0xd1, 0xc6, 0xb4, 0x6c, 0x89, 0xf2, 0xe6, 0x7f, 0x01, 0x0d, 0xa8, 0x28, + 0xda, 0xfc, 0x5f, 0xa9, 0xdb, 0x34, 0x02, 0x4a, 0x83, 0x21, 0xb1, 0xc5, 0x93, 0x97, 0xbf, 0xb3, + 0xfb, 0x79, 0x8a, 0xb3, 0x90, 0xc6, 0x65, 0xdd, 0xfc, 0x5a, 0x85, 0xf6, 0x21, 0x8d, 0x19, 0x89, + 0x59, 0xce, 0x5e, 0x0b, 0x07, 0xb4, 0x0f, 0xcb, 0xde, 0x90, 0xfa, 0xa7, 0xba, 0xb6, 0xad, 0xed, + 0x34, 0xef, 0x6e, 0x59, 0xf3, 0x5e, 0x56, 0x97, 0x97, 0x4b, 0xb5, 0x53, 0x6a, 0xd1, 0x43, 0xa8, + 0x93, 0x51, 0xd8, 0x27, 0xb1, 0x4f, 0xf4, 0x25, 0xc1, 0x6d, 0x5f, 0xe5, 0x9e, 0x4a, 0x85, 0x44, + 0x2f, 0x09, 0xf4, 0x04, 0x1a, 0x23, 0x3c, 0x0c, 0xfb, 0x38, 0xa3, 0xa9, 0x5e, 0x15, 0xf8, 0xed, + 0xab, 0xf8, 0x5b, 0x25, 0x91, 0xfc, 0x94, 0x41, 0x0f, 0x60, 0x75, 0x44, 0x52, 0x16, 0xd2, 0x58, + 0xaf, 0x09, 0xbc, 0xf3, 0x07, 0xbc, 0x14, 0x48, 0x58, 0xe9, 0xb9, 0x37, 0x2b, 0x62, 0x7f, 0x90, + 0xd2, 0xb8, 0xd0, 0x97, 0xaf, 0xf3, 0x7e, 0xa3, 0x24, 0xca, 0xfb, 0x92, 0xe1, 0xde, 0x59, 0x18, + 0x11, 0x9a, 0x67, 0xfa, 0xca, 0x75, 0xde, 0xc7, 0xa5, 0x40, 0x79, 0x4b, 0x3d, 0xda, 0x83, 0x1a, + 0xf6, 0xfc, 0x50, 0x5f, 0x15, 0xdc, 0xad, 0xab, 0xdc, 0x41, 0xf7, 0xf0, 0x85, 0x84, 0x84, 0xd2, + 0x3c, 0x84, 0xe6, 0x6f, 0xe9, 0xa3, 0x9b, 0xd0, 0x88, 0xf0, 0xd8, 0xf5, 0x8a, 0x8c, 0x30, 0xd1, + 0xaf, 0xaa, 0x53, 0x8f, 0xf0, 0xb8, 0xcb, 0x9f, 0xd1, 0xff, 0xb0, 0xca, 0x8b, 0x01, 0x66, 0xa2, + 0x25, 0x55, 0x67, 0x25, 0xc2, 0xe3, 0x67, 0x98, 0x99, 0x5f, 0x34, 0x58, 0x9f, 0xed, 0x05, 0xda, + 0x05, 0xc4, 0xb5, 0x38, 0x20, 0x6e, 0x9c, 0x47, 0xae, 0x68, 0xaa, 0x7a, 0x63, 0x3b, 0xc2, 0xe3, + 0x83, 0x80, 0xbc, 0xca, 0x23, 0x61, 0xcd, 0xd0, 0x11, 0x6c, 0x28, 0xb1, 0x9a, 0x27, 0xd9, 0xf4, + 0x1b, 0x56, 0x39, 0x70, 0x96, 0x1a, 0x38, 0xab, 0x27, 0x05, 0xdd, 0xfa, 0xd9, 0xf7, 0x4e, 0xe5, + 0xd3, 0x8f, 0x8e, 0xe6, 0xac, 0x97, 0xef, 0x53, 0x95, 0xd9, 0x4d, 0x54, 0x67, 0x37, 0x61, 0xde, + 0x87, 0xf6, 0x5c, 0xdf, 0x91, 0x09, 0xad, 0x24, 0xf7, 0xdc, 0x53, 0x52, 0xb8, 0x22, 0x25, 0x5d, + 0xdb, 0xae, 0xee, 0x34, 0x9c, 0x66, 0x92, 0x7b, 0x2f, 0x49, 0x71, 0xcc, 0x97, 0xcc, 0x3d, 0x68, + 0xcd, 0xf4, 0x1b, 0x75, 0xa0, 0x89, 0x93, 0xc4, 0x55, 0x53, 0xc2, 0x77, 0x56, 0x73, 0x00, 0x27, + 0x89, 0x94, 0x99, 0x27, 0xb0, 0xf6, 0x1c, 0xb3, 0x01, 0xe9, 0x4b, 0xe0, 0x0e, 0xb4, 0x45, 0x0a, + 0xee, 0x7c, 0xc0, 0x2d, 0xb1, 0x7c, 0xa4, 0x52, 0x36, 0xa1, 0x35, 0xd5, 0x4d, 0xb3, 0x6e, 0x2a, + 0x15, 0x0f, 0xfc, 0xa3, 0x06, 0xed, 0xb9, 0x09, 0x42, 0x3d, 0x68, 0x45, 0x84, 0x31, 0x11, 0x22, + 0x19, 0xe2, 0x42, 0x1e, 0xb7, 0xbf, 0x24, 0x58, 0x13, 0xe9, 0xad, 0x49, 0xaa, 0xc7, 0x21, 0xf4, + 0x08, 0x1a, 0x49, 0x4a, 0xfc, 0x90, 0x2d, 0xd4, 0x83, 0xf2, 0x0d, 0x53, 0xc2, 0x7c, 0xbf, 0x04, + 0xad, 0x99, 0xd9, 0xe4, 0xd3, 0x9c, 0xa4, 0x34, 0xa1, 0x8c, 0x2c, 0xfa, 0x41, 0x4a, 0xcf, 0x77, + 0x24, 0xff, 0xf2, 0x1d, 0x65, 0x78, 0xd1, 0xef, 0x59, 0x93, 0x54, 0x8f, 0x43, 0x68, 0x1f, 0x6a, + 0x23, 0x9a, 0x11, 0x79, 0x0d, 0xfc, 0x13, 0x16, 0x62, 0xf4, 0x18, 0x80, 0xff, 0x4a, 0xdf, 0xda, + 0x82, 0x39, 0x70, 0x44, 0x98, 0x9a, 0xbb, 0x00, 0xd3, 0xa3, 0x86, 0xb6, 0x00, 0x52, 0xe2, 0x0f, + 0x88, 0x7f, 0xea, 0x66, 0x63, 0x11, 0x43, 0xdd, 0x69, 0xc8, 0x95, 0xe3, 0x71, 0xd7, 0xf9, 0x3c, + 0x31, 0xb4, 0xb3, 0x89, 0xa1, 0x9d, 0x4f, 0x0c, 0xed, 0xe7, 0xc4, 0xd0, 0x3e, 0x5c, 0x18, 0x95, + 0xf3, 0x0b, 0xa3, 0xf2, 0xed, 0xc2, 0xa8, 0x9c, 0xdc, 0x0b, 0xc2, 0x6c, 0x90, 0x7b, 0x96, 0x4f, + 0x23, 0xbb, 0x8f, 0xd9, 0x20, 0xc1, 0x85, 0x5d, 0x9e, 0x6b, 0xfe, 0x54, 0xde, 0xc4, 0xf6, 0xfc, + 0xed, 0xee, 0xad, 0x88, 0xf5, 0xfd, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xdf, 0xd1, 0x2a, + 0xf8, 0x05, 0x00, 0x00, } func (this *ConsensusParams) Equal(that interface{}) bool { @@ -958,18 +932,6 @@ func (this *TimeoutParams) Equal(that interface{}) bool { } else if that1.VoteDelta != nil { return false } - if this.Commit != nil && that1.Commit != nil { - if *this.Commit != *that1.Commit { - return false - } - } else if this.Commit != nil { - return false - } else if that1.Commit != nil { - return false - } - if this.BypassCommitTimeout != that1.BypassCommitTimeout { - return false - } return true } func (this *ABCIParams) Equal(that interface{}) bool { @@ -1333,64 +1295,44 @@ func (m *TimeoutParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.BypassCommitTimeout { - i-- - if m.BypassCommitTimeout { - dAtA[i] = 1 - } else { - dAtA[i] = 0 - } - i-- - dAtA[i] = 0x30 - } - if m.Commit != nil { - n11, err11 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.Commit, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Commit):]) + if m.VoteDelta != nil { + n11, err11 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.VoteDelta, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.VoteDelta):]) if err11 != nil { return 0, err11 } i -= n11 i = encodeVarintParams(dAtA, i, uint64(n11)) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } - if m.VoteDelta != nil { - n12, err12 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.VoteDelta, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.VoteDelta):]) + if m.Vote != nil { + n12, err12 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.Vote, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Vote):]) if err12 != nil { return 0, err12 } i -= n12 i = encodeVarintParams(dAtA, i, uint64(n12)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } - if m.Vote != nil { - n13, err13 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.Vote, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Vote):]) + if m.ProposeDelta != nil { + n13, err13 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ProposeDelta, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ProposeDelta):]) if err13 != nil { return 0, err13 } i -= n13 i = encodeVarintParams(dAtA, i, uint64(n13)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x12 } - if m.ProposeDelta != nil { - n14, err14 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.ProposeDelta, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.ProposeDelta):]) + if m.Propose != nil { + n14, err14 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.Propose, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Propose):]) if err14 != nil { return 0, err14 } i -= n14 i = encodeVarintParams(dAtA, i, uint64(n14)) i-- - dAtA[i] = 0x12 - } - if m.Propose != nil { - n15, err15 := github_com_gogo_protobuf_types.StdDurationMarshalTo(*m.Propose, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Propose):]) - if err15 != nil { - return 0, err15 - } - i -= n15 - i = encodeVarintParams(dAtA, i, uint64(n15)) - i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -1590,13 +1532,6 @@ func (m *TimeoutParams) Size() (n int) { l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.VoteDelta) n += 1 + l + sovParams(uint64(l)) } - if m.Commit != nil { - l = github_com_gogo_protobuf_types.SizeOfStdDuration(*m.Commit) - n += 1 + l + sovParams(uint64(l)) - } - if m.BypassCommitTimeout { - n += 2 - } return n } @@ -2663,62 +2598,6 @@ func (m *TimeoutParams) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Commit", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthParams - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthParams - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Commit == nil { - m.Commit = new(time.Duration) - } - if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(m.Commit, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 6: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BypassCommitTimeout", wireType) - } - var v int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - m.BypassCommitTimeout = bool(v != 0) default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/proto/tendermint/types/params.proto b/proto/tendermint/types/params.proto index 302ca71971..3fdb8a4557 100644 --- a/proto/tendermint/types/params.proto +++ b/proto/tendermint/types/params.proto @@ -115,18 +115,6 @@ message TimeoutParams { // to the next step immediately. google.protobuf.Duration vote = 3 [(gogoproto.stdduration) = true]; google.protobuf.Duration vote_delta = 4 [(gogoproto.stdduration) = true]; - - // commit configures how long Tendermint will wait after receiving a quorum of - // precommits before beginning consensus for the next height. This can be - // used to allow slow precommits to arrive for inclusion in the next height before progressing. - google.protobuf.Duration commit = 5 [(gogoproto.stdduration) = true]; - - // bypass_commit_timeout configures the node to proceed immediately to - // the next height once the node has received all precommits for a block, forgoing - // the remaining commit timeout. - // Setting bypass_commit_timeout false (the default) causes Tendermint to wait - // for the full commit timeout. - bool bypass_commit_timeout = 6; } // ABCIParams configure functionality specific to the Application Blockchain Interface. diff --git a/types/params.go b/types/params.go index 04ceda4693..5e6c65bd59 100644 --- a/types/params.go +++ b/types/params.go @@ -86,12 +86,10 @@ type SynchronyParams struct { // TimeoutParams configure the timings of the steps of the Tendermint consensus algorithm. type TimeoutParams struct { - Propose time.Duration `json:"propose,string"` - ProposeDelta time.Duration `json:"propose_delta,string"` - Vote time.Duration `json:"vote,string"` - VoteDelta time.Duration `json:"vote_delta,string"` - Commit time.Duration `json:"commit,string"` - BypassCommitTimeout bool `json:"bypass_commit_timeout"` + Propose time.Duration `json:"propose,string"` + ProposeDelta time.Duration `json:"propose_delta,string"` + Vote time.Duration `json:"vote,string"` + VoteDelta time.Duration `json:"vote_delta,string"` } // ABCIParams configure ABCI functionality specific to the Application Blockchain @@ -172,12 +170,10 @@ func (s SynchronyParams) SynchronyParamsOrDefaults() SynchronyParams { func DefaultTimeoutParams() TimeoutParams { return TimeoutParams{ - Propose: 3000 * time.Millisecond, - ProposeDelta: 500 * time.Millisecond, - Vote: 1000 * time.Millisecond, - VoteDelta: 500 * time.Millisecond, - Commit: 1000 * time.Millisecond, - BypassCommitTimeout: false, + Propose: 3000 * time.Millisecond, + ProposeDelta: 500 * time.Millisecond, + Vote: 1000 * time.Millisecond, + VoteDelta: 500 * time.Millisecond, } } @@ -207,9 +203,6 @@ func (t TimeoutParams) TimeoutParamsOrDefaults() TimeoutParams { if t.VoteDelta == 0 { t.VoteDelta = defaults.VoteDelta } - if t.Commit == 0 { - t.Commit = defaults.Commit - } return t } @@ -227,13 +220,6 @@ func (t TimeoutParams) VoteTimeout(round int32) time.Duration { ) * time.Nanosecond } -// CommitTime accepts ti, the time at which the consensus engine received +2/3 -// precommits for a block and returns the point in time at which the consensus -// engine should begin consensus on the next block. -func (t TimeoutParams) CommitTime(ti time.Time) time.Time { - return ti.Add(t.Commit) -} - func (val *ValidatorParams) IsValidPubkeyType(pubkeyType string) bool { for i := 0; i < len(val.PubKeyTypes); i++ { if val.PubKeyTypes[i] == pubkeyType { @@ -319,10 +305,6 @@ func (params ConsensusParams) ValidateConsensusParams() error { return fmt.Errorf("timeout.VoteDelta must be greater than 0. Got: %d", params.Timeout.VoteDelta) } - if params.Timeout.Commit <= 0 { - return fmt.Errorf("timeout.Commit must be greater than 0. Got: %d", params.Timeout.Commit) - } - if len(params.Validator.PubKeyTypes) == 0 { return errors.New("len(Validator.PubKeyTypes) must be greater than 0") } @@ -418,10 +400,6 @@ func (params ConsensusParams) UpdateConsensusParams(params2 *tmproto.ConsensusPa if params2.Timeout.VoteDelta != nil { res.Timeout.VoteDelta = *params2.Timeout.GetVoteDelta() } - if params2.Timeout.Commit != nil { - res.Timeout.Commit = *params2.Timeout.GetCommit() - } - res.Timeout.BypassCommitTimeout = params2.Timeout.GetBypassCommitTimeout() } if params2.Abci != nil { res.ABCI.RecheckTx = params2.Abci.GetRecheckTx() @@ -451,12 +429,10 @@ func (params *ConsensusParams) ToProto() tmproto.ConsensusParams { Precision: ¶ms.Synchrony.Precision, }, Timeout: &tmproto.TimeoutParams{ - Propose: ¶ms.Timeout.Propose, - ProposeDelta: ¶ms.Timeout.ProposeDelta, - Vote: ¶ms.Timeout.Vote, - VoteDelta: ¶ms.Timeout.VoteDelta, - Commit: ¶ms.Timeout.Commit, - BypassCommitTimeout: params.Timeout.BypassCommitTimeout, + Propose: ¶ms.Timeout.Propose, + ProposeDelta: ¶ms.Timeout.ProposeDelta, + Vote: ¶ms.Timeout.Vote, + VoteDelta: ¶ms.Timeout.VoteDelta, }, Abci: &tmproto.ABCIParams{ RecheckTx: params.ABCI.RecheckTx, @@ -503,10 +479,6 @@ func ConsensusParamsFromProto(pbParams tmproto.ConsensusParams) ConsensusParams if pbParams.Timeout.VoteDelta != nil { c.Timeout.VoteDelta = *pbParams.Timeout.GetVoteDelta() } - if pbParams.Timeout.Commit != nil { - c.Timeout.Commit = *pbParams.Timeout.GetCommit() - } - c.Timeout.BypassCommitTimeout = pbParams.Timeout.BypassCommitTimeout } if pbParams.Abci != nil { c.ABCI.RecheckTx = pbParams.Abci.GetRecheckTx() diff --git a/types/params_test.go b/types/params_test.go index 7e74c21315..a5abcfa6a4 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -173,21 +173,19 @@ func TestConsensusParamsValidation(t *testing.T) { } type makeParamsArgs struct { - blockBytes int64 - blockGas int64 - recheck bool - evidenceAge int64 - maxEvidenceBytes int64 - pubkeyTypes []string - precision time.Duration - messageDelay time.Duration - bypassCommitTimeout bool + blockBytes int64 + blockGas int64 + recheck bool + evidenceAge int64 + maxEvidenceBytes int64 + pubkeyTypes []string + precision time.Duration + messageDelay time.Duration propose *time.Duration proposeDelta *time.Duration vote *time.Duration voteDelta *time.Duration - commit *time.Duration } func makeParams(args makeParamsArgs) ConsensusParams { @@ -206,9 +204,7 @@ func makeParams(args makeParamsArgs) ConsensusParams { if args.voteDelta == nil { args.voteDelta = durationPtr(1) } - if args.commit == nil { - args.commit = durationPtr(1) - } + return ConsensusParams{ Block: BlockParams{ MaxBytes: args.blockBytes, @@ -227,12 +223,10 @@ func makeParams(args makeParamsArgs) ConsensusParams { MessageDelay: args.messageDelay, }, Timeout: TimeoutParams{ - Propose: *args.propose, - ProposeDelta: *args.proposeDelta, - Vote: *args.vote, - VoteDelta: *args.voteDelta, - Commit: *args.commit, - BypassCommitTimeout: args.bypassCommitTimeout, + Propose: *args.propose, + ProposeDelta: *args.proposeDelta, + Vote: *args.vote, + VoteDelta: *args.voteDelta, }, ABCI: ABCIParams{ RecheckTx: args.recheck, @@ -293,30 +287,24 @@ func TestConsensusParamsUpdate(t *testing.T) { { // update timeout params initialParams: makeParams(makeParamsArgs{ - propose: durationPtr(3 * time.Second), - proposeDelta: durationPtr(500 * time.Millisecond), - vote: durationPtr(time.Second), - voteDelta: durationPtr(500 * time.Millisecond), - commit: durationPtr(time.Second), - bypassCommitTimeout: false, + propose: durationPtr(3 * time.Second), + proposeDelta: durationPtr(500 * time.Millisecond), + vote: durationPtr(time.Second), + voteDelta: durationPtr(500 * time.Millisecond), }), updates: &tmproto.ConsensusParams{ Timeout: &tmproto.TimeoutParams{ - Propose: durationPtr(2 * time.Second), - ProposeDelta: durationPtr(400 * time.Millisecond), - Vote: durationPtr(5 * time.Second), - VoteDelta: durationPtr(400 * time.Millisecond), - Commit: durationPtr(time.Minute), - BypassCommitTimeout: true, + Propose: durationPtr(2 * time.Second), + ProposeDelta: durationPtr(400 * time.Millisecond), + Vote: durationPtr(5 * time.Second), + VoteDelta: durationPtr(400 * time.Millisecond), }, }, updatedParams: makeParams(makeParamsArgs{ - propose: durationPtr(2 * time.Second), - proposeDelta: durationPtr(400 * time.Millisecond), - vote: durationPtr(5 * time.Second), - voteDelta: durationPtr(400 * time.Millisecond), - commit: durationPtr(time.Minute), - bypassCommitTimeout: true, + propose: durationPtr(2 * time.Second), + proposeDelta: durationPtr(400 * time.Millisecond), + vote: durationPtr(5 * time.Second), + voteDelta: durationPtr(400 * time.Millisecond), }), }, // fine updates @@ -396,12 +384,10 @@ func TestProto(t *testing.T) { makeParams(makeParamsArgs{precision: time.Second, messageDelay: time.Minute}), makeParams(makeParamsArgs{precision: time.Nanosecond, messageDelay: time.Millisecond}), makeParams(makeParamsArgs{ - propose: durationPtr(2 * time.Second), - proposeDelta: durationPtr(400 * time.Millisecond), - vote: durationPtr(5 * time.Second), - voteDelta: durationPtr(400 * time.Millisecond), - commit: durationPtr(time.Minute), - bypassCommitTimeout: true, + propose: durationPtr(2 * time.Second), + proposeDelta: durationPtr(400 * time.Millisecond), + vote: durationPtr(5 * time.Second), + voteDelta: durationPtr(400 * time.Millisecond), }), } diff --git a/version/version.go b/version/version.go index ecb1f6e1f3..99d8e1e551 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ const ( // when not using git describe. It is formatted with semantic versioning. TMVersionDefault = "0.14.0-dev.1" // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.24.0" + ABCISemVer = "0.25.0" ABCIVersion = ABCISemVer ) From b9c498aa284ff123375915cda1e7e6b9ef719fab Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:44:08 +0100 Subject: [PATCH 013/111] chore: remove unused consensus params - backward-compat way --- proto/tendermint/types/params.pb.go | 92 +++++++++++++++-------------- proto/tendermint/types/params.proto | 7 +++ version/version.go | 2 +- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/proto/tendermint/types/params.pb.go b/proto/tendermint/types/params.pb.go index 2b2c4813c0..e8573e5a47 100644 --- a/proto/tendermint/types/params.pb.go +++ b/proto/tendermint/types/params.pb.go @@ -612,51 +612,53 @@ func init() { func init() { proto.RegisterFile("tendermint/types/params.proto", fileDescriptor_e12598271a686f57) } var fileDescriptor_e12598271a686f57 = []byte{ - // 692 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0xcf, 0x6e, 0xd3, 0x4c, - 0x14, 0xc5, 0xe3, 0x26, 0x6d, 0x93, 0x9b, 0xa6, 0xa9, 0x46, 0x9f, 0xf4, 0x99, 0x42, 0x9d, 0xe2, - 0x05, 0xaa, 0x54, 0xc9, 0xae, 0x28, 0x2c, 0x90, 0xf8, 0xa3, 0xa6, 0x41, 0x80, 0x50, 0x11, 0x32, - 0x15, 0x8b, 0x6e, 0xac, 0xb1, 0x33, 0x38, 0x56, 0x63, 0x8f, 0xe5, 0xb1, 0xa3, 0xf8, 0x01, 0xd8, - 0xb3, 0x42, 0x3c, 0x02, 0x6c, 0x78, 0x8e, 0x2e, 0xbb, 0x64, 0x05, 0x28, 0x7d, 0x11, 0x34, 0xe3, - 0x99, 0x86, 0xa4, 0x14, 0xb2, 0x4a, 0x3c, 0xf7, 0xfc, 0x7c, 0x3c, 0xe7, 0xde, 0x19, 0xd8, 0xca, - 0x48, 0xdc, 0x27, 0x69, 0x14, 0xc6, 0x99, 0x9d, 0x15, 0x09, 0x61, 0x76, 0x82, 0x53, 0x1c, 0x31, - 0x2b, 0x49, 0x69, 0x46, 0xd1, 0xc6, 0xb4, 0x6c, 0x89, 0xf2, 0xe6, 0x7f, 0x01, 0x0d, 0xa8, 0x28, - 0xda, 0xfc, 0x5f, 0xa9, 0xdb, 0x34, 0x02, 0x4a, 0x83, 0x21, 0xb1, 0xc5, 0x93, 0x97, 0xbf, 0xb3, - 0xfb, 0x79, 0x8a, 0xb3, 0x90, 0xc6, 0x65, 0xdd, 0xfc, 0x5a, 0x85, 0xf6, 0x21, 0x8d, 0x19, 0x89, - 0x59, 0xce, 0x5e, 0x0b, 0x07, 0xb4, 0x0f, 0xcb, 0xde, 0x90, 0xfa, 0xa7, 0xba, 0xb6, 0xad, 0xed, - 0x34, 0xef, 0x6e, 0x59, 0xf3, 0x5e, 0x56, 0x97, 0x97, 0x4b, 0xb5, 0x53, 0x6a, 0xd1, 0x43, 0xa8, - 0x93, 0x51, 0xd8, 0x27, 0xb1, 0x4f, 0xf4, 0x25, 0xc1, 0x6d, 0x5f, 0xe5, 0x9e, 0x4a, 0x85, 0x44, - 0x2f, 0x09, 0xf4, 0x04, 0x1a, 0x23, 0x3c, 0x0c, 0xfb, 0x38, 0xa3, 0xa9, 0x5e, 0x15, 0xf8, 0xed, - 0xab, 0xf8, 0x5b, 0x25, 0x91, 0xfc, 0x94, 0x41, 0x0f, 0x60, 0x75, 0x44, 0x52, 0x16, 0xd2, 0x58, - 0xaf, 0x09, 0xbc, 0xf3, 0x07, 0xbc, 0x14, 0x48, 0x58, 0xe9, 0xb9, 0x37, 0x2b, 0x62, 0x7f, 0x90, - 0xd2, 0xb8, 0xd0, 0x97, 0xaf, 0xf3, 0x7e, 0xa3, 0x24, 0xca, 0xfb, 0x92, 0xe1, 0xde, 0x59, 0x18, - 0x11, 0x9a, 0x67, 0xfa, 0xca, 0x75, 0xde, 0xc7, 0xa5, 0x40, 0x79, 0x4b, 0x3d, 0xda, 0x83, 0x1a, - 0xf6, 0xfc, 0x50, 0x5f, 0x15, 0xdc, 0xad, 0xab, 0xdc, 0x41, 0xf7, 0xf0, 0x85, 0x84, 0x84, 0xd2, - 0x3c, 0x84, 0xe6, 0x6f, 0xe9, 0xa3, 0x9b, 0xd0, 0x88, 0xf0, 0xd8, 0xf5, 0x8a, 0x8c, 0x30, 0xd1, - 0xaf, 0xaa, 0x53, 0x8f, 0xf0, 0xb8, 0xcb, 0x9f, 0xd1, 0xff, 0xb0, 0xca, 0x8b, 0x01, 0x66, 0xa2, - 0x25, 0x55, 0x67, 0x25, 0xc2, 0xe3, 0x67, 0x98, 0x99, 0x5f, 0x34, 0x58, 0x9f, 0xed, 0x05, 0xda, - 0x05, 0xc4, 0xb5, 0x38, 0x20, 0x6e, 0x9c, 0x47, 0xae, 0x68, 0xaa, 0x7a, 0x63, 0x3b, 0xc2, 0xe3, - 0x83, 0x80, 0xbc, 0xca, 0x23, 0x61, 0xcd, 0xd0, 0x11, 0x6c, 0x28, 0xb1, 0x9a, 0x27, 0xd9, 0xf4, - 0x1b, 0x56, 0x39, 0x70, 0x96, 0x1a, 0x38, 0xab, 0x27, 0x05, 0xdd, 0xfa, 0xd9, 0xf7, 0x4e, 0xe5, - 0xd3, 0x8f, 0x8e, 0xe6, 0xac, 0x97, 0xef, 0x53, 0x95, 0xd9, 0x4d, 0x54, 0x67, 0x37, 0x61, 0xde, - 0x87, 0xf6, 0x5c, 0xdf, 0x91, 0x09, 0xad, 0x24, 0xf7, 0xdc, 0x53, 0x52, 0xb8, 0x22, 0x25, 0x5d, - 0xdb, 0xae, 0xee, 0x34, 0x9c, 0x66, 0x92, 0x7b, 0x2f, 0x49, 0x71, 0xcc, 0x97, 0xcc, 0x3d, 0x68, - 0xcd, 0xf4, 0x1b, 0x75, 0xa0, 0x89, 0x93, 0xc4, 0x55, 0x53, 0xc2, 0x77, 0x56, 0x73, 0x00, 0x27, - 0x89, 0x94, 0x99, 0x27, 0xb0, 0xf6, 0x1c, 0xb3, 0x01, 0xe9, 0x4b, 0xe0, 0x0e, 0xb4, 0x45, 0x0a, - 0xee, 0x7c, 0xc0, 0x2d, 0xb1, 0x7c, 0xa4, 0x52, 0x36, 0xa1, 0x35, 0xd5, 0x4d, 0xb3, 0x6e, 0x2a, - 0x15, 0x0f, 0xfc, 0xa3, 0x06, 0xed, 0xb9, 0x09, 0x42, 0x3d, 0x68, 0x45, 0x84, 0x31, 0x11, 0x22, - 0x19, 0xe2, 0x42, 0x1e, 0xb7, 0xbf, 0x24, 0x58, 0x13, 0xe9, 0xad, 0x49, 0xaa, 0xc7, 0x21, 0xf4, - 0x08, 0x1a, 0x49, 0x4a, 0xfc, 0x90, 0x2d, 0xd4, 0x83, 0xf2, 0x0d, 0x53, 0xc2, 0x7c, 0xbf, 0x04, - 0xad, 0x99, 0xd9, 0xe4, 0xd3, 0x9c, 0xa4, 0x34, 0xa1, 0x8c, 0x2c, 0xfa, 0x41, 0x4a, 0xcf, 0x77, - 0x24, 0xff, 0xf2, 0x1d, 0x65, 0x78, 0xd1, 0xef, 0x59, 0x93, 0x54, 0x8f, 0x43, 0x68, 0x1f, 0x6a, - 0x23, 0x9a, 0x11, 0x79, 0x0d, 0xfc, 0x13, 0x16, 0x62, 0xf4, 0x18, 0x80, 0xff, 0x4a, 0xdf, 0xda, - 0x82, 0x39, 0x70, 0x44, 0x98, 0x9a, 0xbb, 0x00, 0xd3, 0xa3, 0x86, 0xb6, 0x00, 0x52, 0xe2, 0x0f, - 0x88, 0x7f, 0xea, 0x66, 0x63, 0x11, 0x43, 0xdd, 0x69, 0xc8, 0x95, 0xe3, 0x71, 0xd7, 0xf9, 0x3c, - 0x31, 0xb4, 0xb3, 0x89, 0xa1, 0x9d, 0x4f, 0x0c, 0xed, 0xe7, 0xc4, 0xd0, 0x3e, 0x5c, 0x18, 0x95, - 0xf3, 0x0b, 0xa3, 0xf2, 0xed, 0xc2, 0xa8, 0x9c, 0xdc, 0x0b, 0xc2, 0x6c, 0x90, 0x7b, 0x96, 0x4f, - 0x23, 0xbb, 0x8f, 0xd9, 0x20, 0xc1, 0x85, 0x5d, 0x9e, 0x6b, 0xfe, 0x54, 0xde, 0xc4, 0xf6, 0xfc, - 0xed, 0xee, 0xad, 0x88, 0xf5, 0xfd, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe9, 0xdf, 0xd1, 0x2a, - 0xf8, 0x05, 0x00, 0x00, + // 724 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x95, 0x4f, 0x6f, 0xd3, 0x48, + 0x18, 0xc6, 0xe3, 0xc6, 0xcd, 0x9f, 0x37, 0x4d, 0x13, 0x8d, 0x76, 0xb5, 0xde, 0xee, 0xd6, 0xe9, + 0xfa, 0xb0, 0xaa, 0x54, 0xc9, 0xae, 0xb6, 0xbb, 0x87, 0x95, 0xf8, 0xa3, 0xa6, 0x41, 0x40, 0x51, + 0x11, 0x32, 0x15, 0x87, 0x5e, 0xac, 0xb1, 0x33, 0x38, 0x56, 0x63, 0x8f, 0xe5, 0xb1, 0xa3, 0xf8, + 0x5b, 0x70, 0x42, 0x7c, 0x04, 0xb8, 0x20, 0x3e, 0x46, 0x8f, 0x3d, 0x72, 0x02, 0x94, 0x7e, 0x11, + 0x34, 0xe3, 0x71, 0x43, 0x52, 0x0a, 0x39, 0xc5, 0x33, 0xef, 0xf3, 0xf3, 0xe3, 0x79, 0xde, 0xd7, + 0x0e, 0x6c, 0xa7, 0x24, 0x1a, 0x92, 0x24, 0x0c, 0xa2, 0xd4, 0x4a, 0xf3, 0x98, 0x30, 0x2b, 0xc6, + 0x09, 0x0e, 0x99, 0x19, 0x27, 0x34, 0xa5, 0xa8, 0x3b, 0x2f, 0x9b, 0xa2, 0xbc, 0xf5, 0x8b, 0x4f, + 0x7d, 0x2a, 0x8a, 0x16, 0xbf, 0x2a, 0x74, 0x5b, 0xba, 0x4f, 0xa9, 0x3f, 0x26, 0x96, 0x58, 0xb9, + 0xd9, 0x4b, 0x6b, 0x98, 0x25, 0x38, 0x0d, 0x68, 0x54, 0xd4, 0x8d, 0xf7, 0x55, 0xe8, 0x1c, 0xd1, + 0x88, 0x91, 0x88, 0x65, 0xec, 0x99, 0x70, 0x40, 0x07, 0xb0, 0xee, 0x8e, 0xa9, 0x77, 0xae, 0x29, + 0x3b, 0xca, 0x6e, 0xeb, 0x9f, 0x6d, 0x73, 0xd9, 0xcb, 0xec, 0xf3, 0x72, 0xa1, 0xb6, 0x0b, 0x2d, + 0xba, 0x03, 0x0d, 0x32, 0x09, 0x86, 0x24, 0xf2, 0x88, 0xb6, 0x26, 0xb8, 0x9d, 0x9b, 0xdc, 0x03, + 0xa9, 0x90, 0xe8, 0x35, 0x81, 0xee, 0x43, 0x73, 0x82, 0xc7, 0xc1, 0x10, 0xa7, 0x34, 0xd1, 0xaa, + 0x02, 0xff, 0xeb, 0x26, 0xfe, 0xa2, 0x94, 0x48, 0x7e, 0xce, 0xa0, 0xff, 0xa1, 0x3e, 0x21, 0x09, + 0x0b, 0x68, 0xa4, 0xa9, 0x02, 0xef, 0x7d, 0x07, 0x2f, 0x04, 0x12, 0x2e, 0xf5, 0xdc, 0x9b, 0xe5, + 0x91, 0x37, 0x4a, 0x68, 0x94, 0x6b, 0xeb, 0xb7, 0x79, 0x3f, 0x2f, 0x25, 0xa5, 0xf7, 0x35, 0xc3, + 0xbd, 0xd3, 0x20, 0x24, 0x34, 0x4b, 0xb5, 0xda, 0x6d, 0xde, 0xa7, 0x85, 0xa0, 0xf4, 0x96, 0x7a, + 0xb4, 0x0f, 0x2a, 0x76, 0xbd, 0x40, 0xab, 0x0b, 0xee, 0xcf, 0x9b, 0xdc, 0x61, 0xff, 0xe8, 0xb1, + 0x84, 0x84, 0xd2, 0x38, 0x82, 0xd6, 0x37, 0xe9, 0xa3, 0x3f, 0xa0, 0x19, 0xe2, 0xa9, 0xe3, 0xe6, + 0x29, 0x61, 0xa2, 0x5f, 0x55, 0xbb, 0x11, 0xe2, 0x69, 0x9f, 0xaf, 0xd1, 0x6f, 0x50, 0xe7, 0x45, + 0x1f, 0x33, 0xd1, 0x92, 0xaa, 0x5d, 0x0b, 0xf1, 0xf4, 0x21, 0x66, 0xc6, 0x3b, 0x05, 0x36, 0x17, + 0x7b, 0x81, 0xf6, 0x00, 0x71, 0x2d, 0xf6, 0x89, 0x13, 0x65, 0xa1, 0x23, 0x9a, 0x5a, 0xde, 0xb1, + 0x13, 0xe2, 0xe9, 0xa1, 0x4f, 0x9e, 0x66, 0xa1, 0xb0, 0x66, 0xe8, 0x04, 0xba, 0xa5, 0xb8, 0x9c, + 0x27, 0xd9, 0xf4, 0xdf, 0xcd, 0x62, 0xe0, 0xcc, 0x72, 0xe0, 0xcc, 0x81, 0x14, 0xf4, 0x1b, 0x17, + 0x9f, 0x7a, 0x95, 0x37, 0x9f, 0x7b, 0x8a, 0xbd, 0x59, 0xdc, 0xaf, 0xac, 0x2c, 0x1e, 0xa2, 0xba, + 0x78, 0x08, 0xe3, 0x3f, 0xe8, 0x2c, 0xf5, 0x1d, 0x19, 0xd0, 0x8e, 0x33, 0xd7, 0x39, 0x27, 0xb9, + 0x23, 0x52, 0xd2, 0x94, 0x9d, 0xea, 0x6e, 0xd3, 0x6e, 0xc5, 0x99, 0xfb, 0x84, 0xe4, 0xa7, 0x7c, + 0xcb, 0xd8, 0x87, 0xf6, 0x42, 0xbf, 0x51, 0x0f, 0x5a, 0x38, 0x8e, 0x9d, 0x72, 0x4a, 0xf8, 0xc9, + 0x54, 0x1b, 0x70, 0x1c, 0x4b, 0x99, 0x71, 0x06, 0x1b, 0x8f, 0x30, 0x1b, 0x91, 0xa1, 0x04, 0xfe, + 0x86, 0x8e, 0x48, 0xc1, 0x59, 0x0e, 0xb8, 0x2d, 0xb6, 0x4f, 0xca, 0x94, 0x0d, 0x68, 0xcf, 0x75, + 0xf3, 0xac, 0x5b, 0xa5, 0x8a, 0x07, 0xfe, 0x5a, 0x81, 0xce, 0xd2, 0x04, 0xa1, 0x01, 0xb4, 0x43, + 0xc2, 0x98, 0x08, 0x91, 0x8c, 0x71, 0x2e, 0x5f, 0xb7, 0x1f, 0x24, 0xa8, 0x8a, 0xf4, 0x36, 0x24, + 0x35, 0xe0, 0x10, 0xba, 0x0b, 0xcd, 0x38, 0x21, 0x5e, 0xc0, 0x56, 0xea, 0x41, 0x71, 0x87, 0x39, + 0x61, 0x7c, 0x58, 0x83, 0xf6, 0xc2, 0x6c, 0xf2, 0x69, 0x8e, 0x13, 0x1a, 0x53, 0x46, 0x56, 0x7d, + 0xa0, 0x52, 0xcf, 0x4f, 0x24, 0x2f, 0xf9, 0x89, 0x52, 0xbc, 0xea, 0xf3, 0x6c, 0x48, 0x6a, 0xc0, + 0x21, 0x74, 0x00, 0xea, 0x84, 0xa6, 0x44, 0x7e, 0x06, 0x7e, 0x0a, 0x0b, 0x31, 0xba, 0x07, 0xc0, + 0x7f, 0xa5, 0xaf, 0xba, 0x62, 0x0e, 0x1c, 0x11, 0xa6, 0xc7, 0x6a, 0x63, 0xbd, 0x5b, 0x3b, 0x56, + 0x1b, 0xb5, 0x6e, 0xdd, 0xae, 0x79, 0x34, 0x0c, 0x83, 0xd4, 0xfe, 0xd5, 0xcd, 0x63, 0xcc, 0x98, + 0x53, 0x2c, 0x1d, 0xf9, 0xce, 0x1a, 0x7b, 0x00, 0xf3, 0xb7, 0x12, 0x6d, 0x03, 0x24, 0xc4, 0x1b, + 0x11, 0xef, 0xdc, 0x49, 0xa7, 0x22, 0xb1, 0x86, 0xdd, 0x94, 0x3b, 0xa7, 0xd3, 0xbe, 0xfd, 0x76, + 0xa6, 0x2b, 0x17, 0x33, 0x5d, 0xb9, 0x9c, 0xe9, 0xca, 0x97, 0x99, 0xae, 0xbc, 0xba, 0xd2, 0x2b, + 0x97, 0x57, 0x7a, 0xe5, 0xe3, 0x95, 0x5e, 0x39, 0xfb, 0xd7, 0x0f, 0xd2, 0x51, 0xe6, 0x9a, 0x1e, + 0x0d, 0xad, 0x21, 0x66, 0xa3, 0x18, 0xe7, 0x56, 0xf1, 0x09, 0xe0, 0xab, 0xe2, 0xa3, 0x6d, 0x2d, + 0xff, 0x11, 0xb8, 0x35, 0xb1, 0x7f, 0xf0, 0x35, 0x00, 0x00, 0xff, 0xff, 0x17, 0x03, 0x59, 0x60, + 0x23, 0x06, 0x00, 0x00, } func (this *ConsensusParams) Equal(that interface{}) bool { diff --git a/proto/tendermint/types/params.proto b/proto/tendermint/types/params.proto index 3fdb8a4557..3e8585f0c5 100644 --- a/proto/tendermint/types/params.proto +++ b/proto/tendermint/types/params.proto @@ -115,6 +115,13 @@ message TimeoutParams { // to the next step immediately. google.protobuf.Duration vote = 3 [(gogoproto.stdduration) = true]; google.protobuf.Duration vote_delta = 4 [(gogoproto.stdduration) = true]; + + // UNUSED + reserved "commit"; + reserved 5; + + reserved "bypass_commit_timeout"; + reserved 6; } // ABCIParams configure functionality specific to the Application Blockchain Interface. diff --git a/version/version.go b/version/version.go index 99d8e1e551..4914dedb96 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ const ( // when not using git describe. It is formatted with semantic versioning. TMVersionDefault = "0.14.0-dev.1" // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.25.0" + ABCISemVer = "0.24.1" ABCIVersion = ABCISemVer ) From 1eefd4687ee8ea283cc45a84a62a1308a4bd3e26 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:49:05 +0100 Subject: [PATCH 014/111] chore: proto abci version revert --- version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version/version.go b/version/version.go index 4914dedb96..ecb1f6e1f3 100644 --- a/version/version.go +++ b/version/version.go @@ -11,7 +11,7 @@ const ( // when not using git describe. It is formatted with semantic versioning. TMVersionDefault = "0.14.0-dev.1" // ABCISemVer is the semantic version of the ABCI library - ABCISemVer = "0.24.1" + ABCISemVer = "0.24.0" ABCIVersion = ABCISemVer ) From 5e41958bf8e6c0e58f7eeb1363049967d38b8353 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 20:46:06 +0100 Subject: [PATCH 015/111] feat(p2p): throttled channel --- internal/p2p/throttled_channel.go | 57 ++++++++++++++++++++ internal/p2p/throttled_channel_test.go | 74 ++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 internal/p2p/throttled_channel.go create mode 100644 internal/p2p/throttled_channel_test.go diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go new file mode 100644 index 0000000000..92dbe5edb2 --- /dev/null +++ b/internal/p2p/throttled_channel.go @@ -0,0 +1,57 @@ +package p2p + +import ( + "context" + + "golang.org/x/time/rate" +) + +// / Channel that will block if the send limit is reached +type ThrottledChannel struct { + channel Channel + limiter *rate.Limiter +} + +// NewThrottledChannel creates a new throttled channel. +// The rate is specified in messages per second. +// The burst is specified in messages. +// +// If unsure, use burst equal to 60 times the rate. +func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { + return &ThrottledChannel{ + channel: channel, + limiter: rate.NewLimiter(r, burst), + } +} + +var _ Channel = (*ThrottledChannel)(nil) + +func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { + // Wait until limiter allows us to proceed. + if err := ch.limiter.Wait(ctx); err != nil { + return err + } + + return ch.channel.Send(ctx, envelope) +} + +func (ch *ThrottledChannel) SendError(ctx context.Context, pe PeerError) error { + // Wait until limiter allows us to proceed. + if err := ch.limiter.Wait(ctx); err != nil { + return err + } + + return ch.channel.SendError(ctx, pe) +} + +func (ch *ThrottledChannel) Receive(ctx context.Context) *ChannelIterator { + return ch.channel.Receive(ctx) +} + +func (ch *ThrottledChannel) Err() error { + return ch.channel.Err() +} + +func (ch *ThrottledChannel) String() string { + return ch.channel.String() +} diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go new file mode 100644 index 0000000000..75512d2516 --- /dev/null +++ b/internal/p2p/throttled_channel_test.go @@ -0,0 +1,74 @@ +package p2p_test + +import ( + "context" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/dashpay/tenderdash/internal/p2p" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/time/rate" +) + +type mockChannel struct { + counter atomic.Uint32 +} + +func (c *mockChannel) Len() int { + return int(c.counter.Load()) +} + +func (c *mockChannel) Send(_ context.Context, e p2p.Envelope) error { + c.counter.Add(1) + return nil +} + +func (c *mockChannel) SendError(_ context.Context, _ p2p.PeerError) error { + panic("not implemented") +} + +func (c *mockChannel) Receive(_ context.Context) *p2p.ChannelIterator { + panic("not implemented") +} + +func (c *mockChannel) Err() error { + panic("not implemented") +} + +func (c *mockChannel) String() string { + return "mock_channel" +} + +func TestThrottledChannel(t *testing.T) { + const n = 31 + const rate rate.Limit = 10 + const burst = int(rate) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst) // 1 message per second + + wg := sync.WaitGroup{} + start := time.Now() + for i := 0; i < n; i++ { + wg.Add(1) + go func() { + err := ch.Send(context.Background(), p2p.Envelope{}) + require.NoError(t, err) + wg.Done() + }() + } + + time.Sleep(time.Second) + assert.LessOrEqual(t, mock.Len(), burst+int(rate)) + + // Wait until all finish + + wg.Wait() + took := time.Since(start) + assert.Equal(t, n, mock.Len()) + assert.GreaterOrEqual(t, took.Seconds(), 2.0) +} From cdde233c1372968bfbf03095ab6242f74a721062 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 21:07:35 +0100 Subject: [PATCH 016/111] feat: limit mempool broadcast to 5/s --- internal/p2p/channel_params.go | 2 ++ internal/p2p/conn/connection.go | 4 ++++ internal/p2p/router.go | 3 +++ internal/p2p/throttled_channel.go | 2 -- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 8a0aa8418b..4e3341e507 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -68,6 +68,8 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", + SendRateLimit: 5, + SendRateBurst: 20, }, SnapshotChannel: { ID: SnapshotChannel, diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index 1ecdd1a4dc..d09cd8baeb 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -14,6 +14,7 @@ import ( "time" sync "github.com/sasha-s/go-deadlock" + "golang.org/x/time/rate" "github.com/gogo/protobuf/proto" @@ -615,6 +616,9 @@ type ChannelDescriptor struct { SendQueueCapacity int RecvMessageCapacity int + SendRateLimit rate.Limit + SendRateBurst int + // RecvBufferCapacity defines the max buffer size of inbound messages for a // given p2p Channel queue. RecvBufferCapacity int diff --git a/internal/p2p/router.go b/internal/p2p/router.go index ed6e2c0d52..2db3ccef97 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -262,6 +262,9 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (Ch outCh := make(chan Envelope, chDesc.RecvBufferCapacity) errCh := make(chan PeerError, chDesc.RecvBufferCapacity) channel := NewChannel(chDesc.ID, chDesc.Name, queue.dequeue(), outCh, errCh) + if chDesc.SendRateLimit > 0 { + channel = NewThrottledChannel(channel, chDesc.SendRateLimit, chDesc.SendRateBurst) + } r.channelQueues[id] = queue diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go index 92dbe5edb2..bf7d0e06b7 100644 --- a/internal/p2p/throttled_channel.go +++ b/internal/p2p/throttled_channel.go @@ -15,8 +15,6 @@ type ThrottledChannel struct { // NewThrottledChannel creates a new throttled channel. // The rate is specified in messages per second. // The burst is specified in messages. -// -// If unsure, use burst equal to 60 times the rate. func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { return &ThrottledChannel{ channel: channel, From f356737746c771814590cb4b1f5786b64aec7908 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:28:23 +0100 Subject: [PATCH 017/111] refactor(p2p): move chan descs to p2p.channel_params and tune priorities --- go.mod | 2 +- go.sum | 4 +- internal/consensus/reactor.go | 65 +++------------- internal/consensus/reactor_test.go | 16 ++-- internal/evidence/reactor.go | 2 +- internal/p2p/channel_params.go | 120 ++++++++++++++++++++++------- internal/statesync/reactor.go | 36 +-------- node/setup.go | 8 +- 8 files changed, 119 insertions(+), 134 deletions(-) diff --git a/go.mod b/go.mod index 3b24448362..82e74f9a47 100644 --- a/go.mod +++ b/go.mod @@ -115,7 +115,6 @@ require ( go.opentelemetry.io/otel v1.8.0 // indirect go.opentelemetry.io/otel/trace v1.8.0 // indirect go.tmz.dev/musttag v0.7.2 // indirect - golang.org/x/time v0.3.0 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect ) @@ -309,4 +308,5 @@ require ( github.com/tendermint/go-amino v0.16.0 github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa + golang.org/x/time v0.5.0 ) diff --git a/go.sum b/go.sum index 0414e8cfb8..8f599f3700 100644 --- a/go.sum +++ b/go.sum @@ -1208,8 +1208,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index bd789bfeec..03acee4157 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -30,54 +30,7 @@ var ( _ p2p.Wrapper = (*tmcons.Message)(nil) ) -// GetChannelDescriptor produces an instance of a descriptor for this -// package's required channels. -func getChannelDescriptors() map[p2p.ChannelID]*p2p.ChannelDescriptor { - return map[p2p.ChannelID]*p2p.ChannelDescriptor{ - StateChannel: { - ID: StateChannel, - Priority: 8, - SendQueueCapacity: 64, - RecvMessageCapacity: maxMsgSize, - RecvBufferCapacity: 128, - Name: "state", - }, - DataChannel: { - // TODO: Consider a split between gossiping current block and catchup - // stuff. Once we gossip the whole block there is nothing left to send - // until next height or round. - ID: DataChannel, - Priority: 12, - SendQueueCapacity: 64, - RecvBufferCapacity: 512, - RecvMessageCapacity: maxMsgSize, - Name: "data", - }, - VoteChannel: { - ID: VoteChannel, - Priority: 10, - SendQueueCapacity: 64, - RecvBufferCapacity: 4096, - RecvMessageCapacity: maxMsgSize, - Name: "vote", - }, - VoteSetBitsChannel: { - ID: VoteSetBitsChannel, - Priority: 5, - SendQueueCapacity: 8, - RecvBufferCapacity: 128, - RecvMessageCapacity: maxMsgSize, - Name: "voteSet", - }, - } -} - const ( - StateChannel = p2p.ChannelID(0x20) - DataChannel = p2p.ChannelID(0x21) - VoteChannel = p2p.ChannelID(0x22) - VoteSetBitsChannel = p2p.ChannelID(0x23) - maxMsgSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. blocksToContributeToBecomeGoodPeer = 10000 @@ -173,23 +126,23 @@ func (r *Reactor) OnStart(ctx context.Context) error { var chBundle channelBundle var err error - chans := getChannelDescriptors() - chBundle.state, err = r.chCreator(ctx, chans[StateChannel]) + chans := p2p.ConsensusChannelDescriptors() + chBundle.state, err = r.chCreator(ctx, chans[p2p.ConsensusStateChannel]) if err != nil { return err } - chBundle.data, err = r.chCreator(ctx, chans[DataChannel]) + chBundle.data, err = r.chCreator(ctx, chans[p2p.ConsensusDataChannel]) if err != nil { return err } - chBundle.vote, err = r.chCreator(ctx, chans[VoteChannel]) + chBundle.vote, err = r.chCreator(ctx, chans[p2p.ConsensusVoteChannel]) if err != nil { return err } - chBundle.voteSet, err = r.chCreator(ctx, chans[VoteSetBitsChannel]) + chBundle.voteSet, err = r.chCreator(ctx, chans[p2p.VoteSetBitsChannel]) if err != nil { return err } @@ -780,13 +733,13 @@ func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, cha } switch envelope.ChannelID { - case StateChannel: + case p2p.ConsensusStateChannel: err = r.handleStateMessage(ctx, envelope, msg, chans.voteSet) - case DataChannel: + case p2p.ConsensusDataChannel: err = r.handleDataMessage(ctx, envelope, msg) - case VoteChannel: + case p2p.ConsensusVoteChannel: err = r.handleVoteMessage(ctx, envelope, msg) - case VoteSetBitsChannel: + case p2p.VoteSetBitsChannel: err = r.handleVoteSetBitsMessage(ctx, envelope, msg) default: err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", envelope.ChannelID, envelope) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 6b54be08dc..d48c8d1ba8 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -88,10 +88,10 @@ func setup( blocksyncSubs: make(map[types.NodeID]eventbus.Subscription, numNodes), } - rts.stateChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(StateChannel, size)) - rts.dataChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(DataChannel, size)) - rts.voteChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(VoteChannel, size)) - rts.voteSetBitsChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(VoteSetBitsChannel, size)) + rts.stateChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusStateChannel, size)) + rts.dataChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusDataChannel, size)) + rts.voteChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusVoteChannel, size)) + rts.voteSetBitsChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.VoteSetBitsChannel, size)) ctx, cancel := context.WithCancel(ctx) t.Cleanup(cancel) @@ -99,13 +99,13 @@ func setup( chCreator := func(nodeID types.NodeID) p2p.ChannelCreator { return func(ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { switch desc.ID { - case StateChannel: + case p2p.ConsensusStateChannel: return rts.stateChannels[nodeID], nil - case DataChannel: + case p2p.ConsensusDataChannel: return rts.dataChannels[nodeID], nil - case VoteChannel: + case p2p.ConsensusVoteChannel: return rts.voteChannels[nodeID], nil - case VoteSetBitsChannel: + case p2p.VoteSetBitsChannel: return rts.voteSetBitsChannels[nodeID], nil default: return nil, fmt.Errorf("invalid channel; %v", desc.ID) diff --git a/internal/evidence/reactor.go b/internal/evidence/reactor.go index ff8f6b6309..54dd75a810 100644 --- a/internal/evidence/reactor.go +++ b/internal/evidence/reactor.go @@ -27,7 +27,7 @@ const ( func GetChannelDescriptor() *p2p.ChannelDescriptor { return &p2p.ChannelDescriptor{ ID: EvidenceChannel, - Priority: 6, + Priority: 3, RecvMessageCapacity: maxMsgSize, RecvBufferCapacity: 32, Name: "evidence", diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 4e3341e507..dbbfc13468 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -16,6 +16,14 @@ import ( ) const ( + // + // Consensus channels + // + ConsensusStateChannel = ChannelID(0x20) + ConsensusDataChannel = ChannelID(0x21) + ConsensusVoteChannel = ChannelID(0x22) + VoteSetBitsChannel = ChannelID(0x23) + ErrorChannel = ChannelID(0x10) // BlockSyncChannel is a channelStore for blocks and status updates BlockSyncChannel = ChannelID(0x40) @@ -40,21 +48,24 @@ const ( lightBlockMsgSize = int(1e7) // ~1MB // paramMsgSize is the maximum size of a paramsResponseMessage paramMsgSize = int(1e5) // ~100kb + // consensusMsgSize is the maximum size of a consensus message + maxMsgSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. + ) // ChannelDescriptors returns a map of all supported descriptors func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { - return map[ChannelID]*ChannelDescriptor{ + channels := map[ChannelID]*ChannelDescriptor{ ErrorChannel: { ID: ErrorChannel, - Priority: 6, + Priority: 7, RecvMessageCapacity: blockMaxMsgSize, RecvBufferCapacity: 32, Name: "error", }, BlockSyncChannel: { ID: BlockSyncChannel, - Priority: 5, + Priority: 6, SendQueueCapacity: 1000, RecvBufferCapacity: 1024, RecvMessageCapacity: types.MaxBlockSizeBytes + @@ -64,13 +75,28 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, MempoolChannel: { ID: MempoolChannel, - Priority: 5, + Priority: 2, // 5 RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", - SendRateLimit: 5, - SendRateBurst: 20, + // SendRateLimit: 5, + // SendRateBurst: 20, }, + } + + for k, v := range StatesyncChannelDescriptors() { + channels[k] = v + } + for k, v := range ConsensusChannelDescriptors() { + channels[k] = v + } + + return channels +} + +// ChannelDescriptors returns a map of all supported descriptors +func StatesyncChannelDescriptors() map[ChannelID]*ChannelDescriptor { + return map[ChannelID]*ChannelDescriptor{ SnapshotChannel: { ID: SnapshotChannel, Priority: 6, @@ -81,7 +107,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, ChunkChannel: { ID: ChunkChannel, - Priority: 3, + Priority: 4, SendQueueCapacity: 4, RecvMessageCapacity: chunkMsgSize, RecvBufferCapacity: 128, @@ -89,7 +115,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, LightBlockChannel: { ID: LightBlockChannel, - Priority: 5, + Priority: 6, SendQueueCapacity: 10, RecvMessageCapacity: lightBlockMsgSize, RecvBufferCapacity: 128, @@ -97,7 +123,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, ParamsChannel: { ID: ParamsChannel, - Priority: 2, + Priority: 3, SendQueueCapacity: 10, RecvMessageCapacity: paramMsgSize, RecvBufferCapacity: 128, @@ -106,6 +132,48 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { } } +// GetChannelDescriptor produces an instance of a descriptor for this +// package's required channels. +func ConsensusChannelDescriptors() map[ChannelID]*ChannelDescriptor { + return map[ChannelID]*ChannelDescriptor{ + ConsensusStateChannel: { + ID: ConsensusStateChannel, + Priority: 18, + SendQueueCapacity: 64, + RecvMessageCapacity: maxMsgSize, + RecvBufferCapacity: 128, + Name: "state", + }, + ConsensusDataChannel: { + // TODO: Consider a split between gossiping current block and catchup + // stuff. Once we gossip the whole block there is nothing left to send + // until next height or round. + ID: ConsensusDataChannel, + Priority: 22, + SendQueueCapacity: 64, + RecvBufferCapacity: 512, + RecvMessageCapacity: maxMsgSize, + Name: "data", + }, + ConsensusVoteChannel: { + ID: ConsensusVoteChannel, + Priority: 20, + SendQueueCapacity: 64, + RecvBufferCapacity: 4096, + RecvMessageCapacity: maxMsgSize, + Name: "vote", + }, + VoteSetBitsChannel: { + ID: VoteSetBitsChannel, + Priority: 15, + SendQueueCapacity: 8, + RecvBufferCapacity: 128, + RecvMessageCapacity: maxMsgSize, + Name: "voteSet", + }, + } +} + // ResolveChannelID returns channel ID according to message type // currently only is supported blocksync channelID, the remaining channelIDs should be added as it will be necessary func ResolveChannelID(msg proto.Message) ChannelID { @@ -116,6 +184,7 @@ func ResolveChannelID(msg proto.Message) ChannelID { *blocksync.StatusRequest, *blocksync.StatusResponse: return BlockSyncChannel + // State sync case *statesync.ChunkRequest, *statesync.ChunkResponse: return ChunkChannel @@ -128,30 +197,27 @@ func ResolveChannelID(msg proto.Message) ChannelID { case *statesync.LightBlockRequest, *statesync.LightBlockResponse: return LightBlockChannel - case *consensus.NewRoundStep, - *consensus.NewValidBlock, + // Consensus messages + case *consensus.VoteSetBits: + return VoteSetBitsChannel + case *consensus.Vote, *consensus.Commit: + return ConsensusVoteChannel + case *consensus.ProposalPOL, *consensus.Proposal, - *consensus.ProposalPOL, - *consensus.BlockPart, - *consensus.Vote, + *consensus.BlockPart: + return ConsensusDataChannel + case *consensus.NewRoundStep, *consensus.NewValidBlock, + *consensus.HasCommit, *consensus.HasVote, - *consensus.VoteSetMaj23, - *consensus.VoteSetBits, - *consensus.Commit, - *consensus.HasCommit: - // TODO: enable these channels when they are implemented - //*statesync.SnapshotsRequest, - //*statesync.SnapshotsResponse, - //*statesync.ChunkRequest, - //*statesync.ChunkResponse, - //*statesync.LightBlockRequest, - //*statesync.LightBlockResponse, - //*statesync.ParamsRequest, - //*statesync.ParamsResponse: + *consensus.VoteSetMaj23: + return ConsensusStateChannel + // pex case *p2pproto.PexRequest, *p2pproto.PexResponse, *p2pproto.Echo: + // evidence case *prototypes.Evidence: + // mempool case *mempool.Txs: return MempoolChannel } diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index d1b64b329a..04bc62c01c 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -83,41 +83,7 @@ const ( ) func getChannelDescriptors() map[p2p.ChannelID]*p2p.ChannelDescriptor { - return map[p2p.ChannelID]*p2p.ChannelDescriptor{ - SnapshotChannel: { - ID: SnapshotChannel, - Priority: 6, - SendQueueCapacity: 10, - RecvMessageCapacity: snapshotMsgSize, - RecvBufferCapacity: 128, - Name: "snapshot", - }, - ChunkChannel: { - ID: ChunkChannel, - Priority: 3, - SendQueueCapacity: 4, - RecvMessageCapacity: chunkMsgSize, - RecvBufferCapacity: 128, - Name: "chunk", - }, - LightBlockChannel: { - ID: LightBlockChannel, - Priority: 5, - SendQueueCapacity: 10, - RecvMessageCapacity: lightBlockMsgSize, - RecvBufferCapacity: 128, - Name: "light-block", - }, - ParamsChannel: { - ID: ParamsChannel, - Priority: 2, - SendQueueCapacity: 10, - RecvMessageCapacity: paramMsgSize, - RecvBufferCapacity: 128, - Name: "params", - }, - } - + return p2p.StatesyncChannelDescriptors() } // Metricer defines an interface used for the rpc sync info query, please see statesync.metrics diff --git a/node/setup.go b/node/setup.go index f78d8f4f47..19f12513df 100644 --- a/node/setup.go +++ b/node/setup.go @@ -365,10 +365,10 @@ func makeNodeInfo( Version: version.TMCoreSemVer, Channels: []byte{ byte(p2p.BlockSyncChannel), - byte(consensus.StateChannel), - byte(consensus.DataChannel), - byte(consensus.VoteChannel), - byte(consensus.VoteSetBitsChannel), + byte(p2p.ConsensusStateChannel), + byte(p2p.ConsensusDataChannel), + byte(p2p.ConsensusVoteChannel), + byte(p2p.VoteSetBitsChannel), byte(p2p.MempoolChannel), byte(evidence.EvidenceChannel), byte(statesync.SnapshotChannel), From 6a142e77536204a339f1175ea86c226bdac2a9d4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:50:41 +0100 Subject: [PATCH 018/111] feat: detect non-deterministic ResponsePrepareProposal --- internal/consensus/state_add_vote.go | 2 +- internal/state/execution.go | 78 +++++++++++++++++++++------- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/internal/consensus/state_add_vote.go b/internal/consensus/state_add_vote.go index 781c692e86..54959ca1a8 100644 --- a/internal/consensus/state_add_vote.go +++ b/internal/consensus/state_add_vote.go @@ -395,7 +395,7 @@ func addVoteLoggingMw() AddVoteMiddlewareFunc { return added, err } votes := stateData.Votes.GetVoteSet(vote.Round, vote.Type) - logger.Trace("vote added", "data", votes) + logger.Debug("vote added", "data", votes, "nil", vote.BlockID.IsNil()) return added, err } } diff --git a/internal/state/execution.go b/internal/state/execution.go index e1d7bd220c..8ed407f1a2 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -5,6 +5,7 @@ package state import ( "bytes" "context" + "encoding/hex" "errors" "fmt" "time" @@ -103,6 +104,10 @@ type BlockExecutor struct { // cache the verification results over a single height cache map[string]struct{} + + // detect non-deterministic prepare proposal responses + lastRequestPrepareProposalHash []byte + lastResponsePrepareProposalHash []byte } // BlockExecWithLogger is an option function to set a logger to BlockExecutor @@ -209,26 +214,25 @@ func (blockExec *BlockExecutor) CreateProposalBlock( localLastCommit := buildLastCommitInfo(block, state.InitialHeight) version := block.Version.ToProto() - rpp, err := blockExec.appClient.PrepareProposal( - ctx, - &abci.RequestPrepareProposal{ - MaxTxBytes: maxDataBytes, - Txs: block.Txs.ToSliceOfBytes(), - LocalLastCommit: localLastCommit, - Misbehavior: block.Evidence.ToABCI(), - Height: block.Height, - Round: round, - Time: block.Time, - NextValidatorsHash: block.NextValidatorsHash, - - // Dash's fields - CoreChainLockedHeight: state.LastCoreChainLockedBlockHeight, - ProposerProTxHash: block.ProposerProTxHash, - ProposedAppVersion: block.ProposedAppVersion, - Version: &version, - QuorumHash: state.Validators.QuorumHash, - }, - ) + request := abci.RequestPrepareProposal{ + MaxTxBytes: maxDataBytes, + Txs: block.Txs.ToSliceOfBytes(), + LocalLastCommit: localLastCommit, + Misbehavior: block.Evidence.ToABCI(), + Height: block.Height, + Round: round, + Time: block.Time, + NextValidatorsHash: block.NextValidatorsHash, + + // Dash's fields + CoreChainLockedHeight: state.LastCoreChainLockedBlockHeight, + ProposerProTxHash: block.ProposerProTxHash, + ProposedAppVersion: block.ProposedAppVersion, + Version: &version, + QuorumHash: state.Validators.QuorumHash, + } + start := time.Now() + rpp, err := blockExec.appClient.PrepareProposal(ctx, &request) if err != nil { // The App MUST ensure that only valid (and hence 'processable') transactions // enter the mempool. Hence, at this point, we can't have any non-processable @@ -241,6 +245,23 @@ func (blockExec *BlockExecutor) CreateProposalBlock( return nil, CurrentRoundState{}, err } + // ensure that the proposal response is deterministic + reqHash, respHash := deterministicPrepareProposalHashes(&request, rpp) + blockExec.logger.Debug("PrepareProposal executed", + "request_hash", hex.EncodeToString(reqHash), + "response_hash", hex.EncodeToString(respHash), + "took", time.Since(start).String(), + ) + if bytes.Equal(blockExec.lastRequestPrepareProposalHash, reqHash) && + !bytes.Equal(blockExec.lastResponsePrepareProposalHash, respHash) { + blockExec.logger.Error("PrepareProposal response is non-deterministic", + "request_hash", hex.EncodeToString(reqHash), + "response_hash", hex.EncodeToString(respHash), + ) + // TODO: Remove panic after we find the root cause of the non-determinism + panic("PrepareProposal response is non-deterministic") + } + if err := rpp.Validate(); err != nil { return nil, CurrentRoundState{}, fmt.Errorf("PrepareProposal responded with invalid response: %w", err) } @@ -281,6 +302,23 @@ func (blockExec *BlockExecutor) CreateProposalBlock( return block, stateChanges, nil } +func deterministicPrepareProposalHashes(request *abci.RequestPrepareProposal, response *abci.ResponsePrepareProposal) (requestHash, responseHash []byte) { + deterministicReq := *request + deterministicReq.Round = 0 + + reqBytes, err := deterministicReq.Marshal() + if err != nil { + // should never happen, as we just marshaled it before sending + panic("failed to marshal RequestPrepareProposal: " + err.Error()) + } + respBytes, err := response.Marshal() + if err != nil { + // should never happen, as we just marshaled it before sending + panic("failed to marshal ResponsePrepareProposal: " + err.Error()) + } + return crypto.Checksum(reqBytes), crypto.Checksum(respBytes) +} + // ProcessProposal sends the proposal to ABCI App and verifies the response func (blockExec *BlockExecutor) ProcessProposal( ctx context.Context, From 1f0e9d9d2acdc0e04e8f85e9a68b7dd953cf0df2 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 15:10:29 +0100 Subject: [PATCH 019/111] chore: decrease log size --- internal/consensus/state_prevoter.go | 6 ++++++ internal/consensus/state_proposaler.go | 2 +- internal/state/execution.go | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/consensus/state_prevoter.go b/internal/consensus/state_prevoter.go index fdc7913603..c2149af8b4 100644 --- a/internal/consensus/state_prevoter.go +++ b/internal/consensus/state_prevoter.go @@ -102,6 +102,7 @@ func (p *prevoter) checkProposalBlock(rs cstypes.RoundState) bool { or the proposal matches our locked block, we prevote the proposal. */ if rs.Proposal.POLRound != -1 { + p.logger.Trace("prevote step: proposal has POLRound; no decision", "POLRound", rs.Proposal.POLRound) return false } if rs.LockedRound == -1 { @@ -112,6 +113,11 @@ func (p *prevoter) checkProposalBlock(rs cstypes.RoundState) bool { p.logger.Debug("prevote step: ProposalBlock is valid and matches our locked block; prevoting the proposal") return true } + + p.logger.Debug("prevote step: this block is not locked", + "locked_block_hash", rs.LockedBlock.Hash(), + "proposal_block_hash", rs.ProposalBlock.Hash()) + return false } diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index ff0ea61400..43d1da8ebe 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -177,7 +177,7 @@ func (p *Proposaler) checkValidBlock(rs *cstypes.RoundState) bool { "height", rs.Height, "round", rs.ValidRound, "received", rs.ValidBlockRecvTime, - "block", rs.ValidBlock) + "block", rs.ValidBlock.Hash()) return false } return true diff --git a/internal/state/execution.go b/internal/state/execution.go index 8ed407f1a2..c0d1e3b297 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -250,6 +250,8 @@ func (blockExec *BlockExecutor) CreateProposalBlock( blockExec.logger.Debug("PrepareProposal executed", "request_hash", hex.EncodeToString(reqHash), "response_hash", hex.EncodeToString(respHash), + "height", height, + "round", round, "took", time.Since(start).String(), ) if bytes.Equal(blockExec.lastRequestPrepareProposalHash, reqHash) && From 5b2a3938ded5b6f362b443e37c21dfb9bfcbc9e4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:35:54 +0100 Subject: [PATCH 020/111] chore: more debug --- internal/consensus/state_prevoter.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/consensus/state_prevoter.go b/internal/consensus/state_prevoter.go index c2149af8b4..800a01cf49 100644 --- a/internal/consensus/state_prevoter.go +++ b/internal/consensus/state_prevoter.go @@ -142,9 +142,13 @@ func (p *prevoter) checkPrevoteMaj23(rs cstypes.RoundState) bool { */ blockID, ok := rs.Votes.Prevotes(rs.Proposal.POLRound).TwoThirdsMajority() if !ok { + p.logger.Trace("prevote step: no 2/3 majority for proposal block", "POLRound", rs.Proposal.POLRound) return false } if !rs.ProposalBlock.HashesTo(blockID.Hash) { + p.logger.Trace("prevote step: proposal block does not match 2/3 majority", "POLRound", rs.Proposal.POLRound, + "proposal_block_hash", rs.ProposalBlock.Hash(), + "majority_block_hash", blockID.Hash) return false } if rs.Proposal.POLRound < 0 { @@ -161,9 +165,14 @@ func (p *prevoter) checkPrevoteMaj23(rs cstypes.RoundState) bool { return true } if rs.ProposalBlock.HashesTo(rs.LockedBlock.Hash()) { - p.logger.Debug("prevote step: ProposalBlock is valid and matches our locked block; prevoting the proposal") + p.logger.Debug("prevote step: ProposalBlock is valid and matches our locked block", + "outcome", "prevoting the proposal") return true } + p.logger.Debug("prevote step: ProposalBlock does not match our locked block", + "proposal_block_hash", rs.ProposalBlock.Hash(), + "majority_block_hash", blockID.Hash) + return false } From 6be0eaa64547e3d879405d845c79fa567c7d5776 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:40:34 +0100 Subject: [PATCH 021/111] fix(consensus): propose locked block when it is available --- internal/consensus/state_proposaler.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 43d1da8ebe..4cb6648a1b 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -86,12 +86,22 @@ func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cst } // Create creates, sings and sends a created proposal to the queue +// +// We prioritize LockedBlock. If it's not set, then we use ValidBlock. // To create a proposal is used RoundState.ValidBlock if it isn't nil and valid, otherwise create a new one func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs *cstypes.RoundState) error { - // If there is valid block, choose that. - block, blockParts := rs.ValidBlock, rs.ValidBlockParts - // Create on block - if !p.checkValidBlock(rs) { + create := false + // If we are locked on some block, propose that. + // We don't check the timestamp in this case, as the block is already valid + block, blockParts := rs.LockedBlock, rs.LockedBlockParts + // when no locked block, use valid block + if block == nil || blockParts == nil { + block, blockParts = rs.ValidBlock, rs.ValidBlockParts + create = !p.checkValidBlock(rs) + } + + // Create a block + if create { var err error start := time.Now() block, blockParts, err = p.createProposalBlock(ctx, round, rs) From f75ae58b86629e3ae18e9a70bf99c536a5db1ff4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 09:27:52 +0100 Subject: [PATCH 022/111] chore: improve logs --- internal/consensus/state.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index edf21edf12..3bac2e6037 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -723,18 +723,18 @@ func (cs *State) handleTimeout( ti timeoutInfo, stateData *StateData, ) { - cs.logger.Trace("received tock", "timeout", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) // timeouts must be for current height, round, step if ti.Height != stateData.Height || ti.Round < stateData.Round || (ti.Round == stateData.Round && ti.Step < stateData.Step) { - cs.logger.Debug("ignoring tock because we are ahead", - "height", stateData.Height, - "round", stateData.Round, - "step", stateData.Step.String(), + cs.logger.Trace("ignoring tock because we are ahead", + "timeout", ti.Duration, "tock_height", ti.Height, "tock_round", ti.Round, "tock_step", ti.Step, + "height", stateData.Height, "round", stateData.Round, "step", stateData.Step.String(), ) return } + cs.logger.Trace("received tock", "timeout", ti.Duration, "height", ti.Height, "round", ti.Round, "step", ti.Step) + // the timeout will now cause a state transition cs.mtx.Lock() defer cs.mtx.Unlock() From 51317c5e9da5e4896413dcd286ad9c90055d0e97 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 10:46:43 +0100 Subject: [PATCH 023/111] fix(consensus): ValidBlock must be equal LockedBlock https://arxiv.org/abs/1807.04938 --- internal/consensus/state_data.go | 31 +++++++++++++++++---- internal/consensus/state_enter_precommit.go | 6 ++-- internal/consensus/state_proposaler.go | 19 ++++--------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/internal/consensus/state_data.go b/internal/consensus/state_data.go index 0262a3a89c..f2782742da 100644 --- a/internal/consensus/state_data.go +++ b/internal/consensus/state_data.go @@ -320,10 +320,30 @@ func (s *StateData) proposalIsTimely() bool { } func (s *StateData) updateValidBlock() { + // we only update valid block if it's not set already; otherwise we might overwrite the recv time + if !s.ValidBlock.HashesTo(s.ProposalBlock.Hash()) { + s.ValidBlock = s.ProposalBlock + s.ValidBlockRecvTime = s.ProposalReceiveTime + s.ValidBlockParts = s.ProposalBlockParts + } else { + s.logger.Debug("valid block is already up to date, not updating", + "proposal_block", s.ProposalBlock.Hash(), + "proposal_round", s.Round, + "valid_block", s.ValidBlock.Hash(), + "valid_block_round", s.ValidRound, + ) + } + s.ValidRound = s.Round - s.ValidBlock = s.ProposalBlock - s.ValidBlockRecvTime = s.ProposalReceiveTime - s.ValidBlockParts = s.ProposalBlockParts +} + +// Locks the proposed block. Note that it also updates ValidBlock. +func (s *StateData) updateLockedBlock() { + s.LockedRound = s.Round + s.LockedBlock = s.ProposalBlock + s.LockedBlockParts = s.ProposalBlockParts + + s.updateValidBlock() } func (s *StateData) verifyCommit(commit *types.Commit, peerID types.NodeID, ignoreProposalBlock bool) (verified bool, err error) { @@ -458,10 +478,11 @@ func (s *StateData) isValidForPrevote() error { if !s.Proposal.Timestamp.Equal(s.ProposalBlock.Header.Time) { return errPrevoteTimestampNotEqual } - //TODO: Remove this temporary fix when the complete solution is ready. See #8739 - if !s.replayMode && s.Proposal.POLRound == -1 && s.LockedRound == -1 && !s.proposalIsTimely() { + + if !s.replayMode && !s.proposalIsTimely() { return errPrevoteProposalNotTimely } + // Validate proposal core chain lock err := sm.ValidateBlockChainLock(s.state, s.ProposalBlock) if err != nil { diff --git a/internal/consensus/state_enter_precommit.go b/internal/consensus/state_enter_precommit.go index 41e53b1075..b827e4c729 100644 --- a/internal/consensus/state_enter_precommit.go +++ b/internal/consensus/state_enter_precommit.go @@ -134,12 +134,12 @@ func (c *EnterPrecommitAction) Execute(ctx context.Context, stateEvent StateEven // Validate the block. c.blockExec.mustValidate(ctx, stateData) - stateData.LockedRound = round - stateData.LockedBlock = stateData.ProposalBlock - stateData.LockedBlockParts = stateData.ProposalBlockParts + stateData.updateLockedBlock() c.eventPublisher.PublishLockEvent(stateData.RoundState) c.voteSigner.signAddVote(ctx, stateData, tmproto.PrecommitType, blockID) + + stateData.updateValidBlock() return nil } diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 4cb6648a1b..1f71bf68e4 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -87,21 +87,12 @@ func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cst // Create creates, sings and sends a created proposal to the queue // -// We prioritize LockedBlock. If it's not set, then we use ValidBlock. // To create a proposal is used RoundState.ValidBlock if it isn't nil and valid, otherwise create a new one func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs *cstypes.RoundState) error { - create := false - // If we are locked on some block, propose that. - // We don't check the timestamp in this case, as the block is already valid - block, blockParts := rs.LockedBlock, rs.LockedBlockParts - // when no locked block, use valid block - if block == nil || blockParts == nil { - block, blockParts = rs.ValidBlock, rs.ValidBlockParts - create = !p.checkValidBlock(rs) - } - - // Create a block - if create { + // Create a block. + // Note that we only create a block if we don't have a valid block already. + block, blockParts := rs.ValidBlock, rs.ValidBlockParts + if !p.checkValidBlock(rs) { var err error start := time.Now() block, blockParts, err = p.createProposalBlock(ctx, round, rs) @@ -183,7 +174,7 @@ func (p *Proposaler) checkValidBlock(rs *cstypes.RoundState) bool { } if !rs.ValidBlock.IsTimely(rs.ValidBlockRecvTime, sp, rs.ValidRound) { p.logger.Error( - "proposal block is outdated", + "proposal block is not timely", "height", rs.Height, "round", rs.ValidRound, "received", rs.ValidBlockRecvTime, From 07beb3f281078bf2079f91a09aff8ce478dce06f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 11:54:53 +0100 Subject: [PATCH 024/111] fix(consensus): publish valid block event if it's updated --- internal/consensus/state_data.go | 28 ++++++++++++--------- internal/consensus/state_enter_precommit.go | 5 +++- internal/consensus/state_prevoter.go | 6 ++++- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/internal/consensus/state_data.go b/internal/consensus/state_data.go index f2782742da..ca761b230a 100644 --- a/internal/consensus/state_data.go +++ b/internal/consensus/state_data.go @@ -319,31 +319,35 @@ func (s *StateData) proposalIsTimely() bool { return s.Proposal.IsTimely(s.ProposalReceiveTime, sp, s.Round) } -func (s *StateData) updateValidBlock() { +// Updates ValidBlock to current proposal. +// Returns true if the block was updated. +func (s *StateData) updateValidBlock() bool { + s.ValidRound = s.Round // we only update valid block if it's not set already; otherwise we might overwrite the recv time if !s.ValidBlock.HashesTo(s.ProposalBlock.Hash()) { s.ValidBlock = s.ProposalBlock s.ValidBlockRecvTime = s.ProposalReceiveTime s.ValidBlockParts = s.ProposalBlockParts - } else { - s.logger.Debug("valid block is already up to date, not updating", - "proposal_block", s.ProposalBlock.Hash(), - "proposal_round", s.Round, - "valid_block", s.ValidBlock.Hash(), - "valid_block_round", s.ValidRound, - ) + + return true } - s.ValidRound = s.Round + s.logger.Debug("valid block is already up to date, not updating", + "proposal_block", s.ProposalBlock.Hash(), + "proposal_round", s.Round, + "valid_block", s.ValidBlock.Hash(), + "valid_block_round", s.ValidRound, + ) + + return false } -// Locks the proposed block. Note that it also updates ValidBlock. +// Locks the proposed block. +// You might also need to call updateValidBlock(). func (s *StateData) updateLockedBlock() { s.LockedRound = s.Round s.LockedBlock = s.ProposalBlock s.LockedBlockParts = s.ProposalBlockParts - - s.updateValidBlock() } func (s *StateData) verifyCommit(commit *types.Commit, peerID types.NodeID, ignoreProposalBlock bool) (verified bool, err error) { diff --git a/internal/consensus/state_enter_precommit.go b/internal/consensus/state_enter_precommit.go index b827e4c729..ce0981af58 100644 --- a/internal/consensus/state_enter_precommit.go +++ b/internal/consensus/state_enter_precommit.go @@ -139,7 +139,10 @@ func (c *EnterPrecommitAction) Execute(ctx context.Context, stateEvent StateEven c.eventPublisher.PublishLockEvent(stateData.RoundState) c.voteSigner.signAddVote(ctx, stateData, tmproto.PrecommitType, blockID) - stateData.updateValidBlock() + if stateData.updateValidBlock() { + c.eventPublisher.PublishValidBlockEvent(stateData.RoundState) + } + return nil } diff --git a/internal/consensus/state_prevoter.go b/internal/consensus/state_prevoter.go index 800a01cf49..c562b3a3d8 100644 --- a/internal/consensus/state_prevoter.go +++ b/internal/consensus/state_prevoter.go @@ -39,7 +39,11 @@ func (p *prevoter) Do(ctx context.Context, stateData *StateData) error { err := stateData.isValidForPrevote() if err != nil { keyVals := append(prevoteKeyVals(stateData), "error", err) - p.logger.Error("prevote is invalid", keyVals...) + + if !errors.Is(err, errPrevoteProposalBlockNil) { + p.logger.Error("prevote is invalid", keyVals...) + } + p.logger.Debug("we don't have a valid block for this round, prevoting nil", keyVals...) p.signAndAddNilVote(ctx, stateData) return nil } From cc457a6a4b50bb395883b5b414618967eb8de0a6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:50:04 +0100 Subject: [PATCH 025/111] chore: improve log readability --- internal/state/current_round_state.go | 25 +++++++++++++++++++++++++ types/block.go | 11 +++++++++++ types/core_chainlock.go | 11 +++++++++++ types/tx.go | 15 +++++++++++++++ 4 files changed, 62 insertions(+) diff --git a/internal/state/current_round_state.go b/internal/state/current_round_state.go index b88ed95a59..c2cb72e18b 100644 --- a/internal/state/current_round_state.go +++ b/internal/state/current_round_state.go @@ -8,6 +8,7 @@ import ( tmbytes "github.com/dashpay/tenderdash/libs/bytes" tmtypes "github.com/dashpay/tenderdash/proto/tendermint/types" "github.com/dashpay/tenderdash/types" + "github.com/rs/zerolog" ) const ( @@ -236,6 +237,30 @@ func (rp RoundParams) ToProcessProposal() *abci.ResponseProcessProposal { } } +func (rp *RoundParams) MarshalZerologObject(e *zerolog.Event) { + if rp == nil { + e.Bool("nil", true) + return + } + + e.Str("app_hash", rp.AppHash.ShortString()) + + e.Int("tx_results_len", len(rp.TxResults)) + for i, txResult := range rp.TxResults { + e.Interface(fmt.Sprintf("tx_result[%d]", i), txResult) + if i >= 20 { + e.Str("tx_result[...]", "...") + break + } + } + + e.Interface("consensus_param_updates", rp.ConsensusParamUpdates) + e.Interface("validator_set_update", rp.ValidatorSetUpdate) + e.Interface("core_chain_lock", rp.CoreChainLock) + e.Str("source", rp.Source) + e.Int32("round", rp.Round) +} + // RoundParamsFromPrepareProposal creates RoundParams from ResponsePrepareProposal func RoundParamsFromPrepareProposal(resp *abci.ResponsePrepareProposal, round int32) (RoundParams, error) { rp := RoundParams{ diff --git a/types/block.go b/types/block.go index df65dc7be3..940e455686 100644 --- a/types/block.go +++ b/types/block.go @@ -1034,6 +1034,17 @@ func (data *Data) ToProto() tmproto.Data { return *tp } +func (data *Data) MarshalZerologObject(e *zerolog.Event) { + if data == nil { + e.Bool("nil", true) + return + } + + e.Str("hash", data.Hash().ShortString()) + e.Int("num_txs", len(data.Txs)) + e.Array("txs", &data.Txs) +} + // DataFromProto takes a protobuf representation of Data & // returns the native type. func DataFromProto(dp *tmproto.Data) (Data, error) { diff --git a/types/core_chainlock.go b/types/core_chainlock.go index b6c9d3b1c2..07643796c9 100644 --- a/types/core_chainlock.go +++ b/types/core_chainlock.go @@ -8,6 +8,7 @@ import ( "github.com/dashpay/tenderdash/crypto" tmproto "github.com/dashpay/tenderdash/proto/tendermint/types" + "github.com/rs/zerolog" ) type CoreChainLock struct { @@ -107,6 +108,16 @@ func (cl *CoreChainLock) IsZero() bool { return cl == nil || (len(cl.CoreBlockHash) == 0 && len(cl.Signature) == 0 && cl.CoreBlockHeight == 0) } +func (cl *CoreChainLock) MarshalZerologObject(e *zerolog.Event) { + if cl == nil { + e.Bool("nil", true) + return + } + e.Hex("core_block_hash", cl.CoreBlockHash) + e.Uint32("core_block_height", cl.CoreBlockHeight) + e.Hex("signature", cl.Signature) +} + // FromProto sets a protobuf Header to the given pointer. // It returns an error if the chain lock is invalid. func CoreChainLockFromProto(clp *tmproto.CoreChainLock) (*CoreChainLock, error) { diff --git a/types/tx.go b/types/tx.go index 9080ad564b..62aa61180a 100644 --- a/types/tx.go +++ b/types/tx.go @@ -12,6 +12,7 @@ import ( "github.com/dashpay/tenderdash/crypto/merkle" tmbytes "github.com/dashpay/tenderdash/libs/bytes" tmproto "github.com/dashpay/tenderdash/proto/tendermint/types" + "github.com/rs/zerolog" ) // Tx is an arbitrary byte array. @@ -103,6 +104,20 @@ func (txs Txs) ToSliceOfBytes() [][]byte { return txBzs } +func (txs *Txs) MarshalZerologArray(e *zerolog.Array) { + if txs == nil { + return + } + + for i, tx := range *txs { + e.Str(tx.Hash().ShortString()) + if i >= 20 { + e.Str("...") + return + } + } +} + // TxRecordSet contains indexes into an underlying set of transactions. // These indexes are useful for validating and working with a list of TxRecords // from the PrepareProposal response. From b0224ef69f72be6f0f3a620bf5fdecdc3cddfd5e Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:52:09 +0100 Subject: [PATCH 026/111] chore: log num txs of complete proposal block --- internal/consensus/state_add_prop_block.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/consensus/state_add_prop_block.go b/internal/consensus/state_add_prop_block.go index bf2b5d4376..f75303ad78 100644 --- a/internal/consensus/state_add_prop_block.go +++ b/internal/consensus/state_add_prop_block.go @@ -179,6 +179,7 @@ func (c *AddProposalBlockPartAction) addProposalBlockPart( "proposal_height", stateData.ProposalBlock.Height, "hash", stateData.ProposalBlock.Hash(), "round_height", stateData.RoundState.GetHeight(), + "num_txs", len(stateData.ProposalBlock.Txs), ) c.eventPublisher.PublishCompleteProposalEvent(stateData.CompleteProposalEvent()) From 2109237f323ad38227b63e1efac100ee2af25b3a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:04:27 +0100 Subject: [PATCH 027/111] chore(mempool): log when txs are processed --- internal/mempool/p2p_msg_handler.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index c93fc6177d..f449be5f11 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "time" "github.com/dashpay/tenderdash/internal/p2p" "github.com/dashpay/tenderdash/internal/p2p/client" @@ -52,6 +53,10 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, SenderID: h.ids.GetForPeer(envelope.From), SenderNodeID: envelope.From, } + // some stats for logging + start := time.Now() + known := 0 + failed := 0 for _, tx := range protoTxs { if err := h.checker.CheckTx(ctx, tx, nil, txInfo); err != nil { if errors.Is(err, types.ErrTxInCache) { @@ -61,6 +66,7 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, // got. Gossip should be // smarter, but it's not a // problem. + known++ continue } if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { @@ -71,10 +77,16 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, // message if we are shutting down. return err } + failed++ logger.Error("checktx failed for tx", "tx", fmt.Sprintf("%X", types.Tx(tx).Hash()), "error", err) } } + logger.Debug("processed txs from peer", "took", time.Since(start).String(), + "num_txs", len(protoTxs), + "already_known", known, + "failed", failed, + ) return nil } From 80f3c9c19f2e3eaa63d2930aba1fc2dfcc94d568 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:24:59 +0100 Subject: [PATCH 028/111] chore(mempool): add timeout of checktx for p2p messages --- internal/mempool/p2p_msg_handler.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index f449be5f11..56ed840c79 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -13,6 +13,11 @@ import ( "github.com/dashpay/tenderdash/types" ) +const ( + // max time to wait for a response from CheckTx + p2pCheckTxTimeout = 5 * time.Second +) + type ( mempoolP2PMessageHandler struct { logger log.Logger @@ -58,6 +63,9 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known := 0 failed := 0 for _, tx := range protoTxs { + // TODO: Move to abciclient, define configuration settings + ctx, cancel := context.WithTimeout(ctx, p2pCheckTxTimeout) + defer cancel() if err := h.checker.CheckTx(ctx, tx, nil, txInfo); err != nil { if errors.Is(err, types.ErrTxInCache) { // if the tx is in the cache, From 66186bdf2144ae83fcd694c088e8691d7c20e29b Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:34:28 +0100 Subject: [PATCH 029/111] chore(p2p): remove unneeded stopMtx from MConnection --- internal/consensus/block_executor.go | 2 +- internal/p2p/conn/connection.go | 8 +------- internal/p2p/peermanager.go | 1 + 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/internal/consensus/block_executor.go b/internal/consensus/block_executor.go index c2beffcb46..defdb5c606 100644 --- a/internal/consensus/block_executor.go +++ b/internal/consensus/block_executor.go @@ -65,7 +65,7 @@ func (c *blockExecutor) ensureProcess(ctx context.Context, rs *cstypes.RoundStat block := rs.ProposalBlock crs := rs.CurrentRoundState if crs.Params.Source != sm.ProcessProposalSource || !crs.MatchesBlock(block.Header, round) { - c.logger.Debug("CurrentRoundState is outdated, executing ProcessProposal", "crs", crs) + c.logger.Trace("CurrentRoundState is outdated, executing ProcessProposal", "crs", crs) uncommittedState, err := c.blockExec.ProcessProposal(ctx, block, round, c.committedState, true) if err != nil { return fmt.Errorf("ProcessProposal abci method: %w", err) diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index d09cd8baeb..2311632bf7 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -101,9 +101,6 @@ type MConnection struct { // Closing quitRecvRouting will cause the recvRouting to eventually quit. quitRecvRoutine chan struct{} - // used to ensure FlushStop and OnStop - // are safe to call concurrently. - stopMtx sync.Mutex stopSignal <-chan struct{} cancel context.CancelFunc @@ -232,11 +229,8 @@ func (c *MConnection) getLastMessageAt() time.Time { // stopServices stops the BaseService and timers and closes the quitSendRoutine. // if the quitSendRoutine was already closed, it returns true, otherwise it returns false. -// It uses the stopMtx to ensure only one of FlushStop and OnStop can do this at a time. +// It doesn't lock, as we rely on the caller (eg. BaseService) locking func (c *MConnection) stopServices() (alreadyStopped bool) { - c.stopMtx.Lock() - defer c.stopMtx.Unlock() - select { case <-c.quitSendRoutine: // already quit diff --git a/internal/p2p/peermanager.go b/internal/p2p/peermanager.go index e38b7751b1..d9ee365ec1 100644 --- a/internal/p2p/peermanager.go +++ b/internal/p2p/peermanager.go @@ -980,6 +980,7 @@ func (m *PeerManager) Disconnected(ctx context.Context, peerID types.NodeID) { } m.dialWaker.Wake() + m.logger.Debug("peer disconnected", "peer", peerID, "ready", ready) } // Errored reports a peer error, causing the peer to be evicted if it's From 23cb8c67acbe1ec4164b85e9ce944f9ea500e5c5 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:30:20 +0100 Subject: [PATCH 030/111] chore(p2p): further debugging --- internal/p2p/router.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 2db3ccef97..5a7b493534 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -703,14 +703,18 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec sendQueue := r.getOrMakeQueue(peerID, channels) defer func() { + r.logger.Debug("routePeer cleanup: terminated peer", "peer", peerID) r.peerMtx.Lock() delete(r.peerQueues, peerID) delete(r.peerChannels, peerID) r.peerMtx.Unlock() + r.logger.Debug("routePeer cleanup: deleted peer queues", "peer", peerID) sendQueue.close() + r.logger.Debug("routePeer cleanup: closed send queue", "peer", peerID) r.peerManager.Disconnected(ctx, peerID) + r.logger.Debug("routePeer cleanup: peer marked as disconnected", "peer", peerID) r.metrics.PeersConnected.Add(-1) }() From c39ef2c1da0084c3406f2921c2c639892c553665 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 15 Jan 2024 17:53:50 +0100 Subject: [PATCH 031/111] revert: remove checktx timeout as it needs more careful error handling --- internal/mempool/p2p_msg_handler.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index 56ed840c79..f449be5f11 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -13,11 +13,6 @@ import ( "github.com/dashpay/tenderdash/types" ) -const ( - // max time to wait for a response from CheckTx - p2pCheckTxTimeout = 5 * time.Second -) - type ( mempoolP2PMessageHandler struct { logger log.Logger @@ -63,9 +58,6 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known := 0 failed := 0 for _, tx := range protoTxs { - // TODO: Move to abciclient, define configuration settings - ctx, cancel := context.WithTimeout(ctx, p2pCheckTxTimeout) - defer cancel() if err := h.checker.CheckTx(ctx, tx, nil, txInfo); err != nil { if errors.Is(err, types.ErrTxInCache) { // if the tx is in the cache, From 052af3823ab872b10503cec51b0a7323cf6c70e5 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:07:29 +0100 Subject: [PATCH 032/111] feat(abciclient): expire checktx abci calls on messages from p2p --- abci/client/client.go | 7 +++-- abci/client/socket_client.go | 48 +++++++++++++++++++++-------- internal/mempool/p2p_msg_handler.go | 17 +++++----- internal/p2p/client/client.go | 9 ++++-- 4 files changed, 57 insertions(+), 24 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index 19c6a7bf61..5f74015272 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -51,7 +51,9 @@ type requestAndResponse struct { *types.Request *types.Response - mtx sync.Mutex + mtx sync.Mutex + // context for the request; we check if it's not expired before sending + ctx context.Context signal chan struct{} } @@ -90,10 +92,11 @@ func (reqResp *requestAndResponse) priority() (priority int8) { return priority } -func makeReqRes(req *types.Request) *requestAndResponse { +func makeReqRes(ctx context.Context, req *types.Request) *requestAndResponse { return &requestAndResponse{ Request: req, Response: nil, + ctx: ctx, signal: make(chan struct{}), } } diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index a96fe7977d..7aa7deedf2 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -14,11 +14,17 @@ import ( sync "github.com/sasha-s/go-deadlock" "github.com/dashpay/tenderdash/abci/types" + tmsync "github.com/dashpay/tenderdash/internal/libs/sync" "github.com/dashpay/tenderdash/libs/log" tmnet "github.com/dashpay/tenderdash/libs/net" "github.com/dashpay/tenderdash/libs/service" ) +const ( + // Maximum number of requests stored in the request queue + RequestQueueSize = 1000 +) + // This is goroutine-safe, but users should beware that the application in // general is not meant to be interfaced with concurrent callers. type socketClient struct { @@ -31,8 +37,8 @@ type socketClient struct { // Requests queue reqQueue *prque.Prque[int8, *requestAndResponse] - // Signal emitted when new request is added to the queue. - reqSignal chan struct{} + // Wake up sender when new request is added to the queue. + reqWaker *tmsync.Waker mtx sync.Mutex err error @@ -52,9 +58,9 @@ func NewSocketClient(logger log.Logger, addr string, mustConnect bool, metrics * } cli := &socketClient{ - logger: logger, - reqQueue: prque.New[int8, *requestAndResponse](nil), - reqSignal: make(chan struct{}), + logger: logger, + reqQueue: prque.New[int8, *requestAndResponse](nil), + reqWaker: tmsync.NewWaker(), mustConnect: mustConnect, addr: addr, @@ -141,14 +147,29 @@ func (cli *socketClient) dequeue() *requestAndResponse { return reqres } +func (cli *socketClient) reqQueueEmpty() bool { + cli.mtx.Lock() + defer cli.mtx.Unlock() + return cli.reqQueue.Empty() +} + func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer) { bw := bufio.NewWriter(conn) for { + // wait for new message to arrive select { case <-ctx.Done(): return - case <-cli.reqSignal: + case <-cli.reqWaker.Sleep(): + } + + for !cli.reqQueueEmpty() { reqres := cli.dequeue() + if err := reqres.ctx.Err(); err != nil { + // request expired, skip it + cli.logger.Debug("abci.socketClient request expired, skipping", "req", reqres.Request.Value, "error", err) + continue + } // N.B. We must track request before sending it out, otherwise the // server may reply before we do it, and the receiver will fail for an @@ -236,15 +257,13 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty return nil, errors.New("client has stopped") } - reqres := makeReqRes(req) + reqres := makeReqRes(ctx, req) cli.enqueue(reqres) - select { - case cli.reqSignal <- struct{}{}: - case <-ctx.Done(): - return nil, fmt.Errorf("can't queue req: %w", ctx.Err()) - } + // Asynchronously wake up the sender. + cli.reqWaker.Wake() + // wait for response for our request select { case <-reqres.signal: if err := cli.Error(); err != nil { @@ -263,6 +282,11 @@ func (cli *socketClient) drainQueue() { cli.mtx.Lock() defer cli.mtx.Unlock() + if err := cli.reqWaker.Close(); err != nil { + cli.logger.Debug("abci.socketClient failed to close waker", "err", err) + } + cli.reqWaker = tmsync.NewWaker() + cli.reqQueue.Reset() // mark all in-flight messages as resolved (they will get cli.Error()) for req := cli.reqSent.Front(); req != nil; req = req.Next() { diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index f449be5f11..1da679fedf 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -58,7 +58,10 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known := 0 failed := 0 for _, tx := range protoTxs { - if err := h.checker.CheckTx(ctx, tx, nil, txInfo); err != nil { + subCtx, subCtxCancel := context.WithTimeout(ctx, 5*time.Second) + defer subCtxCancel() + + if err := h.checker.CheckTx(subCtx, tx, nil, txInfo); err != nil { if errors.Is(err, types.ErrTxInCache) { // if the tx is in the cache, // then we've been gossiped a @@ -69,13 +72,11 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known++ continue } - if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) { - // Do not propagate context - // cancellation errors, but do - // not continue to check - // transactions from this - // message if we are shutting down. - return err + + // In case of ctx cancelation, we return error as we are most likely shutting down. + // Otherwise we just reject the tx. + if errCtx := ctx.Err(); errCtx != nil { + return errCtx } failed++ logger.Error("checktx failed for tx", diff --git a/internal/p2p/client/client.go b/internal/p2p/client/client.go index fffc4a36df..3ea4009090 100644 --- a/internal/p2p/client/client.go +++ b/internal/p2p/client/client.go @@ -224,10 +224,15 @@ func (c *Client) GetSyncStatus(ctx context.Context) error { } // SendTxs sends a transaction to the peer -func (c *Client) SendTxs(ctx context.Context, peerID types.NodeID, tx types.Tx) error { +func (c *Client) SendTxs(ctx context.Context, peerID types.NodeID, tx ...types.Tx) error { + txs := make([][]byte, len(tx)) + for i := 0; i < len(tx); i++ { + txs[i] = tx[i] + } + return c.Send(ctx, p2p.Envelope{ To: peerID, - Message: &protomem.Txs{Txs: [][]byte{tx}}, + Message: &protomem.Txs{Txs: txs}, }) } From ed4c661df5aac3fff8c5d6f3ed47c01f10eab009 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:31:20 +0100 Subject: [PATCH 033/111] feat: socket client prio queue improved --- abci/client/socket_client.go | 39 ++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 7aa7deedf2..a21e905e53 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "net" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common/prque" @@ -45,6 +46,9 @@ type socketClient struct { reqSent *list.List // list of requests sent, waiting for response metrics *Metrics + + // if true, send blocks until response is received + blocking atomic.Bool } var _ Client = (*socketClient)(nil) @@ -126,6 +130,12 @@ func (cli *socketClient) Error() error { return cli.err } +// setBlocking sets the blocking mode of the client. +// Used in tests. +func (cli *socketClient) setBlocking(blocking bool) { + cli.blocking.Store(blocking) +} + // Add the request to the pending messages queue. // // Note that you still need to wake up sendRequestsRoutine writing to `cli.reqSignal` @@ -150,9 +160,24 @@ func (cli *socketClient) dequeue() *requestAndResponse { func (cli *socketClient) reqQueueEmpty() bool { cli.mtx.Lock() defer cli.mtx.Unlock() + return cli.reqQueue.Empty() } +func (cli *socketClient) reqWake() { + cli.mtx.Lock() + defer cli.mtx.Unlock() + + cli.reqWaker.Wake() +} + +func (cli *socketClient) reqSleep() <-chan struct{} { + cli.mtx.Lock() + defer cli.mtx.Unlock() + + return cli.reqWaker.Sleep() +} + func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer) { bw := bufio.NewWriter(conn) for { @@ -160,7 +185,7 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer select { case <-ctx.Done(): return - case <-cli.reqWaker.Sleep(): + case <-cli.reqSleep(): } for !cli.reqQueueEmpty() { @@ -185,6 +210,14 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer cli.stopForError(fmt.Errorf("flush buffer: %w", err)) return } + + if cli.blocking.Load() { + select { + case <-reqres.signal: + case <-ctx.Done(): + return + } + } } } } @@ -250,8 +283,6 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { return nil } -//---------------------------------------- - func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*types.Response, error) { if !cli.IsRunning() { return nil, errors.New("client has stopped") @@ -261,7 +292,7 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty cli.enqueue(reqres) // Asynchronously wake up the sender. - cli.reqWaker.Wake() + cli.reqWake() // wait for response for our request select { From cefd01457dd1a977b5ca581bfefe7c2e90f5f2b4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:31:30 +0100 Subject: [PATCH 034/111] test: socket client priority queue --- abci/client/socket_client_test.go | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 abci/client/socket_client_test.go diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go new file mode 100644 index 0000000000..c1a9df5752 --- /dev/null +++ b/abci/client/socket_client_test.go @@ -0,0 +1,127 @@ +package abciclient + +import ( + "context" + "sync" + "testing" + "time" + + "github.com/dashpay/tenderdash/abci/server" + "github.com/dashpay/tenderdash/abci/types" + "github.com/dashpay/tenderdash/libs/log" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestSocketClientCheckTxAfterPrepareProposal tests that the socket client +// executes CheckTx after PrepareProposal due to use of priority queue. +// +// Given the socket client and the socket server and socket client waiting +// When the socket client sends a CheckTx request followed by a PrepareProposal request +// Then the socket server executes the PrepareProposal request before the CheckTx request +func TestCheckTxAfterPrepareProposal(t *testing.T) { + // how long we sleep between each request + const SleepTime = 10 * time.Millisecond + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + socket := "unix://" + t.TempDir() + "/socket" + + app := &testApp{ + t: t, + logger: logger, + } + + server, err := server.NewServer(logger, socket, "socket", app) + require.NoError(t, err) + err = server.Start(ctx) + require.NoError(t, err) + + cli1 := NewSocketClient(logger, socket, true, nil) + cli := cli1.(*socketClient) + cli.setBlocking(true) + + err = cli.Start(ctx) + require.NoError(t, err) + + // wait until all requests are queued; we're unlock this when we're ready to start the test, and then + // lock inside Info handler will be unlocked + app.wait.Lock() + + // Send Info request that will block on app.wait mutex. + // Then send checkTx followed by PreparaProposal, + // but the server should execute PrepareProposal first due to use of priority queue + requests := []types.Request{ + {Value: &types.Request_Info{}}, + {Value: &types.Request_CheckTx{}}, + {Value: &types.Request_PrepareProposal{}}, + } + + wg := sync.WaitGroup{} + for i, req := range requests { + wg.Add(1) + // We use goroutines because these functions are blocking + go func(i int, req types.Request) { + var err error + defer wg.Done() + logger.Info("sending request", "id", i, "req", req.Value) + switch req.Value.(type) { + case *types.Request_Info: + _, err = cli.Info(ctx, &types.RequestInfo{}) + case *types.Request_CheckTx: + _, err = cli.CheckTx(ctx, &types.RequestCheckTx{}) + case *types.Request_PrepareProposal: + _, err = cli.PrepareProposal(ctx, &types.RequestPrepareProposal{}) + default: + t.Logf("unknown request type: %T", req.Value) + } + assert.NoError(t, err) + }(i, req) + // time to start the goroutine + time.Sleep(SleepTime) + } + + // start the test + logger.Info("UNLOCK AND START THE TEST") + app.wait.Unlock() + + // wait for the server to finish executing all requests + wg.Wait() +} + +type testApp struct { + // we will wait on this mutex in Info function until we are ready to start the test + wait sync.Mutex + types.BaseApplication + prepareProposalExecuted bool + t *testing.T + logger log.Logger +} + +// Info waits on the mutex until we are ready to start the test +func (app *testApp) Info(_ context.Context, _ *types.RequestInfo) (*types.ResponseInfo, error) { + app.wait.Lock() + defer app.wait.Unlock() + app.logger.Info("Info") + return &types.ResponseInfo{}, nil +} + +func (app *testApp) CheckTx(_ context.Context, _ *types.RequestCheckTx) (*types.ResponseCheckTx, error) { + app.wait.Lock() + defer app.wait.Unlock() + app.logger.Info("CheckTx") + + assert.True(app.t, app.prepareProposalExecuted) + return &types.ResponseCheckTx{Code: types.CodeTypeOK}, nil +} + +func (app *testApp) PrepareProposal(_ context.Context, _ *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { + app.wait.Lock() + defer app.wait.Unlock() + app.logger.Info("PrepareProposal") + + assert.False(app.t, app.prepareProposalExecuted) + app.prepareProposalExecuted = true + return &types.ResponsePrepareProposal{}, nil +} From 96d9aa357d38a924d87d2717cd87370905374e3b Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:33:03 +0100 Subject: [PATCH 035/111] chore(mempool): p2p checktx timeout 1s --- internal/mempool/p2p_msg_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index 1da679fedf..bc804980c5 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -58,7 +58,7 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known := 0 failed := 0 for _, tx := range protoTxs { - subCtx, subCtxCancel := context.WithTimeout(ctx, 5*time.Second) + subCtx, subCtxCancel := context.WithTimeout(ctx, 1*time.Second) defer subCtxCancel() if err := h.checker.CheckTx(subCtx, tx, nil, txInfo); err != nil { From 68a9a7a494a71763d1518e36b4b9a9e978ce837a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 13:37:52 +0100 Subject: [PATCH 036/111] chore(rpc): broadcasttx timeout 1s --- internal/rpc/core/mempool.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index adfd86176f..d1f8d70045 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -37,6 +37,9 @@ func (env *Environment) BroadcastTxSync(ctx context.Context, req *coretypes.Requ // DeliverTx result. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync func (env *Environment) BroadcastTx(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + ctx, cancel := context.WithTimeout(ctx, 1*time.Second) + defer cancel() + resCh := make(chan *abci.ResponseCheckTx, 1) err := env.Mempool.CheckTx( ctx, From 1769d2e55641d6391d5b45d9e484e8bd88d43386 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:04:43 +0100 Subject: [PATCH 037/111] chore(kvstore): check ctx.Err in handlers for testing --- abci/example/kvstore/kvstore.go | 60 +++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 41e9c2e52d..6f670fd9be 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -248,10 +248,13 @@ func NewPersistentApp(cfg Config, opts ...OptFunc) (*Application, error) { } // InitChain implements ABCI -func (app *Application) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { +func (app *Application) InitChain(ctx context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } if req.InitialHeight != 0 { app.initialHeight = req.InitialHeight if app.LastCommittedState.GetHeight() == 0 { @@ -306,10 +309,14 @@ func (app *Application) InitChain(_ context.Context, req *abci.RequestInitChain) } // PrepareProposal implements ABCI -func (app *Application) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { +func (app *Application) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + if req.MaxTxBytes <= 0 { return &abci.ResponsePrepareProposal{}, fmt.Errorf("MaxTxBytes must be positive, got: %d", req.MaxTxBytes) } @@ -385,10 +392,14 @@ func (app *Application) ProcessProposal(_ context.Context, req *abci.RequestProc } // FinalizeBlock implements ABCI -func (app *Application) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (app *Application) FinalizeBlock(ctx context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + blockHash := tmbytes.HexBytes(req.Hash) if err := app.validateHeight(req.Height); err != nil { @@ -474,10 +485,14 @@ func (app *Application) eventValUpdate(height int64) abci.Event { } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(_ context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { +func (app *Application) ListSnapshots(ctx context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + snapshots, err := app.snapshots.List() if err != nil { return &abci.ResponseListSnapshots{}, err @@ -489,10 +504,14 @@ func (app *Application) ListSnapshots(_ context.Context, req *abci.RequestListSn } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(_ context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { +func (app *Application) LoadSnapshotChunk(ctx context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + chunk, err := app.snapshots.LoadChunk(req.Height, req.Version, req.ChunkId) if err != nil { return &abci.ResponseLoadSnapshotChunk{}, err @@ -504,10 +523,14 @@ func (app *Application) LoadSnapshotChunk(_ context.Context, req *abci.RequestLo } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(_ context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { +func (app *Application) OfferSnapshot(ctx context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + app.offerSnapshot = newOfferSnapshot(req.Snapshot, req.AppHash) resp := &abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} @@ -516,10 +539,14 @@ func (app *Application) OfferSnapshot(_ context.Context, req *abci.RequestOfferS } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(_ context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { +func (app *Application) ApplySnapshotChunk(ctx context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + if app.offerSnapshot == nil { return &abci.ResponseApplySnapshotChunk{}, fmt.Errorf("no restore in progress") } @@ -570,9 +597,14 @@ func (app *Application) createSnapshot() error { } // Info implements ABCI -func (app *Application) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { +func (app *Application) Info(ctx context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() + + if err := ctx.Err(); err != nil { + return nil, err + } + appHash := app.LastCommittedState.GetAppHash() resp := &abci.ResponseInfo{ Data: fmt.Sprintf("{\"appHash\":\"%s\"}", appHash.String()), @@ -586,10 +618,14 @@ func (app *Application) Info(_ context.Context, req *abci.RequestInfo) (*abci.Re } // CheckTx implements ABCI -func (app *Application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *Application) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + resp, err := app.verifyTx(req.Tx, req.Type) if app.cfg.CheckTxDelayMS != 0 { time.Sleep(time.Duration(app.cfg.CheckTxDelayMS) * time.Millisecond) @@ -599,10 +635,14 @@ func (app *Application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*a } // Query returns an associated value or nil if missing. -func (app *Application) Query(_ context.Context, reqQuery *abci.RequestQuery) (*abci.ResponseQuery, error) { +func (app *Application) Query(ctx context.Context, reqQuery *abci.RequestQuery) (*abci.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() + if err := ctx.Err(); err != nil { + return nil, err + } + switch reqQuery.Path { case "/val": vu, err := app.findValidatorUpdate(reqQuery.Data) From 06dd3ce788e9bb1b45caf37666b384c9cb670613 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:05:29 +0100 Subject: [PATCH 038/111] chore(mempool,rpc): checktx timeout 1s using const --- internal/mempool/p2p_msg_handler.go | 7 ++++++- internal/rpc/core/mempool.go | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index bc804980c5..027a8f3fad 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -13,6 +13,11 @@ import ( "github.com/dashpay/tenderdash/types" ) +const ( + // CheckTxTimeout is the maximum time we wait for CheckTx to return. + CheckTxTimeout = 1 * time.Second +) + type ( mempoolP2PMessageHandler struct { logger log.Logger @@ -58,7 +63,7 @@ func (h *mempoolP2PMessageHandler) Handle(ctx context.Context, _ *client.Client, known := 0 failed := 0 for _, tx := range protoTxs { - subCtx, subCtxCancel := context.WithTimeout(ctx, 1*time.Second) + subCtx, subCtxCancel := context.WithTimeout(ctx, CheckTxTimeout) defer subCtxCancel() if err := h.checker.CheckTx(subCtx, tx, nil, txInfo); err != nil { diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index d1f8d70045..882aac0de6 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -23,6 +23,9 @@ import ( // https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async // Deprecated and should be removed in 0.37 func (env *Environment) BroadcastTxAsync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + ctx, cancel := context.WithTimeout(ctx, mempool.CheckTxTimeout) + defer cancel() + go func() { _ = env.Mempool.CheckTx(ctx, req.Tx, nil, mempool.TxInfo{}) }() return &coretypes.ResultBroadcastTx{Hash: req.Tx.Hash()}, nil @@ -37,7 +40,7 @@ func (env *Environment) BroadcastTxSync(ctx context.Context, req *coretypes.Requ // DeliverTx result. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync func (env *Environment) BroadcastTx(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { - ctx, cancel := context.WithTimeout(ctx, 1*time.Second) + ctx, cancel := context.WithTimeout(ctx, mempool.CheckTxTimeout) defer cancel() resCh := make(chan *abci.ResponseCheckTx, 1) From f6f934e71eedec500d8eb0939846b69e91d9e768 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:50:12 +0100 Subject: [PATCH 039/111] fix(consensus): proposed block validity conditions --- internal/consensus/state_data.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/consensus/state_data.go b/internal/consensus/state_data.go index ca761b230a..da292755ae 100644 --- a/internal/consensus/state_data.go +++ b/internal/consensus/state_data.go @@ -483,13 +483,13 @@ func (s *StateData) isValidForPrevote() error { return errPrevoteTimestampNotEqual } - if !s.replayMode && !s.proposalIsTimely() { + // if this block was not validated yet, we check if it's timely + if !s.replayMode && !s.ProposalBlock.HashesTo(s.ValidBlock.Hash()) && !s.proposalIsTimely() { return errPrevoteProposalNotTimely } // Validate proposal core chain lock - err := sm.ValidateBlockChainLock(s.state, s.ProposalBlock) - if err != nil { + if err := sm.ValidateBlockChainLock(s.state, s.ProposalBlock); err != nil { return errPrevoteInvalidChainLock } return nil From e2bc0b7ba2260b96051c0add29be6e56f9a03ad0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:51:02 +0100 Subject: [PATCH 040/111] chore(mempool): send rate limits --- internal/p2p/channel_params.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index dbbfc13468..9175063ad7 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -79,8 +79,8 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", - // SendRateLimit: 5, - // SendRateBurst: 20, + SendRateLimit: 5, + SendRateBurst: 20, }, } From f336485c65d607312f805686febf1d508269092f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:48:07 +0100 Subject: [PATCH 041/111] chore: fix after merge --- types/tx.go | 1 - 1 file changed, 1 deletion(-) diff --git a/types/tx.go b/types/tx.go index a121f16138..60ddb4e91f 100644 --- a/types/tx.go +++ b/types/tx.go @@ -14,7 +14,6 @@ import ( "github.com/dashpay/tenderdash/crypto/merkle" tmbytes "github.com/dashpay/tenderdash/libs/bytes" tmproto "github.com/dashpay/tenderdash/proto/tendermint/types" - "github.com/rs/zerolog" ) // Tx is an arbitrary byte array. From e0c447c53b62567da9fba1c8b3e7a6003384ff1c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:57:03 +0100 Subject: [PATCH 042/111] chore: incoming mempool channel size eq to mempool size --- internal/p2p/channel_params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 9175063ad7..66728480fd 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -77,7 +77,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { ID: MempoolChannel, Priority: 2, // 5 RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), - RecvBufferCapacity: 128, + RecvBufferCapacity: cfg.Mempool.Size, Name: "mempool", SendRateLimit: 5, SendRateBurst: 20, From cfa50c220f2a2f6f3af9ec54a5a666af758d27b4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:24:03 +0100 Subject: [PATCH 043/111] feat: timeout when trying to enqueue incoming mempool messages --- internal/p2p/channel_params.go | 4 ++- internal/p2p/conn/connection.go | 7 ++++++ internal/p2p/pqueue.go | 7 ++++-- internal/p2p/pqueue_test.go | 4 +-- internal/p2p/router.go | 35 +++++++++++++++++++++----- internal/p2p/throttled_channel_test.go | 5 ++-- 6 files changed, 49 insertions(+), 13 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 66728480fd..2af88a071b 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -2,6 +2,7 @@ package p2p import ( "fmt" + "time" "github.com/gogo/protobuf/proto" @@ -77,10 +78,11 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { ID: MempoolChannel, Priority: 2, // 5 RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), - RecvBufferCapacity: cfg.Mempool.Size, + RecvBufferCapacity: 1000, Name: "mempool", SendRateLimit: 5, SendRateBurst: 20, + EnqueueTimeout: 1 * time.Millisecond, }, } diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index 2311632bf7..caddd900db 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -620,6 +620,12 @@ type ChannelDescriptor struct { // Human readable name of the channel, used in logging and // diagnostics. Name string + + // Timeout for enqueue operations on the incoming queue. + // When timeout expires, messages will be silently dropped. + // + // If zero, enqueue operations will not time out. + EnqueueTimeout time.Duration } func (chDesc ChannelDescriptor) FillDefaults() (filled ChannelDescriptor) { @@ -632,6 +638,7 @@ func (chDesc ChannelDescriptor) FillDefaults() (filled ChannelDescriptor) { if chDesc.RecvMessageCapacity == 0 { chDesc.RecvMessageCapacity = defaultRecvMessageCapacity } + filled = chDesc return } diff --git a/internal/p2p/pqueue.go b/internal/p2p/pqueue.go index 350c38ce0b..b4fd037096 100644 --- a/internal/p2p/pqueue.go +++ b/internal/p2p/pqueue.go @@ -99,13 +99,16 @@ func newPQScheduler( logger log.Logger, m *Metrics, lc *metricsLabelCache, - chDescs []*ChannelDescriptor, + chDescs map[ChannelID]*ChannelDescriptor, enqueueBuf, dequeueBuf, capacity uint, ) *pqScheduler { // copy each ChannelDescriptor and sort them by ascending channel priority chDescsCopy := make([]*ChannelDescriptor, len(chDescs)) - copy(chDescsCopy, chDescs) + for _, chDesc := range chDescs { + chDescsCopy = append(chDescsCopy, chDesc) + } + sort.Slice(chDescsCopy, func(i, j int) bool { return chDescsCopy[i].Priority < chDescsCopy[j].Priority }) var ( diff --git a/internal/p2p/pqueue_test.go b/internal/p2p/pqueue_test.go index 3e1594d79c..7058b7e4cc 100644 --- a/internal/p2p/pqueue_test.go +++ b/internal/p2p/pqueue_test.go @@ -14,8 +14,8 @@ type testMessage = gogotypes.StringValue func TestCloseWhileDequeueFull(t *testing.T) { enqueueLength := 5 - chDescs := []*ChannelDescriptor{ - {ID: 0x01, Priority: 1}, + chDescs := map[ChannelID]*ChannelDescriptor{ + 0x01: {ID: 0x01, Priority: 1}, } pqueue := newPQScheduler(log.NewNopLogger(), NopMetrics(), newMetricsLabelCache(), chDescs, uint(enqueueLength), 1, 120) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 6ce284aa74..325b0019e1 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "net" + "reflect" "runtime" "time" @@ -151,7 +152,7 @@ type Router struct { options RouterOptions privKey crypto.PrivKey peerManager *PeerManager - chDescs []*ChannelDescriptor + chDescs map[ChannelID]*ChannelDescriptor transport Transport endpoint *Endpoint connTracker connectionTracker @@ -198,7 +199,7 @@ func NewRouter( options.MaxIncomingConnectionAttempts, options.IncomingConnectionWindow, ), - chDescs: make([]*ChannelDescriptor, 0), + chDescs: make(map[ChannelID]*ChannelDescriptor, 0), transport: transport, endpoint: endpoint, peerManager: peerManager, @@ -256,7 +257,7 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (Ch if _, ok := r.channelQueues[id]; ok { return nil, fmt.Errorf("channel %v already exists", id) } - r.chDescs = append(r.chDescs, chDesc) + r.chDescs[id] = chDesc queue := r.queueFactory(chDesc.RecvBufferCapacity) outCh := make(chan Envelope, chDesc.RecvBufferCapacity) @@ -771,6 +772,10 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec // receivePeer receives inbound messages from a peer, deserializes them and // passes them on to the appropriate channel. func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Connection) error { + // default timeout; by default, we set it to ~ 10 years so that it will practically never fire + timeout := time.NewTimer(24 * 30 * 12 * 10 * time.Hour) + defer timeout.Stop() + for { chID, bz, err := conn.ReceiveMessage(ctx) if err != nil { @@ -778,11 +783,14 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn } r.channelMtx.RLock() - queue, ok := r.channelQueues[chID] + queue, queueOk := r.channelQueues[chID] + chDesc, chDescOk := r.chDescs[chID] r.channelMtx.RUnlock() - if !ok { - r.logger.Debug("dropping message for unknown channel", "peer", peerID, "channel", chID) + if !queueOk || !chDescOk { + r.logger.Debug("dropping message for unknown channel", + "peer", peerID, "channel", chID, + "queue", queueOk, "chDesc", chDescOk) continue } @@ -799,6 +807,11 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn } envelope.From = peerID envelope.ChannelID = chID + + if chDesc.EnqueueTimeout > 0 { + timeout.Reset(chDesc.EnqueueTimeout) + } + select { case queue.enqueue() <- envelope: r.metrics.PeerReceiveBytesTotal.With( @@ -811,6 +824,16 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn case <-queue.closed(): r.logger.Debug("channel closed, dropping message", "peer", peerID, "channel", chID) + case <-timeout.C: + // TODO change to Trace + r.logger.Debug("dropping message from peer due to enqueue timeout", + "peer", peerID, + "channel", chID, + "channel_name", chDesc.Name, + "timeout", chDesc.EnqueueTimeout, + "type", reflect.TypeOf((envelope.Message)).Name(), + ) + case <-ctx.Done(): return nil } diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go index 75512d2516..a5b218ffdc 100644 --- a/internal/p2p/throttled_channel_test.go +++ b/internal/p2p/throttled_channel_test.go @@ -7,10 +7,11 @@ import ( "testing" "time" - "github.com/dashpay/tenderdash/internal/p2p" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/time/rate" + + "github.com/dashpay/tenderdash/internal/p2p" ) type mockChannel struct { @@ -21,7 +22,7 @@ func (c *mockChannel) Len() int { return int(c.counter.Load()) } -func (c *mockChannel) Send(_ context.Context, e p2p.Envelope) error { +func (c *mockChannel) Send(_ context.Context, _e p2p.Envelope) error { c.counter.Add(1) return nil } From 27caa0a8da8e62386d9eb31dbfe524fc339e180f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:24:34 +0100 Subject: [PATCH 044/111] chore: disable rate limits on mempool --- internal/p2p/channel_params.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 2af88a071b..188bd855e6 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -80,9 +80,9 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 1000, Name: "mempool", - SendRateLimit: 5, - SendRateBurst: 20, - EnqueueTimeout: 1 * time.Millisecond, + // SendRateLimit: 5, + // SendRateBurst: 20, + EnqueueTimeout: 1 * time.Millisecond, }, } From 310ad0b65af0727a88f643c2ec3fa9d6dfa730ca Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:08:33 +0100 Subject: [PATCH 045/111] chore: fix panic --- internal/p2p/pqueue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p2p/pqueue.go b/internal/p2p/pqueue.go index b4fd037096..eea4ea2142 100644 --- a/internal/p2p/pqueue.go +++ b/internal/p2p/pqueue.go @@ -104,7 +104,7 @@ func newPQScheduler( ) *pqScheduler { // copy each ChannelDescriptor and sort them by ascending channel priority - chDescsCopy := make([]*ChannelDescriptor, len(chDescs)) + chDescsCopy := make([]*ChannelDescriptor, 0, len(chDescs)) for _, chDesc := range chDescs { chDescsCopy = append(chDescsCopy, chDesc) } From bc991ffef5f91705d4b02e3d12dacb447010fddf Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:20:25 +0100 Subject: [PATCH 046/111] chore: increase enqueue timeout to 10ms --- internal/p2p/channel_params.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 188bd855e6..fffe5a60d6 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -82,7 +82,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { Name: "mempool", // SendRateLimit: 5, // SendRateBurst: 20, - EnqueueTimeout: 1 * time.Millisecond, + EnqueueTimeout: 10 * time.Millisecond, }, } From 3bba22f4fe46c6c829783a2434275eb47eeff4f9 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:52:40 +0100 Subject: [PATCH 047/111] chore: improve error desc --- internal/p2p/router.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 325b0019e1..fb3c33d4c8 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -830,7 +830,7 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn "peer", peerID, "channel", chID, "channel_name", chDesc.Name, - "timeout", chDesc.EnqueueTimeout, + "timeout", chDesc.EnqueueTimeout.String(), "type", reflect.TypeOf((envelope.Message)).Name(), ) From 11791dc789148d6234f4f9ce0826614251c0799d Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:53:17 +0100 Subject: [PATCH 048/111] chore: improve logging --- internal/consensus/vote_signer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/consensus/vote_signer.go b/internal/consensus/vote_signer.go index 62ef6cee30..470d154125 100644 --- a/internal/consensus/vote_signer.go +++ b/internal/consensus/vote_signer.go @@ -34,7 +34,8 @@ func (s *voteSigner) signAddVote( } // If the node not in the validator set, do nothing. if !stateData.Validators.HasProTxHash(s.privValidator.ProTxHash) { - s.logger.Error("do nothing, node is not a part of validator set") + s.logger.Error("do nothing, node %s is not a part of validator set %+v", + s.privValidator.ProTxHash.ShortString(), stateData.Validators) return nil } keyVals := []any{"height", stateData.Height, "round", stateData.Round, "quorum_hash", stateData.Validators.QuorumHash} From 4a0c564ed27fd4497b76394cb12a9279b46e8916 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:27:17 +0100 Subject: [PATCH 049/111] chore(consensus): a bit better logging --- internal/consensus/state_proposaler.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 1f71bf68e4..a3f8c37bb1 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -44,8 +44,15 @@ func NewProposaler( // Set updates Proposal, ProposalReceiveTime and ProposalBlockParts in RoundState if the passed proposal met conditions func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cstypes.RoundState) error { - // Does not apply - if rs.Proposal != nil || proposal.Height != rs.Height || proposal.Round != rs.Round { + + if rs.Proposal != nil { + // We already have a proposal + return nil + } + + if proposal.Height != rs.Height || proposal.Round != rs.Round { + p.logger.Debug("received proposal for invalid height/round, ignoring", "proposal", proposal, + "height", rs.Height, "round", rs.Round, "received", receivedAt) return nil } From 3cac6e5209ec9061edec2327d20cbfafe2fb14a6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:29:30 +0100 Subject: [PATCH 050/111] refactor: remove unused LastPrecommits We don't need LastPrecommits because they are only used in Tenderdash to construct commit. In our case, it's enough to just set LastCommit, as we use threshold signatures and don't need these precommits. --- internal/consensus/block_executor.go | 1 - internal/consensus/gossiper.go | 4 -- internal/consensus/gossiper_test.go | 4 +- internal/consensus/peer_state.go | 8 +--- internal/consensus/reactor.go | 5 ++- internal/consensus/state_add_vote.go | 41 -------------------- internal/consensus/state_data.go | 10 +---- internal/consensus/types/peer_round_state.go | 6 +-- internal/consensus/types/round_state.go | 1 - 9 files changed, 9 insertions(+), 71 deletions(-) diff --git a/internal/consensus/block_executor.go b/internal/consensus/block_executor.go index 21e1b83ef8..4cd6108f74 100644 --- a/internal/consensus/block_executor.go +++ b/internal/consensus/block_executor.go @@ -42,7 +42,6 @@ func (c *blockExecutor) create(ctx context.Context, rs *cstypes.RoundState, roun // The commit is empty, but not nil. commit = types.NewCommit(0, 0, types.BlockID{}, nil, nil) case rs.LastCommit != nil: - // Make the commit from LastPrecommits commit = rs.LastCommit default: // This shouldn't happen. diff --git a/internal/consensus/gossiper.go b/internal/consensus/gossiper.go index 4a3dc5991c..c1ec94adb0 100644 --- a/internal/consensus/gossiper.go +++ b/internal/consensus/gossiper.go @@ -311,10 +311,6 @@ func (g *msgGossiper) ensurePeerPartSetHeader(blockPartSetHeader types.PartSetHe // there is a vote to send and (nil,false) otherwise. func (g *msgGossiper) pickVoteForGossip(rs cstypes.RoundState, prs *cstypes.PeerRoundState) (*types.Vote, bool) { var voteSets []*types.VoteSet - // if there are lastPrecommits to send - if prs.Step == cstypes.RoundStepNewHeight { - voteSets = append(voteSets, rs.LastPrecommits) - } if prs.Round != -1 && prs.Round <= rs.Round { // if there are POL prevotes to send if prs.Step <= cstypes.RoundStepPropose && prs.ProposalPOLRound != -1 { diff --git a/internal/consensus/gossiper_test.go b/internal/consensus/gossiper_test.go index 7007b31b2c..fc04ac89bf 100644 --- a/internal/consensus/gossiper_test.go +++ b/internal/consensus/gossiper_test.go @@ -471,8 +471,6 @@ func (suite *GossiperSuiteTest) TestGossipGossipVote() { defer cancel() precommitH99 := suite.makeSignedVote(99, 0, tmproto.PrecommitType) - lastPercommits := types.NewVoteSet(factory.DefaultTestChainID, 99, 0, tmproto.PrecommitType, suite.valSet) - _, _ = lastPercommits.AddVote(precommitH99) prevoteH100R0 := suite.makeSignedVote(100, 0, tmproto.PrevoteType) prevoteH100R1 := suite.makeSignedVote(100, 1, tmproto.PrevoteType) @@ -490,7 +488,7 @@ func (suite *GossiperSuiteTest) TestGossipGossipVote() { wantMsg *tmproto.Vote }{ { - rs: cstypes.RoundState{LastPrecommits: lastPercommits}, + rs: cstypes.RoundState{}, prs: cstypes.PeerRoundState{ Height: 100, Round: -1, diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index 607fc3be86..a060fc8104 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -268,7 +268,7 @@ func (ps *PeerState) getVoteBitArray(height int64, round int32, votesType tmprot return nil case tmproto.PrecommitType: - return ps.PRS.LastPrecommits + return ps.PRS.Precommits } } @@ -335,10 +335,6 @@ func (ps *PeerState) ensureVoteBitArrays(height int64, numValidators int) { if ps.PRS.ProposalPOL == nil { ps.PRS.ProposalPOL = bits.NewBitArray(numValidators) } - } else if ps.PRS.Height == height+1 { - if ps.PRS.LastPrecommits == nil { - ps.PRS.LastPrecommits = bits.NewBitArray(numValidators) - } } } @@ -530,10 +526,8 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { // Shift Precommits to LastPrecommits. if psHeight+1 == msg.Height && psRound == msg.LastCommitRound { ps.PRS.LastCommitRound = msg.LastCommitRound - ps.PRS.LastPrecommits = ps.PRS.Precommits.Copy() } else { ps.PRS.LastCommitRound = msg.LastCommitRound - ps.PRS.LastPrecommits = nil } // we'll update the BitArray capacity later diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index f35ed1bfa5..222f92e978 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -635,7 +635,8 @@ func (r *Reactor) handleVoteMessage(ctx context.Context, envelope *p2p.Envelope, case *tmcons.Vote: stateData := r.state.stateDataStore.Get() isValidator := stateData.isValidator(r.state.privValidator.ProTxHash) - height, valSize, lastCommitSize := stateData.Height, stateData.Validators.Size(), stateData.LastPrecommits.Size() + height, valSize := stateData.Height, stateData.Validators.Size() + lastValSize := len(stateData.LastValidators.Validators) if isValidator { // ignore votes on non-validator nodes; TODO don't even send it vMsg := msgI.(*VoteMessage) @@ -645,7 +646,7 @@ func (r *Reactor) handleVoteMessage(ctx context.Context, envelope *p2p.Envelope, } ps.EnsureVoteBitArrays(height, valSize) - ps.EnsureVoteBitArrays(height-1, lastCommitSize) + ps.EnsureVoteBitArrays(height-1, lastValSize) if err := ps.SetHasVote(vMsg.Vote); err != nil { return err } diff --git a/internal/consensus/state_add_vote.go b/internal/consensus/state_add_vote.go index 54959ca1a8..9a5d589a98 100644 --- a/internal/consensus/state_add_vote.go +++ b/internal/consensus/state_add_vote.go @@ -45,7 +45,6 @@ func newAddVoteAction(cs *State, ctrl *Controller, statsQueue *chanQueue[msgInfo statsMw := addVoteStatsMw(statsQueue) dispatchPrecommitMw := addVoteDispatchPrecommitMw(ctrl) verifyVoteExtensionMw := addVoteVerifyVoteExtensionMw(cs.privValidator, cs.blockExec, cs.metrics, cs.emitter) - addToLastPrecommitMw := addVoteToLastPrecommitMw(cs.eventPublisher, ctrl) return &AddVoteAction{ prevote: withVoterMws( addToVoteSet, @@ -62,7 +61,6 @@ func newAddVoteAction(cs *State, ctrl *Controller, statsQueue *chanQueue[msgInfo dispatchPrecommitMw, verifyVoteExtensionMw, validateVoteMw, - addToLastPrecommitMw, errorMw, statsMw, ), @@ -101,45 +99,6 @@ func addVoteToVoteSetFunc(metrics *Metrics, ep *EventPublisher) AddVoteFunc { } } -func addVoteToLastPrecommitMw(ep *EventPublisher, ctrl *Controller) AddVoteMiddlewareFunc { - return func(next AddVoteFunc) AddVoteFunc { - return func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { - if vote.Height+1 != stateData.Height || vote.Type != tmproto.PrecommitType { - return next(ctx, stateData, vote) - } - logger := log.FromCtxOrNop(ctx) - if stateData.Step != cstypes.RoundStepNewHeight { - // Late precommit at prior height is ignored - logger.Trace("precommit vote came in after commit timeout and has been ignored") - return false, nil - } - if stateData.LastPrecommits == nil { - logger.Debug("no last round precommits on node", "vote", vote) - return false, nil - } - added, err := stateData.LastPrecommits.AddVote(vote) - if !added { - logger.Debug("vote not added to last precommits", logKeyValsWithError(nil, err)...) - return false, nil - } - logger.Trace("added vote to last precommits", "last_precommits", stateData.LastPrecommits) - - err = ep.PublishVoteEvent(vote) - if err != nil { - return added, err - } - - // if we have reached majority, we can go straight to new round. - // No need to wait, as we don't save all the precommits anyway - if stateData.LastPrecommits.HasTwoThirdsMajority() { - // go straight to new round - _ = ctrl.Dispatch(ctx, &EnterNewRoundEvent{Height: stateData.Height}, stateData) - } - return added, err - } - } -} - func addVoteUpdateValidBlockMw(ep *EventPublisher) AddVoteMiddlewareFunc { return func(next AddVoteFunc) AddVoteFunc { return func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { diff --git a/internal/consensus/state_data.go b/internal/consensus/state_data.go index da292755ae..6fb96eaab4 100644 --- a/internal/consensus/state_data.go +++ b/internal/consensus/state_data.go @@ -226,7 +226,6 @@ func (s *StateData) updateToState(state sm.State, commit *types.Commit) { switch { case state.LastBlockHeight == 0: // Very first commit should be empty. s.LastCommit = (*types.Commit)(nil) - s.LastPrecommits = (*types.VoteSet)(nil) case s.CommitRound > -1 && s.Votes != nil && commit == nil: // Otherwise, use cs.Votes if !s.Votes.Precommits(s.CommitRound).HasTwoThirdsMajority() { panic(fmt.Sprintf( @@ -234,14 +233,9 @@ func (s *StateData) updateToState(state sm.State, commit *types.Commit) { state.LastBlockHeight, s.CommitRound, s.Votes.Precommits(s.CommitRound), )) } - s.LastPrecommits = s.Votes.Precommits(s.CommitRound) - s.LastCommit = s.LastPrecommits.MakeCommit() + precommits := s.Votes.Precommits(s.CommitRound) + s.LastCommit = precommits.MakeCommit() case commit != nil: - // We either got the commit from a remote node - // In which Last precommits will be nil - // Or we got the commit from finalize commit - // In which Last precommits will not be nil - s.LastPrecommits = s.Votes.Precommits(s.CommitRound) s.LastCommit = commit case s.LastCommit == nil: // NOTE: when Tendermint starts, it has no votes. reconstructLastCommit diff --git a/internal/consensus/types/peer_round_state.go b/internal/consensus/types/peer_round_state.go index e5e2e3e6fb..4649e8f9af 100644 --- a/internal/consensus/types/peer_round_state.go +++ b/internal/consensus/types/peer_round_state.go @@ -34,7 +34,6 @@ type PeerRoundState struct { Prevotes *bits.BitArray `json:"prevotes"` // All votes peer has for this round Precommits *bits.BitArray `json:"precommits"` // All precommits peer has for this round LastCommitRound int32 `json:"last_commit_round"` // Round of commit for last height. -1 if none. - LastPrecommits *bits.BitArray `json:"last_commit"` // All commit precommits of commit for last height. HasCommit bool `json:"has_commit"` @@ -69,7 +68,6 @@ func (prs PeerRoundState) Copy() PeerRoundState { prs.ProposalPOL = prs.ProposalPOL.Copy() prs.Prevotes = prs.Prevotes.Copy() prs.Precommits = prs.Precommits.Copy() - prs.LastPrecommits = prs.LastPrecommits.Copy() prs.CatchupCommit = prs.CatchupCommit.Copy() return prs @@ -83,7 +81,7 @@ func (prs PeerRoundState) StringIndented(indent string) string { %s POL %v (round %v) %s Prevotes %v %s Precommits %v -%s LastPrecommits %v (round %v) +%s Last commit round %v %s Catchup %v (round %v) %s}`, indent, prs.Height, prs.Round, prs.Step, prs.StartTime, @@ -91,7 +89,7 @@ func (prs PeerRoundState) StringIndented(indent string) string { indent, prs.ProposalPOL, prs.ProposalPOLRound, indent, prs.Prevotes, indent, prs.Precommits, - indent, prs.LastPrecommits, prs.LastCommitRound, + indent, prs.LastCommitRound, indent, prs.CatchupCommit, prs.CatchupCommitRound, indent) } diff --git a/internal/consensus/types/round_state.go b/internal/consensus/types/round_state.go index 8c9181b9a0..1e93d8d8c7 100644 --- a/internal/consensus/types/round_state.go +++ b/internal/consensus/types/round_state.go @@ -103,7 +103,6 @@ type RoundState struct { ValidBlockParts *types.PartSet `json:"valid_block_parts"` Votes *HeightVoteSet `json:"votes"` CommitRound int32 `json:"commit_round"` - LastPrecommits *types.VoteSet `json:"last_precommits"` LastCommit *types.Commit `json:"last_commit"` LastValidators *types.ValidatorSet `json:"last_validators"` TriggeredTimeoutPrecommit bool `json:"triggered_timeout_precommit"` From 854b14502b2d311ba21ef85e871f2e527b34eb58 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 11:15:43 +0100 Subject: [PATCH 051/111] chore: minor fix of multierror --- types/vote_extension.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/vote_extension.go b/types/vote_extension.go index 784da379a5..13b8a5ddd2 100644 --- a/types/vote_extension.go +++ b/types/vote_extension.go @@ -87,7 +87,7 @@ func (e VoteExtensions) GetExtensions() [][]byte { // Validate returns error if an added vote-extension is invalid func (e VoteExtensions) Validate() error { - var errs *multierror.Error + var errs error for i, ext := range e { if err := ext.Validate(); err != nil { @@ -95,7 +95,7 @@ func (e VoteExtensions) Validate() error { } } - return errs.ErrorOrNil() + return errs } // IsEmpty returns true if a vote-extension container is empty, otherwise false From a7c7a44e4585ec76d5255773755b90b939916ea1 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 13:01:37 +0100 Subject: [PATCH 052/111] chore(mempool): change locking of addNewTransaction --- internal/mempool/mempool.go | 148 ++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 42 deletions(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index e75707e306..393e88a87b 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -448,11 +448,31 @@ func (txmp *TxMempool) Update( // transactions are evicted. // // Finally, the new transaction is added and size stats updated. +// +// Note: due to locking appoach we take, it is possible that meanwhile another thread evicted the same items. +// This means we can put put slightly more items into the mempool, but it has significant performance impact func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.ResponseCheckTx) error { - txmp.mtx.Lock() - defer txmp.mtx.Unlock() - var err error + // RLock here. + + // When the mempool is full, we we don't need a writable lock. RLocking here should add significant + // performance boost in this case, as threads will not need to wait to obtain writable lock. + // + // A disadvantage is that we need to relock RW when we need to evict peers, what introduces race condition + // when two threads want to evict the same transactions. We choose to manage that race condition to gain some + // performance. + txmp.mtx.RLock() + rlocked := true + defer func() { + if rlocked { + txmp.mtx.RUnlock() + } else { + txmp.mtx.Unlock() + } + }() + + txmp.logger.Debug("addNewTransaction postCheck") + if txmp.postCheck != nil { err = txmp.postCheck(wtx.tx, checkTxRes) } @@ -513,7 +533,10 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon // of them as necessary to make room for tx. If no such items exist, we // discard tx. + txmp.logger.Debug("addNewTransaction canAddTx") if err := txmp.canAddTx(wtx); err != nil { + txmp.logger.Debug("addNewTransaction findVictims", "err", err) + var victims []*clist.CElement // eligible transactions for eviction var victimBytes int64 // total size of victims for cur := txmp.txs.Front(); cur != nil; cur = cur.Next() { @@ -524,10 +547,44 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon } } + haveSpace := len(victims) != 0 && victimBytes <= wtx.Size() + txmp.logger.Debug("addNewTransaction haveSpace", "have_space", haveSpace, "victims", victims) + if haveSpace { + // Sort lowest priority items first so they will be evicted first. Break + // ties in favor of newer items (to maintain FIFO semantics in a group). + sort.Slice(victims, func(i, j int) bool { + iw := victims[i].Value.(*WrappedTx) + jw := victims[j].Value.(*WrappedTx) + if iw.Priority() == jw.Priority() { + return iw.timestamp.After(jw.timestamp) + } + return iw.Priority() < jw.Priority() + }) + + txmp.logger.Debug("evicting lower-priority transactions", + "new_tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), + "new_priority", priority) + + // Evict as many of the victims as necessary to make room. + // We need to drop RLock and Lock here, as from now on, we will be modifying the mempool. + // This introduces race condition which we handle inside evict() + if rlocked { + txmp.mtx.RUnlock() + txmp.mtx.Lock() + rlocked = false + } + + haveSpace = txmp.evict(wtx.Size(), victims) + + if !haveSpace { + txmp.logger.Debug("unexpected mempool eviction failure - possibly concurrent eviction happened") + } + } + // If there are no suitable eviction candidates, or the total size of // those candidates is not enough to make room for the new transaction, // drop the new one. - if len(victims) == 0 || victimBytes < wtx.Size() { + if !haveSpace { txmp.cache.Remove(wtx.tx) txmp.logger.Error( "rejected valid incoming transaction; mempool is full", @@ -540,49 +597,19 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon // fmt.Errorf("transaction rejected: mempool is full (%X)", wtx.tx.Hash()) return nil } - - txmp.logger.Debug("evicting lower-priority transactions", - "new_tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), - "new_priority", priority, - ) - - // Sort lowest priority items first so they will be evicted first. Break - // ties in favor of newer items (to maintain FIFO semantics in a group). - sort.Slice(victims, func(i, j int) bool { - iw := victims[i].Value.(*WrappedTx) - jw := victims[j].Value.(*WrappedTx) - if iw.Priority() == jw.Priority() { - return iw.timestamp.After(jw.timestamp) - } - return iw.Priority() < jw.Priority() - }) - - // Evict as many of the victims as necessary to make room. - var evictedBytes int64 - for _, vic := range victims { - w := vic.Value.(*WrappedTx) - - txmp.logger.Debug( - "evicted valid existing transaction; mempool full", - "old_tx", tmstrings.LazySprintf("%X", w.tx.Hash()), - "old_priority", w.priority, - ) - txmp.removeTxByElement(vic) - txmp.cache.Remove(w.tx) - txmp.metrics.EvictedTxs.Add(1) - - // We may not need to evict all the eligible transactions. Bail out - // early if we have made enough room. - evictedBytes += w.Size() - if evictedBytes >= wtx.Size() { - break - } - } } wtx.SetGasWanted(checkTxRes.GasWanted) wtx.SetPriority(priority) wtx.SetSender(sender) + + // Ensure we have writable lock + if rlocked { + txmp.mtx.RUnlock() + txmp.mtx.Lock() + rlocked = false + } + txmp.insertTx(wtx) txmp.metrics.TxSizeBytes.Observe(float64(wtx.Size())) @@ -594,10 +621,47 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon "height", txmp.height, "num_txs", txmp.Size(), ) + txmp.notifyTxsAvailable() + return nil } +// Remove victims from the mempool until we fee up to bytes +// Returns true when enough victims were removed. +// +// Caller should hold writable lock +func (txmp *TxMempool) evict(size int64, victims []*clist.CElement) bool { + var evictedBytes int64 + for _, vic := range victims { + w := vic.Value.(*WrappedTx) + + if vic.Removed() { + // Race condition - some other thread already removed this item + // We handle it by just skipping this tx + continue + } + + txmp.logger.Debug( + "evicted valid existing transaction; mempool full", + "old_tx", tmstrings.LazySprintf("%X", w.tx.Hash()), + "old_priority", w.priority, + ) + txmp.removeTxByElement(vic) + txmp.cache.Remove(w.tx) + txmp.metrics.EvictedTxs.Add(1) + + // We may not need to evict all the eligible transactions. Bail out + // early if we have made enough room. + evictedBytes += w.Size() + if evictedBytes >= size { + return true + } + } + + return false +} + func (txmp *TxMempool) insertTx(wtx *WrappedTx) { elt := txmp.txs.PushBack(wtx) txmp.txByKey[wtx.tx.Key()] = elt From 5c59e34b2e8605d64cf94e4d8122274e728eed3d Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:38:39 +0100 Subject: [PATCH 053/111] fix(p2p): EnqueueTimeout breaks unrelated channels --- internal/p2p/router.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index fb3c33d4c8..6082080afb 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -773,7 +773,8 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec // passes them on to the appropriate channel. func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Connection) error { // default timeout; by default, we set it to ~ 10 years so that it will practically never fire - timeout := time.NewTimer(24 * 30 * 12 * 10 * time.Hour) + const DefaultTimeout = 24 * 30 * 12 * 10 * time.Hour + timeout := time.NewTimer(DefaultTimeout) defer timeout.Stop() for { @@ -808,8 +809,13 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn envelope.From = peerID envelope.ChannelID = chID + if !timeout.Stop() { + <-timeout.C + } if chDesc.EnqueueTimeout > 0 { timeout.Reset(chDesc.EnqueueTimeout) + } else { + timeout.Reset(DefaultTimeout) } select { From 1065a6690b75f64fc4b1999c4918094e92128df9 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:18:01 +0100 Subject: [PATCH 054/111] refactor(mempool): relaxed locking of mempool addNewTransaction --- internal/mempool/mempool.go | 148 ++++++++++++++++++++++++++---------- 1 file changed, 106 insertions(+), 42 deletions(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index e75707e306..393e88a87b 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -448,11 +448,31 @@ func (txmp *TxMempool) Update( // transactions are evicted. // // Finally, the new transaction is added and size stats updated. +// +// Note: due to locking appoach we take, it is possible that meanwhile another thread evicted the same items. +// This means we can put put slightly more items into the mempool, but it has significant performance impact func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.ResponseCheckTx) error { - txmp.mtx.Lock() - defer txmp.mtx.Unlock() - var err error + // RLock here. + + // When the mempool is full, we we don't need a writable lock. RLocking here should add significant + // performance boost in this case, as threads will not need to wait to obtain writable lock. + // + // A disadvantage is that we need to relock RW when we need to evict peers, what introduces race condition + // when two threads want to evict the same transactions. We choose to manage that race condition to gain some + // performance. + txmp.mtx.RLock() + rlocked := true + defer func() { + if rlocked { + txmp.mtx.RUnlock() + } else { + txmp.mtx.Unlock() + } + }() + + txmp.logger.Debug("addNewTransaction postCheck") + if txmp.postCheck != nil { err = txmp.postCheck(wtx.tx, checkTxRes) } @@ -513,7 +533,10 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon // of them as necessary to make room for tx. If no such items exist, we // discard tx. + txmp.logger.Debug("addNewTransaction canAddTx") if err := txmp.canAddTx(wtx); err != nil { + txmp.logger.Debug("addNewTransaction findVictims", "err", err) + var victims []*clist.CElement // eligible transactions for eviction var victimBytes int64 // total size of victims for cur := txmp.txs.Front(); cur != nil; cur = cur.Next() { @@ -524,10 +547,44 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon } } + haveSpace := len(victims) != 0 && victimBytes <= wtx.Size() + txmp.logger.Debug("addNewTransaction haveSpace", "have_space", haveSpace, "victims", victims) + if haveSpace { + // Sort lowest priority items first so they will be evicted first. Break + // ties in favor of newer items (to maintain FIFO semantics in a group). + sort.Slice(victims, func(i, j int) bool { + iw := victims[i].Value.(*WrappedTx) + jw := victims[j].Value.(*WrappedTx) + if iw.Priority() == jw.Priority() { + return iw.timestamp.After(jw.timestamp) + } + return iw.Priority() < jw.Priority() + }) + + txmp.logger.Debug("evicting lower-priority transactions", + "new_tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), + "new_priority", priority) + + // Evict as many of the victims as necessary to make room. + // We need to drop RLock and Lock here, as from now on, we will be modifying the mempool. + // This introduces race condition which we handle inside evict() + if rlocked { + txmp.mtx.RUnlock() + txmp.mtx.Lock() + rlocked = false + } + + haveSpace = txmp.evict(wtx.Size(), victims) + + if !haveSpace { + txmp.logger.Debug("unexpected mempool eviction failure - possibly concurrent eviction happened") + } + } + // If there are no suitable eviction candidates, or the total size of // those candidates is not enough to make room for the new transaction, // drop the new one. - if len(victims) == 0 || victimBytes < wtx.Size() { + if !haveSpace { txmp.cache.Remove(wtx.tx) txmp.logger.Error( "rejected valid incoming transaction; mempool is full", @@ -540,49 +597,19 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon // fmt.Errorf("transaction rejected: mempool is full (%X)", wtx.tx.Hash()) return nil } - - txmp.logger.Debug("evicting lower-priority transactions", - "new_tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), - "new_priority", priority, - ) - - // Sort lowest priority items first so they will be evicted first. Break - // ties in favor of newer items (to maintain FIFO semantics in a group). - sort.Slice(victims, func(i, j int) bool { - iw := victims[i].Value.(*WrappedTx) - jw := victims[j].Value.(*WrappedTx) - if iw.Priority() == jw.Priority() { - return iw.timestamp.After(jw.timestamp) - } - return iw.Priority() < jw.Priority() - }) - - // Evict as many of the victims as necessary to make room. - var evictedBytes int64 - for _, vic := range victims { - w := vic.Value.(*WrappedTx) - - txmp.logger.Debug( - "evicted valid existing transaction; mempool full", - "old_tx", tmstrings.LazySprintf("%X", w.tx.Hash()), - "old_priority", w.priority, - ) - txmp.removeTxByElement(vic) - txmp.cache.Remove(w.tx) - txmp.metrics.EvictedTxs.Add(1) - - // We may not need to evict all the eligible transactions. Bail out - // early if we have made enough room. - evictedBytes += w.Size() - if evictedBytes >= wtx.Size() { - break - } - } } wtx.SetGasWanted(checkTxRes.GasWanted) wtx.SetPriority(priority) wtx.SetSender(sender) + + // Ensure we have writable lock + if rlocked { + txmp.mtx.RUnlock() + txmp.mtx.Lock() + rlocked = false + } + txmp.insertTx(wtx) txmp.metrics.TxSizeBytes.Observe(float64(wtx.Size())) @@ -594,10 +621,47 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon "height", txmp.height, "num_txs", txmp.Size(), ) + txmp.notifyTxsAvailable() + return nil } +// Remove victims from the mempool until we fee up to bytes +// Returns true when enough victims were removed. +// +// Caller should hold writable lock +func (txmp *TxMempool) evict(size int64, victims []*clist.CElement) bool { + var evictedBytes int64 + for _, vic := range victims { + w := vic.Value.(*WrappedTx) + + if vic.Removed() { + // Race condition - some other thread already removed this item + // We handle it by just skipping this tx + continue + } + + txmp.logger.Debug( + "evicted valid existing transaction; mempool full", + "old_tx", tmstrings.LazySprintf("%X", w.tx.Hash()), + "old_priority", w.priority, + ) + txmp.removeTxByElement(vic) + txmp.cache.Remove(w.tx) + txmp.metrics.EvictedTxs.Add(1) + + // We may not need to evict all the eligible transactions. Bail out + // early if we have made enough room. + evictedBytes += w.Size() + if evictedBytes >= size { + return true + } + } + + return false +} + func (txmp *TxMempool) insertTx(wtx *WrappedTx) { elt := txmp.txs.PushBack(wtx) txmp.txByKey[wtx.tx.Key()] = elt From b42b653a00e1cb89772e31e1a7dd5a11864331a6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:20:18 +0100 Subject: [PATCH 055/111] fix: wrong condition --- internal/mempool/mempool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 393e88a87b..22c7811256 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -549,7 +549,7 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon haveSpace := len(victims) != 0 && victimBytes <= wtx.Size() txmp.logger.Debug("addNewTransaction haveSpace", "have_space", haveSpace, "victims", victims) - if haveSpace { + if !haveSpace { // Sort lowest priority items first so they will be evicted first. Break // ties in favor of newer items (to maintain FIFO semantics in a group). sort.Slice(victims, func(i, j int) bool { From e2718ef50394e9f1c15e776d9303a3c474e63530 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:27:32 +0100 Subject: [PATCH 056/111] chore: fix condition again --- internal/mempool/mempool.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 22c7811256..e8f5bf1ff4 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -547,9 +547,9 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon } } - haveSpace := len(victims) != 0 && victimBytes <= wtx.Size() + haveSpace := victimBytes >= wtx.Size() txmp.logger.Debug("addNewTransaction haveSpace", "have_space", haveSpace, "victims", victims) - if !haveSpace { + if haveSpace { // Sort lowest priority items first so they will be evicted first. Break // ties in favor of newer items (to maintain FIFO semantics in a group). sort.Slice(victims, func(i, j int) bool { From 63743b6b7474b451cbf6bba00177b985b30bd10e Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon, 12 Feb 2024 18:40:24 +0100 Subject: [PATCH 057/111] fix(rpc): broadcastasync is broken due to invalid ctx cancellation --- internal/rpc/core/mempool.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/internal/rpc/core/mempool.go b/internal/rpc/core/mempool.go index 2fa4157cdd..e20eacd70c 100644 --- a/internal/rpc/core/mempool.go +++ b/internal/rpc/core/mempool.go @@ -22,11 +22,17 @@ import ( // More: // https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async // Deprecated and should be removed in 0.37 -func (env *Environment) BroadcastTxAsync(ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { - ctx, cancel := context.WithTimeout(ctx, mempool.CheckTxTimeout) - defer cancel() - - go func() { _ = env.Mempool.CheckTx(ctx, req.Tx, nil, mempool.TxInfo{}) }() +func (env *Environment) BroadcastTxAsync(_ctx context.Context, req *coretypes.RequestBroadcastTx) (*coretypes.ResultBroadcastTx, error) { + go func() { + // We need to create a new context here, because the original context + // may be canceled after parent function returns. + ctx, cancel := context.WithTimeout(context.Background(), mempool.CheckTxTimeout) + defer cancel() + + if res, err := env.BroadcastTx(ctx, req); err != nil || res.Code != abci.CodeTypeOK { + env.Logger.Error("error on broadcastTxAsync", "err", err, "result", res, "tx", req.Tx.Hash()) + } + }() return &coretypes.ResultBroadcastTx{Hash: req.Tx.Hash()}, nil } From e75aeb291cbcefdac06ed4bc517559b22dceefdc Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 13 Feb 2024 12:28:40 +0100 Subject: [PATCH 058/111] chore(p2p): more logging of disconnect errors --- internal/p2p/router.go | 9 +++++++++ internal/p2p/transport_mconn.go | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 2fa9d0c238..24eaa9bf6d 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -740,15 +740,21 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec var err error select { case err = <-errCh: + r.logger.Debug("routePeer: received error from subroutine 1", "peer", peerID, "err", err) case <-ctx.Done(): + r.logger.Debug("routePeer: ctx done in subroutine 1", "peer", peerID) } _ = conn.Close() sendQueue.close() + r.logger.Debug("routePeer: closed conn and send queue", "peer", peerID, "err", err) + select { case <-ctx.Done(): + r.logger.Debug("routePeer: ctx done in subroutine 2", "peer", peerID) case e := <-errCh: + r.logger.Debug("routePeer: received error from subroutine 2", "peer", peerID, "err", e) // The first err was nil, so we update it with the second err, which may // or may not be nil. if err == nil { @@ -778,15 +784,18 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn defer timeout.Stop() for { + r.logger.Debug("receivePeer: before ReceiveMessage", "peer", peerID) chID, bz, err := conn.ReceiveMessage(ctx) if err != nil { return err } + r.logger.Debug("receivePeer: before RLock", "peer", peerID, "chID", chID) r.channelMtx.RLock() queue, queueOk := r.channelQueues[chID] chDesc, chDescOk := r.chDescs[chID] r.channelMtx.RUnlock() + r.logger.Debug("receivePeer: after RUnlock", "peer", peerID, "chID", chID) if !queueOk || !chDescOk { r.logger.Debug("dropping message for unknown channel", diff --git a/internal/p2p/transport_mconn.go b/internal/p2p/transport_mconn.go index 7d4b3d046f..a25ed4e23b 100644 --- a/internal/p2p/transport_mconn.go +++ b/internal/p2p/transport_mconn.go @@ -458,10 +458,13 @@ func (c *mConnConnection) SendMessage(ctx context.Context, chID ChannelID, msg [ func (c *mConnConnection) ReceiveMessage(ctx context.Context) (ChannelID, []byte, error) { select { case err := <-c.errorCh: + c.logger.Debug("ReceiveMessage: error occurred", "err", err) return 0, nil, err case <-c.doneCh: + c.logger.Debug("ReceiveMessage: connection closed - doneCh") return 0, nil, io.EOF case <-ctx.Done(): + c.logger.Debug("ReceiveMessage: connection closed - ctx.Done()") return 0, nil, io.EOF case msg := <-c.receiveCh: return msg.channelID, msg.payload, nil @@ -496,6 +499,7 @@ func (c *mConnConnection) RemoteEndpoint() Endpoint { func (c *mConnConnection) Close() error { var err error c.closeOnce.Do(func() { + c.logger.Debug("mConnConnection.Close(): closing doneCh") defer close(c.doneCh) if c.mconn != nil && c.mconn.IsRunning() { From 03aa8148c578fcf4eb60066fd603dd6c24363c0d Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:18:40 +0100 Subject: [PATCH 059/111] refactor(p2p): refactor routePeer and mConn shutdown --- internal/p2p/router.go | 53 +++++++++++++++++++++++---------- internal/p2p/transport_mconn.go | 22 ++++++++++---- 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 24eaa9bf6d..1b972e6e7c 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -702,6 +702,10 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec r.metrics.PeersConnected.Add(1) r.peerManager.Ready(ctx, peerID, channels) + // we use context to manage the lifecycle of the peer + ctx, cancel := context.WithCancel(ctx) + defer cancel() + sendQueue := r.getOrMakeQueue(peerID, channels) defer func() { r.logger.Debug("routePeer cleanup: terminated peer", "peer", peerID) @@ -711,6 +715,7 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec r.peerMtx.Unlock() r.logger.Debug("routePeer cleanup: deleted peer queues", "peer", peerID) + _ = conn.Close() sendQueue.close() r.logger.Debug("routePeer cleanup: closed send queue", "peer", peerID) @@ -722,12 +727,15 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec r.logger.Info("peer connected", "peer", peerID, "endpoint", conn) errCh := make(chan error, 2) + wg := sync.WaitGroup{} + wg.Add(2) go func() { select { case errCh <- r.receivePeer(ctx, peerID, conn): case <-ctx.Done(): } + wg.Done() }() go func() { @@ -735,36 +743,51 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec case errCh <- r.sendPeer(ctx, peerID, conn, sendQueue): case <-ctx.Done(): } + wg.Done() }() - var err error + // wait for error from first goroutine + + var ( + err error + ctxErr error + ) + select { case err = <-errCh: r.logger.Debug("routePeer: received error from subroutine 1", "peer", peerID, "err", err) case <-ctx.Done(): - r.logger.Debug("routePeer: ctx done in subroutine 1", "peer", peerID) + r.logger.Debug("routePeer: ctx done", "peer", peerID) + ctxErr = ctx.Err() } + // goroutine 1 has finished, so we can cancel the context and close everything + cancel() _ = conn.Close() sendQueue.close() - r.logger.Debug("routePeer: closed conn and send queue", "peer", peerID, "err", err) + r.logger.Debug("routePeer: closed conn and send queue, waiting for all goroutines to finish", "peer", peerID, "err", err) + wg.Wait() - select { - case <-ctx.Done(): - r.logger.Debug("routePeer: ctx done in subroutine 2", "peer", peerID) - case e := <-errCh: - r.logger.Debug("routePeer: received error from subroutine 2", "peer", peerID, "err", e) - // The first err was nil, so we update it with the second err, which may - // or may not be nil. - if err == nil { - err = e + // Drain the error channel; these should typically not be interesting +FOR: + for i := 0; ; i++ { + select { + case e := <-errCh: + r.logger.Debug("routePeer: received error when draining errCh", "peer", peerID, "err", e) + // if we received non-context error, we should return it + if err == nil && !errors.Is(e, context.Canceled) && !errors.Is(e, context.DeadlineExceeded) { + err = e + } + default: + break FOR } } + close(errCh) - // if the context was canceled - if e := ctx.Err(); err == nil && e != nil { - err = e + // if the context was canceled, and no other error received on errCh + if err == nil { + err = ctxErr } switch err { diff --git a/internal/p2p/transport_mconn.go b/internal/p2p/transport_mconn.go index a25ed4e23b..2c05c59cca 100644 --- a/internal/p2p/transport_mconn.go +++ b/internal/p2p/transport_mconn.go @@ -147,11 +147,15 @@ func (m *MConnTransport) Accept(ctx context.Context) (Connection, error) { if err != nil { select { case errCh <- err: + case <-m.doneCh: + m.logger.Debug("MConnTransport Accept: connection closed - doneCh") case <-ctx.Done(): } } select { case conCh <- tcpConn: + case <-m.doneCh: + m.logger.Debug("MConnTransport Accept: connection closed - doneCh") case <-ctx.Done(): } }() @@ -187,12 +191,10 @@ func (m *MConnTransport) Dial(ctx context.Context, endpoint *Endpoint) (Connecti tcpConn, err := dialer.DialContext(ctx, "tcp", net.JoinHostPort( endpoint.IP.String(), strconv.Itoa(int(endpoint.Port)))) if err != nil { - select { - case <-ctx.Done(): - return nil, ctx.Err() - default: - return nil, err + if e := ctx.Err(); e != nil { + return nil, e } + return nil, err } return newMConnConnection(m.logger, tcpConn, m.mConnConfig, m.channelDescs), nil @@ -313,6 +315,7 @@ func (c *mConnConnection) Handshake( select { case errCh <- err: + case <-c.doneCh: case <-handshakeCtx.Done(): } @@ -322,7 +325,8 @@ func (c *mConnConnection) Handshake( case <-handshakeCtx.Done(): _ = c.Close() return types.NodeInfo{}, nil, handshakeCtx.Err() - + case <-c.doneCh: + return types.NodeInfo{}, nil, io.EOF case err := <-errCh: if err != nil { return types.NodeInfo{}, nil, err @@ -365,6 +369,7 @@ func (c *mConnConnection) handshake( _, err := protoio.NewDelimitedWriter(secretConn).WriteMsg(nodeInfo.ToProto()) select { case errCh <- err: + case <-c.doneCh: case <-ctx.Done(): } @@ -375,6 +380,7 @@ func (c *mConnConnection) handshake( _, err := protoio.NewDelimitedReader(secretConn, types.MaxNodeInfoSize()).ReadMsg(&pbPeerInfo) select { case errCh <- err: + case <-c.doneCh: case <-ctx.Done(): } }() @@ -410,6 +416,7 @@ func (c *mConnConnection) handshake( func (c *mConnConnection) onReceive(ctx context.Context, chID ChannelID, payload []byte) { select { case c.receiveCh <- mConnMessage{channelID: chID, payload: payload}: + case <-c.doneCh: case <-ctx.Done(): } } @@ -426,6 +433,7 @@ func (c *mConnConnection) onError(ctx context.Context, e interface{}) { _ = c.Close() select { case c.errorCh <- err: + case <-c.doneCh: case <-ctx.Done(): } } @@ -445,6 +453,8 @@ func (c *mConnConnection) SendMessage(ctx context.Context, chID ChannelID, msg [ return err case <-ctx.Done(): return io.EOF + case <-c.doneCh: + return io.EOF default: if ok := c.mconn.Send(chID, msg); !ok { return errors.New("sending message timed out") From c90576edc5231d7e142538225fd199d1a6db15f0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:48:05 +0100 Subject: [PATCH 060/111] chore(p2p): drait EnqueueTimeout chan safely --- internal/p2p/router.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 1b972e6e7c..1edbae701d 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -768,6 +768,7 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec r.logger.Debug("routePeer: closed conn and send queue, waiting for all goroutines to finish", "peer", peerID, "err", err) wg.Wait() + r.logger.Debug("routePeer: all goroutines finished", "peer", peerID, "err", err) // Drain the error channel; these should typically not be interesting FOR: @@ -807,18 +808,15 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn defer timeout.Stop() for { - r.logger.Debug("receivePeer: before ReceiveMessage", "peer", peerID) chID, bz, err := conn.ReceiveMessage(ctx) if err != nil { return err } - r.logger.Debug("receivePeer: before RLock", "peer", peerID, "chID", chID) r.channelMtx.RLock() queue, queueOk := r.channelQueues[chID] chDesc, chDescOk := r.chDescs[chID] r.channelMtx.RUnlock() - r.logger.Debug("receivePeer: after RUnlock", "peer", peerID, "chID", chID) if !queueOk || !chDescOk { r.logger.Debug("dropping message for unknown channel", @@ -841,9 +839,12 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn envelope.From = peerID envelope.ChannelID = chID - if !timeout.Stop() { - <-timeout.C + timeout.Stop() + select { + case <-timeout.C: + default: } + if chDesc.EnqueueTimeout > 0 { timeout.Reset(chDesc.EnqueueTimeout) } else { @@ -873,6 +874,7 @@ func (r *Router) receivePeer(ctx context.Context, peerID types.NodeID, conn Conn ) case <-ctx.Done(): + r.logger.Debug("receivePeer: ctx is done", "peer", peerID, "channel", chID) return nil } } From feeae960fb634163c30e6e7c99089bff20fcf36a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:46:57 +0100 Subject: [PATCH 061/111] fix(mempool): mempool size not decreased on RemoveTxByKey --- internal/mempool/mempool.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index e8f5bf1ff4..2713093e6f 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -245,7 +245,11 @@ func (txmp *TxMempool) CheckTx( func (txmp *TxMempool) RemoveTxByKey(txKey types.TxKey) error { txmp.mtx.Lock() defer txmp.mtx.Unlock() - return txmp.removeTxByKey(txKey) + if err := txmp.removeTxByKey(txKey); err != nil { + return err + } + txmp.metrics.Size.Add(-1) + return nil } // removeTxByKey removes the specified transaction key from the mempool. From 5bf16e261cf9609b287703d787b8ac359286c96f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 08:58:00 +0100 Subject: [PATCH 062/111] refactor(mempool): use tmsync.Waker for available txs notifications --- internal/consensus/state.go | 2 ++ internal/consensus/vote_signer.go | 5 +++-- internal/mempool/mempool.go | 20 +++++++++++--------- internal/mempool/reactor.go | 3 ++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 3bac2e6037..47fc5a4fc6 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -768,6 +768,8 @@ func (cs *State) handleTimeout( } func (cs *State) handleTxsAvailable(ctx context.Context, stateData *StateData) { + // TODO: Change to trace + cs.logger.Debug("new transactions are available", "height", stateData.Height, "round", stateData.Round, "step", stateData.Step) // We only need to do this for round 0. if stateData.Round != 0 { return diff --git a/internal/consensus/vote_signer.go b/internal/consensus/vote_signer.go index 470d154125..e649261147 100644 --- a/internal/consensus/vote_signer.go +++ b/internal/consensus/vote_signer.go @@ -34,8 +34,9 @@ func (s *voteSigner) signAddVote( } // If the node not in the validator set, do nothing. if !stateData.Validators.HasProTxHash(s.privValidator.ProTxHash) { - s.logger.Error("do nothing, node %s is not a part of validator set %+v", - s.privValidator.ProTxHash.ShortString(), stateData.Validators) + s.logger.Error("do nothing, node is not a part of validator set", + "protxhash", s.privValidator.ProTxHash.ShortString(), + "validators", stateData.Validators) return nil } keyVals := []any{"height", stateData.Height, "round", stateData.Round, "quorum_hash", stateData.Validators.QuorumHash} diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 2713093e6f..72f4dbbf58 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -16,6 +16,7 @@ import ( "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/internal/libs/clist" tmstrings "github.com/dashpay/tenderdash/internal/libs/strings" + tmsync "github.com/dashpay/tenderdash/internal/libs/sync" "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/types" ) @@ -48,7 +49,7 @@ type TxMempool struct { // Synchronized fields, protected by mtx. mtx *sync.RWMutex notifiedTxsAvailable bool - txsAvailable chan struct{} // one value sent per height when mempool is not empty + txsAvailable *tmsync.Waker preCheck PreCheckFunc postCheck PostCheckFunc height int64 // the latest height passed to Update @@ -146,12 +147,12 @@ func (txmp *TxMempool) EnableTxsAvailable() { txmp.mtx.Lock() defer txmp.mtx.Unlock() - txmp.txsAvailable = make(chan struct{}, 1) + txmp.txsAvailable = tmsync.NewWaker() } // TxsAvailable returns a channel which fires once for every height, and only // when transactions are available in the mempool. It is thread-safe. -func (txmp *TxMempool) TxsAvailable() <-chan struct{} { return txmp.txsAvailable } +func (txmp *TxMempool) TxsAvailable() <-chan struct{} { return txmp.txsAvailable.Sleep() } // CheckTx adds the given transaction to the mempool if it fits and passes the // application's ABCI CheckTx method. @@ -771,8 +772,7 @@ func (txmp *TxMempool) recheckTransactions(ctx context.Context) { // When recheck is complete, trigger a notification for more transactions. _ = g.Wait() - txmp.mtx.Lock() - defer txmp.mtx.Unlock() + txmp.notifyTxsAvailable() }() } @@ -827,6 +827,11 @@ func (txmp *TxMempool) purgeExpiredTxs(blockHeight int64) { } } +// notifyTxsAvailable triggers a notification that transactions are available in +// the mempool. It is a no-op if the mempool is empty or if a notification has +// already been sent. +// +// No locking is required to call this method. func (txmp *TxMempool) notifyTxsAvailable() { if txmp.Size() == 0 { return // nothing to do @@ -836,9 +841,6 @@ func (txmp *TxMempool) notifyTxsAvailable() { // channel cap is 1, so this will send once txmp.notifiedTxsAvailable = true - select { - case txmp.txsAvailable <- struct{}{}: - default: - } + txmp.txsAvailable.Wake() } } diff --git a/internal/mempool/reactor.go b/internal/mempool/reactor.go index 6794e8a62a..2e3e16656d 100644 --- a/internal/mempool/reactor.go +++ b/internal/mempool/reactor.go @@ -29,7 +29,8 @@ type Reactor struct { cfg *config.MempoolConfig mempool *TxMempool - ids *IDs + // Peer IDs assigned for peers + ids *IDs peerEvents p2p.PeerEventSubscriber p2pClient *client.Client From 1870ef95ae8a9244e365462e8ca91af11cf4ee0b Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:23:36 +0100 Subject: [PATCH 063/111] fix(mempool): mark tx as delivered after it's sent --- internal/mempool/reactor.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/mempool/reactor.go b/internal/mempool/reactor.go index 2e3e16656d..c24df4564f 100644 --- a/internal/mempool/reactor.go +++ b/internal/mempool/reactor.go @@ -205,6 +205,9 @@ func (r *Reactor) broadcastTxRoutine(ctx context.Context, peerID types.NodeID) { r.logger.Error("failed to gossip transaction", "peerID", peerID, "error", err) return } + // This is optimistic approach, we assume that the transaction was successfully + // gossiped to the peer. + memTx.SetPeer(peerMempoolID) r.logger.Debug("gossiped tx to peer", "tx", tmstrings.LazySprintf("%X", memTx.tx.Hash()), From 718339acb58f49a6124778ac639287f02d0eacc0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:36:47 +0100 Subject: [PATCH 064/111] fix(p2p): peerManager.Disconnected context expires too soon --- internal/p2p/router.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 1edbae701d..fc14034dea 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -703,7 +703,8 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec r.peerManager.Ready(ctx, peerID, channels) // we use context to manage the lifecycle of the peer - ctx, cancel := context.WithCancel(ctx) + // note that original ctx will be used in cleanup + ioCtx, cancel := context.WithCancel(ctx) defer cancel() sendQueue := r.getOrMakeQueue(peerID, channels) @@ -732,16 +733,16 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec go func() { select { - case errCh <- r.receivePeer(ctx, peerID, conn): - case <-ctx.Done(): + case errCh <- r.receivePeer(ioCtx, peerID, conn): + case <-ioCtx.Done(): } wg.Done() }() go func() { select { - case errCh <- r.sendPeer(ctx, peerID, conn, sendQueue): - case <-ctx.Done(): + case errCh <- r.sendPeer(ioCtx, peerID, conn, sendQueue): + case <-ioCtx.Done(): } wg.Done() }() @@ -756,9 +757,9 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec select { case err = <-errCh: r.logger.Debug("routePeer: received error from subroutine 1", "peer", peerID, "err", err) - case <-ctx.Done(): + case <-ioCtx.Done(): r.logger.Debug("routePeer: ctx done", "peer", peerID) - ctxErr = ctx.Err() + ctxErr = ioCtx.Err() } // goroutine 1 has finished, so we can cancel the context and close everything From 3a37576b68d4d68e5d34ef87f61fa754c7e3db05 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:37:19 +0100 Subject: [PATCH 065/111] doc(config): improve mempool.cache-size docs --- config/config.go | 1 + config/toml.go | 1 + 2 files changed, 2 insertions(+) diff --git a/config/config.go b/config/config.go index 985236acef..7f469e9597 100644 --- a/config/config.go +++ b/config/config.go @@ -788,6 +788,7 @@ type MempoolConfig struct { MaxTxsBytes int64 `mapstructure:"max-txs-bytes"` // Size of the cache (used to filter transactions we saw earlier) in transactions + // Should be much bigger than mempool size. CacheSize int `mapstructure:"cache-size"` // Do not remove invalid transactions from the cache (default: false) diff --git a/config/toml.go b/config/toml.go index d3e7aa2eca..2347673f80 100644 --- a/config/toml.go +++ b/config/toml.go @@ -389,6 +389,7 @@ size = {{ .Mempool.Size }} max-txs-bytes = {{ .Mempool.MaxTxsBytes }} # Size of the cache (used to filter transactions we saw earlier) in transactions +# Should be much bigger than mempool size. cache-size = {{ .Mempool.CacheSize }} # Do not remove invalid transactions from the cache (default: false) From eb3b0bb18558f408aadd645505e187b228bb4179 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:21:47 +0100 Subject: [PATCH 066/111] Revert "fix(mempool): mark tx as delivered after it's sent" This reverts commit 1870ef95ae8a9244e365462e8ca91af11cf4ee0b. --- internal/mempool/reactor.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/mempool/reactor.go b/internal/mempool/reactor.go index c24df4564f..99d9d4ae3b 100644 --- a/internal/mempool/reactor.go +++ b/internal/mempool/reactor.go @@ -195,6 +195,8 @@ func (r *Reactor) broadcastTxRoutine(ctx context.Context, peerID types.NodeID) { memTx := nextGossipTx.Value.(*WrappedTx) + // We expect the peer to send tx back once it gets it, and that's + // when we will mark it as seen. // NOTE: Transaction batching was disabled due to: // https://github.com/tendermint/tendermint/issues/5796 if !memTx.HasPeer(peerMempoolID) { @@ -205,9 +207,6 @@ func (r *Reactor) broadcastTxRoutine(ctx context.Context, peerID types.NodeID) { r.logger.Error("failed to gossip transaction", "peerID", peerID, "error", err) return } - // This is optimistic approach, we assume that the transaction was successfully - // gossiped to the peer. - memTx.SetPeer(peerMempoolID) r.logger.Debug("gossiped tx to peer", "tx", tmstrings.LazySprintf("%X", memTx.tx.Hash()), From 7f254b9904afacdfc5d0c600b1c741cc5a721c54 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:23:35 +0100 Subject: [PATCH 067/111] chore: mempool channel rate limit to 5/sec --- internal/p2p/channel_params.go | 6 +++--- internal/p2p/conn/connection.go | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index fffe5a60d6..481fe2e86c 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -80,9 +80,9 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 1000, Name: "mempool", - // SendRateLimit: 5, - // SendRateBurst: 20, - EnqueueTimeout: 10 * time.Millisecond, + SendRateLimit: 5, + SendRateBurst: 20, + EnqueueTimeout: 10 * time.Millisecond, }, } diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index caddd900db..ebb1061e71 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -622,6 +622,8 @@ type ChannelDescriptor struct { Name string // Timeout for enqueue operations on the incoming queue. + // It is applied to all messages received from remote peer + // and delievered to this channel. // When timeout expires, messages will be silently dropped. // // If zero, enqueue operations will not time out. From 1d5f72f4976fa936983d6efa3970569b3e2e6ad6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:25:22 +0100 Subject: [PATCH 068/111] chore(mempool): add some TODOs --- internal/p2p/channel_params.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 481fe2e86c..4debeab4ea 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -80,8 +80,8 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 1000, Name: "mempool", - SendRateLimit: 5, - SendRateBurst: 20, + SendRateLimit: 5, // TODO: make it configurable + SendRateBurst: 20, // TODO: make it configurable EnqueueTimeout: 10 * time.Millisecond, }, } From 52c698328189ea093b20c2624931f2ea19f424dd Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:54:04 +0100 Subject: [PATCH 069/111] test(abciclient): test parallel execution of grpc abci client and server --- abci/client/grpc_client_test.go | 114 ++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 abci/client/grpc_client_test.go diff --git a/abci/client/grpc_client_test.go b/abci/client/grpc_client_test.go new file mode 100644 index 0000000000..86b6a2399e --- /dev/null +++ b/abci/client/grpc_client_test.go @@ -0,0 +1,114 @@ +package abciclient_test + +import ( + "context" + "fmt" + "sync" + "testing" + "time" + + "github.com/fortytw2/leaktest" + + abciclient "github.com/dashpay/tenderdash/abci/client" + abciserver "github.com/dashpay/tenderdash/abci/server" + "github.com/dashpay/tenderdash/abci/types" + "github.com/dashpay/tenderdash/libs/log" + "github.com/dashpay/tenderdash/libs/service" +) + +// TestGRPCClientServerParallel tests that gRPC client and server can handle multiple parallel requests +func TestGRPCClientServerParallel(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + logger := log.NewNopLogger() + app := &mockApplication{t: t} + + socket := t.TempDir() + "/grpc_test" + client, _, err := makeGRPCClientServer(ctx, t, logger, app, socket) + if err != nil { + t.Fatal(err) + } + + // we'll use that mutex to ensure threads don't finish before we check status + app.mtx.Lock() + + const threads = 5 + // started will be marked as done as soon as app.Info() handler executes on the server + app.started.Add(threads) + // done will be used to wait for all threads to finish + var done sync.WaitGroup + done.Add(threads) + + for i := 0; i < threads; i++ { + thread := uint64(i) + go func() { + _, _ = client.Info(ctx, &types.RequestInfo{BlockVersion: thread}) + done.Done() + }() + } + + // wait for threads to execute + // note it doesn't mean threads are really done, as they are waiting on the mtx + // so if all `started` are marked as done, it means all threads have started + // in parallel + app.started.Wait() + + // unlock the mutex so that threads can finish their execution + app.mtx.Unlock() + + // wait for all threads to really finish + done.Wait() +} + +func makeGRPCClientServer( + ctx context.Context, + t *testing.T, + logger log.Logger, + app types.Application, + name string, +) (abciclient.Client, service.Service, error) { + ctx, cancel := context.WithCancel(ctx) + t.Cleanup(cancel) + t.Cleanup(leaktest.Check(t)) + + // Start the listener + socket := fmt.Sprintf("unix://%s.sock", name) + + server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, app) + + if err := server.Start(ctx); err != nil { + cancel() + return nil, nil, err + } + + client := abciclient.NewGRPCClient(logger.With("module", "abci-client"), socket, true) + + if err := client.Start(ctx); err != nil { + cancel() + return nil, nil, err + } + return client, server, nil +} + +// mockApplication that will decrease mcokApplication.started when called Info, and then wait until +// mtx is unlocked before it finishes +type mockApplication struct { + types.BaseApplication + mtx sync.Mutex + // we'll use that to ensure all threads have started + started sync.WaitGroup + + t *testing.T +} + +func (m *mockApplication) Info(_ctx context.Context, req *types.RequestInfo) (res *types.ResponseInfo, err error) { + m.t.Logf("Info %d called", req.BlockVersion) + // mark wg as done to signal that we have executed + m.started.Done() + // we will wait here until all threads mark wg as done + m.mtx.Lock() + defer m.mtx.Unlock() + m.t.Logf("Info %d finished", req.BlockVersion) + return &types.ResponseInfo{}, nil +} From c77d710135ff3dcde6d9ff825788deede689ff5f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:20:18 +0100 Subject: [PATCH 070/111] chore(mempool): remove unnecessary tx hash calculation --- internal/mempool/mempool.go | 20 ++++++++++---------- types/mempool.go | 5 +++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 72f4dbbf58..8f4200e59b 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -486,7 +486,7 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon txmp.logger.Info( "rejected bad transaction", "priority", wtx.Priority(), - "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "tx", fmt.Sprintf("%X", wtx.hash), "peer_id", wtx.peers, "code", checkTxRes.Code, "post_check_err", err, @@ -521,13 +521,13 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon w := elt.Value.(*WrappedTx) txmp.logger.Debug( "rejected valid incoming transaction; tx already exists for sender", - "tx", fmt.Sprintf("%X", w.tx.Hash()), + "tx", fmt.Sprintf("%X", w.hash), "sender", sender, ) txmp.metrics.RejectedTxs.Add(1) // TODO(creachadair): Report an error for a duplicate sender. // This is an API change, unfortunately, but should be made safe if it isn't. - // fmt.Errorf("transaction rejected: tx already exists for sender %q (%X)", sender, w.tx.Hash()) + // fmt.Errorf("transaction rejected: tx already exists for sender %q (%X)", sender, w.hash) return nil } } @@ -567,7 +567,7 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon }) txmp.logger.Debug("evicting lower-priority transactions", - "new_tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), + "new_tx", tmstrings.LazySprintf("%X", wtx.hash), "new_priority", priority) // Evict as many of the victims as necessary to make room. @@ -593,13 +593,13 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon txmp.cache.Remove(wtx.tx) txmp.logger.Error( "rejected valid incoming transaction; mempool is full", - "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "tx", fmt.Sprintf("%X", wtx.hash), "err", err.Error(), ) txmp.metrics.RejectedTxs.Add(1) // TODO(creachadair): Report an error for a full mempool. // This is an API change, unfortunately, but should be made safe if it isn't. - // fmt.Errorf("transaction rejected: mempool is full (%X)", wtx.tx.Hash()) + // fmt.Errorf("transaction rejected: mempool is full (%X)", wtx.hash) return nil } } @@ -622,7 +622,7 @@ func (txmp *TxMempool) addNewTransaction(wtx *WrappedTx, checkTxRes *abci.Respon txmp.logger.Debug( "inserted new valid transaction", "priority", wtx.Priority(), - "tx", tmstrings.LazySprintf("%X", wtx.tx.Hash()), + "tx", tmstrings.LazySprintf("%X", wtx.hash), "height", txmp.height, "num_txs", txmp.Size(), ) @@ -649,7 +649,7 @@ func (txmp *TxMempool) evict(size int64, victims []*clist.CElement) bool { txmp.logger.Debug( "evicted valid existing transaction; mempool full", - "old_tx", tmstrings.LazySprintf("%X", w.tx.Hash()), + "old_tx", tmstrings.LazySprintf("%X", w.hash), "old_priority", w.priority, ) txmp.removeTxByElement(vic) @@ -711,7 +711,7 @@ func (txmp *TxMempool) handleRecheckResult(tx types.Tx, checkTxRes *abci.Respons txmp.logger.Debug( "existing transaction no longer valid; failed re-CheckTx callback", "priority", wtx.Priority(), - "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "tx", fmt.Sprintf("%X", wtx.hash), "err", err, "code", checkTxRes.Code, ) @@ -759,7 +759,7 @@ func (txmp *TxMempool) recheckTransactions(ctx context.Context) { }) if err != nil { txmp.logger.Error("failed to execute CheckTx during recheck", - "err", err, "hash", fmt.Sprintf("%x", wtx.tx.Hash())) + "err", err, "hash", fmt.Sprintf("%x", wtx.hash)) } else { txmp.handleRecheckResult(wtx.tx, rsp) } diff --git a/types/mempool.go b/types/mempool.go index fa0f8a2082..4b61eff8f2 100644 --- a/types/mempool.go +++ b/types/mempool.go @@ -2,6 +2,7 @@ package types import ( "crypto/sha256" + "encoding/hex" "errors" "fmt" ) @@ -12,6 +13,10 @@ var ErrTxInCache = errors.New("tx already exists in cache") // TxKey is the fixed length array key used as an index. type TxKey [sha256.Size]byte +func (k TxKey) String() string { + return hex.EncodeToString(k[:]) +} + // ErrTxTooLarge defines an error when a transaction is too big to be sent in a // message to other peers. type ErrTxTooLarge struct { From e843216e5c35c23eb4ecfedf013ecd3548c27d79 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:27:22 +0100 Subject: [PATCH 071/111] fix(mempool): cancel previous mempool run when starting new one --- internal/mempool/mempool.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index 8f4200e59b..aa94649587 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -57,6 +57,9 @@ type TxMempool struct { txs *clist.CList // valid transactions (passed CheckTx) txByKey map[types.TxKey]*clist.CElement txBySender map[string]*clist.CElement // for sender != "" + + // cancellation function for recheck txs tasks + recheckCancel context.CancelFunc } // NewTxMempool constructs a new, empty priority mempool at the specified @@ -730,6 +733,12 @@ func (txmp *TxMempool) handleRecheckResult(tx types.Tx, checkTxRes *abci.Respons // Precondition: The mempool is not empty. // The caller must hold txmp.mtx exclusively. func (txmp *TxMempool) recheckTransactions(ctx context.Context) { + // cancel previous recheck if it is still running + if txmp.recheckCancel != nil { + txmp.recheckCancel() + } + ctx, txmp.recheckCancel = context.WithCancel(ctx) + if txmp.Size() == 0 { panic("mempool: cannot run recheck on an empty mempool") } @@ -753,6 +762,10 @@ func (txmp *TxMempool) recheckTransactions(ctx context.Context) { for _, wtx := range wtxs { wtx := wtx start(func() error { + if err := ctx.Err(); err != nil { + txmp.logger.Trace("recheck txs task canceled", "err", err, "tx", wtx.hash.String()) + return err + } rsp, err := txmp.proxyAppConn.CheckTx(ctx, &abci.RequestCheckTx{ Tx: wtx.tx, Type: abci.CheckTxType_Recheck, From f7f7ce7fdc0cfcefac9465a7dc9a9913d80d4afd Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:10:04 +0100 Subject: [PATCH 072/111] feat(p2p): channel recv rate limiting - not tested --- internal/consensus/peer_state.go | 3 + internal/p2p/channel.go | 137 +++++++++++++++++++---- internal/p2p/client/chanstore.go | 2 +- internal/p2p/client/client.go | 2 +- internal/p2p/client/client_test.go | 6 +- internal/p2p/conn/connection.go | 9 ++ internal/p2p/router.go | 7 +- internal/p2p/throttled_channel.go | 56 ++++++++-- internal/p2p/throttled_channel_test.go | 143 ++++++++++++++++++++++--- 9 files changed, 313 insertions(+), 52 deletions(-) diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index a060fc8104..c094d829ca 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -483,6 +483,9 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { ps.mtx.Lock() defer ps.mtx.Unlock() + // TODO change to TRACE + ps.logger.Debug("apply new round step message", "peer", ps.peerID, "msg", msg.String()) + // ignore duplicates or decreases if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 { return diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go index 9e8cb3283d..96fd6b37d0 100644 --- a/internal/p2p/channel.go +++ b/internal/p2p/channel.go @@ -12,11 +12,17 @@ import ( "github.com/gogo/protobuf/proto" "github.com/rs/zerolog" sync "github.com/sasha-s/go-deadlock" + "golang.org/x/time/rate" + log "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/proto/tendermint/p2p" "github.com/dashpay/tenderdash/types" ) +var ( + ErrRecvRateLimitExceeded = errors.New("receive rate limit exceeded") +) + // Envelope contains a message with sender/receiver routing info. type Envelope struct { From types.NodeID // sender (empty if outbound) @@ -117,7 +123,7 @@ type Channel interface { Send(context.Context, Envelope) error SendError(context.Context, PeerError) error - Receive(context.Context) *ChannelIterator + Receive(context.Context) ChannelIterator } // PeerError is a peer error reported via Channel.Error. @@ -194,8 +200,8 @@ func (ch *legacyChannel) String() string { return fmt.Sprintf("p2p.Channel<%d:%s // Receive returns a new unbuffered iterator to receive messages from ch. // The iterator runs until ctx ends. -func (ch *legacyChannel) Receive(ctx context.Context) *ChannelIterator { - iter := &ChannelIterator{ +func (ch *legacyChannel) Receive(ctx context.Context) ChannelIterator { + iter := &channelIterator{ pipe: make(chan Envelope), // unbuffered } go func(pipe chan<- Envelope) { @@ -216,32 +222,38 @@ func (ch *legacyChannel) Receive(ctx context.Context) *ChannelIterator { return iter } -// ChannelIterator provides a context-aware path for callers +// ChannelIterator is an iterator for receiving messages from a Channel. +type ChannelIterator interface { + // Next returns true when the Envelope value has advanced, and false + // when the context is canceled or iteration should stop. If an iterator has returned false, + // it will never return true again. + // in general, use Next, as in: + // + // for iter.Next(ctx) { + // envelope := iter.Envelope() + // // ... do things ... + // } + Next(ctx context.Context) bool + Envelope() *Envelope +} + +// channelIterator provides a context-aware path for callers // (reactors) to process messages from the P2P layer without relying // on the implementation details of the P2P layer. Channel provides // access to it's Outbound stream as an iterator, and the // MergedChannelIterator makes it possible to combine multiple // channels into a single iterator. -type ChannelIterator struct { +type channelIterator struct { pipe chan Envelope current *Envelope } -// NewChannelIterator returns a new instance of ChannelIterator -func NewChannelIterator(pipe chan Envelope) *ChannelIterator { - return &ChannelIterator{pipe: pipe} +// NewChannelIterator returns a new instance of channelIterator +func NewChannelIterator(pipe chan Envelope) ChannelIterator { + return &channelIterator{pipe: pipe} } -// Next returns true when the Envelope value has advanced, and false -// when the context is canceled or iteration should stop. If an iterator has returned false, -// it will never return true again. -// in general, use Next, as in: -// -// for iter.Next(ctx) { -// envelope := iter.Envelope() -// // ... do things ... -// } -func (iter *ChannelIterator) Next(ctx context.Context) bool { +func (iter *channelIterator) Next(ctx context.Context) bool { select { case <-ctx.Done(): iter.current = nil @@ -262,15 +274,15 @@ func (iter *ChannelIterator) Next(ctx context.Context) bool { // iterator. When the last call to Next returned true, Envelope will // return a non-nil object. If Next returned false then Envelope is // always nil. -func (iter *ChannelIterator) Envelope() *Envelope { return iter.current } +func (iter *channelIterator) Envelope() *Envelope { return iter.current } // MergedChannelIterator produces an iterator that merges the // messages from the given channels in arbitrary order. // // This allows the caller to consume messages from multiple channels // without needing to manage the concurrency separately. -func MergedChannelIterator(ctx context.Context, chs ...Channel) *ChannelIterator { - iter := &ChannelIterator{ +func MergedChannelIterator(ctx context.Context, chs ...Channel) ChannelIterator { + iter := &channelIterator{ pipe: make(chan Envelope), // unbuffered } wg := new(sync.WaitGroup) @@ -304,3 +316,86 @@ func MergedChannelIterator(ctx context.Context, chs ...Channel) *ChannelIterator return iter } + +type throttledChannelIterator struct { + innerChan Channel + innerIter ChannelIterator + limiter *rate.Limiter + reportErr bool + logger log.Logger +} + +// ThrottledChannelIterator wraps an existing channel iterator with a rate limiter. +// +// ## Arguments +// - ctx: the context in which the iterator will run +// - limiter: the rate limiter to use +// - innerIterator: the underlying iterator to use +// - reportError: if true, errors will be sent to the channel whenever the rate limit is exceeded; otherwise +// the messages will be dropped without error +// - innerChannel: the channel related; errors will be sent to this channel, also used for logging +// - logger: the logger to use +func ThrottledChannelIterator(ctx context.Context, limiter *rate.Limiter, innerIterator ChannelIterator, + reportError bool, innerChannel Channel, logger log.Logger) (ChannelIterator, error) { + if innerChannel == nil { + if reportError { + return nil, fmt.Errorf("inner channel is required to report errors") + } + } else { + logger = logger.With("channel", innerChannel) + } + + throttledChannelIterator := &throttledChannelIterator{ + innerChan: innerChannel, + innerIter: innerIterator, + limiter: limiter, + reportErr: reportError, + logger: logger, + } + + return throttledChannelIterator, nil +} + +func (tci *throttledChannelIterator) Next(ctx context.Context) bool { + if tci.innerIter == nil { + tci.logger.Error("inner channel iterator is nil", "channel", tci.innerChan) + return false + } + + for { + if ctx.Err() != nil { + return false + } + + if !tci.innerIter.Next(ctx) { + return false + } + + // If the limiter allows the message to be sent, we break the loop + if tci.limiter.Allow() { + break + } + e := tci.innerIter.Envelope() + if tci.reportErr && e != nil { + tci.innerChan.SendError(ctx, PeerError{ + NodeID: e.From, + Err: ErrRecvRateLimitExceeded, + Fatal: false, + }) + + } else { + tci.logger.Trace("dropping message due to rate limit", "channel", tci.innerChan, "rate", tci.limiter.Limit()) + } + } + + return true +} + +func (tci *throttledChannelIterator) Envelope() *Envelope { + if tci.innerIter == nil { + tci.logger.Error("inner channel iterator is nil", "channel", tci.innerChan) + return nil + } + + return tci.innerIter.Envelope() +} diff --git a/internal/p2p/client/chanstore.go b/internal/p2p/client/chanstore.go index e49c3994f4..e25858f6a5 100644 --- a/internal/p2p/client/chanstore.go +++ b/internal/p2p/client/chanstore.go @@ -31,7 +31,7 @@ func newChanStore(descriptors map[p2p.ChannelID]*p2p.ChannelDescriptor, creator return store } -func (c *chanStore) iter(ctx context.Context, chanIDs ...p2p.ChannelID) (*p2p.ChannelIterator, error) { +func (c *chanStore) iter(ctx context.Context, chanIDs ...p2p.ChannelID) (p2p.ChannelIterator, error) { chans := make([]p2p.Channel, 0, len(chanIDs)) for _, chanID := range chanIDs { ch, err := c.get(ctx, chanID) diff --git a/internal/p2p/client/client.go b/internal/p2p/client/client.go index 3ea4009090..8aaa4206b2 100644 --- a/internal/p2p/client/client.go +++ b/internal/p2p/client/client.go @@ -272,7 +272,7 @@ func (c *Client) Consume(ctx context.Context, params ConsumerParams) error { return c.iter(ctx, iter, params.Handler) } -func (c *Client) iter(ctx context.Context, iter *p2p.ChannelIterator, handler ConsumerHandler) error { +func (c *Client) iter(ctx context.Context, iter p2p.ChannelIterator, handler ConsumerHandler) error { for iter.Next(ctx) { envelope := iter.Envelope() if isMessageResolvable(envelope.Message) { diff --git a/internal/p2p/client/client_test.go b/internal/p2p/client/client_test.go index 5a02123db0..50a88c4bb4 100644 --- a/internal/p2p/client/client_test.go +++ b/internal/p2p/client/client_test.go @@ -185,7 +185,7 @@ func (suite *ChannelTestSuite) TestConsumeHandle() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) consumer := newMockConsumer(suite.T()) @@ -226,7 +226,7 @@ func (suite *ChannelTestSuite) TestConsumeResolve() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) resCh := suite.client.addPending(reqID) @@ -278,7 +278,7 @@ func (suite *ChannelTestSuite) TestConsumeError() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) consumer := newMockConsumer(suite.T()) diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index ebb1061e71..8c4de11ae9 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -610,9 +610,18 @@ type ChannelDescriptor struct { SendQueueCapacity int RecvMessageCapacity int + /// SendRateLimit is used to limit the rate of sending messages, per second. SendRateLimit rate.Limit SendRateBurst int + /// RecvRateLimit is used to limit the rate of receiving messages, per second. + RecvRateLimit rate.Limit + RecvRateBurst int + // RecvRateShouldErr is used to determine if the rate limiter should + // report an error whenever recv rate limit is exceeded, most likely + // causing the peer to disconnect. + RecvRateShouldErr bool + // RecvBufferCapacity defines the max buffer size of inbound messages for a // given p2p Channel queue. RecvBufferCapacity int diff --git a/internal/p2p/router.go b/internal/p2p/router.go index fc14034dea..5c494fb91c 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -263,8 +263,11 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (Ch outCh := make(chan Envelope, chDesc.RecvBufferCapacity) errCh := make(chan PeerError, chDesc.RecvBufferCapacity) channel := NewChannel(chDesc.ID, chDesc.Name, queue.dequeue(), outCh, errCh) - if chDesc.SendRateLimit > 0 { - channel = NewThrottledChannel(channel, chDesc.SendRateLimit, chDesc.SendRateBurst) + if chDesc.SendRateLimit > 0 || chDesc.RecvRateLimit > 0 { + channel = NewThrottledChannel(channel, + chDesc.SendRateLimit, chDesc.SendRateBurst, + chDesc.RecvRateLimit, chDesc.RecvRateBurst, chDesc.RecvRateShouldErr, + r.logger) } r.channelQueues[id] = queue diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go index bf7d0e06b7..f82f0374b2 100644 --- a/internal/p2p/throttled_channel.go +++ b/internal/p2p/throttled_channel.go @@ -4,21 +4,44 @@ import ( "context" "golang.org/x/time/rate" + + "github.com/dashpay/tenderdash/libs/log" ) // / Channel that will block if the send limit is reached type ThrottledChannel struct { - channel Channel - limiter *rate.Limiter + channel Channel + sendLimiter *rate.Limiter + recvLimiter *rate.Limiter + recvShouldErr bool + + logger log.Logger } // NewThrottledChannel creates a new throttled channel. // The rate is specified in messages per second. // The burst is specified in messages. -func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { +func NewThrottledChannel(channel Channel, sendLimit rate.Limit, sendBurst int, + recvLimit rate.Limit, recvBurst int, recvShouldErr bool, + logger log.Logger) *ThrottledChannel { + + var ( + sendLimiter *rate.Limiter + recvLimiter *rate.Limiter + ) + if sendLimit > 0 { + sendLimiter = rate.NewLimiter(sendLimit, sendBurst) + } + if recvLimit > 0 { + recvLimiter = rate.NewLimiter(recvLimit, recvBurst) + } + return &ThrottledChannel{ - channel: channel, - limiter: rate.NewLimiter(r, burst), + channel: channel, + sendLimiter: sendLimiter, + recvLimiter: recvLimiter, + recvShouldErr: recvShouldErr, + logger: logger, } } @@ -26,8 +49,10 @@ var _ Channel = (*ThrottledChannel)(nil) func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { // Wait until limiter allows us to proceed. - if err := ch.limiter.Wait(ctx); err != nil { - return err + if ch.sendLimiter != nil { + if err := ch.sendLimiter.Wait(ctx); err != nil { + return err + } } return ch.channel.Send(ctx, envelope) @@ -35,15 +60,26 @@ func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { func (ch *ThrottledChannel) SendError(ctx context.Context, pe PeerError) error { // Wait until limiter allows us to proceed. - if err := ch.limiter.Wait(ctx); err != nil { + if err := ch.sendLimiter.Wait(ctx); err != nil { return err } return ch.channel.SendError(ctx, pe) } -func (ch *ThrottledChannel) Receive(ctx context.Context) *ChannelIterator { - return ch.channel.Receive(ctx) +func (ch *ThrottledChannel) Receive(ctx context.Context) ChannelIterator { + if ch.recvLimiter == nil { + return ch.channel.Receive(ctx) + } + + innerIter := ch.channel.Receive(ctx) + iter, err := ThrottledChannelIterator(ctx, ch.recvLimiter, innerIter, ch.recvShouldErr, ch.channel, ch.logger) + if err != nil { + ch.logger.Error("error creating ThrottledChannelIterator", "err", err) + return nil + } + + return iter } func (ch *ThrottledChannel) Err() error { diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go index a5b218ffdc..4ebdef2e4b 100644 --- a/internal/p2p/throttled_channel_test.go +++ b/internal/p2p/throttled_channel_test.go @@ -2,6 +2,7 @@ package p2p_test import ( "context" + "fmt" "sync" "sync/atomic" "testing" @@ -12,64 +13,178 @@ import ( "golang.org/x/time/rate" "github.com/dashpay/tenderdash/internal/p2p" + "github.com/dashpay/tenderdash/libs/log" ) type mockChannel struct { - counter atomic.Uint32 + sent atomic.Uint32 + received atomic.Uint32 + errored atomic.Uint32 } -func (c *mockChannel) Len() int { - return int(c.counter.Load()) +func (c *mockChannel) SendCount() int { + return int(c.sent.Load()) +} + +func (c *mockChannel) RecvCount() int { + return int(c.received.Load()) } func (c *mockChannel) Send(_ context.Context, _e p2p.Envelope) error { - c.counter.Add(1) + c.sent.Add(1) return nil } func (c *mockChannel) SendError(_ context.Context, _ p2p.PeerError) error { - panic("not implemented") + c.errored.Add(1) + return nil } -func (c *mockChannel) Receive(_ context.Context) *p2p.ChannelIterator { - panic("not implemented") +func (c *mockChannel) Receive(ctx context.Context) p2p.ChannelIterator { + var pipe = make(chan p2p.Envelope, 5) + + go func() { + for { + select { + case pipe <- p2p.Envelope{}: + c.received.Add(1) + case <-ctx.Done(): + close(pipe) + return + } + } + }() + + return p2p.NewChannelIterator(pipe) } func (c *mockChannel) Err() error { - panic("not implemented") + if e := c.errored.Load(); e > 0 { + return fmt.Errorf("mock_channel_error: error count: %d", e) + } + return nil } func (c *mockChannel) String() string { return "mock_channel" } -func TestThrottledChannel(t *testing.T) { +func TestThrottledChannelSend(t *testing.T) { const n = 31 const rate rate.Limit = 10 const burst = int(rate) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + mock := &mockChannel{} - ch := p2p.NewThrottledChannel(mock, rate, burst) // 1 message per second + ch := p2p.NewThrottledChannel(mock, rate, burst, 0, 0, false, logger) // 1 message per second wg := sync.WaitGroup{} start := time.Now() for i := 0; i < n; i++ { wg.Add(1) go func() { - err := ch.Send(context.Background(), p2p.Envelope{}) + err := ch.Send(ctx, p2p.Envelope{}) require.NoError(t, err) wg.Done() }() } time.Sleep(time.Second) - assert.LessOrEqual(t, mock.Len(), burst+int(rate)) + assert.LessOrEqual(t, mock.SendCount(), burst+int(rate)) // Wait until all finish - wg.Wait() took := time.Since(start) - assert.Equal(t, n, mock.Len()) + assert.Equal(t, n, mock.SendCount()) assert.GreaterOrEqual(t, took.Seconds(), 2.0) } + +// Given some thrrottled channel that generates messages all the time, we should error out after receiving a rate +// of 10 messages per second. +func TestThrottledChannelRecvError(t *testing.T) { + const rate rate.Limit = 10 + const burst = int(rate) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst, rate, burst, true, logger) // 1 message per second + + start := time.Now() + + assert.NoError(t, mock.Err()) + + iter := ch.Receive(ctx) + + for i := 0; i < burst+int(rate)+1; i++ { + assert.True(t, iter.Next(ctx)) + + e := iter.Envelope() + if e == nil { + t.Error("nil envelope") + } + } + + err := mock.Err() + t.Logf("expected mock error: %v", err) + assert.Error(t, mock.Err()) + + // Wait until all finish + cancel() + + took := time.Since(start) + assert.GreaterOrEqual(t, took.Seconds(), 1.0) +} + +// Given some thrrottled channel that generates messages all the time, we should be able to receive them at a rate +// of 10 messages per second. +func TestThrottledChannelRecv(t *testing.T) { + const n = 31 + const rate rate.Limit = 10 + const burst = int(rate) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst, rate, burst, false, logger) // 1 message per second + + start := time.Now() + count := 0 + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + iter := ch.Receive(ctx) + for iter.Next(ctx) { + e := iter.Envelope() + if e == nil { + t.Error("nil envelope") + } + count++ + } + wg.Done() + }() + + time.Sleep(time.Second) + assert.LessOrEqual(t, mock.SendCount(), burst+int(rate)) + + // Wait until all finish + cancel() + wg.Wait() + + took := time.Since(start) + assert.Greater(t, mock.RecvCount(), count*100, "we should generate much more messages than we can receive") + assert.GreaterOrEqual(t, took.Seconds(), 1.0) +} From 38f9b36bb78a967a1fda9b5a2b034b20580d8b7f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:36:08 +0100 Subject: [PATCH 073/111] chore: regenerate mocks --- abci/client/mocks/client.go | 72 +++++++++ abci/types/mocks/application.go | 52 +++++++ dash/core/mocks/client.go | 32 ++++ internal/evidence/mocks/block_store.go | 12 ++ internal/mempool/mocks/mempool.go | 36 +++++ internal/p2p/channel_params.go | 7 +- internal/p2p/client/mocks/block_client.go | 12 ++ internal/p2p/client/mocks/snapshot_client.go | 16 ++ internal/p2p/mocks/channel.go | 28 +++- internal/p2p/mocks/connection.go | 28 ++++ internal/p2p/mocks/transport.go | 28 ++++ internal/state/indexer/mocks/event_sink.go | 32 ++++ internal/state/mocks/block_store.go | 56 +++++++ internal/state/mocks/evidence_pool.go | 12 ++ internal/state/mocks/executor.go | 28 ++++ internal/state/mocks/store.go | 40 +++++ internal/statesync/mocks/state_provider.go | 12 ++ libs/store/mocks/store.go | 24 +++ light/provider/mocks/provider.go | 12 ++ light/rpc/mocks/light_client.go | 20 +++ rpc/client/mocks/abci_client.go | 28 ++++ rpc/client/mocks/client.go | 144 ++++++++++++++++++ rpc/client/mocks/events_client.go | 4 + rpc/client/mocks/evidence_client.go | 4 + rpc/client/mocks/history_client.go | 12 ++ rpc/client/mocks/mempool_client.go | 16 ++ rpc/client/mocks/network_client.go | 20 +++ rpc/client/mocks/remote_client.go | 148 +++++++++++++++++++ rpc/client/mocks/sign_client.go | 40 +++++ rpc/client/mocks/status_client.go | 4 + rpc/client/mocks/subscription_client.go | 12 ++ types/mocks/block_event_publisher.go | 20 +++ types/mocks/priv_validator.go | 36 +++++ 33 files changed, 1041 insertions(+), 6 deletions(-) diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 984e97ef7e..433a0cb60d 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -18,6 +18,10 @@ type Client struct { func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ApplySnapshotChunk") + } + var r0 *types.ResponseApplySnapshotChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error)); ok { @@ -44,6 +48,10 @@ func (_m *Client) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestAppl func (_m *Client) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*types.ResponseCheckTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 *types.ResponseCheckTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) (*types.ResponseCheckTx, error)); ok { @@ -70,6 +78,10 @@ func (_m *Client) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*type func (_m *Client) Echo(_a0 context.Context, _a1 string) (*types.ResponseEcho, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Echo") + } + var r0 *types.ResponseEcho var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*types.ResponseEcho, error)); ok { @@ -96,6 +108,10 @@ func (_m *Client) Echo(_a0 context.Context, _a1 string) (*types.ResponseEcho, er func (_m *Client) Error() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Error") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -110,6 +126,10 @@ func (_m *Client) Error() error { func (_m *Client) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendVote) (*types.ResponseExtendVote, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ExtendVote") + } + var r0 *types.ResponseExtendVote var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestExtendVote) (*types.ResponseExtendVote, error)); ok { @@ -136,6 +156,10 @@ func (_m *Client) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendVote) func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for FinalizeBlock") + } + var r0 *types.ResponseFinalizeBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error)); ok { @@ -162,6 +186,10 @@ func (_m *Client) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeB func (_m *Client) Flush(_a0 context.Context) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Flush") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) @@ -176,6 +204,10 @@ func (_m *Client) Flush(_a0 context.Context) error { func (_m *Client) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Info") + } + var r0 *types.ResponseInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) (*types.ResponseInfo, error)); ok { @@ -202,6 +234,10 @@ func (_m *Client) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.Resp func (_m *Client) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for InitChain") + } + var r0 *types.ResponseInitChain var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) (*types.ResponseInitChain, error)); ok { @@ -228,6 +264,10 @@ func (_m *Client) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (* func (_m *Client) IsRunning() bool { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for IsRunning") + } + var r0 bool if rf, ok := ret.Get(0).(func() bool); ok { r0 = rf() @@ -242,6 +282,10 @@ func (_m *Client) IsRunning() bool { func (_m *Client) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ListSnapshots") + } + var r0 *types.ResponseListSnapshots var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) (*types.ResponseListSnapshots, error)); ok { @@ -268,6 +312,10 @@ func (_m *Client) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnaps func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for LoadSnapshotChunk") + } + var r0 *types.ResponseLoadSnapshotChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error)); ok { @@ -294,6 +342,10 @@ func (_m *Client) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadS func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for OfferSnapshot") + } + var r0 *types.ResponseOfferSnapshot var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error)); ok { @@ -320,6 +372,10 @@ func (_m *Client) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnap func (_m *Client) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for PrepareProposal") + } + var r0 *types.ResponsePrepareProposal var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)); ok { @@ -346,6 +402,10 @@ func (_m *Client) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepare func (_m *Client) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ProcessProposal") + } + var r0 *types.ResponseProcessProposal var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) (*types.ResponseProcessProposal, error)); ok { @@ -372,6 +432,10 @@ func (_m *Client) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcess func (_m *Client) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Query") + } + var r0 *types.ResponseQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) (*types.ResponseQuery, error)); ok { @@ -398,6 +462,10 @@ func (_m *Client) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.Re func (_m *Client) Start(_a0 context.Context) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) @@ -412,6 +480,10 @@ func (_m *Client) Start(_a0 context.Context) error { func (_m *Client) VerifyVoteExtension(_a0 context.Context, _a1 *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for VerifyVoteExtension") + } + var r0 *types.ResponseVerifyVoteExtension var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error)); ok { diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index e7767821d9..04ca3c5777 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -18,6 +18,10 @@ type Application struct { func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ApplySnapshotChunk") + } + var r0 *types.ResponseApplySnapshotChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error)); ok { @@ -44,6 +48,10 @@ func (_m *Application) ApplySnapshotChunk(_a0 context.Context, _a1 *types.Reques func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) (*types.ResponseCheckTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 *types.ResponseCheckTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestCheckTx) (*types.ResponseCheckTx, error)); ok { @@ -70,6 +78,10 @@ func (_m *Application) CheckTx(_a0 context.Context, _a1 *types.RequestCheckTx) ( func (_m *Application) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendVote) (*types.ResponseExtendVote, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ExtendVote") + } + var r0 *types.ResponseExtendVote var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestExtendVote) (*types.ResponseExtendVote, error)); ok { @@ -96,6 +108,10 @@ func (_m *Application) ExtendVote(_a0 context.Context, _a1 *types.RequestExtendV func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for FinalizeBlock") + } + var r0 *types.ResponseFinalizeBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error)); ok { @@ -122,6 +138,10 @@ func (_m *Application) FinalizeBlock(_a0 context.Context, _a1 *types.RequestFina func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types.ResponseInfo, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Info") + } + var r0 *types.ResponseInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInfo) (*types.ResponseInfo, error)); ok { @@ -148,6 +168,10 @@ func (_m *Application) Info(_a0 context.Context, _a1 *types.RequestInfo) (*types func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChain) (*types.ResponseInitChain, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for InitChain") + } + var r0 *types.ResponseInitChain var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestInitChain) (*types.ResponseInitChain, error)); ok { @@ -174,6 +198,10 @@ func (_m *Application) InitChain(_a0 context.Context, _a1 *types.RequestInitChai func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ListSnapshots") + } + var r0 *types.ResponseListSnapshots var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestListSnapshots) (*types.ResponseListSnapshots, error)); ok { @@ -200,6 +228,10 @@ func (_m *Application) ListSnapshots(_a0 context.Context, _a1 *types.RequestList func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for LoadSnapshotChunk") + } + var r0 *types.ResponseLoadSnapshotChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error)); ok { @@ -226,6 +258,10 @@ func (_m *Application) LoadSnapshotChunk(_a0 context.Context, _a1 *types.Request func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for OfferSnapshot") + } + var r0 *types.ResponseOfferSnapshot var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error)); ok { @@ -252,6 +288,10 @@ func (_m *Application) OfferSnapshot(_a0 context.Context, _a1 *types.RequestOffe func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for PrepareProposal") + } + var r0 *types.ResponsePrepareProposal var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error)); ok { @@ -278,6 +318,10 @@ func (_m *Application) PrepareProposal(_a0 context.Context, _a1 *types.RequestPr func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ProcessProposal") + } + var r0 *types.ResponseProcessProposal var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestProcessProposal) (*types.ResponseProcessProposal, error)); ok { @@ -304,6 +348,10 @@ func (_m *Application) ProcessProposal(_a0 context.Context, _a1 *types.RequestPr func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*types.ResponseQuery, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Query") + } + var r0 *types.ResponseQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestQuery) (*types.ResponseQuery, error)); ok { @@ -330,6 +378,10 @@ func (_m *Application) Query(_a0 context.Context, _a1 *types.RequestQuery) (*typ func (_m *Application) VerifyVoteExtension(_a0 context.Context, _a1 *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for VerifyVoteExtension") + } + var r0 *types.ResponseVerifyVoteExtension var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error)); ok { diff --git a/dash/core/mocks/client.go b/dash/core/mocks/client.go index 8f5b8e7ba6..19511f16ac 100644 --- a/dash/core/mocks/client.go +++ b/dash/core/mocks/client.go @@ -18,6 +18,10 @@ type Client struct { func (_m *Client) Close() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Close") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -32,6 +36,10 @@ func (_m *Client) Close() error { func (_m *Client) GetNetworkInfo() (*btcjson.GetNetworkInfoResult, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetNetworkInfo") + } + var r0 *btcjson.GetNetworkInfoResult var r1 error if rf, ok := ret.Get(0).(func() (*btcjson.GetNetworkInfoResult, error)); ok { @@ -58,6 +66,10 @@ func (_m *Client) GetNetworkInfo() (*btcjson.GetNetworkInfoResult, error) { func (_m *Client) MasternodeListJSON(filter string) (map[string]btcjson.MasternodelistResultJSON, error) { ret := _m.Called(filter) + if len(ret) == 0 { + panic("no return value specified for MasternodeListJSON") + } + var r0 map[string]btcjson.MasternodelistResultJSON var r1 error if rf, ok := ret.Get(0).(func(string) (map[string]btcjson.MasternodelistResultJSON, error)); ok { @@ -84,6 +96,10 @@ func (_m *Client) MasternodeListJSON(filter string) (map[string]btcjson.Masterno func (_m *Client) MasternodeStatus() (*btcjson.MasternodeStatusResult, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for MasternodeStatus") + } + var r0 *btcjson.MasternodeStatusResult var r1 error if rf, ok := ret.Get(0).(func() (*btcjson.MasternodeStatusResult, error)); ok { @@ -110,6 +126,10 @@ func (_m *Client) MasternodeStatus() (*btcjson.MasternodeStatusResult, error) { func (_m *Client) Ping() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Ping") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -124,6 +144,10 @@ func (_m *Client) Ping() error { func (_m *Client) QuorumInfo(quorumType btcjson.LLMQType, quorumHash bytes.HexBytes) (*btcjson.QuorumInfoResult, error) { ret := _m.Called(quorumType, quorumHash) + if len(ret) == 0 { + panic("no return value specified for QuorumInfo") + } + var r0 *btcjson.QuorumInfoResult var r1 error if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes) (*btcjson.QuorumInfoResult, error)); ok { @@ -150,6 +174,10 @@ func (_m *Client) QuorumInfo(quorumType btcjson.LLMQType, quorumHash bytes.HexBy func (_m *Client) QuorumSign(quorumType btcjson.LLMQType, requestID bytes.HexBytes, messageHash bytes.HexBytes, quorumHash bytes.HexBytes) (*btcjson.QuorumSignResult, error) { ret := _m.Called(quorumType, requestID, messageHash, quorumHash) + if len(ret) == 0 { + panic("no return value specified for QuorumSign") + } + var r0 *btcjson.QuorumSignResult var r1 error if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) (*btcjson.QuorumSignResult, error)); ok { @@ -176,6 +204,10 @@ func (_m *Client) QuorumSign(quorumType btcjson.LLMQType, requestID bytes.HexByt func (_m *Client) QuorumVerify(quorumType btcjson.LLMQType, requestID bytes.HexBytes, messageHash bytes.HexBytes, signature bytes.HexBytes, quorumHash bytes.HexBytes) (bool, error) { ret := _m.Called(quorumType, requestID, messageHash, signature, quorumHash) + if len(ret) == 0 { + panic("no return value specified for QuorumVerify") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(btcjson.LLMQType, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes, bytes.HexBytes) (bool, error)); ok { diff --git a/internal/evidence/mocks/block_store.go b/internal/evidence/mocks/block_store.go index 344c2f7992..41fff57cde 100644 --- a/internal/evidence/mocks/block_store.go +++ b/internal/evidence/mocks/block_store.go @@ -16,6 +16,10 @@ type BlockStore struct { func (_m *BlockStore) Height() int64 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Height") + } + var r0 int64 if rf, ok := ret.Get(0).(func() int64); ok { r0 = rf() @@ -30,6 +34,10 @@ func (_m *BlockStore) Height() int64 { func (_m *BlockStore) LoadBlockCommit(height int64) *types.Commit { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadBlockCommit") + } + var r0 *types.Commit if rf, ok := ret.Get(0).(func(int64) *types.Commit); ok { r0 = rf(height) @@ -46,6 +54,10 @@ func (_m *BlockStore) LoadBlockCommit(height int64) *types.Commit { func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadBlockMeta") + } + var r0 *types.BlockMeta if rf, ok := ret.Get(0).(func(int64) *types.BlockMeta); ok { r0 = rf(height) diff --git a/internal/mempool/mocks/mempool.go b/internal/mempool/mocks/mempool.go index 890e3d7b41..6f4996f400 100644 --- a/internal/mempool/mocks/mempool.go +++ b/internal/mempool/mocks/mempool.go @@ -23,6 +23,10 @@ type Mempool struct { func (_m *Mempool) CheckTx(ctx context.Context, tx types.Tx, cb func(*abcitypes.ResponseCheckTx), txInfo mempool.TxInfo) error { ret := _m.Called(ctx, tx, cb, txInfo) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx, func(*abcitypes.ResponseCheckTx), mempool.TxInfo) error); ok { r0 = rf(ctx, tx, cb, txInfo) @@ -47,6 +51,10 @@ func (_m *Mempool) Flush() { func (_m *Mempool) FlushAppConn(_a0 context.Context) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for FlushAppConn") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) @@ -66,6 +74,10 @@ func (_m *Mempool) Lock() { func (_m *Mempool) ReapMaxBytesMaxGas(maxBytes int64, maxGas int64) types.Txs { ret := _m.Called(maxBytes, maxGas) + if len(ret) == 0 { + panic("no return value specified for ReapMaxBytesMaxGas") + } + var r0 types.Txs if rf, ok := ret.Get(0).(func(int64, int64) types.Txs); ok { r0 = rf(maxBytes, maxGas) @@ -82,6 +94,10 @@ func (_m *Mempool) ReapMaxBytesMaxGas(maxBytes int64, maxGas int64) types.Txs { func (_m *Mempool) ReapMaxTxs(max int) types.Txs { ret := _m.Called(max) + if len(ret) == 0 { + panic("no return value specified for ReapMaxTxs") + } + var r0 types.Txs if rf, ok := ret.Get(0).(func(int) types.Txs); ok { r0 = rf(max) @@ -98,6 +114,10 @@ func (_m *Mempool) ReapMaxTxs(max int) types.Txs { func (_m *Mempool) RemoveTxByKey(txKey types.TxKey) error { ret := _m.Called(txKey) + if len(ret) == 0 { + panic("no return value specified for RemoveTxByKey") + } + var r0 error if rf, ok := ret.Get(0).(func(types.TxKey) error); ok { r0 = rf(txKey) @@ -112,6 +132,10 @@ func (_m *Mempool) RemoveTxByKey(txKey types.TxKey) error { func (_m *Mempool) Size() int { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Size") + } + var r0 int if rf, ok := ret.Get(0).(func() int); ok { r0 = rf() @@ -126,6 +150,10 @@ func (_m *Mempool) Size() int { func (_m *Mempool) SizeBytes() int64 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for SizeBytes") + } + var r0 int64 if rf, ok := ret.Get(0).(func() int64); ok { r0 = rf() @@ -140,6 +168,10 @@ func (_m *Mempool) SizeBytes() int64 { func (_m *Mempool) TxsAvailable() <-chan struct{} { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for TxsAvailable") + } + var r0 <-chan struct{} if rf, ok := ret.Get(0).(func() <-chan struct{}); ok { r0 = rf() @@ -161,6 +193,10 @@ func (_m *Mempool) Unlock() { func (_m *Mempool) Update(ctx context.Context, blockHeight int64, blockTxs types.Txs, txResults []*abcitypes.ExecTxResult, newPreFn mempool.PreCheckFunc, newPostFn mempool.PostCheckFunc, recheck bool) error { ret := _m.Called(ctx, blockHeight, blockTxs, txResults, newPreFn, newPostFn, recheck) + if len(ret) == 0 { + panic("no return value specified for Update") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, int64, types.Txs, []*abcitypes.ExecTxResult, mempool.PreCheckFunc, mempool.PostCheckFunc, bool) error); ok { r0 = rf(ctx, blockHeight, blockTxs, txResults, newPreFn, newPostFn, recheck) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 4debeab4ea..b3cb73e795 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -80,8 +80,11 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 1000, Name: "mempool", - SendRateLimit: 5, // TODO: make it configurable - SendRateBurst: 20, // TODO: make it configurable + SendRateLimit: 5, // TODO: make it configurable + SendRateBurst: 20, // TODO: make it configurable + RecvRateLimit: 1, // TODO: make it configurable + RecvRateBurst: 1, // TODO: make it configurable + RecvRateShouldErr: true, // TODO: make it configurable EnqueueTimeout: 10 * time.Millisecond, }, } diff --git a/internal/p2p/client/mocks/block_client.go b/internal/p2p/client/mocks/block_client.go index b094d38ccb..5d1e5a90ce 100644 --- a/internal/p2p/client/mocks/block_client.go +++ b/internal/p2p/client/mocks/block_client.go @@ -23,6 +23,10 @@ type BlockClient struct { func (_m *BlockClient) GetBlock(ctx context.Context, height int64, peerID types.NodeID) (*promise.Promise[*blocksync.BlockResponse], error) { ret := _m.Called(ctx, height, peerID) + if len(ret) == 0 { + panic("no return value specified for GetBlock") + } + var r0 *promise.Promise[*blocksync.BlockResponse] var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64, types.NodeID) (*promise.Promise[*blocksync.BlockResponse], error)); ok { @@ -49,6 +53,10 @@ func (_m *BlockClient) GetBlock(ctx context.Context, height int64, peerID types. func (_m *BlockClient) GetSyncStatus(ctx context.Context) error { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for GetSyncStatus") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(ctx) @@ -63,6 +71,10 @@ func (_m *BlockClient) GetSyncStatus(ctx context.Context) error { func (_m *BlockClient) Send(ctx context.Context, msg interface{}) error { ret := _m.Called(ctx, msg) + if len(ret) == 0 { + panic("no return value specified for Send") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, interface{}) error); ok { r0 = rf(ctx, msg) diff --git a/internal/p2p/client/mocks/snapshot_client.go b/internal/p2p/client/mocks/snapshot_client.go index e2eb8d643d..a88f2e269b 100644 --- a/internal/p2p/client/mocks/snapshot_client.go +++ b/internal/p2p/client/mocks/snapshot_client.go @@ -22,6 +22,10 @@ type SnapshotClient struct { func (_m *SnapshotClient) GetChunk(ctx context.Context, peerID types.NodeID, height uint64, format uint32, index uint32) (*promise.Promise[*statesync.ChunkResponse], error) { ret := _m.Called(ctx, peerID, height, format, index) + if len(ret) == 0 { + panic("no return value specified for GetChunk") + } + var r0 *promise.Promise[*statesync.ChunkResponse] var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.NodeID, uint64, uint32, uint32) (*promise.Promise[*statesync.ChunkResponse], error)); ok { @@ -48,6 +52,10 @@ func (_m *SnapshotClient) GetChunk(ctx context.Context, peerID types.NodeID, hei func (_m *SnapshotClient) GetLightBlock(ctx context.Context, peerID types.NodeID, height uint64) (*promise.Promise[*statesync.LightBlockResponse], error) { ret := _m.Called(ctx, peerID, height) + if len(ret) == 0 { + panic("no return value specified for GetLightBlock") + } + var r0 *promise.Promise[*statesync.LightBlockResponse] var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.NodeID, uint64) (*promise.Promise[*statesync.LightBlockResponse], error)); ok { @@ -74,6 +82,10 @@ func (_m *SnapshotClient) GetLightBlock(ctx context.Context, peerID types.NodeID func (_m *SnapshotClient) GetParams(ctx context.Context, peerID types.NodeID, height uint64) (*promise.Promise[*statesync.ParamsResponse], error) { ret := _m.Called(ctx, peerID, height) + if len(ret) == 0 { + panic("no return value specified for GetParams") + } + var r0 *promise.Promise[*statesync.ParamsResponse] var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.NodeID, uint64) (*promise.Promise[*statesync.ParamsResponse], error)); ok { @@ -100,6 +112,10 @@ func (_m *SnapshotClient) GetParams(ctx context.Context, peerID types.NodeID, he func (_m *SnapshotClient) GetSnapshots(ctx context.Context, peerID types.NodeID) error { ret := _m.Called(ctx, peerID) + if len(ret) == 0 { + panic("no return value specified for GetSnapshots") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.NodeID) error); ok { r0 = rf(ctx, peerID) diff --git a/internal/p2p/mocks/channel.go b/internal/p2p/mocks/channel.go index ebee0c7670..ae54580e6f 100644 --- a/internal/p2p/mocks/channel.go +++ b/internal/p2p/mocks/channel.go @@ -18,6 +18,10 @@ type Channel struct { func (_m *Channel) Err() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Err") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -29,15 +33,19 @@ func (_m *Channel) Err() error { } // Receive provides a mock function with given fields: _a0 -func (_m *Channel) Receive(_a0 context.Context) *p2p.ChannelIterator { +func (_m *Channel) Receive(_a0 context.Context) p2p.ChannelIterator { ret := _m.Called(_a0) - var r0 *p2p.ChannelIterator - if rf, ok := ret.Get(0).(func(context.Context) *p2p.ChannelIterator); ok { + if len(ret) == 0 { + panic("no return value specified for Receive") + } + + var r0 p2p.ChannelIterator + if rf, ok := ret.Get(0).(func(context.Context) p2p.ChannelIterator); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*p2p.ChannelIterator) + r0 = ret.Get(0).(p2p.ChannelIterator) } } @@ -48,6 +56,10 @@ func (_m *Channel) Receive(_a0 context.Context) *p2p.ChannelIterator { func (_m *Channel) Send(_a0 context.Context, _a1 p2p.Envelope) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Send") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, p2p.Envelope) error); ok { r0 = rf(_a0, _a1) @@ -62,6 +74,10 @@ func (_m *Channel) Send(_a0 context.Context, _a1 p2p.Envelope) error { func (_m *Channel) SendError(_a0 context.Context, _a1 p2p.PeerError) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for SendError") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, p2p.PeerError) error); ok { r0 = rf(_a0, _a1) @@ -76,6 +92,10 @@ func (_m *Channel) SendError(_a0 context.Context, _a1 p2p.PeerError) error { func (_m *Channel) String() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for String") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() diff --git a/internal/p2p/mocks/connection.go b/internal/p2p/mocks/connection.go index 447bb925ab..879950b6a1 100644 --- a/internal/p2p/mocks/connection.go +++ b/internal/p2p/mocks/connection.go @@ -27,6 +27,10 @@ type Connection struct { func (_m *Connection) Close() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Close") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -41,6 +45,10 @@ func (_m *Connection) Close() error { func (_m *Connection) Handshake(_a0 context.Context, _a1 time.Duration, _a2 types.NodeInfo, _a3 crypto.PrivKey) (types.NodeInfo, crypto.PubKey, error) { ret := _m.Called(_a0, _a1, _a2, _a3) + if len(ret) == 0 { + panic("no return value specified for Handshake") + } + var r0 types.NodeInfo var r1 crypto.PubKey var r2 error @@ -74,6 +82,10 @@ func (_m *Connection) Handshake(_a0 context.Context, _a1 time.Duration, _a2 type func (_m *Connection) LocalEndpoint() p2p.Endpoint { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for LocalEndpoint") + } + var r0 p2p.Endpoint if rf, ok := ret.Get(0).(func() p2p.Endpoint); ok { r0 = rf() @@ -88,6 +100,10 @@ func (_m *Connection) LocalEndpoint() p2p.Endpoint { func (_m *Connection) ReceiveMessage(_a0 context.Context) (conn.ChannelID, []byte, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ReceiveMessage") + } + var r0 conn.ChannelID var r1 []byte var r2 error @@ -121,6 +137,10 @@ func (_m *Connection) ReceiveMessage(_a0 context.Context) (conn.ChannelID, []byt func (_m *Connection) RemoteEndpoint() p2p.Endpoint { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for RemoteEndpoint") + } + var r0 p2p.Endpoint if rf, ok := ret.Get(0).(func() p2p.Endpoint); ok { r0 = rf() @@ -135,6 +155,10 @@ func (_m *Connection) RemoteEndpoint() p2p.Endpoint { func (_m *Connection) SendMessage(_a0 context.Context, _a1 conn.ChannelID, _a2 []byte) error { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for SendMessage") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, conn.ChannelID, []byte) error); ok { r0 = rf(_a0, _a1, _a2) @@ -149,6 +173,10 @@ func (_m *Connection) SendMessage(_a0 context.Context, _a1 conn.ChannelID, _a2 [ func (_m *Connection) String() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for String") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() diff --git a/internal/p2p/mocks/transport.go b/internal/p2p/mocks/transport.go index 0901d27c84..6fbaccacaa 100644 --- a/internal/p2p/mocks/transport.go +++ b/internal/p2p/mocks/transport.go @@ -21,6 +21,10 @@ type Transport struct { func (_m *Transport) Accept(_a0 context.Context) (p2p.Connection, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Accept") + } + var r0 p2p.Connection var r1 error if rf, ok := ret.Get(0).(func(context.Context) (p2p.Connection, error)); ok { @@ -52,6 +56,10 @@ func (_m *Transport) AddChannelDescriptors(_a0 []*conn.ChannelDescriptor) { func (_m *Transport) Close() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Close") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -66,6 +74,10 @@ func (_m *Transport) Close() error { func (_m *Transport) Dial(_a0 context.Context, _a1 *p2p.Endpoint) (p2p.Connection, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for Dial") + } + var r0 p2p.Connection var r1 error if rf, ok := ret.Get(0).(func(context.Context, *p2p.Endpoint) (p2p.Connection, error)); ok { @@ -92,6 +104,10 @@ func (_m *Transport) Dial(_a0 context.Context, _a1 *p2p.Endpoint) (p2p.Connectio func (_m *Transport) Endpoint() (*p2p.Endpoint, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Endpoint") + } + var r0 *p2p.Endpoint var r1 error if rf, ok := ret.Get(0).(func() (*p2p.Endpoint, error)); ok { @@ -118,6 +134,10 @@ func (_m *Transport) Endpoint() (*p2p.Endpoint, error) { func (_m *Transport) Listen(_a0 *p2p.Endpoint) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Listen") + } + var r0 error if rf, ok := ret.Get(0).(func(*p2p.Endpoint) error); ok { r0 = rf(_a0) @@ -132,6 +152,10 @@ func (_m *Transport) Listen(_a0 *p2p.Endpoint) error { func (_m *Transport) Protocols() []p2p.Protocol { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Protocols") + } + var r0 []p2p.Protocol if rf, ok := ret.Get(0).(func() []p2p.Protocol); ok { r0 = rf() @@ -148,6 +172,10 @@ func (_m *Transport) Protocols() []p2p.Protocol { func (_m *Transport) String() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for String") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() diff --git a/internal/state/indexer/mocks/event_sink.go b/internal/state/indexer/mocks/event_sink.go index 45d3f22c8a..8288781bc0 100644 --- a/internal/state/indexer/mocks/event_sink.go +++ b/internal/state/indexer/mocks/event_sink.go @@ -24,6 +24,10 @@ type EventSink struct { func (_m *EventSink) GetTxByHash(_a0 []byte) (*types.TxResult, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetTxByHash") + } + var r0 *types.TxResult var r1 error if rf, ok := ret.Get(0).(func([]byte) (*types.TxResult, error)); ok { @@ -50,6 +54,10 @@ func (_m *EventSink) GetTxByHash(_a0 []byte) (*types.TxResult, error) { func (_m *EventSink) HasBlock(_a0 int64) (bool, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for HasBlock") + } + var r0 bool var r1 error if rf, ok := ret.Get(0).(func(int64) (bool, error)); ok { @@ -74,6 +82,10 @@ func (_m *EventSink) HasBlock(_a0 int64) (bool, error) { func (_m *EventSink) IndexBlockEvents(_a0 tenderdashtypes.EventDataNewBlockHeader) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for IndexBlockEvents") + } + var r0 error if rf, ok := ret.Get(0).(func(tenderdashtypes.EventDataNewBlockHeader) error); ok { r0 = rf(_a0) @@ -88,6 +100,10 @@ func (_m *EventSink) IndexBlockEvents(_a0 tenderdashtypes.EventDataNewBlockHeade func (_m *EventSink) IndexTxEvents(_a0 []*types.TxResult) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for IndexTxEvents") + } + var r0 error if rf, ok := ret.Get(0).(func([]*types.TxResult) error); ok { r0 = rf(_a0) @@ -102,6 +118,10 @@ func (_m *EventSink) IndexTxEvents(_a0 []*types.TxResult) error { func (_m *EventSink) SearchBlockEvents(_a0 context.Context, _a1 *query.Query) ([]int64, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for SearchBlockEvents") + } + var r0 []int64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, *query.Query) ([]int64, error)); ok { @@ -128,6 +148,10 @@ func (_m *EventSink) SearchBlockEvents(_a0 context.Context, _a1 *query.Query) ([ func (_m *EventSink) SearchTxEvents(_a0 context.Context, _a1 *query.Query) ([]*types.TxResult, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for SearchTxEvents") + } + var r0 []*types.TxResult var r1 error if rf, ok := ret.Get(0).(func(context.Context, *query.Query) ([]*types.TxResult, error)); ok { @@ -154,6 +178,10 @@ func (_m *EventSink) SearchTxEvents(_a0 context.Context, _a1 *query.Query) ([]*t func (_m *EventSink) Stop() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Stop") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -168,6 +196,10 @@ func (_m *EventSink) Stop() error { func (_m *EventSink) Type() indexer.EventSinkType { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Type") + } + var r0 indexer.EventSinkType if rf, ok := ret.Get(0).(func() indexer.EventSinkType); ok { r0 = rf() diff --git a/internal/state/mocks/block_store.go b/internal/state/mocks/block_store.go index f4a0636d78..63873d194a 100644 --- a/internal/state/mocks/block_store.go +++ b/internal/state/mocks/block_store.go @@ -17,6 +17,10 @@ type BlockStore struct { func (_m *BlockStore) Base() int64 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Base") + } + var r0 int64 if rf, ok := ret.Get(0).(func() int64); ok { r0 = rf() @@ -31,6 +35,10 @@ func (_m *BlockStore) Base() int64 { func (_m *BlockStore) CoreChainLockedHeight() uint32 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for CoreChainLockedHeight") + } + var r0 uint32 if rf, ok := ret.Get(0).(func() uint32); ok { r0 = rf() @@ -45,6 +53,10 @@ func (_m *BlockStore) CoreChainLockedHeight() uint32 { func (_m *BlockStore) Height() int64 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Height") + } + var r0 int64 if rf, ok := ret.Get(0).(func() int64); ok { r0 = rf() @@ -59,6 +71,10 @@ func (_m *BlockStore) Height() int64 { func (_m *BlockStore) LoadBaseMeta() *types.BlockMeta { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for LoadBaseMeta") + } + var r0 *types.BlockMeta if rf, ok := ret.Get(0).(func() *types.BlockMeta); ok { r0 = rf() @@ -75,6 +91,10 @@ func (_m *BlockStore) LoadBaseMeta() *types.BlockMeta { func (_m *BlockStore) LoadBlock(height int64) *types.Block { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadBlock") + } + var r0 *types.Block if rf, ok := ret.Get(0).(func(int64) *types.Block); ok { r0 = rf(height) @@ -91,6 +111,10 @@ func (_m *BlockStore) LoadBlock(height int64) *types.Block { func (_m *BlockStore) LoadBlockByHash(hash []byte) *types.Block { ret := _m.Called(hash) + if len(ret) == 0 { + panic("no return value specified for LoadBlockByHash") + } + var r0 *types.Block if rf, ok := ret.Get(0).(func([]byte) *types.Block); ok { r0 = rf(hash) @@ -107,6 +131,10 @@ func (_m *BlockStore) LoadBlockByHash(hash []byte) *types.Block { func (_m *BlockStore) LoadBlockCommit(height int64) *types.Commit { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadBlockCommit") + } + var r0 *types.Commit if rf, ok := ret.Get(0).(func(int64) *types.Commit); ok { r0 = rf(height) @@ -123,6 +151,10 @@ func (_m *BlockStore) LoadBlockCommit(height int64) *types.Commit { func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadBlockMeta") + } + var r0 *types.BlockMeta if rf, ok := ret.Get(0).(func(int64) *types.BlockMeta); ok { r0 = rf(height) @@ -139,6 +171,10 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { func (_m *BlockStore) LoadBlockMetaByHash(hash []byte) *types.BlockMeta { ret := _m.Called(hash) + if len(ret) == 0 { + panic("no return value specified for LoadBlockMetaByHash") + } + var r0 *types.BlockMeta if rf, ok := ret.Get(0).(func([]byte) *types.BlockMeta); ok { r0 = rf(hash) @@ -155,6 +191,10 @@ func (_m *BlockStore) LoadBlockMetaByHash(hash []byte) *types.BlockMeta { func (_m *BlockStore) LoadBlockPart(height int64, index int) *types.Part { ret := _m.Called(height, index) + if len(ret) == 0 { + panic("no return value specified for LoadBlockPart") + } + var r0 *types.Part if rf, ok := ret.Get(0).(func(int64, int) *types.Part); ok { r0 = rf(height, index) @@ -171,6 +211,10 @@ func (_m *BlockStore) LoadBlockPart(height int64, index int) *types.Part { func (_m *BlockStore) LoadSeenCommit() *types.Commit { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for LoadSeenCommit") + } + var r0 *types.Commit if rf, ok := ret.Get(0).(func() *types.Commit); ok { r0 = rf() @@ -187,6 +231,10 @@ func (_m *BlockStore) LoadSeenCommit() *types.Commit { func (_m *BlockStore) LoadSeenCommitAt(height int64) *types.Commit { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for LoadSeenCommitAt") + } + var r0 *types.Commit if rf, ok := ret.Get(0).(func(int64) *types.Commit); ok { r0 = rf(height) @@ -203,6 +251,10 @@ func (_m *BlockStore) LoadSeenCommitAt(height int64) *types.Commit { func (_m *BlockStore) PruneBlocks(height int64) (uint64, error) { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for PruneBlocks") + } + var r0 uint64 var r1 error if rf, ok := ret.Get(0).(func(int64) (uint64, error)); ok { @@ -232,6 +284,10 @@ func (_m *BlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, s func (_m *BlockStore) Size() int64 { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Size") + } + var r0 int64 if rf, ok := ret.Get(0).(func() int64); ok { r0 = rf() diff --git a/internal/state/mocks/evidence_pool.go b/internal/state/mocks/evidence_pool.go index 162d1035d3..ff16885fbd 100644 --- a/internal/state/mocks/evidence_pool.go +++ b/internal/state/mocks/evidence_pool.go @@ -20,6 +20,10 @@ type EvidencePool struct { func (_m *EvidencePool) AddEvidence(_a0 context.Context, _a1 types.Evidence) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for AddEvidence") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) error); ok { r0 = rf(_a0, _a1) @@ -34,6 +38,10 @@ func (_m *EvidencePool) AddEvidence(_a0 context.Context, _a1 types.Evidence) err func (_m *EvidencePool) CheckEvidence(_a0 context.Context, _a1 types.EvidenceList) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckEvidence") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.EvidenceList) error); ok { r0 = rf(_a0, _a1) @@ -48,6 +56,10 @@ func (_m *EvidencePool) CheckEvidence(_a0 context.Context, _a1 types.EvidenceLis func (_m *EvidencePool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64) { ret := _m.Called(maxBytes) + if len(ret) == 0 { + panic("no return value specified for PendingEvidence") + } + var r0 []types.Evidence var r1 int64 if rf, ok := ret.Get(0).(func(int64) ([]types.Evidence, int64)); ok { diff --git a/internal/state/mocks/executor.go b/internal/state/mocks/executor.go index daa92ee0dc..e287c60cc0 100644 --- a/internal/state/mocks/executor.go +++ b/internal/state/mocks/executor.go @@ -20,6 +20,10 @@ type Executor struct { func (_m *Executor) ApplyBlock(ctx context.Context, _a1 state.State, blockID types.BlockID, block *types.Block, commit *types.Commit) (state.State, error) { ret := _m.Called(ctx, _a1, blockID, block, commit) + if len(ret) == 0 { + panic("no return value specified for ApplyBlock") + } + var r0 state.State var r1 error if rf, ok := ret.Get(0).(func(context.Context, state.State, types.BlockID, *types.Block, *types.Commit) (state.State, error)); ok { @@ -44,6 +48,10 @@ func (_m *Executor) ApplyBlock(ctx context.Context, _a1 state.State, blockID typ func (_m *Executor) CreateProposalBlock(ctx context.Context, height int64, round int32, _a3 state.State, commit *types.Commit, proposerProTxHash []byte, proposedAppVersion uint64) (*types.Block, state.CurrentRoundState, error) { ret := _m.Called(ctx, height, round, _a3, commit, proposerProTxHash, proposedAppVersion) + if len(ret) == 0 { + panic("no return value specified for CreateProposalBlock") + } + var r0 *types.Block var r1 state.CurrentRoundState var r2 error @@ -82,6 +90,10 @@ func (_m *Executor) ExtendVote(ctx context.Context, vote *types.Vote) { func (_m *Executor) FinalizeBlock(ctx context.Context, _a1 state.State, uncommittedState state.CurrentRoundState, blockID types.BlockID, block *types.Block, commit *types.Commit) (state.State, error) { ret := _m.Called(ctx, _a1, uncommittedState, blockID, block, commit) + if len(ret) == 0 { + panic("no return value specified for FinalizeBlock") + } + var r0 state.State var r1 error if rf, ok := ret.Get(0).(func(context.Context, state.State, state.CurrentRoundState, types.BlockID, *types.Block, *types.Commit) (state.State, error)); ok { @@ -106,6 +118,10 @@ func (_m *Executor) FinalizeBlock(ctx context.Context, _a1 state.State, uncommit func (_m *Executor) ProcessProposal(ctx context.Context, block *types.Block, round int32, _a3 state.State, verify bool) (state.CurrentRoundState, error) { ret := _m.Called(ctx, block, round, _a3, verify) + if len(ret) == 0 { + panic("no return value specified for ProcessProposal") + } + var r0 state.CurrentRoundState var r1 error if rf, ok := ret.Get(0).(func(context.Context, *types.Block, int32, state.State, bool) (state.CurrentRoundState, error)); ok { @@ -130,6 +146,10 @@ func (_m *Executor) ProcessProposal(ctx context.Context, block *types.Block, rou func (_m *Executor) ValidateBlock(ctx context.Context, _a1 state.State, block *types.Block) error { ret := _m.Called(ctx, _a1, block) + if len(ret) == 0 { + panic("no return value specified for ValidateBlock") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, state.State, *types.Block) error); ok { r0 = rf(ctx, _a1, block) @@ -144,6 +164,10 @@ func (_m *Executor) ValidateBlock(ctx context.Context, _a1 state.State, block *t func (_m *Executor) ValidateBlockWithRoundState(ctx context.Context, _a1 state.State, uncommittedState state.CurrentRoundState, block *types.Block) error { ret := _m.Called(ctx, _a1, uncommittedState, block) + if len(ret) == 0 { + panic("no return value specified for ValidateBlockWithRoundState") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, state.State, state.CurrentRoundState, *types.Block) error); ok { r0 = rf(ctx, _a1, uncommittedState, block) @@ -158,6 +182,10 @@ func (_m *Executor) ValidateBlockWithRoundState(ctx context.Context, _a1 state.S func (_m *Executor) VerifyVoteExtension(ctx context.Context, vote *types.Vote) error { ret := _m.Called(ctx, vote) + if len(ret) == 0 { + panic("no return value specified for VerifyVoteExtension") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, *types.Vote) error); ok { r0 = rf(ctx, vote) diff --git a/internal/state/mocks/store.go b/internal/state/mocks/store.go index 8f8fc65857..4a7fa92190 100644 --- a/internal/state/mocks/store.go +++ b/internal/state/mocks/store.go @@ -20,6 +20,10 @@ type Store struct { func (_m *Store) Bootstrap(_a0 state.State) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Bootstrap") + } + var r0 error if rf, ok := ret.Get(0).(func(state.State) error); ok { r0 = rf(_a0) @@ -34,6 +38,10 @@ func (_m *Store) Bootstrap(_a0 state.State) error { func (_m *Store) Close() error { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Close") + } + var r0 error if rf, ok := ret.Get(0).(func() error); ok { r0 = rf() @@ -48,6 +56,10 @@ func (_m *Store) Close() error { func (_m *Store) Load() (state.State, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Load") + } + var r0 state.State var r1 error if rf, ok := ret.Get(0).(func() (state.State, error)); ok { @@ -72,6 +84,10 @@ func (_m *Store) Load() (state.State, error) { func (_m *Store) LoadABCIResponses(_a0 int64) (*tendermintstate.ABCIResponses, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for LoadABCIResponses") + } + var r0 *tendermintstate.ABCIResponses var r1 error if rf, ok := ret.Get(0).(func(int64) (*tendermintstate.ABCIResponses, error)); ok { @@ -98,6 +114,10 @@ func (_m *Store) LoadABCIResponses(_a0 int64) (*tendermintstate.ABCIResponses, e func (_m *Store) LoadConsensusParams(_a0 int64) (types.ConsensusParams, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for LoadConsensusParams") + } + var r0 types.ConsensusParams var r1 error if rf, ok := ret.Get(0).(func(int64) (types.ConsensusParams, error)); ok { @@ -122,6 +142,10 @@ func (_m *Store) LoadConsensusParams(_a0 int64) (types.ConsensusParams, error) { func (_m *Store) LoadValidators(_a0 int64) (*types.ValidatorSet, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for LoadValidators") + } + var r0 *types.ValidatorSet var r1 error if rf, ok := ret.Get(0).(func(int64) (*types.ValidatorSet, error)); ok { @@ -148,6 +172,10 @@ func (_m *Store) LoadValidators(_a0 int64) (*types.ValidatorSet, error) { func (_m *Store) PruneStates(_a0 int64) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PruneStates") + } + var r0 error if rf, ok := ret.Get(0).(func(int64) error); ok { r0 = rf(_a0) @@ -162,6 +190,10 @@ func (_m *Store) PruneStates(_a0 int64) error { func (_m *Store) Save(_a0 state.State) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Save") + } + var r0 error if rf, ok := ret.Get(0).(func(state.State) error); ok { r0 = rf(_a0) @@ -176,6 +208,10 @@ func (_m *Store) Save(_a0 state.State) error { func (_m *Store) SaveABCIResponses(_a0 int64, _a1 tendermintstate.ABCIResponses) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for SaveABCIResponses") + } + var r0 error if rf, ok := ret.Get(0).(func(int64, tendermintstate.ABCIResponses) error); ok { r0 = rf(_a0, _a1) @@ -190,6 +226,10 @@ func (_m *Store) SaveABCIResponses(_a0 int64, _a1 tendermintstate.ABCIResponses) func (_m *Store) SaveValidatorSets(_a0 int64, _a1 int64, _a2 *types.ValidatorSet) error { ret := _m.Called(_a0, _a1, _a2) + if len(ret) == 0 { + panic("no return value specified for SaveValidatorSets") + } + var r0 error if rf, ok := ret.Get(0).(func(int64, int64, *types.ValidatorSet) error); ok { r0 = rf(_a0, _a1, _a2) diff --git a/internal/statesync/mocks/state_provider.go b/internal/statesync/mocks/state_provider.go index b4301dffcb..73b6b7b372 100644 --- a/internal/statesync/mocks/state_provider.go +++ b/internal/statesync/mocks/state_provider.go @@ -23,6 +23,10 @@ type StateProvider struct { func (_m *StateProvider) AppHash(ctx context.Context, height uint64) (bytes.HexBytes, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for AppHash") + } + var r0 bytes.HexBytes var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint64) (bytes.HexBytes, error)); ok { @@ -49,6 +53,10 @@ func (_m *StateProvider) AppHash(ctx context.Context, height uint64) (bytes.HexB func (_m *StateProvider) Commit(ctx context.Context, height uint64) (*types.Commit, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Commit") + } + var r0 *types.Commit var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint64) (*types.Commit, error)); ok { @@ -75,6 +83,10 @@ func (_m *StateProvider) Commit(ctx context.Context, height uint64) (*types.Comm func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for State") + } + var r0 state.State var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint64) (state.State, error)); ok { diff --git a/libs/store/mocks/store.go b/libs/store/mocks/store.go index aa0d3779b8..f8d1989f64 100644 --- a/libs/store/mocks/store.go +++ b/libs/store/mocks/store.go @@ -16,6 +16,10 @@ type Store[K comparable, V interface{}] struct { func (_m *Store[K, V]) All() []V { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for All") + } + var r0 []V if rf, ok := ret.Get(0).(func() []V); ok { r0 = rf() @@ -37,6 +41,10 @@ func (_m *Store[K, V]) Delete(key K) { func (_m *Store[K, V]) Get(key K) (V, bool) { ret := _m.Called(key) + if len(ret) == 0 { + panic("no return value specified for Get") + } + var r0 V var r1 bool if rf, ok := ret.Get(0).(func(K) (V, bool)); ok { @@ -61,6 +69,10 @@ func (_m *Store[K, V]) Get(key K) (V, bool) { func (_m *Store[K, V]) GetAndDelete(key K) (V, bool) { ret := _m.Called(key) + if len(ret) == 0 { + panic("no return value specified for GetAndDelete") + } + var r0 V var r1 bool if rf, ok := ret.Get(0).(func(K) (V, bool)); ok { @@ -85,6 +97,10 @@ func (_m *Store[K, V]) GetAndDelete(key K) (V, bool) { func (_m *Store[K, V]) IsZero() bool { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for IsZero") + } + var r0 bool if rf, ok := ret.Get(0).(func() bool); ok { r0 = rf() @@ -99,6 +115,10 @@ func (_m *Store[K, V]) IsZero() bool { func (_m *Store[K, V]) Len() int { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Len") + } + var r0 int if rf, ok := ret.Get(0).(func() int); ok { r0 = rf() @@ -118,6 +138,10 @@ func (_m *Store[K, V]) Put(key K, data V) { func (_m *Store[K, V]) Query(spec store.QueryFunc[K, V], limit int) []V { ret := _m.Called(spec, limit) + if len(ret) == 0 { + panic("no return value specified for Query") + } + var r0 []V if rf, ok := ret.Get(0).(func(store.QueryFunc[K, V], int) []V); ok { r0 = rf(spec, limit) diff --git a/light/provider/mocks/provider.go b/light/provider/mocks/provider.go index 93042ab3dc..24cd675bf9 100644 --- a/light/provider/mocks/provider.go +++ b/light/provider/mocks/provider.go @@ -19,6 +19,10 @@ type Provider struct { func (_m *Provider) ID() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for ID") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() @@ -33,6 +37,10 @@ func (_m *Provider) ID() string { func (_m *Provider) LightBlock(ctx context.Context, height int64) (*types.LightBlock, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for LightBlock") + } + var r0 *types.LightBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64) (*types.LightBlock, error)); ok { @@ -59,6 +67,10 @@ func (_m *Provider) LightBlock(ctx context.Context, height int64) (*types.LightB func (_m *Provider) ReportEvidence(_a0 context.Context, _a1 types.Evidence) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for ReportEvidence") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) error); ok { r0 = rf(_a0, _a1) diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go index deb22f7d2a..8d53cd4f91 100644 --- a/light/rpc/mocks/light_client.go +++ b/light/rpc/mocks/light_client.go @@ -21,6 +21,10 @@ type LightClient struct { func (_m *LightClient) ChainID() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for ChainID") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() @@ -35,6 +39,10 @@ func (_m *LightClient) ChainID() string { func (_m *LightClient) Status(ctx context.Context) *types.LightClientInfo { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for Status") + } + var r0 *types.LightClientInfo if rf, ok := ret.Get(0).(func(context.Context) *types.LightClientInfo); ok { r0 = rf(ctx) @@ -51,6 +59,10 @@ func (_m *LightClient) Status(ctx context.Context) *types.LightClientInfo { func (_m *LightClient) TrustedLightBlock(height int64) (*types.LightBlock, error) { ret := _m.Called(height) + if len(ret) == 0 { + panic("no return value specified for TrustedLightBlock") + } + var r0 *types.LightBlock var r1 error if rf, ok := ret.Get(0).(func(int64) (*types.LightBlock, error)); ok { @@ -77,6 +89,10 @@ func (_m *LightClient) TrustedLightBlock(height int64) (*types.LightBlock, error func (_m *LightClient) Update(ctx context.Context, now time.Time) (*types.LightBlock, error) { ret := _m.Called(ctx, now) + if len(ret) == 0 { + panic("no return value specified for Update") + } + var r0 *types.LightBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, time.Time) (*types.LightBlock, error)); ok { @@ -103,6 +119,10 @@ func (_m *LightClient) Update(ctx context.Context, now time.Time) (*types.LightB func (_m *LightClient) VerifyLightBlockAtHeight(ctx context.Context, height int64, now time.Time) (*types.LightBlock, error) { ret := _m.Called(ctx, height, now) + if len(ret) == 0 { + panic("no return value specified for VerifyLightBlockAtHeight") + } + var r0 *types.LightBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64, time.Time) (*types.LightBlock, error)); ok { diff --git a/rpc/client/mocks/abci_client.go b/rpc/client/mocks/abci_client.go index fc06ed551d..3d0cc35ca5 100644 --- a/rpc/client/mocks/abci_client.go +++ b/rpc/client/mocks/abci_client.go @@ -24,6 +24,10 @@ type ABCIClient struct { func (_m *ABCIClient) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ABCIInfo") + } + var r0 *coretypes.ResultABCIInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultABCIInfo, error)); ok { @@ -50,6 +54,10 @@ func (_m *ABCIClient) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, func (_m *ABCIClient) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data) + if len(ret) == 0 { + panic("no return value specified for ABCIQuery") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes) (*coretypes.ResultABCIQuery, error)); ok { @@ -76,6 +84,10 @@ func (_m *ABCIClient) ABCIQuery(ctx context.Context, path string, data bytes.Hex func (_m *ABCIClient) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data, opts) + if len(ret) == 0 { + panic("no return value specified for ABCIQueryWithOptions") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes, client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error)); ok { @@ -102,6 +114,10 @@ func (_m *ABCIClient) ABCIQueryWithOptions(ctx context.Context, path string, dat func (_m *ABCIClient) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTx") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -128,6 +144,10 @@ func (_m *ABCIClient) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretypes func (_m *ABCIClient) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxAsync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -154,6 +174,10 @@ func (_m *ABCIClient) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*core func (_m *ABCIClient) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxCommit") + } + var r0 *coretypes.ResultBroadcastTxCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTxCommit, error)); ok { @@ -180,6 +204,10 @@ func (_m *ABCIClient) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*cor func (_m *ABCIClient) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxSync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { diff --git a/rpc/client/mocks/client.go b/rpc/client/mocks/client.go index 22533b3666..c62a3347a0 100644 --- a/rpc/client/mocks/client.go +++ b/rpc/client/mocks/client.go @@ -24,6 +24,10 @@ type Client struct { func (_m *Client) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ABCIInfo") + } + var r0 *coretypes.ResultABCIInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultABCIInfo, error)); ok { @@ -50,6 +54,10 @@ func (_m *Client) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, erro func (_m *Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data) + if len(ret) == 0 { + panic("no return value specified for ABCIQuery") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes) (*coretypes.ResultABCIQuery, error)); ok { @@ -76,6 +84,10 @@ func (_m *Client) ABCIQuery(ctx context.Context, path string, data bytes.HexByte func (_m *Client) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data, opts) + if len(ret) == 0 { + panic("no return value specified for ABCIQueryWithOptions") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes, client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error)); ok { @@ -102,6 +114,10 @@ func (_m *Client) ABCIQueryWithOptions(ctx context.Context, path string, data by func (_m *Client) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Block") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlock, error)); ok { @@ -128,6 +144,10 @@ func (_m *Client) Block(ctx context.Context, height *int64) (*coretypes.ResultBl func (_m *Client) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for BlockByHash") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultBlock, error)); ok { @@ -154,6 +174,10 @@ func (_m *Client) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*corety func (_m *Client) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for BlockResults") + } + var r0 *coretypes.ResultBlockResults var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlockResults, error)); ok { @@ -180,6 +204,10 @@ func (_m *Client) BlockResults(ctx context.Context, height *int64) (*coretypes.R func (_m *Client) BlockSearch(ctx context.Context, query string, page *int, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { ret := _m.Called(ctx, query, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for BlockSearch") + } + var r0 *coretypes.ResultBlockSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, *int, *int, string) (*coretypes.ResultBlockSearch, error)); ok { @@ -206,6 +234,10 @@ func (_m *Client) BlockSearch(ctx context.Context, query string, page *int, perP func (_m *Client) BlockchainInfo(ctx context.Context, minHeight int64, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { ret := _m.Called(ctx, minHeight, maxHeight) + if len(ret) == 0 { + panic("no return value specified for BlockchainInfo") + } + var r0 *coretypes.ResultBlockchainInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (*coretypes.ResultBlockchainInfo, error)); ok { @@ -232,6 +264,10 @@ func (_m *Client) BlockchainInfo(ctx context.Context, minHeight int64, maxHeight func (_m *Client) BroadcastEvidence(_a0 context.Context, _a1 types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastEvidence") + } + var r0 *coretypes.ResultBroadcastEvidence var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) (*coretypes.ResultBroadcastEvidence, error)); ok { @@ -258,6 +294,10 @@ func (_m *Client) BroadcastEvidence(_a0 context.Context, _a1 types.Evidence) (*c func (_m *Client) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTx") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -284,6 +324,10 @@ func (_m *Client) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretypes.Res func (_m *Client) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxAsync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -310,6 +354,10 @@ func (_m *Client) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*coretype func (_m *Client) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxCommit") + } + var r0 *coretypes.ResultBroadcastTxCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTxCommit, error)); ok { @@ -336,6 +384,10 @@ func (_m *Client) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*coretyp func (_m *Client) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxSync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -362,6 +414,10 @@ func (_m *Client) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*coretypes func (_m *Client) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultCheckTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 *coretypes.ResultCheckTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultCheckTx, error)); ok { @@ -388,6 +444,10 @@ func (_m *Client) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultC func (_m *Client) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Commit") + } + var r0 *coretypes.ResultCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultCommit, error)); ok { @@ -414,6 +474,10 @@ func (_m *Client) Commit(ctx context.Context, height *int64) (*coretypes.ResultC func (_m *Client) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for ConsensusParams") + } + var r0 *coretypes.ResultConsensusParams var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultConsensusParams, error)); ok { @@ -440,6 +504,10 @@ func (_m *Client) ConsensusParams(ctx context.Context, height *int64) (*coretype func (_m *Client) ConsensusState(_a0 context.Context) (*coretypes.ResultConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ConsensusState") + } + var r0 *coretypes.ResultConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultConsensusState, error)); ok { @@ -466,6 +534,10 @@ func (_m *Client) ConsensusState(_a0 context.Context) (*coretypes.ResultConsensu func (_m *Client) DumpConsensusState(_a0 context.Context) (*coretypes.ResultDumpConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for DumpConsensusState") + } + var r0 *coretypes.ResultDumpConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultDumpConsensusState, error)); ok { @@ -492,6 +564,10 @@ func (_m *Client) DumpConsensusState(_a0 context.Context) (*coretypes.ResultDump func (_m *Client) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { ret := _m.Called(ctx, req) + if len(ret) == 0 { + panic("no return value specified for Events") + } + var r0 *coretypes.ResultEvents var r1 error if rf, ok := ret.Get(0).(func(context.Context, *coretypes.RequestEvents) (*coretypes.ResultEvents, error)); ok { @@ -518,6 +594,10 @@ func (_m *Client) Events(ctx context.Context, req *coretypes.RequestEvents) (*co func (_m *Client) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Genesis") + } + var r0 *coretypes.ResultGenesis var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultGenesis, error)); ok { @@ -544,6 +624,10 @@ func (_m *Client) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, error) func (_m *Client) GenesisChunked(_a0 context.Context, _a1 uint) (*coretypes.ResultGenesisChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for GenesisChunked") + } + var r0 *coretypes.ResultGenesisChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint) (*coretypes.ResultGenesisChunk, error)); ok { @@ -570,6 +654,10 @@ func (_m *Client) GenesisChunked(_a0 context.Context, _a1 uint) (*coretypes.Resu func (_m *Client) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Header") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultHeader, error)); ok { @@ -596,6 +684,10 @@ func (_m *Client) Header(ctx context.Context, height *int64) (*coretypes.ResultH func (_m *Client) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for HeaderByHash") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultHeader, error)); ok { @@ -622,6 +714,10 @@ func (_m *Client) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coret func (_m *Client) Health(_a0 context.Context) (*coretypes.ResultHealth, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Health") + } + var r0 *coretypes.ResultHealth var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultHealth, error)); ok { @@ -648,6 +744,10 @@ func (_m *Client) Health(_a0 context.Context) (*coretypes.ResultHealth, error) { func (_m *Client) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NetInfo") + } + var r0 *coretypes.ResultNetInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultNetInfo, error)); ok { @@ -674,6 +774,10 @@ func (_m *Client) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, error) func (_m *Client) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NumUnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultUnconfirmedTxs, error)); ok { @@ -700,6 +804,10 @@ func (_m *Client) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.ResultUncon func (_m *Client) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for RemoveTx") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.TxKey) error); ok { r0 = rf(_a0, _a1) @@ -714,6 +822,10 @@ func (_m *Client) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { func (_m *Client) Start(_a0 context.Context) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) @@ -728,6 +840,10 @@ func (_m *Client) Start(_a0 context.Context) error { func (_m *Client) Status(_a0 context.Context) (*coretypes.ResultStatus, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Status") + } + var r0 *coretypes.ResultStatus var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultStatus, error)); ok { @@ -761,6 +877,10 @@ func (_m *Client) Subscribe(ctx context.Context, subscriber string, query string _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + var r0 <-chan coretypes.ResultEvent var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string, ...int) (<-chan coretypes.ResultEvent, error)); ok { @@ -787,6 +907,10 @@ func (_m *Client) Subscribe(ctx context.Context, subscriber string, query string func (_m *Client) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { ret := _m.Called(ctx, hash, prove) + if len(ret) == 0 { + panic("no return value specified for Tx") + } + var r0 *coretypes.ResultTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes, bool) (*coretypes.ResultTx, error)); ok { @@ -813,6 +937,10 @@ func (_m *Client) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*cor func (_m *Client) TxSearch(ctx context.Context, query string, prove bool, page *int, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { ret := _m.Called(ctx, query, prove, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for TxSearch") + } + var r0 *coretypes.ResultTxSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bool, *int, *int, string) (*coretypes.ResultTxSearch, error)); ok { @@ -839,6 +967,10 @@ func (_m *Client) TxSearch(ctx context.Context, query string, prove bool, page * func (_m *Client) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(ctx, page, perPage) + if len(ret) == 0 { + panic("no return value specified for UnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int, *int) (*coretypes.ResultUnconfirmedTxs, error)); ok { @@ -865,6 +997,10 @@ func (_m *Client) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) ( func (_m *Client) Unsubscribe(ctx context.Context, subscriber string, query string) error { ret := _m.Called(ctx, subscriber, query) + if len(ret) == 0 { + panic("no return value specified for Unsubscribe") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, subscriber, query) @@ -879,6 +1015,10 @@ func (_m *Client) Unsubscribe(ctx context.Context, subscriber string, query stri func (_m *Client) UnsubscribeAll(ctx context.Context, subscriber string) error { ret := _m.Called(ctx, subscriber) + if len(ret) == 0 { + panic("no return value specified for UnsubscribeAll") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { r0 = rf(ctx, subscriber) @@ -893,6 +1033,10 @@ func (_m *Client) UnsubscribeAll(ctx context.Context, subscriber string) error { func (_m *Client) Validators(ctx context.Context, height *int64, page *int, perPage *int, requestQuorumInfo *bool) (*coretypes.ResultValidators, error) { ret := _m.Called(ctx, height, page, perPage, requestQuorumInfo) + if len(ret) == 0 { + panic("no return value specified for Validators") + } + var r0 *coretypes.ResultValidators var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64, *int, *int, *bool) (*coretypes.ResultValidators, error)); ok { diff --git a/rpc/client/mocks/events_client.go b/rpc/client/mocks/events_client.go index 092e7b15e6..469ce79ada 100644 --- a/rpc/client/mocks/events_client.go +++ b/rpc/client/mocks/events_client.go @@ -18,6 +18,10 @@ type EventsClient struct { func (_m *EventsClient) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { ret := _m.Called(ctx, req) + if len(ret) == 0 { + panic("no return value specified for Events") + } + var r0 *coretypes.ResultEvents var r1 error if rf, ok := ret.Get(0).(func(context.Context, *coretypes.RequestEvents) (*coretypes.ResultEvents, error)); ok { diff --git a/rpc/client/mocks/evidence_client.go b/rpc/client/mocks/evidence_client.go index 1b7817a0f1..fbd8316844 100644 --- a/rpc/client/mocks/evidence_client.go +++ b/rpc/client/mocks/evidence_client.go @@ -20,6 +20,10 @@ type EvidenceClient struct { func (_m *EvidenceClient) BroadcastEvidence(_a0 context.Context, _a1 types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastEvidence") + } + var r0 *coretypes.ResultBroadcastEvidence var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) (*coretypes.ResultBroadcastEvidence, error)); ok { diff --git a/rpc/client/mocks/history_client.go b/rpc/client/mocks/history_client.go index 280e1738a1..f4ae961c72 100644 --- a/rpc/client/mocks/history_client.go +++ b/rpc/client/mocks/history_client.go @@ -18,6 +18,10 @@ type HistoryClient struct { func (_m *HistoryClient) BlockchainInfo(ctx context.Context, minHeight int64, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { ret := _m.Called(ctx, minHeight, maxHeight) + if len(ret) == 0 { + panic("no return value specified for BlockchainInfo") + } + var r0 *coretypes.ResultBlockchainInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (*coretypes.ResultBlockchainInfo, error)); ok { @@ -44,6 +48,10 @@ func (_m *HistoryClient) BlockchainInfo(ctx context.Context, minHeight int64, ma func (_m *HistoryClient) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Genesis") + } + var r0 *coretypes.ResultGenesis var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultGenesis, error)); ok { @@ -70,6 +78,10 @@ func (_m *HistoryClient) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, func (_m *HistoryClient) GenesisChunked(_a0 context.Context, _a1 uint) (*coretypes.ResultGenesisChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for GenesisChunked") + } + var r0 *coretypes.ResultGenesisChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint) (*coretypes.ResultGenesisChunk, error)); ok { diff --git a/rpc/client/mocks/mempool_client.go b/rpc/client/mocks/mempool_client.go index 66c296e1fd..f294b23de2 100644 --- a/rpc/client/mocks/mempool_client.go +++ b/rpc/client/mocks/mempool_client.go @@ -20,6 +20,10 @@ type MempoolClient struct { func (_m *MempoolClient) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultCheckTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 *coretypes.ResultCheckTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultCheckTx, error)); ok { @@ -46,6 +50,10 @@ func (_m *MempoolClient) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes. func (_m *MempoolClient) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NumUnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultUnconfirmedTxs, error)); ok { @@ -72,6 +80,10 @@ func (_m *MempoolClient) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.Resu func (_m *MempoolClient) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for RemoveTx") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.TxKey) error); ok { r0 = rf(_a0, _a1) @@ -86,6 +98,10 @@ func (_m *MempoolClient) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { func (_m *MempoolClient) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(ctx, page, perPage) + if len(ret) == 0 { + panic("no return value specified for UnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int, *int) (*coretypes.ResultUnconfirmedTxs, error)); ok { diff --git a/rpc/client/mocks/network_client.go b/rpc/client/mocks/network_client.go index f365a8a4c3..f9ae2ea916 100644 --- a/rpc/client/mocks/network_client.go +++ b/rpc/client/mocks/network_client.go @@ -18,6 +18,10 @@ type NetworkClient struct { func (_m *NetworkClient) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for ConsensusParams") + } + var r0 *coretypes.ResultConsensusParams var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultConsensusParams, error)); ok { @@ -44,6 +48,10 @@ func (_m *NetworkClient) ConsensusParams(ctx context.Context, height *int64) (*c func (_m *NetworkClient) ConsensusState(_a0 context.Context) (*coretypes.ResultConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ConsensusState") + } + var r0 *coretypes.ResultConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultConsensusState, error)); ok { @@ -70,6 +78,10 @@ func (_m *NetworkClient) ConsensusState(_a0 context.Context) (*coretypes.ResultC func (_m *NetworkClient) DumpConsensusState(_a0 context.Context) (*coretypes.ResultDumpConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for DumpConsensusState") + } + var r0 *coretypes.ResultDumpConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultDumpConsensusState, error)); ok { @@ -96,6 +108,10 @@ func (_m *NetworkClient) DumpConsensusState(_a0 context.Context) (*coretypes.Res func (_m *NetworkClient) Health(_a0 context.Context) (*coretypes.ResultHealth, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Health") + } + var r0 *coretypes.ResultHealth var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultHealth, error)); ok { @@ -122,6 +138,10 @@ func (_m *NetworkClient) Health(_a0 context.Context) (*coretypes.ResultHealth, e func (_m *NetworkClient) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NetInfo") + } + var r0 *coretypes.ResultNetInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultNetInfo, error)); ok { diff --git a/rpc/client/mocks/remote_client.go b/rpc/client/mocks/remote_client.go index a09c863c8f..1708786162 100644 --- a/rpc/client/mocks/remote_client.go +++ b/rpc/client/mocks/remote_client.go @@ -24,6 +24,10 @@ type RemoteClient struct { func (_m *RemoteClient) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ABCIInfo") + } + var r0 *coretypes.ResultABCIInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultABCIInfo, error)); ok { @@ -50,6 +54,10 @@ func (_m *RemoteClient) ABCIInfo(_a0 context.Context) (*coretypes.ResultABCIInfo func (_m *RemoteClient) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data) + if len(ret) == 0 { + panic("no return value specified for ABCIQuery") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes) (*coretypes.ResultABCIQuery, error)); ok { @@ -76,6 +84,10 @@ func (_m *RemoteClient) ABCIQuery(ctx context.Context, path string, data bytes.H func (_m *RemoteClient) ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error) { ret := _m.Called(ctx, path, data, opts) + if len(ret) == 0 { + panic("no return value specified for ABCIQueryWithOptions") + } + var r0 *coretypes.ResultABCIQuery var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bytes.HexBytes, client.ABCIQueryOptions) (*coretypes.ResultABCIQuery, error)); ok { @@ -102,6 +114,10 @@ func (_m *RemoteClient) ABCIQueryWithOptions(ctx context.Context, path string, d func (_m *RemoteClient) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Block") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlock, error)); ok { @@ -128,6 +144,10 @@ func (_m *RemoteClient) Block(ctx context.Context, height *int64) (*coretypes.Re func (_m *RemoteClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for BlockByHash") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultBlock, error)); ok { @@ -154,6 +174,10 @@ func (_m *RemoteClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (* func (_m *RemoteClient) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for BlockResults") + } + var r0 *coretypes.ResultBlockResults var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlockResults, error)); ok { @@ -180,6 +204,10 @@ func (_m *RemoteClient) BlockResults(ctx context.Context, height *int64) (*coret func (_m *RemoteClient) BlockSearch(ctx context.Context, query string, page *int, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { ret := _m.Called(ctx, query, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for BlockSearch") + } + var r0 *coretypes.ResultBlockSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, *int, *int, string) (*coretypes.ResultBlockSearch, error)); ok { @@ -206,6 +234,10 @@ func (_m *RemoteClient) BlockSearch(ctx context.Context, query string, page *int func (_m *RemoteClient) BlockchainInfo(ctx context.Context, minHeight int64, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) { ret := _m.Called(ctx, minHeight, maxHeight) + if len(ret) == 0 { + panic("no return value specified for BlockchainInfo") + } + var r0 *coretypes.ResultBlockchainInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context, int64, int64) (*coretypes.ResultBlockchainInfo, error)); ok { @@ -232,6 +264,10 @@ func (_m *RemoteClient) BlockchainInfo(ctx context.Context, minHeight int64, max func (_m *RemoteClient) BroadcastEvidence(_a0 context.Context, _a1 types.Evidence) (*coretypes.ResultBroadcastEvidence, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastEvidence") + } + var r0 *coretypes.ResultBroadcastEvidence var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Evidence) (*coretypes.ResultBroadcastEvidence, error)); ok { @@ -258,6 +294,10 @@ func (_m *RemoteClient) BroadcastEvidence(_a0 context.Context, _a1 types.Evidenc func (_m *RemoteClient) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTx") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -284,6 +324,10 @@ func (_m *RemoteClient) BroadcastTx(_a0 context.Context, _a1 types.Tx) (*coretyp func (_m *RemoteClient) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxAsync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -310,6 +354,10 @@ func (_m *RemoteClient) BroadcastTxAsync(_a0 context.Context, _a1 types.Tx) (*co func (_m *RemoteClient) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTxCommit, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxCommit") + } + var r0 *coretypes.ResultBroadcastTxCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTxCommit, error)); ok { @@ -336,6 +384,10 @@ func (_m *RemoteClient) BroadcastTxCommit(_a0 context.Context, _a1 types.Tx) (*c func (_m *RemoteClient) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultBroadcastTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for BroadcastTxSync") + } + var r0 *coretypes.ResultBroadcastTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultBroadcastTx, error)); ok { @@ -362,6 +414,10 @@ func (_m *RemoteClient) BroadcastTxSync(_a0 context.Context, _a1 types.Tx) (*cor func (_m *RemoteClient) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.ResultCheckTx, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for CheckTx") + } + var r0 *coretypes.ResultCheckTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, types.Tx) (*coretypes.ResultCheckTx, error)); ok { @@ -388,6 +444,10 @@ func (_m *RemoteClient) CheckTx(_a0 context.Context, _a1 types.Tx) (*coretypes.R func (_m *RemoteClient) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Commit") + } + var r0 *coretypes.ResultCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultCommit, error)); ok { @@ -414,6 +474,10 @@ func (_m *RemoteClient) Commit(ctx context.Context, height *int64) (*coretypes.R func (_m *RemoteClient) ConsensusParams(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for ConsensusParams") + } + var r0 *coretypes.ResultConsensusParams var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultConsensusParams, error)); ok { @@ -440,6 +504,10 @@ func (_m *RemoteClient) ConsensusParams(ctx context.Context, height *int64) (*co func (_m *RemoteClient) ConsensusState(_a0 context.Context) (*coretypes.ResultConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for ConsensusState") + } + var r0 *coretypes.ResultConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultConsensusState, error)); ok { @@ -466,6 +534,10 @@ func (_m *RemoteClient) ConsensusState(_a0 context.Context) (*coretypes.ResultCo func (_m *RemoteClient) DumpConsensusState(_a0 context.Context) (*coretypes.ResultDumpConsensusState, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for DumpConsensusState") + } + var r0 *coretypes.ResultDumpConsensusState var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultDumpConsensusState, error)); ok { @@ -492,6 +564,10 @@ func (_m *RemoteClient) DumpConsensusState(_a0 context.Context) (*coretypes.Resu func (_m *RemoteClient) Events(ctx context.Context, req *coretypes.RequestEvents) (*coretypes.ResultEvents, error) { ret := _m.Called(ctx, req) + if len(ret) == 0 { + panic("no return value specified for Events") + } + var r0 *coretypes.ResultEvents var r1 error if rf, ok := ret.Get(0).(func(context.Context, *coretypes.RequestEvents) (*coretypes.ResultEvents, error)); ok { @@ -518,6 +594,10 @@ func (_m *RemoteClient) Events(ctx context.Context, req *coretypes.RequestEvents func (_m *RemoteClient) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Genesis") + } + var r0 *coretypes.ResultGenesis var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultGenesis, error)); ok { @@ -544,6 +624,10 @@ func (_m *RemoteClient) Genesis(_a0 context.Context) (*coretypes.ResultGenesis, func (_m *RemoteClient) GenesisChunked(_a0 context.Context, _a1 uint) (*coretypes.ResultGenesisChunk, error) { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for GenesisChunked") + } + var r0 *coretypes.ResultGenesisChunk var r1 error if rf, ok := ret.Get(0).(func(context.Context, uint) (*coretypes.ResultGenesisChunk, error)); ok { @@ -570,6 +654,10 @@ func (_m *RemoteClient) GenesisChunked(_a0 context.Context, _a1 uint) (*coretype func (_m *RemoteClient) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Header") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultHeader, error)); ok { @@ -596,6 +684,10 @@ func (_m *RemoteClient) Header(ctx context.Context, height *int64) (*coretypes.R func (_m *RemoteClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for HeaderByHash") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultHeader, error)); ok { @@ -622,6 +714,10 @@ func (_m *RemoteClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) ( func (_m *RemoteClient) Health(_a0 context.Context) (*coretypes.ResultHealth, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Health") + } + var r0 *coretypes.ResultHealth var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultHealth, error)); ok { @@ -648,6 +744,10 @@ func (_m *RemoteClient) Health(_a0 context.Context) (*coretypes.ResultHealth, er func (_m *RemoteClient) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NetInfo") + } + var r0 *coretypes.ResultNetInfo var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultNetInfo, error)); ok { @@ -674,6 +774,10 @@ func (_m *RemoteClient) NetInfo(_a0 context.Context) (*coretypes.ResultNetInfo, func (_m *RemoteClient) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for NumUnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultUnconfirmedTxs, error)); ok { @@ -700,6 +804,10 @@ func (_m *RemoteClient) NumUnconfirmedTxs(_a0 context.Context) (*coretypes.Resul func (_m *RemoteClient) Remote() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Remote") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() @@ -714,6 +822,10 @@ func (_m *RemoteClient) Remote() string { func (_m *RemoteClient) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { ret := _m.Called(_a0, _a1) + if len(ret) == 0 { + panic("no return value specified for RemoveTx") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, types.TxKey) error); ok { r0 = rf(_a0, _a1) @@ -728,6 +840,10 @@ func (_m *RemoteClient) RemoveTx(_a0 context.Context, _a1 types.TxKey) error { func (_m *RemoteClient) Start(_a0 context.Context) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Start") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context) error); ok { r0 = rf(_a0) @@ -742,6 +858,10 @@ func (_m *RemoteClient) Start(_a0 context.Context) error { func (_m *RemoteClient) Status(_a0 context.Context) (*coretypes.ResultStatus, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Status") + } + var r0 *coretypes.ResultStatus var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultStatus, error)); ok { @@ -775,6 +895,10 @@ func (_m *RemoteClient) Subscribe(ctx context.Context, subscriber string, query _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + var r0 <-chan coretypes.ResultEvent var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string, ...int) (<-chan coretypes.ResultEvent, error)); ok { @@ -801,6 +925,10 @@ func (_m *RemoteClient) Subscribe(ctx context.Context, subscriber string, query func (_m *RemoteClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { ret := _m.Called(ctx, hash, prove) + if len(ret) == 0 { + panic("no return value specified for Tx") + } + var r0 *coretypes.ResultTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes, bool) (*coretypes.ResultTx, error)); ok { @@ -827,6 +955,10 @@ func (_m *RemoteClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) func (_m *RemoteClient) TxSearch(ctx context.Context, query string, prove bool, page *int, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { ret := _m.Called(ctx, query, prove, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for TxSearch") + } + var r0 *coretypes.ResultTxSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bool, *int, *int, string) (*coretypes.ResultTxSearch, error)); ok { @@ -853,6 +985,10 @@ func (_m *RemoteClient) TxSearch(ctx context.Context, query string, prove bool, func (_m *RemoteClient) UnconfirmedTxs(ctx context.Context, page *int, perPage *int) (*coretypes.ResultUnconfirmedTxs, error) { ret := _m.Called(ctx, page, perPage) + if len(ret) == 0 { + panic("no return value specified for UnconfirmedTxs") + } + var r0 *coretypes.ResultUnconfirmedTxs var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int, *int) (*coretypes.ResultUnconfirmedTxs, error)); ok { @@ -879,6 +1015,10 @@ func (_m *RemoteClient) UnconfirmedTxs(ctx context.Context, page *int, perPage * func (_m *RemoteClient) Unsubscribe(ctx context.Context, subscriber string, query string) error { ret := _m.Called(ctx, subscriber, query) + if len(ret) == 0 { + panic("no return value specified for Unsubscribe") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, subscriber, query) @@ -893,6 +1033,10 @@ func (_m *RemoteClient) Unsubscribe(ctx context.Context, subscriber string, quer func (_m *RemoteClient) UnsubscribeAll(ctx context.Context, subscriber string) error { ret := _m.Called(ctx, subscriber) + if len(ret) == 0 { + panic("no return value specified for UnsubscribeAll") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { r0 = rf(ctx, subscriber) @@ -907,6 +1051,10 @@ func (_m *RemoteClient) UnsubscribeAll(ctx context.Context, subscriber string) e func (_m *RemoteClient) Validators(ctx context.Context, height *int64, page *int, perPage *int, requestQuorumInfo *bool) (*coretypes.ResultValidators, error) { ret := _m.Called(ctx, height, page, perPage, requestQuorumInfo) + if len(ret) == 0 { + panic("no return value specified for Validators") + } + var r0 *coretypes.ResultValidators var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64, *int, *int, *bool) (*coretypes.ResultValidators, error)); ok { diff --git a/rpc/client/mocks/sign_client.go b/rpc/client/mocks/sign_client.go index 9d312d993d..dea02efa1d 100644 --- a/rpc/client/mocks/sign_client.go +++ b/rpc/client/mocks/sign_client.go @@ -21,6 +21,10 @@ type SignClient struct { func (_m *SignClient) Block(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Block") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlock, error)); ok { @@ -47,6 +51,10 @@ func (_m *SignClient) Block(ctx context.Context, height *int64) (*coretypes.Resu func (_m *SignClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for BlockByHash") + } + var r0 *coretypes.ResultBlock var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultBlock, error)); ok { @@ -73,6 +81,10 @@ func (_m *SignClient) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*co func (_m *SignClient) BlockResults(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for BlockResults") + } + var r0 *coretypes.ResultBlockResults var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultBlockResults, error)); ok { @@ -99,6 +111,10 @@ func (_m *SignClient) BlockResults(ctx context.Context, height *int64) (*coretyp func (_m *SignClient) BlockSearch(ctx context.Context, query string, page *int, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { ret := _m.Called(ctx, query, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for BlockSearch") + } + var r0 *coretypes.ResultBlockSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, *int, *int, string) (*coretypes.ResultBlockSearch, error)); ok { @@ -125,6 +141,10 @@ func (_m *SignClient) BlockSearch(ctx context.Context, query string, page *int, func (_m *SignClient) Commit(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Commit") + } + var r0 *coretypes.ResultCommit var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultCommit, error)); ok { @@ -151,6 +171,10 @@ func (_m *SignClient) Commit(ctx context.Context, height *int64) (*coretypes.Res func (_m *SignClient) Header(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, height) + if len(ret) == 0 { + panic("no return value specified for Header") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64) (*coretypes.ResultHeader, error)); ok { @@ -177,6 +201,10 @@ func (_m *SignClient) Header(ctx context.Context, height *int64) (*coretypes.Res func (_m *SignClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) { ret := _m.Called(ctx, hash) + if len(ret) == 0 { + panic("no return value specified for HeaderByHash") + } + var r0 *coretypes.ResultHeader var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (*coretypes.ResultHeader, error)); ok { @@ -203,6 +231,10 @@ func (_m *SignClient) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*c func (_m *SignClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) { ret := _m.Called(ctx, hash, prove) + if len(ret) == 0 { + panic("no return value specified for Tx") + } + var r0 *coretypes.ResultTx var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes, bool) (*coretypes.ResultTx, error)); ok { @@ -229,6 +261,10 @@ func (_m *SignClient) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) ( func (_m *SignClient) TxSearch(ctx context.Context, query string, prove bool, page *int, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { ret := _m.Called(ctx, query, prove, page, perPage, orderBy) + if len(ret) == 0 { + panic("no return value specified for TxSearch") + } + var r0 *coretypes.ResultTxSearch var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, bool, *int, *int, string) (*coretypes.ResultTxSearch, error)); ok { @@ -255,6 +291,10 @@ func (_m *SignClient) TxSearch(ctx context.Context, query string, prove bool, pa func (_m *SignClient) Validators(ctx context.Context, height *int64, page *int, perPage *int, requestQuorumInfo *bool) (*coretypes.ResultValidators, error) { ret := _m.Called(ctx, height, page, perPage, requestQuorumInfo) + if len(ret) == 0 { + panic("no return value specified for Validators") + } + var r0 *coretypes.ResultValidators var r1 error if rf, ok := ret.Get(0).(func(context.Context, *int64, *int, *int, *bool) (*coretypes.ResultValidators, error)); ok { diff --git a/rpc/client/mocks/status_client.go b/rpc/client/mocks/status_client.go index 7094efff07..71f5a6f6a5 100644 --- a/rpc/client/mocks/status_client.go +++ b/rpc/client/mocks/status_client.go @@ -18,6 +18,10 @@ type StatusClient struct { func (_m *StatusClient) Status(_a0 context.Context) (*coretypes.ResultStatus, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for Status") + } + var r0 *coretypes.ResultStatus var r1 error if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.ResultStatus, error)); ok { diff --git a/rpc/client/mocks/subscription_client.go b/rpc/client/mocks/subscription_client.go index 512da36df5..84095a2b03 100644 --- a/rpc/client/mocks/subscription_client.go +++ b/rpc/client/mocks/subscription_client.go @@ -25,6 +25,10 @@ func (_m *SubscriptionClient) Subscribe(ctx context.Context, subscriber string, _ca = append(_ca, _va...) ret := _m.Called(_ca...) + if len(ret) == 0 { + panic("no return value specified for Subscribe") + } + var r0 <-chan coretypes.ResultEvent var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, string, ...int) (<-chan coretypes.ResultEvent, error)); ok { @@ -51,6 +55,10 @@ func (_m *SubscriptionClient) Subscribe(ctx context.Context, subscriber string, func (_m *SubscriptionClient) Unsubscribe(ctx context.Context, subscriber string, query string) error { ret := _m.Called(ctx, subscriber, query) + if len(ret) == 0 { + panic("no return value specified for Unsubscribe") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok { r0 = rf(ctx, subscriber, query) @@ -65,6 +73,10 @@ func (_m *SubscriptionClient) Unsubscribe(ctx context.Context, subscriber string func (_m *SubscriptionClient) UnsubscribeAll(ctx context.Context, subscriber string) error { ret := _m.Called(ctx, subscriber) + if len(ret) == 0 { + panic("no return value specified for UnsubscribeAll") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { r0 = rf(ctx, subscriber) diff --git a/types/mocks/block_event_publisher.go b/types/mocks/block_event_publisher.go index 8cd1f3d266..8f5c17f637 100644 --- a/types/mocks/block_event_publisher.go +++ b/types/mocks/block_event_publisher.go @@ -16,6 +16,10 @@ type BlockEventPublisher struct { func (_m *BlockEventPublisher) PublishEventNewBlock(_a0 types.EventDataNewBlock) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PublishEventNewBlock") + } + var r0 error if rf, ok := ret.Get(0).(func(types.EventDataNewBlock) error); ok { r0 = rf(_a0) @@ -30,6 +34,10 @@ func (_m *BlockEventPublisher) PublishEventNewBlock(_a0 types.EventDataNewBlock) func (_m *BlockEventPublisher) PublishEventNewBlockHeader(_a0 types.EventDataNewBlockHeader) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PublishEventNewBlockHeader") + } + var r0 error if rf, ok := ret.Get(0).(func(types.EventDataNewBlockHeader) error); ok { r0 = rf(_a0) @@ -44,6 +52,10 @@ func (_m *BlockEventPublisher) PublishEventNewBlockHeader(_a0 types.EventDataNew func (_m *BlockEventPublisher) PublishEventNewEvidence(_a0 types.EventDataNewEvidence) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PublishEventNewEvidence") + } + var r0 error if rf, ok := ret.Get(0).(func(types.EventDataNewEvidence) error); ok { r0 = rf(_a0) @@ -58,6 +70,10 @@ func (_m *BlockEventPublisher) PublishEventNewEvidence(_a0 types.EventDataNewEvi func (_m *BlockEventPublisher) PublishEventTx(_a0 types.EventDataTx) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PublishEventTx") + } + var r0 error if rf, ok := ret.Get(0).(func(types.EventDataTx) error); ok { r0 = rf(_a0) @@ -72,6 +88,10 @@ func (_m *BlockEventPublisher) PublishEventTx(_a0 types.EventDataTx) error { func (_m *BlockEventPublisher) PublishEventValidatorSetUpdates(_a0 types.EventDataValidatorSetUpdate) error { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for PublishEventValidatorSetUpdates") + } + var r0 error if rf, ok := ret.Get(0).(func(types.EventDataValidatorSetUpdate) error); ok { r0 = rf(_a0) diff --git a/types/mocks/priv_validator.go b/types/mocks/priv_validator.go index 9f75bf3771..4fff072e51 100644 --- a/types/mocks/priv_validator.go +++ b/types/mocks/priv_validator.go @@ -28,6 +28,10 @@ type PrivValidator struct { func (_m *PrivValidator) ExtractIntoValidator(ctx context.Context, quorumHash bytes.HexBytes) *types.Validator { ret := _m.Called(ctx, quorumHash) + if len(ret) == 0 { + panic("no return value specified for ExtractIntoValidator") + } + var r0 *types.Validator if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) *types.Validator); ok { r0 = rf(ctx, quorumHash) @@ -44,6 +48,10 @@ func (_m *PrivValidator) ExtractIntoValidator(ctx context.Context, quorumHash by func (_m *PrivValidator) GetFirstQuorumHash(_a0 context.Context) (bytes.HexBytes, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetFirstQuorumHash") + } + var r0 bytes.HexBytes var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bytes.HexBytes, error)); ok { @@ -70,6 +78,10 @@ func (_m *PrivValidator) GetFirstQuorumHash(_a0 context.Context) (bytes.HexBytes func (_m *PrivValidator) GetHeight(ctx context.Context, quorumHash bytes.HexBytes) (int64, error) { ret := _m.Called(ctx, quorumHash) + if len(ret) == 0 { + panic("no return value specified for GetHeight") + } + var r0 int64 var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (int64, error)); ok { @@ -94,6 +106,10 @@ func (_m *PrivValidator) GetHeight(ctx context.Context, quorumHash bytes.HexByte func (_m *PrivValidator) GetPrivateKey(ctx context.Context, quorumHash bytes.HexBytes) (crypto.PrivKey, error) { ret := _m.Called(ctx, quorumHash) + if len(ret) == 0 { + panic("no return value specified for GetPrivateKey") + } + var r0 crypto.PrivKey var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (crypto.PrivKey, error)); ok { @@ -120,6 +136,10 @@ func (_m *PrivValidator) GetPrivateKey(ctx context.Context, quorumHash bytes.Hex func (_m *PrivValidator) GetProTxHash(_a0 context.Context) (bytes.HexBytes, error) { ret := _m.Called(_a0) + if len(ret) == 0 { + panic("no return value specified for GetProTxHash") + } + var r0 bytes.HexBytes var r1 error if rf, ok := ret.Get(0).(func(context.Context) (bytes.HexBytes, error)); ok { @@ -146,6 +166,10 @@ func (_m *PrivValidator) GetProTxHash(_a0 context.Context) (bytes.HexBytes, erro func (_m *PrivValidator) GetPubKey(ctx context.Context, quorumHash bytes.HexBytes) (crypto.PubKey, error) { ret := _m.Called(ctx, quorumHash) + if len(ret) == 0 { + panic("no return value specified for GetPubKey") + } + var r0 crypto.PubKey var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (crypto.PubKey, error)); ok { @@ -172,6 +196,10 @@ func (_m *PrivValidator) GetPubKey(ctx context.Context, quorumHash bytes.HexByte func (_m *PrivValidator) GetThresholdPublicKey(ctx context.Context, quorumHash bytes.HexBytes) (crypto.PubKey, error) { ret := _m.Called(ctx, quorumHash) + if len(ret) == 0 { + panic("no return value specified for GetThresholdPublicKey") + } + var r0 crypto.PubKey var r1 error if rf, ok := ret.Get(0).(func(context.Context, bytes.HexBytes) (crypto.PubKey, error)); ok { @@ -198,6 +226,10 @@ func (_m *PrivValidator) GetThresholdPublicKey(ctx context.Context, quorumHash b func (_m *PrivValidator) SignProposal(ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash bytes.HexBytes, proposal *tenderminttypes.Proposal) (bytes.HexBytes, error) { ret := _m.Called(ctx, chainID, quorumType, quorumHash, proposal) + if len(ret) == 0 { + panic("no return value specified for SignProposal") + } + var r0 bytes.HexBytes var r1 error if rf, ok := ret.Get(0).(func(context.Context, string, btcjson.LLMQType, bytes.HexBytes, *tenderminttypes.Proposal) (bytes.HexBytes, error)); ok { @@ -224,6 +256,10 @@ func (_m *PrivValidator) SignProposal(ctx context.Context, chainID string, quoru func (_m *PrivValidator) SignVote(ctx context.Context, chainID string, quorumType btcjson.LLMQType, quorumHash bytes.HexBytes, vote *tenderminttypes.Vote, logger log.Logger) error { ret := _m.Called(ctx, chainID, quorumType, quorumHash, vote, logger) + if len(ret) == 0 { + panic("no return value specified for SignVote") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, btcjson.LLMQType, bytes.HexBytes, *tenderminttypes.Vote, log.Logger) error); ok { r0 = rf(ctx, chainID, quorumType, quorumHash, vote, logger) From 623706eec6f68112faa5034ac5d22ffa516d11c0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:17:23 +0100 Subject: [PATCH 074/111] fix(mempool): panic due to uninitialized txsAvailable --- internal/mempool/mempool.go | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/internal/mempool/mempool.go b/internal/mempool/mempool.go index aa94649587..e637b3d9b1 100644 --- a/internal/mempool/mempool.go +++ b/internal/mempool/mempool.go @@ -49,10 +49,12 @@ type TxMempool struct { // Synchronized fields, protected by mtx. mtx *sync.RWMutex notifiedTxsAvailable bool - txsAvailable *tmsync.Waker - preCheck PreCheckFunc - postCheck PostCheckFunc - height int64 // the latest height passed to Update + // txsAvailable is a waker that triggers when transactions are available in the mempool. + // Can be nil if not enabled with EnableTxsAvailable. + txsAvailable *tmsync.Waker + preCheck PreCheckFunc + postCheck PostCheckFunc + height int64 // the latest height passed to Update txs *clist.CList // valid transactions (passed CheckTx) txByKey map[types.TxKey]*clist.CElement @@ -82,6 +84,7 @@ func NewTxMempool( txByKey: make(map[types.TxKey]*clist.CElement), txBySender: make(map[string]*clist.CElement), } + if cfg.CacheSize > 0 { txmp.cache = NewLRUTxCache(cfg.CacheSize) } @@ -150,12 +153,26 @@ func (txmp *TxMempool) EnableTxsAvailable() { txmp.mtx.Lock() defer txmp.mtx.Unlock() + if txmp.txsAvailable != nil { + if err := txmp.txsAvailable.Close(); err != nil { + txmp.logger.Error("failed to close txsAvailable", "err", err) + } + } txmp.txsAvailable = tmsync.NewWaker() } // TxsAvailable returns a channel which fires once for every height, and only // when transactions are available in the mempool. It is thread-safe. -func (txmp *TxMempool) TxsAvailable() <-chan struct{} { return txmp.txsAvailable.Sleep() } +// +// Note: returned channel might never close if EnableTxsAvailable() was not called before +// calling this function. +func (txmp *TxMempool) TxsAvailable() <-chan struct{} { + if txmp.txsAvailable == nil { + return make(<-chan struct{}) + } + + return txmp.txsAvailable.Sleep() +} // CheckTx adds the given transaction to the mempool if it fits and passes the // application's ABCI CheckTx method. From 54e00f7393f13e8e540ff2cf42ffa5fece166d7d Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:20:44 +0100 Subject: [PATCH 075/111] feat(p2p): channel recv rate limiting - continued --- internal/p2p/channel.go | 10 ++++++---- internal/p2p/channel_params.go | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go index 96fd6b37d0..e8de8d6cc5 100644 --- a/internal/p2p/channel.go +++ b/internal/p2p/channel.go @@ -377,12 +377,14 @@ func (tci *throttledChannelIterator) Next(ctx context.Context) bool { } e := tci.innerIter.Envelope() if tci.reportErr && e != nil { - tci.innerChan.SendError(ctx, PeerError{ + msg := PeerError{ NodeID: e.From, Err: ErrRecvRateLimitExceeded, - Fatal: false, - }) - + Fatal: true, + } + if err := tci.innerChan.SendError(ctx, msg); err != nil { + tci.logger.Error("error sending error message", "err", err, "msg", msg) + } } else { tci.logger.Trace("dropping message due to rate limit", "channel", tci.innerChan, "rate", tci.limiter.Limit()) } diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index b3cb73e795..23f1ab1a5e 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -82,8 +82,8 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { Name: "mempool", SendRateLimit: 5, // TODO: make it configurable SendRateBurst: 20, // TODO: make it configurable - RecvRateLimit: 1, // TODO: make it configurable - RecvRateBurst: 1, // TODO: make it configurable + RecvRateLimit: 10, // TODO: make it configurable + RecvRateBurst: 100, // TODO: make it configurable RecvRateShouldErr: true, // TODO: make it configurable EnqueueTimeout: 10 * time.Millisecond, }, From 0d1c11491ba7ff5a2a67ef72003ef352191c46e4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:47:08 +0100 Subject: [PATCH 076/111] chore: improve logging --- internal/consensus/peer_state.go | 2 +- internal/consensus/state_proposaler.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index c094d829ca..58eab517b5 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -59,7 +59,7 @@ type PeerState struct { func NewPeerState(logger log.Logger, peerID types.NodeID) *PeerState { return &PeerState{ peerID: peerID, - logger: logger, + logger: logger.With("peer", peerID), PRS: cstypes.PeerRoundState{ Round: -1, ProposalPOLRound: -1, diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index a3f8c37bb1..00da1038e3 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -206,7 +206,11 @@ func (p *Proposaler) proposalTimestampDifferenceMetric(rs cstypes.RoundState) { func (p *Proposaler) sendMessages(ctx context.Context, msgs ...Message) { for _, msg := range msgs { - _ = p.msgInfoQueue.send(ctx, msg, "") + err := p.msgInfoQueue.send(ctx, msg, "") + if err != nil { + // just warning, we don't want to stop the proposaler + p.logger.Error("proposaler failed to send message to msgInfoQueue", "error", err) + } } } From a3c9635d748b8dd9cbd833af248d9bc8e4e4b1b8 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:45:08 +0100 Subject: [PATCH 077/111] chore: don't use go-deadlock in clist due to performance issues --- internal/libs/clist/clist.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/libs/clist/clist.go b/internal/libs/clist/clist.go index cb01b3f0d8..26ca2e124a 100644 --- a/internal/libs/clist/clist.go +++ b/internal/libs/clist/clist.go @@ -14,7 +14,8 @@ to ensure garbage collection of removed elements. import ( "fmt" - sync "github.com/sasha-s/go-deadlock" + // This is performance-critical code, so we don't use go-deadlock + "sync" ) // MaxLength is the max allowed number of elements a linked list is From 50a828377698105736500ab77db2be721ce58b59 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:01:10 +0100 Subject: [PATCH 078/111] chore: increase log level to info for "sleeping" message --- internal/consensus/state_enter_propose.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/consensus/state_enter_propose.go b/internal/consensus/state_enter_propose.go index e9ae2075c8..bd57f47743 100644 --- a/internal/consensus/state_enter_propose.go +++ b/internal/consensus/state_enter_propose.go @@ -57,7 +57,7 @@ func (c *EnterProposeAction) Execute(ctx context.Context, stateEvent StateEvent) if isProposer { pwt := proposerWaitTime(tmtime.Now(), stateData.state.LastBlockTime) if pwt > 0 { - c.logger.Debug("enter propose: latest block is newer, sleeping", + c.logger.Info("enter propose: latest block is newer, sleeping", "duration", pwt.String(), "last_block_time", stateData.state.LastBlockTime, "now", tmtime.Now(), From 2aa6d6d88d6df91ea2163fa2c6626ed68444733d Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:40:56 +0100 Subject: [PATCH 079/111] test(consensus): minor improvements to TestEmitNewValidBlockEventOnCommitWithoutBlock --- internal/consensus/state_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 2885065954..98d128580a 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -2658,8 +2658,8 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { ensureNewValidBlock(t, validBlockCh, height, round) rs := cs1.GetRoundState() - assert.True(t, rs.Step == cstypes.RoundStepPrecommit) - assert.True(t, rs.ProposalBlock == nil) + assert.EqualValues(t, cstypes.RoundStepPrecommit.String(), rs.Step.String()) + assert.Nil(t, rs.ProposalBlock) assert.True(t, rs.ProposalBlockParts.Header().Equals(blockID.PartSetHeader)) } From 0c53728c42a9c92791e6d0e47074679dd162e8e5 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:44:25 +0100 Subject: [PATCH 080/111] chore(abciclient): fixes after merge --- abci/client/client.go | 10 +++++----- abci/client/routed_client.go | 4 ++-- abci/client/routed_client_test.go | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index ed6c0b124c..c9d2f13493 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -43,7 +43,7 @@ func NewClient(logger log.Logger, addr, transport string, mustConnect bool, metr case "grpc": return NewGRPCClient(logger, addr, mustConnect), nil case "routed": - return NewRoutedClientWithAddr(logger, addr, mustConnect) + return NewRoutedClientWithAddr(logger, addr, mustConnect, metrics) default: return nil, fmt.Errorf("unknown abci transport %s", transport) } @@ -104,9 +104,9 @@ func makeReqRes(ctx context.Context, req *types.Request) *requestAndResponse { } // markDone marks the ReqRes object as done. -func (r *requestAndResponse) markDone() { - r.mtx.Lock() - defer r.mtx.Unlock() +func (reqResp *requestAndResponse) markDone() { + reqResp.mtx.Lock() + defer reqResp.mtx.Unlock() - close(r.signal) + close(reqResp.signal) } diff --git a/abci/client/routed_client.go b/abci/client/routed_client.go index 6743073db6..c758ed79d6 100644 --- a/abci/client/routed_client.go +++ b/abci/client/routed_client.go @@ -51,7 +51,7 @@ type ClientInfo struct { // - `logger` - The logger to use for the client. // - `addr` - comma-separated list of routing rules, consisting of request type, transport name and client address separated with colon. // Special request type "*" is used for default client. -func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool) (Client, error) { +func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool, metrics *Metrics) (Client, error) { // Split the routing rules routing := make(Routing) clients := make(map[string]Client) @@ -71,7 +71,7 @@ func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool) ( // Create a new client if it doesn't exist clientName := fmt.Sprintf("%s:%s", transport, address) if _, ok := clients[clientName]; !ok { - c, err := NewClient(logger, address, transport, mustConnect) + c, err := NewClient(logger, address, transport, mustConnect, metrics) if err != nil { return nil, err } diff --git a/abci/client/routed_client_test.go b/abci/client/routed_client_test.go index b796bf6ec6..f616e3a7c2 100644 --- a/abci/client/routed_client_test.go +++ b/abci/client/routed_client_test.go @@ -70,7 +70,7 @@ func TestRouting(t *testing.T) { fmt.Sprintf(",*:socket:%s", defaultSocket) logger.Info("configuring routed abci client with address", "addr", addr) - routedClient, err := abciclient.NewRoutedClientWithAddr(logger, addr, true) + routedClient, err := abciclient.NewRoutedClientWithAddr(logger, addr, true, abciclient.NopMetrics()) assert.NoError(t, err) err = routedClient.Start(ctx) assert.NoError(t, err) @@ -142,7 +142,7 @@ func TestRoutedClientGrpc(t *testing.T) { addr := "*:grpc:127.0.0.1:1234" logger.Info("configuring routed abci client with address", "addr", addr) - client, err := abciclient.NewRoutedClientWithAddr(logger, addr, true) + client, err := abciclient.NewRoutedClientWithAddr(logger, addr, true, abciclient.NopMetrics()) require.NoError(t, err) require.NoError(t, client.Start(ctx)) From 229c3873107b37d238c09eb300f063396b64e412 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:52:47 +0100 Subject: [PATCH 081/111] Squashed commit of the following: commit 2b406f3e3663100c78f0da4a189e40a6ca4fe98a Merge: 3cc9fe1cf a3c9635d7 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri Feb 23 09:45:31 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit 3cc9fe1cf7d2db57fc3cccee8fecb92440139558 Merge: b658cf274 c6cc0a3ce Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu Feb 22 10:27:31 2024 +0100 Merge branch 'feat/abci-routing' into test/abci-routing commit b658cf2745947ec1d5ce00b3b8886bba88df4755 Merge: 12402110f 0d1c11491 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 21 13:26:04 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit c6cc0a3ce2c8be3b4261169761c014070390a325 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu Feb 15 17:26:07 2024 +0100 test(abciclient): TestRoutedClientGrpc commit 12402110f42bf33508bee9bbf1e8fca0317a0e2e Merge: f66422546 e843216e5 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu Feb 15 16:27:39 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit f664225466d34cf029328b79a5e3c0a37ae01134 Merge: 15622996b 7f254b990 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 14 17:23:58 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit 15622996bded2b6f74e08ce26c6a318ea2e4bd28 Merge: 160fc8672 3a37576b6 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 14 16:37:41 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit 160fc8672997d7d3d21c1e9b5f57cb30c5d93c92 Merge: cc8bbb14f 1870ef95a Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 14 13:23:48 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit cc8bbb14f1548c07bc21f2160e194d66d2e04525 Merge: 3f11b02c2 5bf16e261 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 14 10:07:35 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit 3f11b02c28312d192eef289f30f6a09e7d01cc0b Merge: e07cb6133 c90576edc Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue Feb 13 13:48:25 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit e07cb61337fcce1c6ef634f2b7384798feb64187 Merge: cc7b12a17 03aa8148c Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue Feb 13 13:19:02 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit cc7b12a17ed7e8473efcc8d551bafb651bbf43dc Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon Feb 12 18:43:10 2024 +0100 chore: merge fix commit 6f1e1972f82701ddbdb8b239e5653e093ee16569 Merge: ab60b718a 63743b6b7 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon Feb 12 18:40:43 2024 +0100 Merge branch 'fix-mempool-spam' into test/abci-routing commit ab60b718ac2bea080108381d211dcc2d5c5a83d0 Merge: 8101f0ce5 707d86ed3 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon Feb 12 17:37:28 2024 +0100 Merge branch 'feat/abci-routing' into test/abci-routing commit 707d86ed305059a1c27797a54f7a02bf14ca656d Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon Feb 12 17:09:55 2024 +0100 test(abciclient): test routed client blocking model commit 3b37f0d0370da54c1b0f69a93372ca3b68a2d373 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Mon Feb 12 10:35:10 2024 +0100 chore(abciclient): improve error handling commit f547e7b3bf97c9fdbc9c37a7f43d7d6e09437d19 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 7 12:44:04 2024 +0100 chore: self review commit 64376a5820b59cea9d22e9f1b4d547ac5066c64b Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed Feb 7 09:00:52 2024 +0100 test(abciclient): test routed client using socket server commit df8e5a99993a7cf107b4d543e16f9d443ac4aa9d Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue Feb 6 15:38:40 2024 +0100 chore: routed abci client config commit 201e1c5f51f57e186106d86439b9711d0888c2e1 Author: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue Feb 6 15:06:22 2024 +0100 feat: support multiple ABCI Apps with routing requests to them --- abci/client/routed_client_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/abci/client/routed_client_test.go b/abci/client/routed_client_test.go index f616e3a7c2..a8d85374d4 100644 --- a/abci/client/routed_client_test.go +++ b/abci/client/routed_client_test.go @@ -128,7 +128,6 @@ func TestRoutedClientGrpc(t *testing.T) { logger := log.NewTestingLogger(t) - // app := types.NewBaseApplication() app := mocks.NewApplication(t) defer app.AssertExpectations(t) app.On("Echo", mock.Anything, mock.Anything).Return( From ae74ce48010607d2ad86933b9e0db08eb0e9051a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:50:28 +0100 Subject: [PATCH 082/111] Revert "feat: socket client uses pririority queue to determine processing order" This reverts commit 8fc733ff9596987b2710c78447b7a817e1501d53. --- abci/client/client.go | 35 ------------------------------- abci/client/socket_client.go | 40 +++++++++--------------------------- 2 files changed, 10 insertions(+), 65 deletions(-) diff --git a/abci/client/client.go b/abci/client/client.go index c9d2f13493..b29ee2d537 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -59,41 +59,6 @@ type requestAndResponse struct { signal chan struct{} } -// priority of this request type; higher number means more important -func (reqResp *requestAndResponse) priority() (priority int8) { - if reqResp == nil || reqResp.Request == nil || reqResp.Request.Value == nil { - // Error - return -128 - } - // consensus-related requests are more important - switch reqResp.Request.Value.(type) { - case *types.Request_InitChain: - priority = 110 - case *types.Request_PrepareProposal: - priority = 100 - case *types.Request_ProcessProposal: - priority = 100 - case *types.Request_FinalizeBlock: - priority = 100 - case *types.Request_Flush: - priority = 100 - case *types.Request_ExtendVote: - priority = 100 - case *types.Request_VerifyVoteExtension: - priority = 90 - case *types.Request_Info: - priority = 120 - case *types.Request_CheckTx: - priority = -10 - case *types.Request_Query: - priority = -20 - default: - priority = 0 - } - - return priority -} - func makeReqRes(ctx context.Context, req *types.Request) *requestAndResponse { return &requestAndResponse{ Request: req, diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index f2cae523ce..9008dfa092 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -11,11 +11,9 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/common/prque" sync "github.com/sasha-s/go-deadlock" "github.com/dashpay/tenderdash/abci/types" - tmsync "github.com/dashpay/tenderdash/internal/libs/sync" "github.com/dashpay/tenderdash/libs/log" tmnet "github.com/dashpay/tenderdash/libs/net" "github.com/dashpay/tenderdash/libs/service" @@ -36,10 +34,7 @@ type socketClient struct { mustConnect bool conn net.Conn - // Requests queue - reqQueue *prque.Prque[int8, *requestAndResponse] - // Wake up sender when new request is added to the queue. - reqWaker *tmsync.Waker + reqQueue chan *requestAndResponse mtx sync.Mutex err error @@ -62,10 +57,8 @@ func NewSocketClient(logger log.Logger, addr string, mustConnect bool, metrics * } cli := &socketClient{ - logger: logger, - reqQueue: prque.New[int8, *requestAndResponse](nil), - reqWaker: tmsync.NewWaker(), - + logger: logger, + reqQueue: make(chan *requestAndResponse), mustConnect: mustConnect, addr: addr, reqSent: list.New(), @@ -193,18 +186,8 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer select { case <-ctx.Done(): return - case <-cli.reqSleep(): - } - - for !cli.reqQueueEmpty() { - reqres := cli.dequeue() - if err := reqres.ctx.Err(); err != nil { - // request expired, skip it - cli.logger.Debug("abci.socketClient request expired, skipping", "req", reqres.Request.Value, "error", err) - continue - } - - // N.B. We must track request before sending it out, otherwise the + case reqres := <-cli.reqQueue: + // N.B. We must enqueue before sending out the request, otherwise the // server may reply before we do it, and the receiver will fail for an // unsolicited reply. cli.trackRequest(reqres) @@ -299,8 +282,11 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty reqres := makeReqRes(ctx, req) cli.enqueue(reqres) - // Asynchronously wake up the sender. - cli.reqWake() + select { + case cli.reqQueue <- reqres: + case <-ctx.Done(): + return nil, fmt.Errorf("can't queue req: %w", ctx.Err()) + } // wait for response for our request select { @@ -321,12 +307,6 @@ func (cli *socketClient) drainQueue() { cli.mtx.Lock() defer cli.mtx.Unlock() - if err := cli.reqWaker.Close(); err != nil { - cli.logger.Debug("abci.socketClient failed to close waker", "err", err) - } - cli.reqWaker = tmsync.NewWaker() - - cli.reqQueue.Reset() // mark all in-flight messages as resolved (they will get cli.Error()) for req := cli.reqSent.Front(); req != nil; req = req.Next() { reqres := req.Value.(*requestAndResponse) From 3c48f75ca9e31458b8e55746b1cd9302df49cb97 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:54:45 +0100 Subject: [PATCH 083/111] Revert "feat: abci client prometheus support" This reverts commit 0bbe9bde3e2e8f853a1bb17094397516070f599c. --- abci/client/client.go | 4 +- abci/client/metrics.gen.go | 31 ---------- abci/client/metrics.go | 90 ---------------------------- abci/client/socket_client.go | 14 +---- abci/cmd/abci-cli/abci-cli.go | 2 +- abci/example/example_test.go | 2 +- abci/example/kvstore/kvstore_test.go | 2 +- abci/tests/client_server_test.go | 2 +- internal/consensus/replay_file.go | 6 +- internal/proxy/client.go | 4 +- internal/proxy/client_test.go | 6 +- node/node.go | 27 ++------- node/public.go | 3 +- rpc/test/helpers.go | 2 +- test/e2e/node/main.go | 2 +- 15 files changed, 22 insertions(+), 175 deletions(-) delete mode 100644 abci/client/metrics.gen.go delete mode 100644 abci/client/metrics.go diff --git a/abci/client/client.go b/abci/client/client.go index b29ee2d537..f095342df4 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -36,10 +36,10 @@ type Client interface { // NewClient returns a new ABCI client of the specified transport type. // It returns an error if the transport is not "socket" or "grpc" -func NewClient(logger log.Logger, addr, transport string, mustConnect bool, metrics *Metrics) (Client, error) { +func NewClient(logger log.Logger, addr, transport string, mustConnect bool) (Client, error) { switch transport { case "socket": - return NewSocketClient(logger, addr, mustConnect, metrics), nil + return NewSocketClient(logger, addr, mustConnect), nil case "grpc": return NewGRPCClient(logger, addr, mustConnect), nil case "routed": diff --git a/abci/client/metrics.gen.go b/abci/client/metrics.gen.go deleted file mode 100644 index 62847a1958..0000000000 --- a/abci/client/metrics.gen.go +++ /dev/null @@ -1,31 +0,0 @@ -// Code generated by metricsgen. DO NOT EDIT. - -package abciclient - -import ( - "github.com/go-kit/kit/metrics/discard" - prometheus "github.com/go-kit/kit/metrics/prometheus" - stdprometheus "github.com/prometheus/client_golang/prometheus" -) - -func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { - labels := []string{} - for i := 0; i < len(labelsAndValues); i += 2 { - labels = append(labels, labelsAndValues[i]) - } - return &Metrics{ - QueuedMessages: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ - Namespace: namespace, - Subsystem: MetricsSubsystem, - Name: "queued_messages", - Help: "Number of messages in ABCI Socket queue", - }, append(labels, "type", "priority")).With(labelsAndValues...), - - } -} - -func NopMetrics() *Metrics { - return &Metrics{ - QueuedMessages: discard.NewGauge(), - } -} diff --git a/abci/client/metrics.go b/abci/client/metrics.go deleted file mode 100644 index 26cdc92504..0000000000 --- a/abci/client/metrics.go +++ /dev/null @@ -1,90 +0,0 @@ -package abciclient - -import ( - "fmt" - "reflect" - "regexp" - "strconv" - - sync "github.com/sasha-s/go-deadlock" - - "github.com/go-kit/kit/metrics" -) - -const ( - // MetricsSubsystem is a subsystem shared by all metrics exposed by this - // package. - MetricsSubsystem = "abci" -) - -var ( - // valueToLabelRegexp is used to find the golang package name and type name - // so that the name can be turned into a prometheus label where the characters - // in the label do not include prometheus special characters such as '*' and '.'. - valueToLabelRegexp = regexp.MustCompile(`\*?(\w+)\.(.*)`) -) - -//go:generate go run ../../scripts/metricsgen -struct=Metrics - -// Metrics contains metrics exposed by this package. -type Metrics struct { - // Number of messages in ABCI Socket queue - QueuedMessages metrics.Gauge `metrics_labels:"type, priority"` - - // labels cache - labels metricsLabelCache -} - -type metricsLabelCache struct { - mtx sync.RWMutex - messageLabelNames map[reflect.Type]string -} - -func (m *Metrics) EnqueuedMessage(reqres *requestAndResponse) { - priority := strconv.Itoa(int(reqres.priority())) - typ := "nil" - if reqres != nil && reqres.Request != nil { - typ = m.labels.ValueToMetricLabel(reqres.Request.Value) - } - - m.QueuedMessages.With("type", typ, "priority", priority).Add(1) -} - -func (m *Metrics) DequeuedMessage(reqres *requestAndResponse) { - priority := strconv.Itoa(int(reqres.priority())) - typ := "nil" - if reqres != nil && reqres.Request != nil { - typ = m.labels.ValueToMetricLabel(reqres.Request.Value) - } - - m.QueuedMessages.With("type", typ, "priority", priority).Add(-1) -} - -// ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang -// type that is passed in. -// This method uses a map on the Metrics struct so that each label name only needs -// to be produced once to prevent expensive string operations. -func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string { - if m.messageLabelNames == nil { - m.mtx.Lock() - m.messageLabelNames = map[reflect.Type]string{} - m.mtx.Unlock() - } - - t := reflect.TypeOf(i) - m.mtx.RLock() - - if s, ok := m.messageLabelNames[t]; ok { - m.mtx.RUnlock() - return s - } - m.mtx.RUnlock() - - s := t.String() - ss := valueToLabelRegexp.FindStringSubmatch(s) - l := fmt.Sprintf("%s_%s", ss[1], ss[2]) - m.mtx.Lock() - defer m.mtx.Unlock() - m.messageLabelNames[t] = l - return l -} diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 9008dfa092..6239036a4e 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -8,7 +8,6 @@ import ( "fmt" "io" "net" - "sync/atomic" "time" sync "github.com/sasha-s/go-deadlock" @@ -39,11 +38,6 @@ type socketClient struct { mtx sync.Mutex err error reqSent *list.List // list of requests sent, waiting for response - - metrics *Metrics - - // if true, send blocks until response is received - blocking atomic.Bool } var _ Client = (*socketClient)(nil) @@ -51,19 +45,13 @@ var _ Client = (*socketClient)(nil) // NewSocketClient creates a new socket client, which connects to a given // address. If mustConnect is true, the client will return an error upon start // if it fails to connect. -func NewSocketClient(logger log.Logger, addr string, mustConnect bool, metrics *Metrics) Client { - if metrics == nil { - metrics = NopMetrics() - } - +func NewSocketClient(logger log.Logger, addr string, mustConnect bool) Client { cli := &socketClient{ logger: logger, reqQueue: make(chan *requestAndResponse), mustConnect: mustConnect, addr: addr, reqSent: list.New(), - - metrics: metrics, } cli.BaseService = *service.NewBaseService(logger, "socketClient", cli) return cli diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 3e188afe3d..8dbb9697de 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -63,7 +63,7 @@ func RootCmmand(logger log.Logger) *cobra.Command { if client == nil { var err error - client, err = abciclient.NewClient(logger.With("module", "abci-client"), flagAddress, flagAbci, false, nil) + client, err = abciclient.NewClient(logger.With("module", "abci-client"), flagAddress, flagAbci, false) if err != nil { return err } diff --git a/abci/example/example_test.go b/abci/example/example_test.go index ae9b339d5b..07d0bf5135 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -66,7 +66,7 @@ func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Ap require.NoError(t, err) // Connect to the socket - client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false, nil) + client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false) t.Cleanup(client.Wait) err = client.Start(ctx) diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 1e80e890d5..66274fe414 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -323,7 +323,7 @@ func makeSocketClientServer( } // Connect to the socket - client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false, nil) + client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false) if err := client.Start(ctx); err != nil { cancel() return nil, nil, err diff --git a/abci/tests/client_server_test.go b/abci/tests/client_server_test.go index a4d8ddf363..f95c124e5b 100644 --- a/abci/tests/client_server_test.go +++ b/abci/tests/client_server_test.go @@ -34,7 +34,7 @@ func TestClientServerNoAddrPrefix(t *testing.T) { assert.NoError(t, err, "expected no error on server.Start") t.Cleanup(server.Wait) - client, err := abciclientent.NewClient(logger, addr, transport, true, nil) + client, err := abciclientent.NewClient(logger, addr, transport, true) assert.NoError(t, err, "expected no error on NewClient") err = client.Start(ctx) assert.NoError(t, err, "expected no error on client.Start") diff --git a/internal/consensus/replay_file.go b/internal/consensus/replay_file.go index 692dbfa3f7..0c13b4dd27 100644 --- a/internal/consensus/replay_file.go +++ b/internal/consensus/replay_file.go @@ -12,7 +12,6 @@ import ( dbm "github.com/tendermint/tm-db" - abciclient "github.com/dashpay/tenderdash/abci/client" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/internal/eventbus" "github.com/dashpay/tenderdash/internal/proxy" @@ -39,7 +38,7 @@ func RunReplayFile( csConfig *config.ConsensusConfig, console bool, ) error { - consensusState, err := newConsensusStateForReplay(ctx, cfg, logger, csConfig, nil) + consensusState, err := newConsensusStateForReplay(ctx, cfg, logger, csConfig) if err != nil { return err } @@ -302,7 +301,6 @@ func newConsensusStateForReplay( cfg config.BaseConfig, logger log.Logger, csConfig *config.ConsensusConfig, - clientMetrics *abciclient.Metrics, ) (*State, error) { dbType := dbm.BackendType(cfg.DBBackend) // Get BlockStore @@ -329,7 +327,7 @@ func newConsensusStateForReplay( return nil, err } - client, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir(), clientMetrics) + client, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir()) if err != nil { return nil, err } diff --git a/internal/proxy/client.go b/internal/proxy/client.go index b7d4283510..01daf13d04 100644 --- a/internal/proxy/client.go +++ b/internal/proxy/client.go @@ -24,7 +24,7 @@ import ( // // The Closer is a noop except for persistent_kvstore applications, // which will clean up the store. -func ClientFactory(logger log.Logger, addr, transport, dbDir string, clientMetrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { +func ClientFactory(logger log.Logger, addr, transport, dbDir string) (abciclient.Client, io.Closer, error) { switch addr { case "kvstore": app, err := kvstore.NewMemoryApp( @@ -53,7 +53,7 @@ func ClientFactory(logger log.Logger, addr, transport, dbDir string, clientMetri return abciclient.NewLocalClient(logger, types.NewBaseApplication()), tmos.NoopCloser{}, nil default: const mustConnect = false // loop retrying - client, err := abciclient.NewClient(logger, addr, transport, mustConnect, clientMetrics) + client, err := abciclient.NewClient(logger, addr, transport, mustConnect) if err != nil { return nil, tmos.NoopCloser{}, err } diff --git a/internal/proxy/client_test.go b/internal/proxy/client_test.go index ffa7be03a4..700ee47a65 100644 --- a/internal/proxy/client_test.go +++ b/internal/proxy/client_test.go @@ -60,7 +60,7 @@ var SOCKET = "socket" func TestEcho(t *testing.T) { sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", t.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) if err != nil { t.Fatal(err) } @@ -104,7 +104,7 @@ func BenchmarkEcho(b *testing.B) { b.StopTimer() // Initialize sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", b.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) if err != nil { b.Fatal(err) } @@ -155,7 +155,7 @@ func TestInfo(t *testing.T) { sockPath := fmt.Sprintf("unix://%s/echo_%v.sock", t.TempDir(), tmrand.Str(6)) logger := log.NewNopLogger() - client, err := abciclient.NewClient(logger, sockPath, SOCKET, true, nil) + client, err := abciclient.NewClient(logger, sockPath, SOCKET, true) require.NoError(t, err) // Start server diff --git a/node/node.go b/node/node.go index 7a71e38c9a..b46ec76b08 100644 --- a/node/node.go +++ b/node/node.go @@ -3,7 +3,6 @@ package node import ( "context" "fmt" - "io" "net" "net/http" "strconv" @@ -35,7 +34,6 @@ import ( "github.com/dashpay/tenderdash/internal/store" tmbytes "github.com/dashpay/tenderdash/libs/bytes" "github.com/dashpay/tenderdash/libs/log" - "github.com/dashpay/tenderdash/libs/os" "github.com/dashpay/tenderdash/libs/service" tmtime "github.com/dashpay/tenderdash/libs/time" "github.com/dashpay/tenderdash/privval" @@ -46,15 +44,6 @@ import ( _ "github.com/lib/pq" // provide the psql db driver ) -// Function that creates new abciclient.Client -type ClientCreatorFunc func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) - -func MakeClientCreator(client abciclient.Client) ClientCreatorFunc { - return func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { - return client, os.NoopCloser{}, nil - } -} - // nodeImpl is the highest level interface to a full Tendermint node. // It includes all configuration information and running services. type nodeImpl struct { @@ -112,8 +101,9 @@ func newDefaultNode( ) } - appClient := func(metrics *abciclient.Metrics) (abciclient.Client, io.Closer, error) { - return proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir(), metrics) + appClient, _, err := proxy.ClientFactory(logger, cfg.ProxyApp, cfg.ABCI, cfg.DBDir()) + if err != nil { + return nil, err } return makeNode( @@ -132,7 +122,7 @@ func makeNode( ctx context.Context, cfg *config.Config, nodeKey types.NodeKey, - createClientFunc ClientCreatorFunc, + client abciclient.Client, genesisDocProvider genesisDocProvider, dbProvider config.DBProvider, logger log.Logger, @@ -166,12 +156,6 @@ func makeNode( nodeMetrics := defaultMetricsProvider(cfg.Instrumentation)(genDoc.ChainID) - client, closer, err := createClientFunc(nodeMetrics.abci) - if err != nil { - return nil, err - } - defer closer.Close() - proxyApp := proxy.New(client, logger.With("module", "proxy"), nodeMetrics.proxy) eventBus := eventbus.NewDefault(logger.With("module", "events")) @@ -685,7 +669,6 @@ type nodeMetrics struct { state *sm.Metrics statesync *statesync.Metrics evidence *evidence.Metrics - abci *abciclient.Metrics } // metricsProvider returns consensus, p2p, mempool, state, statesync Metrics. @@ -706,7 +689,6 @@ func defaultMetricsProvider(cfg *config.InstrumentationConfig) metricsProvider { state: sm.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), statesync: statesync.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), evidence: evidence.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), - abci: abciclient.PrometheusMetrics(cfg.Namespace, "chain_id", chainID), } } return &nodeMetrics{ @@ -718,7 +700,6 @@ func defaultMetricsProvider(cfg *config.InstrumentationConfig) metricsProvider { state: sm.NopMetrics(), statesync: statesync.NopMetrics(), evidence: evidence.NopMetrics(), - abci: abciclient.NopMetrics(), } } } diff --git a/node/public.go b/node/public.go index e16f9009e9..db1b80530a 100644 --- a/node/public.go +++ b/node/public.go @@ -5,6 +5,7 @@ import ( "context" "fmt" + abciclient "github.com/dashpay/tenderdash/abci/client" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/libs/service" @@ -33,7 +34,7 @@ func New( ctx context.Context, conf *config.Config, logger log.Logger, - cf ClientCreatorFunc, + cf abciclient.Client, gen *types.GenesisDoc, ) (service.Service, error) { nodeKey, err := types.LoadOrGenNodeKey(conf.NodeKeyFile()) diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 8b13ea3abf..e2e64deabc 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -98,7 +98,7 @@ func StartTendermint( } } papp := abciclient.NewLocalClient(logger, app) - tmNode, err := node.New(ctx, conf, logger, node.MakeClientCreator(papp), nil) + tmNode, err := node.New(ctx, conf, logger, papp, nil) if err != nil { return nil, func(_ context.Context) error { cancel(); return nil }, err } diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index 4a53c5b964..caf90c2ac4 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -204,7 +204,7 @@ func startNode(ctx context.Context, cfg *Config) error { ctx, tmcfg, nodeLogger, - node.MakeClientCreator(abciclient.NewLocalClient(nodeLogger, app)), + abciclient.NewLocalClient(nodeLogger, app), nil, ) if err != nil { From 8da9d8927c03ffe436ef3559d7429ebf21cfb30c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:56:47 +0100 Subject: [PATCH 084/111] Revert "feat: socket client prio queue improved" This reverts commit ed4c661df5aac3fff8c5d6f3ed47c01f10eab009. --- abci/client/socket_client.go | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 6239036a4e..d55580bdb0 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -119,12 +119,6 @@ func (cli *socketClient) Error() error { return cli.err } -// setBlocking sets the blocking mode of the client. -// Used in tests. -func (cli *socketClient) setBlocking(blocking bool) { - cli.blocking.Store(blocking) -} - // Add the request to the pending messages queue. // // Note that you still need to wake up sendRequestsRoutine writing to `cli.reqSignal` @@ -149,24 +143,9 @@ func (cli *socketClient) dequeue() *requestAndResponse { func (cli *socketClient) reqQueueEmpty() bool { cli.mtx.Lock() defer cli.mtx.Unlock() - return cli.reqQueue.Empty() } -func (cli *socketClient) reqWake() { - cli.mtx.Lock() - defer cli.mtx.Unlock() - - cli.reqWaker.Wake() -} - -func (cli *socketClient) reqSleep() <-chan struct{} { - cli.mtx.Lock() - defer cli.mtx.Unlock() - - return cli.reqWaker.Sleep() -} - func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer) { bw := bufio.NewWriter(conn) for { @@ -189,14 +168,6 @@ func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer cli.stopForError(fmt.Errorf("flush buffer: %w", err)) return } - - if cli.blocking.Load() { - select { - case <-reqres.signal: - case <-ctx.Done(): - return - } - } } } } @@ -262,6 +233,8 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error { return nil } +//---------------------------------------- + func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*types.Response, error) { if !cli.IsRunning() { return nil, errors.New("client has stopped") From 20d767f4e684d0bde66216d562fc908cb38819a6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:00:50 +0100 Subject: [PATCH 085/111] chore: revert priority queue - manual fixes --- abci/client/client.go | 2 +- abci/client/routed_client.go | 4 +- abci/client/routed_client_test.go | 4 +- abci/client/socket_client.go | 28 ------- abci/client/socket_client_test.go | 127 ------------------------------ go.mod | 2 +- go.sum | 2 - 7 files changed, 6 insertions(+), 163 deletions(-) delete mode 100644 abci/client/socket_client_test.go diff --git a/abci/client/client.go b/abci/client/client.go index f095342df4..7f829e04fe 100644 --- a/abci/client/client.go +++ b/abci/client/client.go @@ -43,7 +43,7 @@ func NewClient(logger log.Logger, addr, transport string, mustConnect bool) (Cli case "grpc": return NewGRPCClient(logger, addr, mustConnect), nil case "routed": - return NewRoutedClientWithAddr(logger, addr, mustConnect, metrics) + return NewRoutedClientWithAddr(logger, addr, mustConnect) default: return nil, fmt.Errorf("unknown abci transport %s", transport) } diff --git a/abci/client/routed_client.go b/abci/client/routed_client.go index c758ed79d6..6743073db6 100644 --- a/abci/client/routed_client.go +++ b/abci/client/routed_client.go @@ -51,7 +51,7 @@ type ClientInfo struct { // - `logger` - The logger to use for the client. // - `addr` - comma-separated list of routing rules, consisting of request type, transport name and client address separated with colon. // Special request type "*" is used for default client. -func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool, metrics *Metrics) (Client, error) { +func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool) (Client, error) { // Split the routing rules routing := make(Routing) clients := make(map[string]Client) @@ -71,7 +71,7 @@ func NewRoutedClientWithAddr(logger log.Logger, addr string, mustConnect bool, m // Create a new client if it doesn't exist clientName := fmt.Sprintf("%s:%s", transport, address) if _, ok := clients[clientName]; !ok { - c, err := NewClient(logger, address, transport, mustConnect, metrics) + c, err := NewClient(logger, address, transport, mustConnect) if err != nil { return nil, err } diff --git a/abci/client/routed_client_test.go b/abci/client/routed_client_test.go index a8d85374d4..54e765b0f9 100644 --- a/abci/client/routed_client_test.go +++ b/abci/client/routed_client_test.go @@ -70,7 +70,7 @@ func TestRouting(t *testing.T) { fmt.Sprintf(",*:socket:%s", defaultSocket) logger.Info("configuring routed abci client with address", "addr", addr) - routedClient, err := abciclient.NewRoutedClientWithAddr(logger, addr, true, abciclient.NopMetrics()) + routedClient, err := abciclient.NewRoutedClientWithAddr(logger, addr, true) assert.NoError(t, err) err = routedClient.Start(ctx) assert.NoError(t, err) @@ -141,7 +141,7 @@ func TestRoutedClientGrpc(t *testing.T) { addr := "*:grpc:127.0.0.1:1234" logger.Info("configuring routed abci client with address", "addr", addr) - client, err := abciclient.NewRoutedClientWithAddr(logger, addr, true, abciclient.NopMetrics()) + client, err := abciclient.NewRoutedClientWithAddr(logger, addr, true) require.NoError(t, err) require.NoError(t, client.Start(ctx)) diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index d55580bdb0..86cf38f97f 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -119,33 +119,6 @@ func (cli *socketClient) Error() error { return cli.err } -// Add the request to the pending messages queue. -// -// Note that you still need to wake up sendRequestsRoutine writing to `cli.reqSignal` -func (cli *socketClient) enqueue(reqres *requestAndResponse) { - cli.mtx.Lock() - cli.reqQueue.Push(reqres, reqres.priority()) - cli.mtx.Unlock() - - cli.metrics.EnqueuedMessage(reqres) -} - -// Remove the first request from the queue and return it. -func (cli *socketClient) dequeue() *requestAndResponse { - cli.mtx.Lock() - reqres := cli.reqQueue.PopItem() - cli.mtx.Unlock() - - cli.metrics.DequeuedMessage(reqres) - return reqres -} - -func (cli *socketClient) reqQueueEmpty() bool { - cli.mtx.Lock() - defer cli.mtx.Unlock() - return cli.reqQueue.Empty() -} - func (cli *socketClient) sendRequestsRoutine(ctx context.Context, conn io.Writer) { bw := bufio.NewWriter(conn) for { @@ -241,7 +214,6 @@ func (cli *socketClient) doRequest(ctx context.Context, req *types.Request) (*ty } reqres := makeReqRes(ctx, req) - cli.enqueue(reqres) select { case cli.reqQueue <- reqres: diff --git a/abci/client/socket_client_test.go b/abci/client/socket_client_test.go deleted file mode 100644 index c1a9df5752..0000000000 --- a/abci/client/socket_client_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package abciclient - -import ( - "context" - "sync" - "testing" - "time" - - "github.com/dashpay/tenderdash/abci/server" - "github.com/dashpay/tenderdash/abci/types" - "github.com/dashpay/tenderdash/libs/log" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -// TestSocketClientCheckTxAfterPrepareProposal tests that the socket client -// executes CheckTx after PrepareProposal due to use of priority queue. -// -// Given the socket client and the socket server and socket client waiting -// When the socket client sends a CheckTx request followed by a PrepareProposal request -// Then the socket server executes the PrepareProposal request before the CheckTx request -func TestCheckTxAfterPrepareProposal(t *testing.T) { - // how long we sleep between each request - const SleepTime = 10 * time.Millisecond - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) - defer cancel() - - logger := log.NewTestingLogger(t) - socket := "unix://" + t.TempDir() + "/socket" - - app := &testApp{ - t: t, - logger: logger, - } - - server, err := server.NewServer(logger, socket, "socket", app) - require.NoError(t, err) - err = server.Start(ctx) - require.NoError(t, err) - - cli1 := NewSocketClient(logger, socket, true, nil) - cli := cli1.(*socketClient) - cli.setBlocking(true) - - err = cli.Start(ctx) - require.NoError(t, err) - - // wait until all requests are queued; we're unlock this when we're ready to start the test, and then - // lock inside Info handler will be unlocked - app.wait.Lock() - - // Send Info request that will block on app.wait mutex. - // Then send checkTx followed by PreparaProposal, - // but the server should execute PrepareProposal first due to use of priority queue - requests := []types.Request{ - {Value: &types.Request_Info{}}, - {Value: &types.Request_CheckTx{}}, - {Value: &types.Request_PrepareProposal{}}, - } - - wg := sync.WaitGroup{} - for i, req := range requests { - wg.Add(1) - // We use goroutines because these functions are blocking - go func(i int, req types.Request) { - var err error - defer wg.Done() - logger.Info("sending request", "id", i, "req", req.Value) - switch req.Value.(type) { - case *types.Request_Info: - _, err = cli.Info(ctx, &types.RequestInfo{}) - case *types.Request_CheckTx: - _, err = cli.CheckTx(ctx, &types.RequestCheckTx{}) - case *types.Request_PrepareProposal: - _, err = cli.PrepareProposal(ctx, &types.RequestPrepareProposal{}) - default: - t.Logf("unknown request type: %T", req.Value) - } - assert.NoError(t, err) - }(i, req) - // time to start the goroutine - time.Sleep(SleepTime) - } - - // start the test - logger.Info("UNLOCK AND START THE TEST") - app.wait.Unlock() - - // wait for the server to finish executing all requests - wg.Wait() -} - -type testApp struct { - // we will wait on this mutex in Info function until we are ready to start the test - wait sync.Mutex - types.BaseApplication - prepareProposalExecuted bool - t *testing.T - logger log.Logger -} - -// Info waits on the mutex until we are ready to start the test -func (app *testApp) Info(_ context.Context, _ *types.RequestInfo) (*types.ResponseInfo, error) { - app.wait.Lock() - defer app.wait.Unlock() - app.logger.Info("Info") - return &types.ResponseInfo{}, nil -} - -func (app *testApp) CheckTx(_ context.Context, _ *types.RequestCheckTx) (*types.ResponseCheckTx, error) { - app.wait.Lock() - defer app.wait.Unlock() - app.logger.Info("CheckTx") - - assert.True(app.t, app.prepareProposalExecuted) - return &types.ResponseCheckTx{Code: types.CodeTypeOK}, nil -} - -func (app *testApp) PrepareProposal(_ context.Context, _ *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - app.wait.Lock() - defer app.wait.Unlock() - app.logger.Info("PrepareProposal") - - assert.False(app.t, app.prepareProposalExecuted) - app.prepareProposalExecuted = true - return &types.ResponsePrepareProposal{}, nil -} diff --git a/go.mod b/go.mod index 07be024b42..dcdc4c93a4 100644 --- a/go.mod +++ b/go.mod @@ -90,6 +90,7 @@ require ( github.com/go-pkgz/expirable-cache v0.0.3 // indirect github.com/go-pkgz/rest v1.5.0 // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect + github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/iancoleman/strcase v0.2.0 // indirect github.com/jinzhu/copier v0.3.5 // indirect @@ -301,7 +302,6 @@ require ( require ( github.com/creachadair/tomledit v0.0.23 - github.com/ethereum/go-ethereum v1.13.8 github.com/jonboulle/clockwork v0.3.0 github.com/oasisprotocol/oasis-core/go v0.2202.5 github.com/sasha-s/go-deadlock v0.3.1 diff --git a/go.sum b/go.sum index 9e6deab7d4..d80ebebd7c 100644 --- a/go.sum +++ b/go.sum @@ -266,8 +266,6 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= -github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= -github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= From 54f795192386e6b3ea7ab7cc7f8cc0efec0ec8f7 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:54:31 +0100 Subject: [PATCH 086/111] test(e2e): increase TestApp_TxTooBig timeout to 2 mins --- test/e2e/tests/app_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/tests/app_test.go b/test/e2e/tests/app_test.go index 470c523bfe..b14e1ef684 100644 --- a/test/e2e/tests/app_test.go +++ b/test/e2e/tests/app_test.go @@ -218,7 +218,7 @@ func TestApp_TxTooBig(t *testing.T) { /// Timeout to read response from single node const readTimeout = 1 * time.Second /// Time to process whole mempool - const includeInBlockTimeout = 75 * time.Second + const includeInBlockTimeout = 120 * time.Second mainCtx, cancel := context.WithCancel(context.Background()) defer cancel() From ca0b50ffc02b597a8a4bf22d88e240b52f993be9 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:14:30 +0100 Subject: [PATCH 087/111] chore: fix linter warnings --- internal/consensus/common_test.go | 6 ++---- internal/consensus/core_chainlock_test.go | 2 +- internal/consensus/gossip_peer_worker_test.go | 4 ++-- internal/consensus/msg_handlers.go | 9 +-------- internal/consensus/msgs_test.go | 6 +++--- internal/consensus/reactor_test.go | 2 +- internal/consensus/replay_test.go | 4 ++-- internal/consensus/state_add_vote.go | 2 +- internal/consensus/state_add_vote_test.go | 10 +++++----- internal/consensus/state_test.go | 2 +- test/e2e/tests/validator_test.go | 2 +- 11 files changed, 20 insertions(+), 29 deletions(-) diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 7766b3a17f..5b555c54d5 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -246,7 +246,7 @@ func startConsensusState(ctx context.Context, cs *State, maxSteps int) { steps++ } }() - go cs.receiveRoutine(ctx, func(state *State) bool { + go cs.receiveRoutine(ctx, func(_state *State) bool { return maxSteps > 0 && steps >= maxSteps }) } @@ -919,9 +919,7 @@ func genFilePV(dir string) (types.PrivValidator, error) { return nil, err } privVal := privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) - if err != nil { - return nil, err - } + return privVal, nil } diff --git a/internal/consensus/core_chainlock_test.go b/internal/consensus/core_chainlock_test.go index 227d40bf56..b64d9edc0b 100644 --- a/internal/consensus/core_chainlock_test.go +++ b/internal/consensus/core_chainlock_test.go @@ -97,7 +97,7 @@ func TestReactorInvalidBlockChainLock(t *testing.T) { } func newCounterWithCoreChainLocks(initCoreChainHeight uint32, step int32) func(logger log.Logger, _ string) abci.Application { - return func(logger log.Logger, _ string) abci.Application { + return func(_logger log.Logger, _ string) abci.Application { counterApp := counter.NewApplication(true) counterApp.InitCoreChainLock(initCoreChainHeight, step) return counterApp diff --git a/internal/consensus/gossip_peer_worker_test.go b/internal/consensus/gossip_peer_worker_test.go index 23edd6b80c..dc9a16031a 100644 --- a/internal/consensus/gossip_peer_worker_test.go +++ b/internal/consensus/gossip_peer_worker_test.go @@ -26,10 +26,10 @@ func TestPeerGossipWorker(t *testing.T) { clock: fakeClock, logger: logger, handlers: []gossipHandler{ - newGossipHandler(func(ctx context.Context, appState StateData) { + newGossipHandler(func(_ctx context.Context, _appState StateData) { handlerCalledCh <- struct{}{} }, 1*time.Second), - newGossipHandler(func(ctx context.Context, appState StateData) { + newGossipHandler(func(_ctx context.Context, _appState StateData) { handlerCalledCh <- struct{}{} }, 1*time.Second), }, diff --git a/internal/consensus/msg_handlers.go b/internal/consensus/msg_handlers.go index 8477e812b1..3f25c3556c 100644 --- a/internal/consensus/msg_handlers.go +++ b/internal/consensus/msg_handlers.go @@ -73,7 +73,7 @@ func newMsgInfoDispatcher( } func proposalMessageHandler(propSetter cstypes.ProposalSetter) msgHandlerFunc { - return func(ctx context.Context, stateData *StateData, envelope msgEnvelope) error { + return func(_ctx context.Context, stateData *StateData, envelope msgEnvelope) error { msg := envelope.Msg.(*ProposalMessage) return propSetter.Set(msg.Proposal, envelope.ReceiveTime, &stateData.RoundState) } @@ -185,13 +185,6 @@ func msgInfoWithCtxMiddleware() msgMiddlewareFunc { } } -func logKeyValsWithError(keyVals []any, err error) []any { - if err == nil { - return keyVals - } - return append(keyVals, "error", err) -} - func makeLogArgsFromMessage(msg Message) []any { switch m := msg.(type) { case *ProposalMessage: diff --git a/internal/consensus/msgs_test.go b/internal/consensus/msgs_test.go index 85211b2af0..419102e828 100644 --- a/internal/consensus/msgs_test.go +++ b/internal/consensus/msgs_test.go @@ -502,7 +502,7 @@ func TestVoteSetBitsMessageValidateBasic(t *testing.T) { malleateFn func(*VoteSetBitsMessage) expErr string }{ - {func(msg *VoteSetBitsMessage) {}, ""}, + {func(_msg *VoteSetBitsMessage) {}, ""}, {func(msg *VoteSetBitsMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *VoteSetBitsMessage) { msg.Type = 0x03 }, "invalid Type"}, {func(msg *VoteSetBitsMessage) { @@ -616,7 +616,7 @@ func TestNewValidBlockMessageValidateBasic(t *testing.T) { malleateFn func(*NewValidBlockMessage) expErr string }{ - {func(msg *NewValidBlockMessage) {}, ""}, + {func(_msg *NewValidBlockMessage) {}, ""}, {func(msg *NewValidBlockMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *NewValidBlockMessage) { msg.Round = -1 }, "negative Round"}, { @@ -662,7 +662,7 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) { malleateFn func(*ProposalPOLMessage) expErr string }{ - {func(msg *ProposalPOLMessage) {}, ""}, + {func(_msg *ProposalPOLMessage) {}, ""}, {func(msg *ProposalPOLMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *ProposalPOLMessage) { msg.ProposalPOLRound = -1 }, "negative ProposalPOLRound"}, {func(msg *ProposalPOLMessage) { msg.ProposalPOL = bits.NewBitArray(0) }, "empty ProposalPOL bit array"}, diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index d48c8d1ba8..c7668072d7 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -97,7 +97,7 @@ func setup( t.Cleanup(cancel) chCreator := func(nodeID types.NodeID) p2p.ChannelCreator { - return func(ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { + return func(_ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { switch desc.ID { case p2p.ConsensusStateChannel: return rts.stateChannels[nodeID], nil diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 517592e04c..ff6efde35f 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -129,10 +129,10 @@ func TestWALCrash(t *testing.T) { heightToStop int64 }{ {"empty block", - func(stateDB dbm.DB, cs *State, ctx context.Context) {}, + func(_stateDB dbm.DB, _cs *State, _ctx context.Context) {}, 1}, {"many non-empty blocks", - func(stateDB dbm.DB, cs *State, ctx context.Context) { + func(_stateDB dbm.DB, cs *State, ctx context.Context) { go sendTxs(ctx, t, cs) }, 3}, diff --git a/internal/consensus/state_add_vote.go b/internal/consensus/state_add_vote.go index 9a5d589a98..284964cbbd 100644 --- a/internal/consensus/state_add_vote.go +++ b/internal/consensus/state_add_vote.go @@ -84,7 +84,7 @@ func (c *AddVoteAction) Execute(ctx context.Context, stateEvent StateEvent) erro // addVoteToVoteSetFunc adds a vote to the vote-set func addVoteToVoteSetFunc(metrics *Metrics, ep *EventPublisher) AddVoteFunc { - return func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + return func(_ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { added, err := stateData.Votes.AddVote(vote) if !added || err != nil { return added, err diff --git a/internal/consensus/state_add_vote_test.go b/internal/consensus/state_add_vote_test.go index c1caff2734..2667f1eeba 100644 --- a/internal/consensus/state_add_vote_test.go +++ b/internal/consensus/state_add_vote_test.go @@ -60,11 +60,11 @@ func (suite *AddVoteTestSuite) TestAddVoteAction() { prevoteCalled := false precommitCalled := false cmd := AddVoteAction{ - prevote: func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + prevote: func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { prevoteCalled = true return true, nil }, - precommit: func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + precommit: func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { precommitCalled = true return true, nil }, @@ -105,7 +105,7 @@ func (suite *AddVoteTestSuite) TestAddVoteToVoteSet() { defer cancel() const H100 = int64(100) eventFired := false - suite.emitter.AddListener(types.EventVoteValue, func(data eventemitter.EventData) error { + suite.emitter.AddListener(types.EventVoteValue, func(_data eventemitter.EventData) error { eventFired = true return nil }) @@ -171,7 +171,7 @@ func (suite *AddVoteTestSuite) TestAddVoteUpdateValidBlockMw() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() eventFired := false - suite.emitter.AddListener(types.EventValidBlockValue, func(data eventemitter.EventData) error { + suite.emitter.AddListener(types.EventValidBlockValue, func(_data eventemitter.EventData) error { eventFired = true return nil }) @@ -197,7 +197,7 @@ func (suite *AddVoteTestSuite) TestAddVoteUpdateValidBlockMw() { suite.NoError(err) returnAdded := true var returnError error - mockFn := func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + mockFn := func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { return returnAdded, returnError } fn := addVoteUpdateValidBlockMw(suite.publisher)(mockFn) diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 98d128580a..4b2d5d8c5b 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -303,7 +303,7 @@ func TestStateProposalTime(t *testing.T) { expectNewBlock: false, }, { // TEST 1: BLOCK TIME IS IN FUTURE - blockTimeFunc: func(s *State) time.Time { return tmtime.Now().Add(delay + precision + 24*time.Hour) }, + blockTimeFunc: func(_s *State) time.Time { return tmtime.Now().Add(delay + precision + 24*time.Hour) }, expectNewBlock: true, }, { // TEST 2: BLOCK TIME IS OLDER THAN PREVIOUS BLOCK TIME diff --git a/test/e2e/tests/validator_test.go b/test/e2e/tests/validator_test.go index 23c4c2c3da..332f3e5a31 100644 --- a/test/e2e/tests/validator_test.go +++ b/test/e2e/tests/validator_test.go @@ -88,7 +88,7 @@ func TestValidator_Propose(t *testing.T) { defer cancel() blocks := fetchBlockChain(ctx, t) - testNode(t, func(ctx context.Context, t *testing.T, node e2e.Node) { + testNode(t, func(_ctx context.Context, t *testing.T, node e2e.Node) { if node.Mode != e2e.ModeValidator { return } From 787ea9c0622fd0ad2084590ae80c2c02df0e7093 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:14:30 +0100 Subject: [PATCH 088/111] chore: fix linter warnings --- internal/consensus/common_test.go | 6 ++---- internal/consensus/core_chainlock_test.go | 2 +- internal/consensus/gossip_peer_worker_test.go | 4 ++-- internal/consensus/msg_handlers.go | 9 +-------- internal/consensus/msgs_test.go | 6 +++--- internal/consensus/reactor_test.go | 2 +- internal/consensus/replay_test.go | 4 ++-- internal/consensus/state_add_vote.go | 2 +- internal/consensus/state_add_vote_test.go | 10 +++++----- internal/consensus/state_test.go | 2 +- test/e2e/tests/validator_test.go | 2 +- 11 files changed, 20 insertions(+), 29 deletions(-) diff --git a/internal/consensus/common_test.go b/internal/consensus/common_test.go index 7766b3a17f..5b555c54d5 100644 --- a/internal/consensus/common_test.go +++ b/internal/consensus/common_test.go @@ -246,7 +246,7 @@ func startConsensusState(ctx context.Context, cs *State, maxSteps int) { steps++ } }() - go cs.receiveRoutine(ctx, func(state *State) bool { + go cs.receiveRoutine(ctx, func(_state *State) bool { return maxSteps > 0 && steps >= maxSteps }) } @@ -919,9 +919,7 @@ func genFilePV(dir string) (types.PrivValidator, error) { return nil, err } privVal := privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) - if err != nil { - return nil, err - } + return privVal, nil } diff --git a/internal/consensus/core_chainlock_test.go b/internal/consensus/core_chainlock_test.go index 227d40bf56..b64d9edc0b 100644 --- a/internal/consensus/core_chainlock_test.go +++ b/internal/consensus/core_chainlock_test.go @@ -97,7 +97,7 @@ func TestReactorInvalidBlockChainLock(t *testing.T) { } func newCounterWithCoreChainLocks(initCoreChainHeight uint32, step int32) func(logger log.Logger, _ string) abci.Application { - return func(logger log.Logger, _ string) abci.Application { + return func(_logger log.Logger, _ string) abci.Application { counterApp := counter.NewApplication(true) counterApp.InitCoreChainLock(initCoreChainHeight, step) return counterApp diff --git a/internal/consensus/gossip_peer_worker_test.go b/internal/consensus/gossip_peer_worker_test.go index 23edd6b80c..dc9a16031a 100644 --- a/internal/consensus/gossip_peer_worker_test.go +++ b/internal/consensus/gossip_peer_worker_test.go @@ -26,10 +26,10 @@ func TestPeerGossipWorker(t *testing.T) { clock: fakeClock, logger: logger, handlers: []gossipHandler{ - newGossipHandler(func(ctx context.Context, appState StateData) { + newGossipHandler(func(_ctx context.Context, _appState StateData) { handlerCalledCh <- struct{}{} }, 1*time.Second), - newGossipHandler(func(ctx context.Context, appState StateData) { + newGossipHandler(func(_ctx context.Context, _appState StateData) { handlerCalledCh <- struct{}{} }, 1*time.Second), }, diff --git a/internal/consensus/msg_handlers.go b/internal/consensus/msg_handlers.go index 8477e812b1..3f25c3556c 100644 --- a/internal/consensus/msg_handlers.go +++ b/internal/consensus/msg_handlers.go @@ -73,7 +73,7 @@ func newMsgInfoDispatcher( } func proposalMessageHandler(propSetter cstypes.ProposalSetter) msgHandlerFunc { - return func(ctx context.Context, stateData *StateData, envelope msgEnvelope) error { + return func(_ctx context.Context, stateData *StateData, envelope msgEnvelope) error { msg := envelope.Msg.(*ProposalMessage) return propSetter.Set(msg.Proposal, envelope.ReceiveTime, &stateData.RoundState) } @@ -185,13 +185,6 @@ func msgInfoWithCtxMiddleware() msgMiddlewareFunc { } } -func logKeyValsWithError(keyVals []any, err error) []any { - if err == nil { - return keyVals - } - return append(keyVals, "error", err) -} - func makeLogArgsFromMessage(msg Message) []any { switch m := msg.(type) { case *ProposalMessage: diff --git a/internal/consensus/msgs_test.go b/internal/consensus/msgs_test.go index 85211b2af0..419102e828 100644 --- a/internal/consensus/msgs_test.go +++ b/internal/consensus/msgs_test.go @@ -502,7 +502,7 @@ func TestVoteSetBitsMessageValidateBasic(t *testing.T) { malleateFn func(*VoteSetBitsMessage) expErr string }{ - {func(msg *VoteSetBitsMessage) {}, ""}, + {func(_msg *VoteSetBitsMessage) {}, ""}, {func(msg *VoteSetBitsMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *VoteSetBitsMessage) { msg.Type = 0x03 }, "invalid Type"}, {func(msg *VoteSetBitsMessage) { @@ -616,7 +616,7 @@ func TestNewValidBlockMessageValidateBasic(t *testing.T) { malleateFn func(*NewValidBlockMessage) expErr string }{ - {func(msg *NewValidBlockMessage) {}, ""}, + {func(_msg *NewValidBlockMessage) {}, ""}, {func(msg *NewValidBlockMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *NewValidBlockMessage) { msg.Round = -1 }, "negative Round"}, { @@ -662,7 +662,7 @@ func TestProposalPOLMessageValidateBasic(t *testing.T) { malleateFn func(*ProposalPOLMessage) expErr string }{ - {func(msg *ProposalPOLMessage) {}, ""}, + {func(_msg *ProposalPOLMessage) {}, ""}, {func(msg *ProposalPOLMessage) { msg.Height = -1 }, "negative Height"}, {func(msg *ProposalPOLMessage) { msg.ProposalPOLRound = -1 }, "negative ProposalPOLRound"}, {func(msg *ProposalPOLMessage) { msg.ProposalPOL = bits.NewBitArray(0) }, "empty ProposalPOL bit array"}, diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index fde234c87a..8d51c51e2f 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -97,7 +97,7 @@ func setup( t.Cleanup(cancel) chCreator := func(nodeID types.NodeID) p2p.ChannelCreator { - return func(ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { + return func(_ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { switch desc.ID { case StateChannel: return rts.stateChannels[nodeID], nil diff --git a/internal/consensus/replay_test.go b/internal/consensus/replay_test.go index 517592e04c..ff6efde35f 100644 --- a/internal/consensus/replay_test.go +++ b/internal/consensus/replay_test.go @@ -129,10 +129,10 @@ func TestWALCrash(t *testing.T) { heightToStop int64 }{ {"empty block", - func(stateDB dbm.DB, cs *State, ctx context.Context) {}, + func(_stateDB dbm.DB, _cs *State, _ctx context.Context) {}, 1}, {"many non-empty blocks", - func(stateDB dbm.DB, cs *State, ctx context.Context) { + func(_stateDB dbm.DB, cs *State, ctx context.Context) { go sendTxs(ctx, t, cs) }, 3}, diff --git a/internal/consensus/state_add_vote.go b/internal/consensus/state_add_vote.go index 0644beb518..26fc4c87f1 100644 --- a/internal/consensus/state_add_vote.go +++ b/internal/consensus/state_add_vote.go @@ -86,7 +86,7 @@ func (c *AddVoteAction) Execute(ctx context.Context, stateEvent StateEvent) erro // addVoteToVoteSetFunc adds a vote to the vote-set func addVoteToVoteSetFunc(metrics *Metrics, ep *EventPublisher) AddVoteFunc { - return func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + return func(_ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { added, err := stateData.Votes.AddVote(vote) if !added || err != nil { return added, err diff --git a/internal/consensus/state_add_vote_test.go b/internal/consensus/state_add_vote_test.go index c1caff2734..2667f1eeba 100644 --- a/internal/consensus/state_add_vote_test.go +++ b/internal/consensus/state_add_vote_test.go @@ -60,11 +60,11 @@ func (suite *AddVoteTestSuite) TestAddVoteAction() { prevoteCalled := false precommitCalled := false cmd := AddVoteAction{ - prevote: func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + prevote: func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { prevoteCalled = true return true, nil }, - precommit: func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + precommit: func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { precommitCalled = true return true, nil }, @@ -105,7 +105,7 @@ func (suite *AddVoteTestSuite) TestAddVoteToVoteSet() { defer cancel() const H100 = int64(100) eventFired := false - suite.emitter.AddListener(types.EventVoteValue, func(data eventemitter.EventData) error { + suite.emitter.AddListener(types.EventVoteValue, func(_data eventemitter.EventData) error { eventFired = true return nil }) @@ -171,7 +171,7 @@ func (suite *AddVoteTestSuite) TestAddVoteUpdateValidBlockMw() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() eventFired := false - suite.emitter.AddListener(types.EventValidBlockValue, func(data eventemitter.EventData) error { + suite.emitter.AddListener(types.EventValidBlockValue, func(_data eventemitter.EventData) error { eventFired = true return nil }) @@ -197,7 +197,7 @@ func (suite *AddVoteTestSuite) TestAddVoteUpdateValidBlockMw() { suite.NoError(err) returnAdded := true var returnError error - mockFn := func(ctx context.Context, stateData *StateData, vote *types.Vote) (bool, error) { + mockFn := func(_ctx context.Context, _stateData *StateData, _vote *types.Vote) (bool, error) { return returnAdded, returnError } fn := addVoteUpdateValidBlockMw(suite.publisher)(mockFn) diff --git a/internal/consensus/state_test.go b/internal/consensus/state_test.go index 8a5e5a5e9d..e6420a1b30 100644 --- a/internal/consensus/state_test.go +++ b/internal/consensus/state_test.go @@ -303,7 +303,7 @@ func TestStateProposalTime(t *testing.T) { expectNewBlock: false, }, { // TEST 1: BLOCK TIME IS IN FUTURE - blockTimeFunc: func(s *State) time.Time { return tmtime.Now().Add(delay + precision + 24*time.Hour) }, + blockTimeFunc: func(_s *State) time.Time { return tmtime.Now().Add(delay + precision + 24*time.Hour) }, expectNewBlock: true, }, { // TEST 2: BLOCK TIME IS OLDER THAN PREVIOUS BLOCK TIME diff --git a/test/e2e/tests/validator_test.go b/test/e2e/tests/validator_test.go index 23c4c2c3da..332f3e5a31 100644 --- a/test/e2e/tests/validator_test.go +++ b/test/e2e/tests/validator_test.go @@ -88,7 +88,7 @@ func TestValidator_Propose(t *testing.T) { defer cancel() blocks := fetchBlockChain(ctx, t) - testNode(t, func(ctx context.Context, t *testing.T, node e2e.Node) { + testNode(t, func(_ctx context.Context, t *testing.T, node e2e.Node) { if node.Mode != e2e.ModeValidator { return } From 40d36b15101d9c70efee861a33478339dfcf4aea Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:18:28 +0100 Subject: [PATCH 089/111] chore: fix linter warnings --- internal/consensus/msg_handlers.go | 7 +++++++ internal/statesync/peer.go | 2 +- internal/statesync/peer_test.go | 4 ++-- internal/statesync/reactor_test.go | 4 ++-- internal/statesync/stateprovider.go | 3 --- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/internal/consensus/msg_handlers.go b/internal/consensus/msg_handlers.go index 3f25c3556c..282becf5ef 100644 --- a/internal/consensus/msg_handlers.go +++ b/internal/consensus/msg_handlers.go @@ -185,6 +185,13 @@ func msgInfoWithCtxMiddleware() msgMiddlewareFunc { } } +func logKeyValsWithError(keyVals []any, err error) []any { + if err == nil { + return keyVals + } + return append(keyVals, "error", err) +} + func makeLogArgsFromMessage(msg Message) []any { switch m := msg.(type) { case *ProposalMessage: diff --git a/internal/statesync/peer.go b/internal/statesync/peer.go index bc53201de1..589acecacc 100644 --- a/internal/statesync/peer.go +++ b/internal/statesync/peer.go @@ -136,7 +136,7 @@ func (p *PeerManager) Start(ctx context.Context) { } return nil }) - p.peerSubs.On(p2p.PeerStatusDown, func(ctx context.Context, update p2p.PeerUpdate) error { + p.peerSubs.On(p2p.PeerStatusDown, func(_ctx context.Context, update p2p.PeerUpdate) error { p.peerStore.Delete(update.NodeID) return nil }) diff --git a/internal/statesync/peer_test.go b/internal/statesync/peer_test.go index 7b32e9f728..61547e1d63 100644 --- a/internal/statesync/peer_test.go +++ b/internal/statesync/peer_test.go @@ -26,11 +26,11 @@ func TestPeerSubscriberBasic(_t *testing.T) { } peerSub := NewPeerSubscriber(log.NewNopLogger(), p2pSub) outCh := make(chan struct{}) - peerSub.On(p2p.PeerStatusUp, func(ctx context.Context, update p2p.PeerUpdate) error { + peerSub.On(p2p.PeerStatusUp, func(_ctx context.Context, _update p2p.PeerUpdate) error { outCh <- struct{}{} return nil }) - peerSub.On(p2p.PeerStatusDown, func(ctx context.Context, update p2p.PeerUpdate) error { + peerSub.On(p2p.PeerStatusDown, func(_ctx context.Context, _update p2p.PeerUpdate) error { outCh <- struct{}{} return nil }) diff --git a/internal/statesync/reactor_test.go b/internal/statesync/reactor_test.go index ecfa88fa27..dfe523af66 100644 --- a/internal/statesync/reactor_test.go +++ b/internal/statesync/reactor_test.go @@ -154,7 +154,7 @@ func setup( rts.privVal = types.NewMockPV() rts.dashcoreClient = dashcore.NewMockClient(chainID, llmqType, rts.privVal, false) - chCreator := func(ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { + chCreator := func(_ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { switch desc.ID { case SnapshotChannel: return rts.snapshotChannel, nil @@ -716,7 +716,7 @@ func TestReactor_Backfill(t *testing.T) { mock.AnythingOfType("int64"), mock.AnythingOfType("*types.ValidatorSet")). Maybe(). - Return(func(lh, uh int64, vals *types.ValidatorSet) error { + Return(func(lh, uh int64, _vals *types.ValidatorSet) error { require.Equal(t, trackingHeight, lh) require.Equal(t, lh, uh) require.GreaterOrEqual(t, lh, stopHeight) diff --git a/internal/statesync/stateprovider.go b/internal/statesync/stateprovider.go index 2d98e82c51..f30688c735 100644 --- a/internal/statesync/stateprovider.go +++ b/internal/statesync/stateprovider.go @@ -246,9 +246,6 @@ func (s *stateProviderP2P) AppHash(ctx context.Context, height uint64) (tmbytes. if err != nil { return nil, err } - if err != nil { - return nil, err - } return header.AppHash, nil } From 0aa99378ba9a5d0f191bb2e159c05b377d0cb17c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 20:46:06 +0100 Subject: [PATCH 090/111] feat(p2p): throttled channel (cherry picked from commit 5e41958bf8e6c0e58f7eeb1363049967d38b8353) --- internal/p2p/throttled_channel.go | 57 ++++++++++++++++++++ internal/p2p/throttled_channel_test.go | 74 ++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 internal/p2p/throttled_channel.go create mode 100644 internal/p2p/throttled_channel_test.go diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go new file mode 100644 index 0000000000..92dbe5edb2 --- /dev/null +++ b/internal/p2p/throttled_channel.go @@ -0,0 +1,57 @@ +package p2p + +import ( + "context" + + "golang.org/x/time/rate" +) + +// / Channel that will block if the send limit is reached +type ThrottledChannel struct { + channel Channel + limiter *rate.Limiter +} + +// NewThrottledChannel creates a new throttled channel. +// The rate is specified in messages per second. +// The burst is specified in messages. +// +// If unsure, use burst equal to 60 times the rate. +func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { + return &ThrottledChannel{ + channel: channel, + limiter: rate.NewLimiter(r, burst), + } +} + +var _ Channel = (*ThrottledChannel)(nil) + +func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { + // Wait until limiter allows us to proceed. + if err := ch.limiter.Wait(ctx); err != nil { + return err + } + + return ch.channel.Send(ctx, envelope) +} + +func (ch *ThrottledChannel) SendError(ctx context.Context, pe PeerError) error { + // Wait until limiter allows us to proceed. + if err := ch.limiter.Wait(ctx); err != nil { + return err + } + + return ch.channel.SendError(ctx, pe) +} + +func (ch *ThrottledChannel) Receive(ctx context.Context) *ChannelIterator { + return ch.channel.Receive(ctx) +} + +func (ch *ThrottledChannel) Err() error { + return ch.channel.Err() +} + +func (ch *ThrottledChannel) String() string { + return ch.channel.String() +} diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go new file mode 100644 index 0000000000..75512d2516 --- /dev/null +++ b/internal/p2p/throttled_channel_test.go @@ -0,0 +1,74 @@ +package p2p_test + +import ( + "context" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/dashpay/tenderdash/internal/p2p" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "golang.org/x/time/rate" +) + +type mockChannel struct { + counter atomic.Uint32 +} + +func (c *mockChannel) Len() int { + return int(c.counter.Load()) +} + +func (c *mockChannel) Send(_ context.Context, e p2p.Envelope) error { + c.counter.Add(1) + return nil +} + +func (c *mockChannel) SendError(_ context.Context, _ p2p.PeerError) error { + panic("not implemented") +} + +func (c *mockChannel) Receive(_ context.Context) *p2p.ChannelIterator { + panic("not implemented") +} + +func (c *mockChannel) Err() error { + panic("not implemented") +} + +func (c *mockChannel) String() string { + return "mock_channel" +} + +func TestThrottledChannel(t *testing.T) { + const n = 31 + const rate rate.Limit = 10 + const burst = int(rate) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst) // 1 message per second + + wg := sync.WaitGroup{} + start := time.Now() + for i := 0; i < n; i++ { + wg.Add(1) + go func() { + err := ch.Send(context.Background(), p2p.Envelope{}) + require.NoError(t, err) + wg.Done() + }() + } + + time.Sleep(time.Second) + assert.LessOrEqual(t, mock.Len(), burst+int(rate)) + + // Wait until all finish + + wg.Wait() + took := time.Since(start) + assert.Equal(t, n, mock.Len()) + assert.GreaterOrEqual(t, took.Seconds(), 2.0) +} From dfab3a45ddfb2f49ff38a1099c754288746c46df Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Thu, 11 Jan 2024 21:07:35 +0100 Subject: [PATCH 091/111] feat: limit mempool broadcast to 5/s (cherry picked from commit cdde233c1372968bfbf03095ab6242f74a721062) --- internal/p2p/channel_params.go | 2 ++ internal/p2p/conn/connection.go | 4 ++++ internal/p2p/router.go | 3 +++ internal/p2p/throttled_channel.go | 2 -- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 8a0aa8418b..4e3341e507 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -68,6 +68,8 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", + SendRateLimit: 5, + SendRateBurst: 20, }, SnapshotChannel: { ID: SnapshotChannel, diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index 1ecdd1a4dc..d09cd8baeb 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -14,6 +14,7 @@ import ( "time" sync "github.com/sasha-s/go-deadlock" + "golang.org/x/time/rate" "github.com/gogo/protobuf/proto" @@ -615,6 +616,9 @@ type ChannelDescriptor struct { SendQueueCapacity int RecvMessageCapacity int + SendRateLimit rate.Limit + SendRateBurst int + // RecvBufferCapacity defines the max buffer size of inbound messages for a // given p2p Channel queue. RecvBufferCapacity int diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 2dac816c60..f57cc870f3 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -262,6 +262,9 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (Ch outCh := make(chan Envelope, chDesc.RecvBufferCapacity) errCh := make(chan PeerError, chDesc.RecvBufferCapacity) channel := NewChannel(chDesc.ID, chDesc.Name, queue.dequeue(), outCh, errCh) + if chDesc.SendRateLimit > 0 { + channel = NewThrottledChannel(channel, chDesc.SendRateLimit, chDesc.SendRateBurst) + } r.channelQueues[id] = queue diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go index 92dbe5edb2..bf7d0e06b7 100644 --- a/internal/p2p/throttled_channel.go +++ b/internal/p2p/throttled_channel.go @@ -15,8 +15,6 @@ type ThrottledChannel struct { // NewThrottledChannel creates a new throttled channel. // The rate is specified in messages per second. // The burst is specified in messages. -// -// If unsure, use burst equal to 60 times the rate. func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { return &ThrottledChannel{ channel: channel, From c06656c44e568b990a24a851d089ddde79033311 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 16:10:04 +0100 Subject: [PATCH 092/111] feat(p2p): channel recv rate limiting - not tested (cherry picked from commit f7f7ce7fdc0cfcefac9465a7dc9a9913d80d4afd) --- internal/consensus/peer_state.go | 3 + internal/p2p/channel.go | 137 +++++++++++++++++++---- internal/p2p/client/chanstore.go | 2 +- internal/p2p/client/client.go | 2 +- internal/p2p/client/client_test.go | 6 +- internal/p2p/conn/connection.go | 9 ++ internal/p2p/router.go | 7 +- internal/p2p/throttled_channel.go | 56 ++++++++-- internal/p2p/throttled_channel_test.go | 148 ++++++++++++++++++++++--- 9 files changed, 316 insertions(+), 54 deletions(-) diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index 607fc3be86..3a261056f8 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -487,6 +487,9 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { ps.mtx.Lock() defer ps.mtx.Unlock() + // TODO change to TRACE + ps.logger.Debug("apply new round step message", "peer", ps.peerID, "msg", msg.String()) + // ignore duplicates or decreases if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 { return diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go index 9e8cb3283d..96fd6b37d0 100644 --- a/internal/p2p/channel.go +++ b/internal/p2p/channel.go @@ -12,11 +12,17 @@ import ( "github.com/gogo/protobuf/proto" "github.com/rs/zerolog" sync "github.com/sasha-s/go-deadlock" + "golang.org/x/time/rate" + log "github.com/dashpay/tenderdash/libs/log" "github.com/dashpay/tenderdash/proto/tendermint/p2p" "github.com/dashpay/tenderdash/types" ) +var ( + ErrRecvRateLimitExceeded = errors.New("receive rate limit exceeded") +) + // Envelope contains a message with sender/receiver routing info. type Envelope struct { From types.NodeID // sender (empty if outbound) @@ -117,7 +123,7 @@ type Channel interface { Send(context.Context, Envelope) error SendError(context.Context, PeerError) error - Receive(context.Context) *ChannelIterator + Receive(context.Context) ChannelIterator } // PeerError is a peer error reported via Channel.Error. @@ -194,8 +200,8 @@ func (ch *legacyChannel) String() string { return fmt.Sprintf("p2p.Channel<%d:%s // Receive returns a new unbuffered iterator to receive messages from ch. // The iterator runs until ctx ends. -func (ch *legacyChannel) Receive(ctx context.Context) *ChannelIterator { - iter := &ChannelIterator{ +func (ch *legacyChannel) Receive(ctx context.Context) ChannelIterator { + iter := &channelIterator{ pipe: make(chan Envelope), // unbuffered } go func(pipe chan<- Envelope) { @@ -216,32 +222,38 @@ func (ch *legacyChannel) Receive(ctx context.Context) *ChannelIterator { return iter } -// ChannelIterator provides a context-aware path for callers +// ChannelIterator is an iterator for receiving messages from a Channel. +type ChannelIterator interface { + // Next returns true when the Envelope value has advanced, and false + // when the context is canceled or iteration should stop. If an iterator has returned false, + // it will never return true again. + // in general, use Next, as in: + // + // for iter.Next(ctx) { + // envelope := iter.Envelope() + // // ... do things ... + // } + Next(ctx context.Context) bool + Envelope() *Envelope +} + +// channelIterator provides a context-aware path for callers // (reactors) to process messages from the P2P layer without relying // on the implementation details of the P2P layer. Channel provides // access to it's Outbound stream as an iterator, and the // MergedChannelIterator makes it possible to combine multiple // channels into a single iterator. -type ChannelIterator struct { +type channelIterator struct { pipe chan Envelope current *Envelope } -// NewChannelIterator returns a new instance of ChannelIterator -func NewChannelIterator(pipe chan Envelope) *ChannelIterator { - return &ChannelIterator{pipe: pipe} +// NewChannelIterator returns a new instance of channelIterator +func NewChannelIterator(pipe chan Envelope) ChannelIterator { + return &channelIterator{pipe: pipe} } -// Next returns true when the Envelope value has advanced, and false -// when the context is canceled or iteration should stop. If an iterator has returned false, -// it will never return true again. -// in general, use Next, as in: -// -// for iter.Next(ctx) { -// envelope := iter.Envelope() -// // ... do things ... -// } -func (iter *ChannelIterator) Next(ctx context.Context) bool { +func (iter *channelIterator) Next(ctx context.Context) bool { select { case <-ctx.Done(): iter.current = nil @@ -262,15 +274,15 @@ func (iter *ChannelIterator) Next(ctx context.Context) bool { // iterator. When the last call to Next returned true, Envelope will // return a non-nil object. If Next returned false then Envelope is // always nil. -func (iter *ChannelIterator) Envelope() *Envelope { return iter.current } +func (iter *channelIterator) Envelope() *Envelope { return iter.current } // MergedChannelIterator produces an iterator that merges the // messages from the given channels in arbitrary order. // // This allows the caller to consume messages from multiple channels // without needing to manage the concurrency separately. -func MergedChannelIterator(ctx context.Context, chs ...Channel) *ChannelIterator { - iter := &ChannelIterator{ +func MergedChannelIterator(ctx context.Context, chs ...Channel) ChannelIterator { + iter := &channelIterator{ pipe: make(chan Envelope), // unbuffered } wg := new(sync.WaitGroup) @@ -304,3 +316,86 @@ func MergedChannelIterator(ctx context.Context, chs ...Channel) *ChannelIterator return iter } + +type throttledChannelIterator struct { + innerChan Channel + innerIter ChannelIterator + limiter *rate.Limiter + reportErr bool + logger log.Logger +} + +// ThrottledChannelIterator wraps an existing channel iterator with a rate limiter. +// +// ## Arguments +// - ctx: the context in which the iterator will run +// - limiter: the rate limiter to use +// - innerIterator: the underlying iterator to use +// - reportError: if true, errors will be sent to the channel whenever the rate limit is exceeded; otherwise +// the messages will be dropped without error +// - innerChannel: the channel related; errors will be sent to this channel, also used for logging +// - logger: the logger to use +func ThrottledChannelIterator(ctx context.Context, limiter *rate.Limiter, innerIterator ChannelIterator, + reportError bool, innerChannel Channel, logger log.Logger) (ChannelIterator, error) { + if innerChannel == nil { + if reportError { + return nil, fmt.Errorf("inner channel is required to report errors") + } + } else { + logger = logger.With("channel", innerChannel) + } + + throttledChannelIterator := &throttledChannelIterator{ + innerChan: innerChannel, + innerIter: innerIterator, + limiter: limiter, + reportErr: reportError, + logger: logger, + } + + return throttledChannelIterator, nil +} + +func (tci *throttledChannelIterator) Next(ctx context.Context) bool { + if tci.innerIter == nil { + tci.logger.Error("inner channel iterator is nil", "channel", tci.innerChan) + return false + } + + for { + if ctx.Err() != nil { + return false + } + + if !tci.innerIter.Next(ctx) { + return false + } + + // If the limiter allows the message to be sent, we break the loop + if tci.limiter.Allow() { + break + } + e := tci.innerIter.Envelope() + if tci.reportErr && e != nil { + tci.innerChan.SendError(ctx, PeerError{ + NodeID: e.From, + Err: ErrRecvRateLimitExceeded, + Fatal: false, + }) + + } else { + tci.logger.Trace("dropping message due to rate limit", "channel", tci.innerChan, "rate", tci.limiter.Limit()) + } + } + + return true +} + +func (tci *throttledChannelIterator) Envelope() *Envelope { + if tci.innerIter == nil { + tci.logger.Error("inner channel iterator is nil", "channel", tci.innerChan) + return nil + } + + return tci.innerIter.Envelope() +} diff --git a/internal/p2p/client/chanstore.go b/internal/p2p/client/chanstore.go index e49c3994f4..e25858f6a5 100644 --- a/internal/p2p/client/chanstore.go +++ b/internal/p2p/client/chanstore.go @@ -31,7 +31,7 @@ func newChanStore(descriptors map[p2p.ChannelID]*p2p.ChannelDescriptor, creator return store } -func (c *chanStore) iter(ctx context.Context, chanIDs ...p2p.ChannelID) (*p2p.ChannelIterator, error) { +func (c *chanStore) iter(ctx context.Context, chanIDs ...p2p.ChannelID) (p2p.ChannelIterator, error) { chans := make([]p2p.Channel, 0, len(chanIDs)) for _, chanID := range chanIDs { ch, err := c.get(ctx, chanID) diff --git a/internal/p2p/client/client.go b/internal/p2p/client/client.go index 3ea4009090..8aaa4206b2 100644 --- a/internal/p2p/client/client.go +++ b/internal/p2p/client/client.go @@ -272,7 +272,7 @@ func (c *Client) Consume(ctx context.Context, params ConsumerParams) error { return c.iter(ctx, iter, params.Handler) } -func (c *Client) iter(ctx context.Context, iter *p2p.ChannelIterator, handler ConsumerHandler) error { +func (c *Client) iter(ctx context.Context, iter p2p.ChannelIterator, handler ConsumerHandler) error { for iter.Next(ctx) { envelope := iter.Envelope() if isMessageResolvable(envelope.Message) { diff --git a/internal/p2p/client/client_test.go b/internal/p2p/client/client_test.go index 5a02123db0..50a88c4bb4 100644 --- a/internal/p2p/client/client_test.go +++ b/internal/p2p/client/client_test.go @@ -185,7 +185,7 @@ func (suite *ChannelTestSuite) TestConsumeHandle() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) consumer := newMockConsumer(suite.T()) @@ -226,7 +226,7 @@ func (suite *ChannelTestSuite) TestConsumeResolve() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) resCh := suite.client.addPending(reqID) @@ -278,7 +278,7 @@ func (suite *ChannelTestSuite) TestConsumeError() { suite.p2pChannel. On("Receive", ctx). Once(). - Return(func(ctx context.Context) *p2p.ChannelIterator { + Return(func(ctx context.Context) p2p.ChannelIterator { return p2p.NewChannelIterator(outCh) }) consumer := newMockConsumer(suite.T()) diff --git a/internal/p2p/conn/connection.go b/internal/p2p/conn/connection.go index d09cd8baeb..3360c58feb 100644 --- a/internal/p2p/conn/connection.go +++ b/internal/p2p/conn/connection.go @@ -616,9 +616,18 @@ type ChannelDescriptor struct { SendQueueCapacity int RecvMessageCapacity int + /// SendRateLimit is used to limit the rate of sending messages, per second. SendRateLimit rate.Limit SendRateBurst int + /// RecvRateLimit is used to limit the rate of receiving messages, per second. + RecvRateLimit rate.Limit + RecvRateBurst int + // RecvRateShouldErr is used to determine if the rate limiter should + // report an error whenever recv rate limit is exceeded, most likely + // causing the peer to disconnect. + RecvRateShouldErr bool + // RecvBufferCapacity defines the max buffer size of inbound messages for a // given p2p Channel queue. RecvBufferCapacity int diff --git a/internal/p2p/router.go b/internal/p2p/router.go index f57cc870f3..1729049a56 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -262,8 +262,11 @@ func (r *Router) OpenChannel(ctx context.Context, chDesc *ChannelDescriptor) (Ch outCh := make(chan Envelope, chDesc.RecvBufferCapacity) errCh := make(chan PeerError, chDesc.RecvBufferCapacity) channel := NewChannel(chDesc.ID, chDesc.Name, queue.dequeue(), outCh, errCh) - if chDesc.SendRateLimit > 0 { - channel = NewThrottledChannel(channel, chDesc.SendRateLimit, chDesc.SendRateBurst) + if chDesc.SendRateLimit > 0 || chDesc.RecvRateLimit > 0 { + channel = NewThrottledChannel(channel, + chDesc.SendRateLimit, chDesc.SendRateBurst, + chDesc.RecvRateLimit, chDesc.RecvRateBurst, chDesc.RecvRateShouldErr, + r.logger) } r.channelQueues[id] = queue diff --git a/internal/p2p/throttled_channel.go b/internal/p2p/throttled_channel.go index bf7d0e06b7..f82f0374b2 100644 --- a/internal/p2p/throttled_channel.go +++ b/internal/p2p/throttled_channel.go @@ -4,21 +4,44 @@ import ( "context" "golang.org/x/time/rate" + + "github.com/dashpay/tenderdash/libs/log" ) // / Channel that will block if the send limit is reached type ThrottledChannel struct { - channel Channel - limiter *rate.Limiter + channel Channel + sendLimiter *rate.Limiter + recvLimiter *rate.Limiter + recvShouldErr bool + + logger log.Logger } // NewThrottledChannel creates a new throttled channel. // The rate is specified in messages per second. // The burst is specified in messages. -func NewThrottledChannel(channel Channel, r rate.Limit, burst int) *ThrottledChannel { +func NewThrottledChannel(channel Channel, sendLimit rate.Limit, sendBurst int, + recvLimit rate.Limit, recvBurst int, recvShouldErr bool, + logger log.Logger) *ThrottledChannel { + + var ( + sendLimiter *rate.Limiter + recvLimiter *rate.Limiter + ) + if sendLimit > 0 { + sendLimiter = rate.NewLimiter(sendLimit, sendBurst) + } + if recvLimit > 0 { + recvLimiter = rate.NewLimiter(recvLimit, recvBurst) + } + return &ThrottledChannel{ - channel: channel, - limiter: rate.NewLimiter(r, burst), + channel: channel, + sendLimiter: sendLimiter, + recvLimiter: recvLimiter, + recvShouldErr: recvShouldErr, + logger: logger, } } @@ -26,8 +49,10 @@ var _ Channel = (*ThrottledChannel)(nil) func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { // Wait until limiter allows us to proceed. - if err := ch.limiter.Wait(ctx); err != nil { - return err + if ch.sendLimiter != nil { + if err := ch.sendLimiter.Wait(ctx); err != nil { + return err + } } return ch.channel.Send(ctx, envelope) @@ -35,15 +60,26 @@ func (ch *ThrottledChannel) Send(ctx context.Context, envelope Envelope) error { func (ch *ThrottledChannel) SendError(ctx context.Context, pe PeerError) error { // Wait until limiter allows us to proceed. - if err := ch.limiter.Wait(ctx); err != nil { + if err := ch.sendLimiter.Wait(ctx); err != nil { return err } return ch.channel.SendError(ctx, pe) } -func (ch *ThrottledChannel) Receive(ctx context.Context) *ChannelIterator { - return ch.channel.Receive(ctx) +func (ch *ThrottledChannel) Receive(ctx context.Context) ChannelIterator { + if ch.recvLimiter == nil { + return ch.channel.Receive(ctx) + } + + innerIter := ch.channel.Receive(ctx) + iter, err := ThrottledChannelIterator(ctx, ch.recvLimiter, innerIter, ch.recvShouldErr, ch.channel, ch.logger) + if err != nil { + ch.logger.Error("error creating ThrottledChannelIterator", "err", err) + return nil + } + + return iter } func (ch *ThrottledChannel) Err() error { diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go index 75512d2516..4ebdef2e4b 100644 --- a/internal/p2p/throttled_channel_test.go +++ b/internal/p2p/throttled_channel_test.go @@ -2,73 +2,189 @@ package p2p_test import ( "context" + "fmt" "sync" "sync/atomic" "testing" "time" - "github.com/dashpay/tenderdash/internal/p2p" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/time/rate" + + "github.com/dashpay/tenderdash/internal/p2p" + "github.com/dashpay/tenderdash/libs/log" ) type mockChannel struct { - counter atomic.Uint32 + sent atomic.Uint32 + received atomic.Uint32 + errored atomic.Uint32 } -func (c *mockChannel) Len() int { - return int(c.counter.Load()) +func (c *mockChannel) SendCount() int { + return int(c.sent.Load()) } -func (c *mockChannel) Send(_ context.Context, e p2p.Envelope) error { - c.counter.Add(1) +func (c *mockChannel) RecvCount() int { + return int(c.received.Load()) +} + +func (c *mockChannel) Send(_ context.Context, _e p2p.Envelope) error { + c.sent.Add(1) return nil } func (c *mockChannel) SendError(_ context.Context, _ p2p.PeerError) error { - panic("not implemented") + c.errored.Add(1) + return nil } -func (c *mockChannel) Receive(_ context.Context) *p2p.ChannelIterator { - panic("not implemented") +func (c *mockChannel) Receive(ctx context.Context) p2p.ChannelIterator { + var pipe = make(chan p2p.Envelope, 5) + + go func() { + for { + select { + case pipe <- p2p.Envelope{}: + c.received.Add(1) + case <-ctx.Done(): + close(pipe) + return + } + } + }() + + return p2p.NewChannelIterator(pipe) } func (c *mockChannel) Err() error { - panic("not implemented") + if e := c.errored.Load(); e > 0 { + return fmt.Errorf("mock_channel_error: error count: %d", e) + } + return nil } func (c *mockChannel) String() string { return "mock_channel" } -func TestThrottledChannel(t *testing.T) { +func TestThrottledChannelSend(t *testing.T) { const n = 31 const rate rate.Limit = 10 const burst = int(rate) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + mock := &mockChannel{} - ch := p2p.NewThrottledChannel(mock, rate, burst) // 1 message per second + ch := p2p.NewThrottledChannel(mock, rate, burst, 0, 0, false, logger) // 1 message per second wg := sync.WaitGroup{} start := time.Now() for i := 0; i < n; i++ { wg.Add(1) go func() { - err := ch.Send(context.Background(), p2p.Envelope{}) + err := ch.Send(ctx, p2p.Envelope{}) require.NoError(t, err) wg.Done() }() } time.Sleep(time.Second) - assert.LessOrEqual(t, mock.Len(), burst+int(rate)) + assert.LessOrEqual(t, mock.SendCount(), burst+int(rate)) // Wait until all finish - wg.Wait() took := time.Since(start) - assert.Equal(t, n, mock.Len()) + assert.Equal(t, n, mock.SendCount()) assert.GreaterOrEqual(t, took.Seconds(), 2.0) } + +// Given some thrrottled channel that generates messages all the time, we should error out after receiving a rate +// of 10 messages per second. +func TestThrottledChannelRecvError(t *testing.T) { + const rate rate.Limit = 10 + const burst = int(rate) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst, rate, burst, true, logger) // 1 message per second + + start := time.Now() + + assert.NoError(t, mock.Err()) + + iter := ch.Receive(ctx) + + for i := 0; i < burst+int(rate)+1; i++ { + assert.True(t, iter.Next(ctx)) + + e := iter.Envelope() + if e == nil { + t.Error("nil envelope") + } + } + + err := mock.Err() + t.Logf("expected mock error: %v", err) + assert.Error(t, mock.Err()) + + // Wait until all finish + cancel() + + took := time.Since(start) + assert.GreaterOrEqual(t, took.Seconds(), 1.0) +} + +// Given some thrrottled channel that generates messages all the time, we should be able to receive them at a rate +// of 10 messages per second. +func TestThrottledChannelRecv(t *testing.T) { + const n = 31 + const rate rate.Limit = 10 + const burst = int(rate) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + logger := log.NewTestingLogger(t) + + mock := &mockChannel{} + + ch := p2p.NewThrottledChannel(mock, rate, burst, rate, burst, false, logger) // 1 message per second + + start := time.Now() + count := 0 + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + iter := ch.Receive(ctx) + for iter.Next(ctx) { + e := iter.Envelope() + if e == nil { + t.Error("nil envelope") + } + count++ + } + wg.Done() + }() + + time.Sleep(time.Second) + assert.LessOrEqual(t, mock.SendCount(), burst+int(rate)) + + // Wait until all finish + cancel() + wg.Wait() + + took := time.Since(start) + assert.Greater(t, mock.RecvCount(), count*100, "we should generate much more messages than we can receive") + assert.GreaterOrEqual(t, took.Seconds(), 1.0) +} From 73286e96cd86f911e120d2f81a02aacd0205d412 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 16 Feb 2024 17:20:44 +0100 Subject: [PATCH 093/111] feat(p2p): channel recv rate limiting - continued (cherry picked from commit 54e00f7393f13e8e540ff2cf42ffa5fece166d7d) --- internal/p2p/channel.go | 10 ++++++---- internal/p2p/channel_params.go | 7 +++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go index 96fd6b37d0..e8de8d6cc5 100644 --- a/internal/p2p/channel.go +++ b/internal/p2p/channel.go @@ -377,12 +377,14 @@ func (tci *throttledChannelIterator) Next(ctx context.Context) bool { } e := tci.innerIter.Envelope() if tci.reportErr && e != nil { - tci.innerChan.SendError(ctx, PeerError{ + msg := PeerError{ NodeID: e.From, Err: ErrRecvRateLimitExceeded, - Fatal: false, - }) - + Fatal: true, + } + if err := tci.innerChan.SendError(ctx, msg); err != nil { + tci.logger.Error("error sending error message", "err", err, "msg", msg) + } } else { tci.logger.Trace("dropping message due to rate limit", "channel", tci.innerChan, "rate", tci.limiter.Limit()) } diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 4e3341e507..166f2fea5a 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -68,8 +68,11 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", - SendRateLimit: 5, - SendRateBurst: 20, + SendRateLimit: 5, // TODO: make it configurable + SendRateBurst: 20, // TODO: make it configurable + RecvRateLimit: 10, // TODO: make it configurable + RecvRateBurst: 100, // TODO: make it configurable + RecvRateShouldErr: true, // TODO: make it configurable }, SnapshotChannel: { ID: SnapshotChannel, From c128637d6bcf222c1cf04688185e3d036de6c0ba Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:49:00 +0100 Subject: [PATCH 094/111] chore(p2p): regen channel mocks --- internal/p2p/mocks/channel.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/p2p/mocks/channel.go b/internal/p2p/mocks/channel.go index b24f2d48a7..ae54580e6f 100644 --- a/internal/p2p/mocks/channel.go +++ b/internal/p2p/mocks/channel.go @@ -33,19 +33,19 @@ func (_m *Channel) Err() error { } // Receive provides a mock function with given fields: _a0 -func (_m *Channel) Receive(_a0 context.Context) *p2p.ChannelIterator { +func (_m *Channel) Receive(_a0 context.Context) p2p.ChannelIterator { ret := _m.Called(_a0) if len(ret) == 0 { panic("no return value specified for Receive") } - var r0 *p2p.ChannelIterator - if rf, ok := ret.Get(0).(func(context.Context) *p2p.ChannelIterator); ok { + var r0 p2p.ChannelIterator + if rf, ok := ret.Get(0).(func(context.Context) p2p.ChannelIterator); ok { r0 = rf(_a0) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*p2p.ChannelIterator) + r0 = ret.Get(0).(p2p.ChannelIterator) } } From 5ffb0240148ab698e74f5067aa2835dfad75970c Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:44:11 +0100 Subject: [PATCH 095/111] feat(config): mempool tx-send-rate-limit, tx-recv-rate-limit, tx-recv-rate-punish-peer --- config/config.go | 18 ++++++++++++++++++ config/toml.go | 19 +++++++++++++++++++ internal/p2p/channel_params.go | 11 ++++++----- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/config/config.go b/config/config.go index 6600d8e357..0dd8f8ac60 100644 --- a/config/config.go +++ b/config/config.go @@ -819,6 +819,24 @@ type MempoolConfig struct { // has existed in the mempool at least TTLNumBlocks number of blocks or if // it's insertion time into the mempool is beyond TTLDuration. TTLNumBlocks int64 `mapstructure:"ttl-num-blocks"` + + // TxSendRateLimit is the rate limit for sending transactions to peers, in + // transactions per second. If zero, the rate limiter is disabled. + // + // Default: 0 + TxSendRateLimit float64 `mapstructure:"tx-send-rate-limit"` + + // TxRecvRateLimit is the rate limit for receiving transactions from peers, in + // transactions per second. If zero, the rate limiter is disabled. + // + // Default: 0 + TxRecvRateLimit float64 `mapstructure:"tx-recv-rate-limit"` + + // TxRecvRatePunishPeer set to true means that when the rate limit set in TxRecvRateLimit is reached, the + // peer will be punished (disconnected). If set to false, the peer will be throttled (messages will be dropped). + // + // Default: false + TxRecvRatePunishPeer bool `mapstructure:"tx-recv-rate-punish-peer"` } // DefaultMempoolConfig returns a default configuration for the Tendermint mempool. diff --git a/config/toml.go b/config/toml.go index 7eb8bcc845..f10c66c966 100644 --- a/config/toml.go +++ b/config/toml.go @@ -426,6 +426,25 @@ ttl-duration = "{{ .Mempool.TTLDuration }}" # it's insertion time into the mempool is beyond ttl-duration. ttl-num-blocks = {{ .Mempool.TTLNumBlocks }} + +# tx-send-rate-limit is the rate limit for sending transactions to peers, in transactions per second. +# If zero, the rate limiter is disabled. +# +# Default: 0 +tx-send-rate-limit = {{ .Mempool.TxSendRateLimit }} + +# tx-recv-rate-limit is the rate limit for receiving transactions from peers, in transactions per second. +# If zero, the rate limiter is disabled. +# +# Default: 0 +tx-recv-rate-limit = {{ .Mempool.TxRecvRateLimit }} + +# tx-recv-rate-punish-peer set to true means that when tx-recv-rate-limit is reached, the peer will be punished +# (disconnected). If set to false, the peer will be throttled (messages will be dropped). +# +# Default: false +tx-recv-rate-punish-peer = {{ .Mempool.TxRecvRatePunishPeer }} + ####################################################### ### State Sync Configuration Options ### ####################################################### diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 166f2fea5a..dd6776dc35 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/gogo/protobuf/proto" + "golang.org/x/time/rate" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/proto/tendermint/blocksync" @@ -68,11 +69,11 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", - SendRateLimit: 5, // TODO: make it configurable - SendRateBurst: 20, // TODO: make it configurable - RecvRateLimit: 10, // TODO: make it configurable - RecvRateBurst: 100, // TODO: make it configurable - RecvRateShouldErr: true, // TODO: make it configurable + SendRateLimit: rate.Limit(cfg.Mempool.TxSendRateLimit), + SendRateBurst: int(10 * cfg.Mempool.TxSendRateLimit), + RecvRateLimit: rate.Limit(cfg.Mempool.TxRecvRateLimit), + RecvRateBurst: int(10 * cfg.Mempool.TxRecvRateLimit), + RecvRateShouldErr: cfg.Mempool.TxRecvRatePunishPeer, }, SnapshotChannel: { ID: SnapshotChannel, From aa82ab92502ff5633de2378b769c9320b7181b16 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:47:13 +0100 Subject: [PATCH 096/111] chore: lint --- internal/p2p/throttled_channel_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/p2p/throttled_channel_test.go b/internal/p2p/throttled_channel_test.go index 4ebdef2e4b..4571d89f10 100644 --- a/internal/p2p/throttled_channel_test.go +++ b/internal/p2p/throttled_channel_test.go @@ -148,7 +148,6 @@ func TestThrottledChannelRecvError(t *testing.T) { // Given some thrrottled channel that generates messages all the time, we should be able to receive them at a rate // of 10 messages per second. func TestThrottledChannelRecv(t *testing.T) { - const n = 31 const rate rate.Limit = 10 const burst = int(rate) From 7fef01933530f9a2d4172212f7e51138f208e123 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:51:58 +0100 Subject: [PATCH 097/111] chore(mempool): burst recv twice as big as burst send --- internal/p2p/channel_params.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index dd6776dc35..a50c593e5c 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -70,9 +70,9 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvBufferCapacity: 128, Name: "mempool", SendRateLimit: rate.Limit(cfg.Mempool.TxSendRateLimit), - SendRateBurst: int(10 * cfg.Mempool.TxSendRateLimit), + SendRateBurst: int(5 * cfg.Mempool.TxSendRateLimit), RecvRateLimit: rate.Limit(cfg.Mempool.TxRecvRateLimit), - RecvRateBurst: int(10 * cfg.Mempool.TxRecvRateLimit), + RecvRateBurst: int(10 * cfg.Mempool.TxRecvRateLimit), // twice as big as send, to avoid false punishment RecvRateShouldErr: cfg.Mempool.TxRecvRatePunishPeer, }, SnapshotChannel: { From 1c1631b728a0b4ddbdeb6f2ef62a7ae3f6abc6b7 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:52:17 +0100 Subject: [PATCH 098/111] chore: lint --- internal/p2p/channel.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/p2p/channel.go b/internal/p2p/channel.go index e8de8d6cc5..c77b4f39f9 100644 --- a/internal/p2p/channel.go +++ b/internal/p2p/channel.go @@ -335,7 +335,7 @@ type throttledChannelIterator struct { // the messages will be dropped without error // - innerChannel: the channel related; errors will be sent to this channel, also used for logging // - logger: the logger to use -func ThrottledChannelIterator(ctx context.Context, limiter *rate.Limiter, innerIterator ChannelIterator, +func ThrottledChannelIterator(_ context.Context, limiter *rate.Limiter, innerIterator ChannelIterator, reportError bool, innerChannel Channel, logger log.Logger) (ChannelIterator, error) { if innerChannel == nil { if reportError { From 7d6aba7948ae8228bdebe2d89a99d7d4a1c978f1 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:54:19 +0100 Subject: [PATCH 099/111] chore: remove not needed log --- internal/consensus/peer_state.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index 3a261056f8..607fc3be86 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -487,9 +487,6 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { ps.mtx.Lock() defer ps.mtx.Unlock() - // TODO change to TRACE - ps.logger.Debug("apply new round step message", "peer", ps.peerID, "msg", msg.String()) - // ignore duplicates or decreases if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 { return From ae5d8a6ce775d386021aec715ee25bbc24327b56 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:08:55 +0100 Subject: [PATCH 100/111] chore: fix after merge --- internal/mempool/p2p_msg_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/mempool/p2p_msg_handler.go b/internal/mempool/p2p_msg_handler.go index 25fa62b6dd..df8158aceb 100644 --- a/internal/mempool/p2p_msg_handler.go +++ b/internal/mempool/p2p_msg_handler.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "time" "github.com/dashpay/tenderdash/config" "github.com/dashpay/tenderdash/internal/p2p" From e75088daf4f5a86d722d7a201415788294e7a57e Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:54:36 +0100 Subject: [PATCH 101/111] chore: fixes after merge --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c521ea9e80..0d8c3a5b9d 100644 --- a/go.mod +++ b/go.mod @@ -114,7 +114,6 @@ require ( go.opentelemetry.io/otel v1.8.0 // indirect go.opentelemetry.io/otel/trace v1.8.0 // indirect go.tmz.dev/musttag v0.7.2 // indirect - golang.org/x/time v0.1.0 // indirect google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect ) @@ -307,4 +306,5 @@ require ( github.com/tendermint/go-amino v0.16.0 github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/exp v0.0.0-20240119083558-1b970713d09a + golang.org/x/time v0.1.0 ) From f7e507da2f13552717b4b40a957722217a798391 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:22:44 +0100 Subject: [PATCH 102/111] revert(kvstore): kvstore ctx.Done() checks are not needed Standard abci app will not respect our context :) --- abci/example/kvstore/kvstore.go | 60 ++++++--------------------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index f9118b7411..ab04ac3c71 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -253,13 +253,10 @@ func NewPersistentApp(cfg Config, opts ...OptFunc) (*Application, error) { } // InitChain implements ABCI -func (app *Application) InitChain(ctx context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { +func (app *Application) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } if req.InitialHeight != 0 { app.initialHeight = req.InitialHeight if app.LastCommittedState.GetHeight() == 0 { @@ -314,14 +311,10 @@ func (app *Application) InitChain(ctx context.Context, req *abci.RequestInitChai } // PrepareProposal implements ABCI -func (app *Application) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { +func (app *Application) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - if req.MaxTxBytes <= 0 { return &abci.ResponsePrepareProposal{}, fmt.Errorf("MaxTxBytes must be positive, got: %d", req.MaxTxBytes) } @@ -397,14 +390,10 @@ func (app *Application) ProcessProposal(_ context.Context, req *abci.RequestProc } // FinalizeBlock implements ABCI -func (app *Application) FinalizeBlock(ctx context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { +func (app *Application) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - blockHash := tmbytes.HexBytes(req.Hash) if err := app.validateHeight(req.Height); err != nil { @@ -491,14 +480,10 @@ func (app *Application) eventValUpdate(height int64) abci.Event { } // ListSnapshots implements ABCI. -func (app *Application) ListSnapshots(ctx context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { +func (app *Application) ListSnapshots(_ context.Context, req *abci.RequestListSnapshots) (*abci.ResponseListSnapshots, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - snapshots, err := app.snapshots.List() if err != nil { return &abci.ResponseListSnapshots{}, err @@ -510,14 +495,10 @@ func (app *Application) ListSnapshots(ctx context.Context, req *abci.RequestList } // LoadSnapshotChunk implements ABCI. -func (app *Application) LoadSnapshotChunk(ctx context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { +func (app *Application) LoadSnapshotChunk(_ context.Context, req *abci.RequestLoadSnapshotChunk) (*abci.ResponseLoadSnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - chunk, err := app.snapshots.LoadChunk(req.Height, req.Version, req.ChunkId) if err != nil { return &abci.ResponseLoadSnapshotChunk{}, err @@ -529,14 +510,10 @@ func (app *Application) LoadSnapshotChunk(ctx context.Context, req *abci.Request } // OfferSnapshot implements ABCI. -func (app *Application) OfferSnapshot(ctx context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { +func (app *Application) OfferSnapshot(_ context.Context, req *abci.RequestOfferSnapshot) (*abci.ResponseOfferSnapshot, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - app.offerSnapshot = newOfferSnapshot(req.Snapshot, req.AppHash) resp := &abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} @@ -545,14 +522,10 @@ func (app *Application) OfferSnapshot(ctx context.Context, req *abci.RequestOffe } // ApplySnapshotChunk implements ABCI. -func (app *Application) ApplySnapshotChunk(ctx context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { +func (app *Application) ApplySnapshotChunk(_ context.Context, req *abci.RequestApplySnapshotChunk) (*abci.ResponseApplySnapshotChunk, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - if app.offerSnapshot == nil { return &abci.ResponseApplySnapshotChunk{}, fmt.Errorf("no restore in progress") } @@ -604,14 +577,9 @@ func (app *Application) createSnapshot() error { } // Info implements ABCI -func (app *Application) Info(ctx context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { +func (app *Application) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) { app.mu.Lock() defer app.mu.Unlock() - - if err := ctx.Err(); err != nil { - return nil, err - } - appHash := app.LastCommittedState.GetAppHash() resp := &abci.ResponseInfo{ Data: fmt.Sprintf("{\"appHash\":\"%s\"}", appHash.String()), @@ -625,14 +593,10 @@ func (app *Application) Info(ctx context.Context, req *abci.RequestInfo) (*abci. } // CheckTx implements ABCI -func (app *Application) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *Application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - resp, err := app.verifyTx(req.Tx, req.Type) if app.cfg.CheckTxDelayMS != 0 { time.Sleep(time.Duration(app.cfg.CheckTxDelayMS) * time.Millisecond) @@ -642,14 +606,10 @@ func (app *Application) CheckTx(ctx context.Context, req *abci.RequestCheckTx) ( } // Query returns an associated value or nil if missing. -func (app *Application) Query(ctx context.Context, reqQuery *abci.RequestQuery) (*abci.ResponseQuery, error) { +func (app *Application) Query(_ context.Context, reqQuery *abci.RequestQuery) (*abci.ResponseQuery, error) { app.mu.Lock() defer app.mu.Unlock() - if err := ctx.Err(); err != nil { - return nil, err - } - switch reqQuery.Path { case "/val": vu, err := app.findValidatorUpdate(reqQuery.Data) From d2bf391a6cd24a605c0b5bcb1f5f3af3fa9399b4 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:28:23 +0100 Subject: [PATCH 103/111] refactor(p2p): move chan descs to p2p.channel_params and tune priorities --- go.mod | 2 +- go.sum | 4 +- internal/consensus/reactor.go | 65 +++------------- internal/consensus/reactor_test.go | 16 ++-- internal/evidence/reactor.go | 2 +- internal/p2p/channel_params.go | 116 ++++++++++++++++++++++------- internal/statesync/reactor.go | 36 +-------- node/setup.go | 28 +++---- 8 files changed, 127 insertions(+), 142 deletions(-) diff --git a/go.mod b/go.mod index 0d8c3a5b9d..2723784b59 100644 --- a/go.mod +++ b/go.mod @@ -306,5 +306,5 @@ require ( github.com/tendermint/go-amino v0.16.0 github.com/tyler-smith/go-bip39 v1.1.0 golang.org/x/exp v0.0.0-20240119083558-1b970713d09a - golang.org/x/time v0.1.0 + golang.org/x/time v0.5.0 ) diff --git a/go.sum b/go.sum index 2d03878a93..4f74de4350 100644 --- a/go.sum +++ b/go.sum @@ -1200,8 +1200,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index 48499df38b..222f92e978 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -30,54 +30,7 @@ var ( _ p2p.Wrapper = (*tmcons.Message)(nil) ) -// GetChannelDescriptor produces an instance of a descriptor for this -// package's required channels. -func getChannelDescriptors() map[p2p.ChannelID]*p2p.ChannelDescriptor { - return map[p2p.ChannelID]*p2p.ChannelDescriptor{ - StateChannel: { - ID: StateChannel, - Priority: 8, - SendQueueCapacity: 64, - RecvMessageCapacity: maxMsgSize, - RecvBufferCapacity: 128, - Name: "state", - }, - DataChannel: { - // TODO: Consider a split between gossiping current block and catchup - // stuff. Once we gossip the whole block there is nothing left to send - // until next height or round. - ID: DataChannel, - Priority: 12, - SendQueueCapacity: 64, - RecvBufferCapacity: 512, - RecvMessageCapacity: maxMsgSize, - Name: "data", - }, - VoteChannel: { - ID: VoteChannel, - Priority: 10, - SendQueueCapacity: 64, - RecvBufferCapacity: 4096, - RecvMessageCapacity: maxMsgSize, - Name: "vote", - }, - VoteSetBitsChannel: { - ID: VoteSetBitsChannel, - Priority: 5, - SendQueueCapacity: 8, - RecvBufferCapacity: 128, - RecvMessageCapacity: maxMsgSize, - Name: "voteSet", - }, - } -} - const ( - StateChannel = p2p.ChannelID(0x20) - DataChannel = p2p.ChannelID(0x21) - VoteChannel = p2p.ChannelID(0x22) - VoteSetBitsChannel = p2p.ChannelID(0x23) - maxMsgSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. blocksToContributeToBecomeGoodPeer = 10000 @@ -173,23 +126,23 @@ func (r *Reactor) OnStart(ctx context.Context) error { var chBundle channelBundle var err error - chans := getChannelDescriptors() - chBundle.state, err = r.chCreator(ctx, chans[StateChannel]) + chans := p2p.ConsensusChannelDescriptors() + chBundle.state, err = r.chCreator(ctx, chans[p2p.ConsensusStateChannel]) if err != nil { return err } - chBundle.data, err = r.chCreator(ctx, chans[DataChannel]) + chBundle.data, err = r.chCreator(ctx, chans[p2p.ConsensusDataChannel]) if err != nil { return err } - chBundle.vote, err = r.chCreator(ctx, chans[VoteChannel]) + chBundle.vote, err = r.chCreator(ctx, chans[p2p.ConsensusVoteChannel]) if err != nil { return err } - chBundle.voteSet, err = r.chCreator(ctx, chans[VoteSetBitsChannel]) + chBundle.voteSet, err = r.chCreator(ctx, chans[p2p.VoteSetBitsChannel]) if err != nil { return err } @@ -785,13 +738,13 @@ func (r *Reactor) handleMessage(ctx context.Context, envelope *p2p.Envelope, cha } switch envelope.ChannelID { - case StateChannel: + case p2p.ConsensusStateChannel: err = r.handleStateMessage(ctx, envelope, msg, chans.voteSet) - case DataChannel: + case p2p.ConsensusDataChannel: err = r.handleDataMessage(ctx, envelope, msg) - case VoteChannel: + case p2p.ConsensusVoteChannel: err = r.handleVoteMessage(ctx, envelope, msg) - case VoteSetBitsChannel: + case p2p.VoteSetBitsChannel: err = r.handleVoteSetBitsMessage(ctx, envelope, msg) default: err = fmt.Errorf("unknown channel ID (%d) for envelope (%v)", envelope.ChannelID, envelope) diff --git a/internal/consensus/reactor_test.go b/internal/consensus/reactor_test.go index 07cc40dc37..269ff7a578 100644 --- a/internal/consensus/reactor_test.go +++ b/internal/consensus/reactor_test.go @@ -88,10 +88,10 @@ func setup( blocksyncSubs: make(map[types.NodeID]eventbus.Subscription, numNodes), } - rts.stateChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(StateChannel, size)) - rts.dataChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(DataChannel, size)) - rts.voteChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(VoteChannel, size)) - rts.voteSetBitsChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(VoteSetBitsChannel, size)) + rts.stateChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusStateChannel, size)) + rts.dataChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusDataChannel, size)) + rts.voteChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.ConsensusVoteChannel, size)) + rts.voteSetBitsChannels = rts.network.MakeChannelsNoCleanup(ctx, t, chDesc(p2p.VoteSetBitsChannel, size)) ctx, cancel := context.WithCancel(ctx) t.Cleanup(cancel) @@ -99,13 +99,13 @@ func setup( chCreator := func(nodeID types.NodeID) p2p.ChannelCreator { return func(_ctx context.Context, desc *p2p.ChannelDescriptor) (p2p.Channel, error) { switch desc.ID { - case StateChannel: + case p2p.ConsensusStateChannel: return rts.stateChannels[nodeID], nil - case DataChannel: + case p2p.ConsensusDataChannel: return rts.dataChannels[nodeID], nil - case VoteChannel: + case p2p.ConsensusVoteChannel: return rts.voteChannels[nodeID], nil - case VoteSetBitsChannel: + case p2p.VoteSetBitsChannel: return rts.voteSetBitsChannels[nodeID], nil default: return nil, fmt.Errorf("invalid channel; %v", desc.ID) diff --git a/internal/evidence/reactor.go b/internal/evidence/reactor.go index ff8f6b6309..54dd75a810 100644 --- a/internal/evidence/reactor.go +++ b/internal/evidence/reactor.go @@ -27,7 +27,7 @@ const ( func GetChannelDescriptor() *p2p.ChannelDescriptor { return &p2p.ChannelDescriptor{ ID: EvidenceChannel, - Priority: 6, + Priority: 3, RecvMessageCapacity: maxMsgSize, RecvBufferCapacity: 32, Name: "evidence", diff --git a/internal/p2p/channel_params.go b/internal/p2p/channel_params.go index 14b3676b1d..41b8272982 100644 --- a/internal/p2p/channel_params.go +++ b/internal/p2p/channel_params.go @@ -17,6 +17,14 @@ import ( ) const ( + // + // Consensus channels + // + ConsensusStateChannel = ChannelID(0x20) + ConsensusDataChannel = ChannelID(0x21) + ConsensusVoteChannel = ChannelID(0x22) + VoteSetBitsChannel = ChannelID(0x23) + ErrorChannel = ChannelID(0x10) // BlockSyncChannel is a channelStore for blocks and status updates BlockSyncChannel = ChannelID(0x40) @@ -41,21 +49,24 @@ const ( lightBlockMsgSize = int(1e7) // ~1MB // paramMsgSize is the maximum size of a paramsResponseMessage paramMsgSize = int(1e5) // ~100kb + // consensusMsgSize is the maximum size of a consensus message + maxMsgSize = 1048576 // 1MB; NOTE: keep in sync with types.PartSet sizes. + ) // ChannelDescriptors returns a map of all supported descriptors func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { - return map[ChannelID]*ChannelDescriptor{ + channels := map[ChannelID]*ChannelDescriptor{ ErrorChannel: { ID: ErrorChannel, - Priority: 6, + Priority: 7, RecvMessageCapacity: blockMaxMsgSize, RecvBufferCapacity: 32, Name: "error", }, BlockSyncChannel: { ID: BlockSyncChannel, - Priority: 5, + Priority: 6, SendQueueCapacity: 1000, RecvBufferCapacity: 1024, RecvMessageCapacity: types.MaxBlockSizeBytes + @@ -65,7 +76,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, MempoolChannel: { ID: MempoolChannel, - Priority: 5, + Priority: 2, // 5 RecvMessageCapacity: mempoolBatchSize(cfg.Mempool.MaxTxBytes), RecvBufferCapacity: 128, Name: "mempool", @@ -76,6 +87,21 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { RecvRateShouldErr: cfg.Mempool.TxRecvRatePunishPeer, EnqueueTimeout: cfg.Mempool.TxEnqueueTimeout, }, + } + + for k, v := range StatesyncChannelDescriptors() { + channels[k] = v + } + for k, v := range ConsensusChannelDescriptors() { + channels[k] = v + } + + return channels +} + +// ChannelDescriptors returns a map of all supported descriptors +func StatesyncChannelDescriptors() map[ChannelID]*ChannelDescriptor { + return map[ChannelID]*ChannelDescriptor{ SnapshotChannel: { ID: SnapshotChannel, Priority: 6, @@ -86,7 +112,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, ChunkChannel: { ID: ChunkChannel, - Priority: 3, + Priority: 4, SendQueueCapacity: 4, RecvMessageCapacity: chunkMsgSize, RecvBufferCapacity: 128, @@ -94,7 +120,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, LightBlockChannel: { ID: LightBlockChannel, - Priority: 5, + Priority: 6, SendQueueCapacity: 10, RecvMessageCapacity: lightBlockMsgSize, RecvBufferCapacity: 128, @@ -102,7 +128,7 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { }, ParamsChannel: { ID: ParamsChannel, - Priority: 2, + Priority: 3, SendQueueCapacity: 10, RecvMessageCapacity: paramMsgSize, RecvBufferCapacity: 128, @@ -111,6 +137,48 @@ func ChannelDescriptors(cfg *config.Config) map[ChannelID]*ChannelDescriptor { } } +// GetChannelDescriptor produces an instance of a descriptor for this +// package's required channels. +func ConsensusChannelDescriptors() map[ChannelID]*ChannelDescriptor { + return map[ChannelID]*ChannelDescriptor{ + ConsensusStateChannel: { + ID: ConsensusStateChannel, + Priority: 18, + SendQueueCapacity: 64, + RecvMessageCapacity: maxMsgSize, + RecvBufferCapacity: 128, + Name: "state", + }, + ConsensusDataChannel: { + // TODO: Consider a split between gossiping current block and catchup + // stuff. Once we gossip the whole block there is nothing left to send + // until next height or round. + ID: ConsensusDataChannel, + Priority: 22, + SendQueueCapacity: 64, + RecvBufferCapacity: 512, + RecvMessageCapacity: maxMsgSize, + Name: "data", + }, + ConsensusVoteChannel: { + ID: ConsensusVoteChannel, + Priority: 20, + SendQueueCapacity: 64, + RecvBufferCapacity: 4096, + RecvMessageCapacity: maxMsgSize, + Name: "vote", + }, + VoteSetBitsChannel: { + ID: VoteSetBitsChannel, + Priority: 15, + SendQueueCapacity: 8, + RecvBufferCapacity: 128, + RecvMessageCapacity: maxMsgSize, + Name: "voteSet", + }, + } +} + // ResolveChannelID returns channel ID according to message type // currently only is supported blocksync channelID, the remaining channelIDs should be added as it will be necessary func ResolveChannelID(msg proto.Message) ChannelID { @@ -121,6 +189,7 @@ func ResolveChannelID(msg proto.Message) ChannelID { *blocksync.StatusRequest, *blocksync.StatusResponse: return BlockSyncChannel + // State sync case *statesync.ChunkRequest, *statesync.ChunkResponse: return ChunkChannel @@ -133,30 +202,27 @@ func ResolveChannelID(msg proto.Message) ChannelID { case *statesync.LightBlockRequest, *statesync.LightBlockResponse: return LightBlockChannel - case *consensus.NewRoundStep, - *consensus.NewValidBlock, + // Consensus messages + case *consensus.VoteSetBits: + return VoteSetBitsChannel + case *consensus.Vote, *consensus.Commit: + return ConsensusVoteChannel + case *consensus.ProposalPOL, *consensus.Proposal, - *consensus.ProposalPOL, - *consensus.BlockPart, - *consensus.Vote, + *consensus.BlockPart: + return ConsensusDataChannel + case *consensus.NewRoundStep, *consensus.NewValidBlock, + *consensus.HasCommit, *consensus.HasVote, - *consensus.VoteSetMaj23, - *consensus.VoteSetBits, - *consensus.Commit, - *consensus.HasCommit: - // TODO: enable these channels when they are implemented - //*statesync.SnapshotsRequest, - //*statesync.SnapshotsResponse, - //*statesync.ChunkRequest, - //*statesync.ChunkResponse, - //*statesync.LightBlockRequest, - //*statesync.LightBlockResponse, - //*statesync.ParamsRequest, - //*statesync.ParamsResponse: + *consensus.VoteSetMaj23: + return ConsensusStateChannel + // pex case *p2pproto.PexRequest, *p2pproto.PexResponse, *p2pproto.Echo: + // evidence case *prototypes.Evidence: + // mempool case *mempool.Txs: return MempoolChannel } diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index 4dd794268d..c5a3bb40e3 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -83,41 +83,7 @@ const ( ) func getChannelDescriptors() map[p2p.ChannelID]*p2p.ChannelDescriptor { - return map[p2p.ChannelID]*p2p.ChannelDescriptor{ - SnapshotChannel: { - ID: SnapshotChannel, - Priority: 6, - SendQueueCapacity: 10, - RecvMessageCapacity: snapshotMsgSize, - RecvBufferCapacity: 128, - Name: "snapshot", - }, - ChunkChannel: { - ID: ChunkChannel, - Priority: 3, - SendQueueCapacity: 4, - RecvMessageCapacity: chunkMsgSize, - RecvBufferCapacity: 128, - Name: "chunk", - }, - LightBlockChannel: { - ID: LightBlockChannel, - Priority: 5, - SendQueueCapacity: 10, - RecvMessageCapacity: lightBlockMsgSize, - RecvBufferCapacity: 128, - Name: "light-block", - }, - ParamsChannel: { - ID: ParamsChannel, - Priority: 2, - SendQueueCapacity: 10, - RecvMessageCapacity: paramMsgSize, - RecvBufferCapacity: 128, - Name: "params", - }, - } - + return p2p.StatesyncChannelDescriptors() } // Metricer defines an interface used for the rpc sync info query, please see statesync.metrics diff --git a/node/setup.go b/node/setup.go index 0262749f13..ff9b3e0381 100644 --- a/node/setup.go +++ b/node/setup.go @@ -365,20 +365,20 @@ func makeNodeInfo( NodeID: nodeKey.ID, Network: genDoc.ChainID, Version: version.TMCoreSemVer, - Channels: tmsync.NewConcurrentSlice[uint16]( - uint16(p2p.BlockSyncChannel), - uint16(consensus.StateChannel), - uint16(consensus.DataChannel), - uint16(consensus.VoteChannel), - uint16(consensus.VoteSetBitsChannel), - uint16(p2p.MempoolChannel), - uint16(evidence.EvidenceChannel), - uint16(statesync.SnapshotChannel), - uint16(statesync.ChunkChannel), - uint16(statesync.LightBlockChannel), - uint16(statesync.ParamsChannel), - uint16(pex.PexChannel), - ), + Channels: tmsync.NewConcurrentSlice[uint16]( + byte(p2p.BlockSyncChannel), + byte(p2p.ConsensusStateChannel), + byte(p2p.ConsensusDataChannel), + byte(p2p.ConsensusVoteChannel), + byte(p2p.VoteSetBitsChannel), + byte(p2p.MempoolChannel), + byte(evidence.EvidenceChannel), + byte(statesync.SnapshotChannel), + byte(statesync.ChunkChannel), + byte(statesync.LightBlockChannel), + byte(statesync.ParamsChannel), + byte(pex.PexChannel), + }, Moniker: cfg.Moniker, Other: types.NodeInfoOther{ TxIndex: txIndexerStatus, From cc6bfde7460e5c18e059b1bb38abe479fa9254fc Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:35:09 +0100 Subject: [PATCH 104/111] chore: fix after merge --- node/setup.go | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/node/setup.go b/node/setup.go index ff9b3e0381..8d3dbf2bef 100644 --- a/node/setup.go +++ b/node/setup.go @@ -365,20 +365,20 @@ func makeNodeInfo( NodeID: nodeKey.ID, Network: genDoc.ChainID, Version: version.TMCoreSemVer, - Channels: tmsync.NewConcurrentSlice[uint16]( - byte(p2p.BlockSyncChannel), - byte(p2p.ConsensusStateChannel), - byte(p2p.ConsensusDataChannel), - byte(p2p.ConsensusVoteChannel), - byte(p2p.VoteSetBitsChannel), - byte(p2p.MempoolChannel), - byte(evidence.EvidenceChannel), - byte(statesync.SnapshotChannel), - byte(statesync.ChunkChannel), - byte(statesync.LightBlockChannel), - byte(statesync.ParamsChannel), - byte(pex.PexChannel), - }, + Channels: tmsync.NewConcurrentSlice[uint16]( + uint16(p2p.BlockSyncChannel), + uint16(p2p.ConsensusStateChannel), + uint16(p2p.ConsensusDataChannel), + uint16(p2p.ConsensusVoteChannel), + uint16(p2p.VoteSetBitsChannel), + uint16(p2p.MempoolChannel), + uint16(evidence.EvidenceChannel), + uint16(statesync.SnapshotChannel), + uint16(statesync.ChunkChannel), + uint16(statesync.LightBlockChannel), + uint16(statesync.ParamsChannel), + uint16(pex.PexChannel), + ), Moniker: cfg.Moniker, Other: types.NodeInfoOther{ TxIndex: txIndexerStatus, From 33f54c22ebcf7ce7566569e89d17819c252e744f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:40:19 +0100 Subject: [PATCH 105/111] chore(p2p): remove some logs --- internal/p2p/router.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/p2p/router.go b/internal/p2p/router.go index 7a52f9409c..43bdde8164 100644 --- a/internal/p2p/router.go +++ b/internal/p2p/router.go @@ -712,19 +712,15 @@ func (r *Router) routePeer(ctx context.Context, peerID types.NodeID, conn Connec sendQueue := r.getOrMakeQueue(peerID, channels) defer func() { - r.logger.Debug("routePeer cleanup: terminated peer", "peer", peerID) r.peerMtx.Lock() delete(r.peerQueues, peerID) delete(r.peerChannels, peerID) r.peerMtx.Unlock() - r.logger.Debug("routePeer cleanup: deleted peer queues", "peer", peerID) _ = conn.Close() sendQueue.close() - r.logger.Debug("routePeer cleanup: closed send queue", "peer", peerID) r.peerManager.Disconnected(ctx, peerID) - r.logger.Debug("routePeer cleanup: peer marked as disconnected", "peer", peerID) r.metrics.PeersConnected.Add(-1) }() From 9e5cf6c963affdc0aaa3c9521d7b509acd787a18 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:41:59 +0100 Subject: [PATCH 106/111] chore(statesync): fix linter issues - remove unused consts --- internal/statesync/reactor.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/internal/statesync/reactor.go b/internal/statesync/reactor.go index c5a3bb40e3..602bfcfe0a 100644 --- a/internal/statesync/reactor.go +++ b/internal/statesync/reactor.go @@ -48,18 +48,6 @@ const ( // recentSnapshots is the number of recent snapshots to send and receive per peer. recentSnapshots = 10 - // snapshotMsgSize is the maximum size of a snapshotResponseMessage - snapshotMsgSize = int(4e6) // ~4MB - - // chunkMsgSize is the maximum size of a chunkResponseMessage - chunkMsgSize = int(16e6) // ~16MB - - // lightBlockMsgSize is the maximum size of a lightBlockResponseMessage - lightBlockMsgSize = int(1e7) // ~1MB - - // paramMsgSize is the maximum size of a paramsResponseMessage - paramMsgSize = int(1e5) // ~100kb - // lightBlockResponseTimeout is how long the dispatcher waits for a peer to // return a light block lightBlockResponseTimeout = 10 * time.Second From 5b44f5ad598eedffc693b2e5530895324215fdf6 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Tue, 12 Mar 2024 13:58:43 +0100 Subject: [PATCH 107/111] chore: self-review --- internal/consensus/peer_state.go | 3 +-- internal/consensus/state_enter_propose.go | 2 +- internal/consensus/state_proposaler.go | 8 +------- scripts/txs/random.sh | 15 +++++++-------- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/internal/consensus/peer_state.go b/internal/consensus/peer_state.go index 58eab517b5..8ab8f90be6 100644 --- a/internal/consensus/peer_state.go +++ b/internal/consensus/peer_state.go @@ -483,8 +483,7 @@ func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage) { ps.mtx.Lock() defer ps.mtx.Unlock() - // TODO change to TRACE - ps.logger.Debug("apply new round step message", "peer", ps.peerID, "msg", msg.String()) + ps.logger.Trace("apply new round step message", "peer", ps.peerID, "msg", msg.String()) // ignore duplicates or decreases if CompareHRS(msg.Height, msg.Round, msg.Step, ps.PRS.Height, ps.PRS.Round, ps.PRS.Step) <= 0 { diff --git a/internal/consensus/state_enter_propose.go b/internal/consensus/state_enter_propose.go index bd57f47743..e9ae2075c8 100644 --- a/internal/consensus/state_enter_propose.go +++ b/internal/consensus/state_enter_propose.go @@ -57,7 +57,7 @@ func (c *EnterProposeAction) Execute(ctx context.Context, stateEvent StateEvent) if isProposer { pwt := proposerWaitTime(tmtime.Now(), stateData.state.LastBlockTime) if pwt > 0 { - c.logger.Info("enter propose: latest block is newer, sleeping", + c.logger.Debug("enter propose: latest block is newer, sleeping", "duration", pwt.String(), "last_block_time", stateData.state.LastBlockTime, "now", tmtime.Now(), diff --git a/internal/consensus/state_proposaler.go b/internal/consensus/state_proposaler.go index 00da1038e3..a5f34cd9a2 100644 --- a/internal/consensus/state_proposaler.go +++ b/internal/consensus/state_proposaler.go @@ -73,12 +73,6 @@ func (p *Proposaler) Set(proposal *types.Proposal, receivedAt time.Time, rs *cst rs.Proposal = proposal rs.ProposalReceiveTime = receivedAt - // if rand.Intn(5) != 0 && !rs.Validators.Proposer.ProTxHash.Equal(p.privVal.ProTxHash) { - // p.logger.Debug("waiting for proposal to get outdated as a test") - // sleepTime := p.blockExec.committedState.ConsensusParams.Synchrony.MessageDelay + p.blockExec.committedState.ConsensusParams.Synchrony.Precision - // rs.ProposalReceiveTime = rs.ProposalReceiveTime.Add(sleepTime) - // } - p.proposalTimestampDifferenceMetric(*rs) // We don't update cs.ProposalBlockParts if it is already set. // This happens if we're already in cstypes.RoundStepApplyCommit or if there is a valid block in the current round. @@ -103,7 +97,7 @@ func (p *Proposaler) Create(ctx context.Context, height int64, round int32, rs * var err error start := time.Now() block, blockParts, err = p.createProposalBlock(ctx, round, rs) - p.logger.Debug("createProposalBlock executed", "took", time.Since(start).String()) + p.logger.Trace("createProposalBlock executed", "took", time.Since(start).String()) if err != nil { return err diff --git a/scripts/txs/random.sh b/scripts/txs/random.sh index 60c74f1a9c..dae4c42d74 100755 --- a/scripts/txs/random.sh +++ b/scripts/txs/random.sh @@ -2,19 +2,18 @@ set -u function toHex() { - echo -n $1 | hexdump -ve '1/1 "%.2X"' + echo -n "$1" | hexdump -ve '1/1 "%.2X"' } -N=$1 -PORT=$2 +N="$1" +PORT="$2" -for i in `seq 1 $N`; do +for i in $(seq 1 $N); do # store key value pair KEY=$(head -c 10 /dev/urandom) VALUE="$i" - echo $(toHex $KEY=$VALUE) - curl 127.0.0.1:$PORT/broadcast_tx_sync?tx=0x$(toHex $KEY=$VALUE) + KV="$(toHex "$KEY=$VALUE")" + echo "$KV" + curl "127.0.0.1:$PORT/broadcast_tx_sync?tx=0x${KV}" echo done - - From 39dedb66daed9fd5a1971af3901913d075bb51df Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:14:24 +0100 Subject: [PATCH 108/111] chore: fix linter issues --- internal/state/execution.go | 15 ++++----------- internal/state/state_test.go | 2 +- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/internal/state/execution.go b/internal/state/execution.go index 566cd11532..64cc38b2ac 100644 --- a/internal/state/execution.go +++ b/internal/state/execution.go @@ -493,9 +493,6 @@ func (blockExec *BlockExecutor) FinalizeBlock( } endTime := time.Now().UnixNano() blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000) - if err != nil { - return state, ErrProxyAppConn(err) - } // Save the results before we commit. // We need to save Prepare/ProcessProposal AND FinalizeBlock responses, as we don't have details like validators @@ -508,8 +505,7 @@ func (blockExec *BlockExecutor) FinalizeBlock( return state, err } - state, err = state.Update(blockID, &block.Header, &uncommittedState) - if err != nil { + if state, err = state.Update(blockID, &block.Header, &uncommittedState); err != nil { return state, fmt.Errorf("commit failed for application: %w", err) } @@ -522,7 +518,7 @@ func (blockExec *BlockExecutor) FinalizeBlock( // Update evpool with the latest state. blockExec.evpool.Update(ctx, state, block.Evidence) - if err := blockExec.store.Save(state); err != nil { + if err = blockExec.store.Save(state); err != nil { return state, err } @@ -535,8 +531,7 @@ func (blockExec *BlockExecutor) FinalizeBlock( // Events are fired after everything else. // NOTE: if we crash between Commit and Save, events wont be fired during replay es := NewFullEventSet(block, blockID, uncommittedState, fbResp, state.Validators) - err = es.Publish(blockExec.eventPublisher) - if err != nil { + if err = es.Publish(blockExec.eventPublisher); err != nil { blockExec.logger.Error("failed publishing event", "err", err) } @@ -713,9 +708,7 @@ func execBlock( } blockID := block.BlockID(nil) protoBlockID := blockID.ToProto() - if err != nil { - return nil, err - } + responseFinalizeBlock, err := appConn.FinalizeBlock( ctx, &abci.RequestFinalizeBlock{ diff --git a/internal/state/state_test.go b/internal/state/state_test.go index ebf3d17701..942dae3e1c 100644 --- a/internal/state/state_test.go +++ b/internal/state/state_test.go @@ -44,7 +44,7 @@ func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, sm.State) { err = stateStore.Save(state) require.NoError(t, err) - tearDown := func(t *testing.T) { _ = os.RemoveAll(cfg.RootDir) } + tearDown := func(_ *testing.T) { _ = os.RemoveAll(cfg.RootDir) } return tearDown, stateDB, state } From 8e527cde67c79f6102850e2c2c3897f3f990a4c0 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 13 Mar 2024 13:29:23 +0100 Subject: [PATCH 109/111] chore: lint --- internal/mempool/reactor.go | 2 +- internal/mempool/reactor_test.go | 4 ++-- internal/mempool/types.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/mempool/reactor.go b/internal/mempool/reactor.go index 88e69454f6..3f62f958ec 100644 --- a/internal/mempool/reactor.go +++ b/internal/mempool/reactor.go @@ -58,7 +58,7 @@ func NewReactor( p2pClient: p2pClient, peerEvents: peerEvents, peerRoutines: make(map[types.NodeID]context.CancelFunc), - observePanic: func(i interface{}) {}, + observePanic: func(_i interface{}) {}, } r.BaseService = *service.NewBaseService(logger, "Mempool", r) diff --git a/internal/mempool/reactor_test.go b/internal/mempool/reactor_test.go index d857c68e1e..691324e721 100644 --- a/internal/mempool/reactor_test.go +++ b/internal/mempool/reactor_test.go @@ -74,7 +74,7 @@ func setupReactors(ctx context.Context, t *testing.T, logger log.Logger, numNode cfg.Mempool, mempool, rts.network.Nodes[nodeID].Client, - func(ctx context.Context, n string) *p2p.PeerUpdates { return rts.peerUpdates[nodeID] }, + func(_ctx context.Context, _n string) *p2p.PeerUpdates { return rts.peerUpdates[nodeID] }, ) rts.nodes = append(rts.nodes, nodeID) @@ -146,7 +146,7 @@ func TestReactorBroadcastDoesNotPanic(t *testing.T) { logger := log.NewNopLogger() rts := setupReactors(ctx, t, logger, numNodes, 0) - observePanic := func(r interface{}) { + observePanic := func(_r interface{}) { t.Fatal("panic detected in reactor") } diff --git a/internal/mempool/types.go b/internal/mempool/types.go index 28b3dc7f34..48dc52041d 100644 --- a/internal/mempool/types.go +++ b/internal/mempool/types.go @@ -131,7 +131,7 @@ func PreCheckMaxBytes(maxBytes int64) PreCheckFunc { // PostCheckMaxGas checks that the wanted gas is smaller or equal to the passed // maxGas. Returns nil if maxGas is -1. func PostCheckMaxGas(maxGas int64) PostCheckFunc { - return func(tx types.Tx, res *abci.ResponseCheckTx) error { + return func(_tx types.Tx, res *abci.ResponseCheckTx) error { if maxGas == -1 { return nil } From 2fb9bf706af703516cd781843cf16c24b9e666ab Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:37:00 +0100 Subject: [PATCH 110/111] fix(sync): race condition in ConcurrentSlice debug --- internal/libs/sync/concurrent_slice.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/libs/sync/concurrent_slice.go b/internal/libs/sync/concurrent_slice.go index 48d674eb78..743a75112f 100644 --- a/internal/libs/sync/concurrent_slice.go +++ b/internal/libs/sync/concurrent_slice.go @@ -2,6 +2,7 @@ package sync import ( "encoding/json" + "fmt" "sync" ) @@ -114,3 +115,10 @@ func (cs *ConcurrentSlice[T]) UnmarshalJSON(data []byte) error { cs.items = items return nil } + +func (cs *ConcurrentSlice[T]) String() string { + cs.mtx.RLock() + defer cs.mtx.RUnlock() + + return fmt.Sprintf("%v", cs.items) +} From 9eeddf973b170d298a0f25bf384b89223373ff1f Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 13 Mar 2024 14:37:57 +0100 Subject: [PATCH 111/111] fix(consensus): invalid block height gossiped to lagging peer --- internal/consensus/gossip_handlers.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/consensus/gossip_handlers.go b/internal/consensus/gossip_handlers.go index d9bddb8c8c..deaf9060ca 100644 --- a/internal/consensus/gossip_handlers.go +++ b/internal/consensus/gossip_handlers.go @@ -117,9 +117,14 @@ func shouldProposalBeGossiped(rs cstypes.RoundState, prs *cstypes.PeerRoundState } func shouldBlockPartsBeGossiped(rs cstypes.RoundState, prs *cstypes.PeerRoundState, isValidator bool) bool { + if rs.Height != prs.Height || rs.Round < prs.Round { + return false + } + if isValidator && rs.ProposalBlockParts.HasHeader(prs.ProposalBlockPartSetHeader) { return true } + return prs.HasCommit && rs.ProposalBlockParts != nil }