From 0dcca1633451262ffc84bf37d7191813d2b4a9f8 Mon Sep 17 00:00:00 2001 From: Toshimasa Nasu Date: Wed, 19 Jul 2023 18:24:30 +0900 Subject: [PATCH] Backport tendermint-v0.34.20 into main (#642) * rpc: avoid leaking threads (#8329) Co-authored-by: Sam Kleinman * (fixup) Revert the CheckTxSync callback parameter from https://github.com/Finschia/ostracon/pull/163/files#diff-eafa5360d0b71c14dba6ad5b29be23f69f0fe93e0751fe89fe208a5dafcfbbcf * (fixup) Test the reverted CheckTxSync callback parameter from https://github.com/Finschia/ostracon/pull/163/files#diff-eafa5360d0b71c14dba6ad5b29be23f69f0fe93e0751fe89fe208a5dafcfbbcf * (fixup) Add tests for code coverage: rpc/core/mempool_test.go * Set a cap on the length of subscription queries. (#8349) A manual backport of #7263. As a safety measure, don't allow a query string to be unreasonably long. The query filter is not especially efficient, so a query that needs more than basic detail should filter coarsely in the subscriber and refine on the client side. This affects Subscribe and TxSearch queries. Co-authored-by: M. J. Fromberger * blocksync: validate block before persisting it (backport #8493) (#8495) * Update default config docs for PSQL indexer settings. (#8728) Co-authored-by: M. J. Fromberger * cmd: add tool for compaction of goleveldb (backport #8564) (#8674) * (fixup) Add compact_test for improving coverage * makefile: change buf to use tools.go ; backport v0.34 (#8852) * makefile: update buf commands to use tools.go (#8609) This will keep the version of `buf` consistent between all developer machines. Co-authored-by: Jasmina Malicevic * (fixup) Improve to work for Ostracon with tendermint proto files * fix: "Lazy" Stringers to defer Sprintf and Hash until logs print (#8845) Co-authored-by: Joe Abbey * makefile: buf setup backport v0.34 (#8863) Co-authored-by: Jasmina Malicevic * (fixup) Remove proto.yml since don't work and remove the next version of tendermint-v0.34.21: https://github.com/tendermint/tendermint/commit/c72335712beade92256e07e80cfce3c3615fa8b7 * (fixup) Remove unused import: buf-lint rule: IMPORT_USED * (fixup) Remove duplicated a rule of `FILE_LOWER_SNAKE_CASE` since BASIC includes it * (fixup) Use mockery latest v2.31.4 since v2.30.17 doesn't release: https://github.com/vektra/mockery/releases * (fixup) Re-generate mocks with mockery-v2.30.18 * feat: v0.34.x Prioritized Mempool (#8695) * Updated mocks * add reactor tests * add v1 reactor tests * Fix fuzz test for priority mempool * e2e adapted to mempool v1; prio pool is default now * Reverted default mempool to be fifo * Changed buf version * Added priority mempool to ci testnet * Fixed linter * Updated makefile * Aligned makefile changes to v0.34.x * Added go install for proto * Add log message to warn about prioritized mempool bug Signed-off-by: Thane Thomson * Changelog message Co-authored-by: Aleksandr Bezobchuk Co-authored-by: Jasmina Malicevic Co-authored-by: Callum Waters Co-authored-by: Sam Kleinman Co-authored-by: Thane Thomson * release: prepare v0.34.20-rc0 (#8888) Co-authored-by: Callum Waters * Backport priority mempool fixes from v0.35.x to v0.34.x. (#8962) This is a manual backport of the changes from these commits: - bc49f66 Add more unit tests for the priority mempool. (#8961) - 9b02094 Fix unbounded heap growth in the priority mempool. (#8944) Imports and type signatures have been updated to match the v0.34 usage. Co-authored-by: M. J. Fromberger * mempool: minor cleanup after backport from v0.35 (#8971) - Remove warning log for issue #8775. - Fix call to FlushAsync (no error is reported). - Don't log on rechecks, it's the default (manual backport of #8969). Co-authored-by: M. J. Fromberger * mempool: reduce lock contention during CheckTx (backport #8983) (#8985) A manual cherry-pick of 9e64c95. The way this was originally structured, we reacquired the lock after issuing the initial ABCI CheckTx call, only to immediately release it. Restructure the code so that this redundant acquire is no longer necessary. Co-authored-by: M. J. Fromberger * mempool: release lock during app connection flush (#8986) A manual backport of #8984. This case is symmetric to what we did for CheckTx calls, where we release the mempool mutex to ensure callbacks can fire during call setup. We also need this behaviour for application flush, for the same reason: The caller holds the lock by contract from the Mempool interface. Co-authored-by: M. J. Fromberger * config: remove obsolete mempool v1 warning (#8987) Co-authored-by: M. J. Fromberger * mempool: ensure evicted transactions are removed from the cache (backport #9000) (#9004) This is a manual cherry-pick of commit b94470a6a42e8ffe7e7467521de5f51eb937c454. In the original implementation transactions evicted for priority were also removed from the cache. In addition, remove expired transactions from the cache. Related: - Add Has method to cache implementations. - Update tests to exercise this condition. Co-authored-by: M. J. Fromberger * mempool: ensure async requests are flushed to the server (#9010) In the v0.34 line, the socket and gRPC clients require explicit flushes to ensure that the client and server have received an async request. Add these calls explicitly where required in the backport of the priority mempool. In addition, the gRPC client's flush plumbing was not fully hooked up in the v0.34 line, so this change includes that update as well. Co-authored: M. J. Fromberger * Upgrade to tendermint/tendermint v0.34.20 * (fixup) Improve libraries to work well --------- Co-authored-by: Sam Kleinman Co-authored-by: M. J. Fromberger Co-authored-by: Jasmina Malicevic Co-authored-by: Joe Abbey Co-authored-by: Aleksandr Bezobchuk Co-authored-by: Callum Waters Co-authored-by: Thane Thomson --- .github/workflows/check-generated.yml | 75 ++ .github/workflows/proto-docker.yml | 58 -- .github/workflows/proto-lint.yml | 19 + .github/workflows/proto.yml | 22 - Makefile | 53 +- abci/client/grpc_client.go | 1 + abci/client/mocks/client.go | 9 +- abci/types/mocks/application.go | 9 +- abci/types/types.pb.go | 184 ++-- blockchain/v0/reactor.go | 38 +- blockchain/v2/routine.go | 8 +- buf.gen.yaml | 9 + buf.work.yaml | 4 + cmd/ostracon/commands/compact.go | 66 ++ cmd/ostracon/commands/compact_test.go | 52 ++ cmd/ostracon/main.go | 1 + config/config.go | 42 +- config/toml.go | 27 + consensus/byzantine_test.go | 41 +- consensus/common_test.go | 35 +- consensus/mempool_test.go | 2 +- consensus/reactor.go | 8 +- consensus/reactor_test.go | 37 +- consensus/replay_stubs.go | 16 +- consensus/replay_test.go | 12 +- consensus/state.go | 42 +- evidence/mocks/block_store.go | 9 +- go.mod | 25 +- go.sum | 620 ++++++++++++-- libs/os/os.go | 4 +- libs/service/service.go | 30 +- light/rpc/mocks/light_client.go | 9 +- mempool/bench_test.go | 100 --- mempool/cache.go | 120 +++ mempool/cache_bench_test.go | 41 + mempool/cache_test.go | 98 +-- mempool/errors.go | 54 -- mempool/ids.go | 3 + mempool/ids_test.go | 23 + mempool/mempool.go | 151 +++- mempool/mempool_test.go | 3 +- mempool/metrics.go | 43 +- mempool/mock/mempool.go | 17 +- mempool/tx.go | 17 + mempool/v0/bench_test.go | 101 +++ mempool/v0/cache_test.go | 81 ++ mempool/{ => v0}/clist_mempool.go | 388 ++++----- mempool/{ => v0}/clist_mempool_system_test.go | 17 +- mempool/{ => v0}/clist_mempool_test.go | 412 ++++----- mempool/{ => v0}/doc.go | 2 +- mempool/{ => v0}/reactor.go | 47 +- mempool/{ => v0}/reactor_test.go | 19 +- mempool/v1/mempool.go | 803 ++++++++++++++++++ mempool/v1/mempool_bench_test.go | 33 + mempool/v1/mempool_test.go | 656 ++++++++++++++ mempool/v1/reactor.go | 312 +++++++ mempool/v1/reactor_test.go | 188 ++++ mempool/v1/tx.go | 89 ++ node/node.go | 100 ++- node/node_test.go | 73 +- p2p/conn/connection.go | 6 +- p2p/mocks/node_info.go | 9 +- p2p/mocks/peer.go | 9 +- p2p/pex/addrbook.go | 3 +- p2p/switch.go | 3 +- p2p/upnp/probe.go | 26 +- proto/README.md | 16 + proto/buf.lock | 8 + proto/buf.yaml | 11 + proto/ostracon/abci/types.proto | 4 - proto/ostracon/privval/types.pb.go | 69 +- proto/ostracon/privval/types.proto | 3 - proto/ostracon/state/types.pb.go | 94 +- proto/ostracon/state/types.proto | 3 - proxy/mocks/app_conn_consensus.go | 9 +- proxy/mocks/app_conn_mempool.go | 9 +- proxy/mocks/app_conn_query.go | 9 +- proxy/mocks/app_conn_snapshot.go | 9 +- proxy/mocks/client_creator.go | 9 +- rpc/client/mocks/client.go | 9 +- rpc/client/mocks/remote_client.go | 9 +- rpc/client/rpc_test.go | 4 +- rpc/core/events.go | 8 + rpc/core/mempool.go | 129 +-- rpc/core/mempool_test.go | 439 ++++++++++ rpc/core/tx.go | 2 + rpc/jsonrpc/client/ws_client.go | 3 +- rpc/jsonrpc/server/http_server.go | 4 +- scripts/proto-gen.sh | 19 + scripts/protocgen.sh | 22 - state/mocks/block_store.go | 9 +- state/mocks/evidence_pool.go | 9 +- state/mocks/store.go | 9 +- state/txindex/mocks/tx_indexer.go | 9 +- statesync/mocks/state_provider.go | 9 +- statesync/syncer.go | 4 +- test/e2e/generator/generate.go | 2 + test/e2e/networks/ci.toml | 2 +- test/e2e/pkg/manifest.go | 4 + test/e2e/pkg/testnet.go | 8 + test/e2e/runner/load.go | 2 +- test/e2e/runner/setup.go | 3 + test/fuzz/mempool/{ => v0}/checktx.go | 8 +- test/fuzz/mempool/v0/fuzz_test.go | 34 + test/fuzz/mempool/v0/testdata/cases/empty | 0 test/fuzz/mempool/v1/checktx.go | 39 + test/fuzz/mempool/v1/fuzz_test.go | 35 + test/fuzz/mempool/v1/testdata/cases/empty | 0 third_party/proto/README.md | 16 + third_party/proto/buf.lock | 8 + third_party/proto/buf.yaml | 11 + third_party/proto/gogoproto/gogo.proto | 147 ---- third_party/proto/tendermint/abci/types.proto | 42 +- types/tx.go | 21 +- 114 files changed, 5295 insertions(+), 1651 deletions(-) create mode 100644 .github/workflows/check-generated.yml delete mode 100644 .github/workflows/proto-docker.yml create mode 100644 .github/workflows/proto-lint.yml delete mode 100644 .github/workflows/proto.yml create mode 100644 buf.gen.yaml create mode 100644 buf.work.yaml create mode 100644 cmd/ostracon/commands/compact.go create mode 100644 cmd/ostracon/commands/compact_test.go delete mode 100644 mempool/bench_test.go create mode 100644 mempool/cache.go create mode 100644 mempool/cache_bench_test.go delete mode 100644 mempool/errors.go create mode 100644 mempool/ids.go create mode 100644 mempool/ids_test.go create mode 100644 mempool/tx.go create mode 100644 mempool/v0/bench_test.go create mode 100644 mempool/v0/cache_test.go rename mempool/{ => v0}/clist_mempool.go (73%) rename mempool/{ => v0}/clist_mempool_system_test.go (96%) rename mempool/{ => v0}/clist_mempool_test.go (59%) rename mempool/{ => v0}/doc.go (98%) rename mempool/{ => v0}/reactor.go (88%) rename mempool/{ => v0}/reactor_test.go (93%) create mode 100644 mempool/v1/mempool.go create mode 100644 mempool/v1/mempool_bench_test.go create mode 100644 mempool/v1/mempool_test.go create mode 100644 mempool/v1/reactor.go create mode 100644 mempool/v1/reactor_test.go create mode 100644 mempool/v1/tx.go create mode 100644 proto/README.md create mode 100644 proto/buf.lock create mode 100644 proto/buf.yaml create mode 100644 rpc/core/mempool_test.go create mode 100755 scripts/proto-gen.sh delete mode 100755 scripts/protocgen.sh rename test/fuzz/mempool/{ => v0}/checktx.go (75%) create mode 100644 test/fuzz/mempool/v0/fuzz_test.go create mode 100644 test/fuzz/mempool/v0/testdata/cases/empty create mode 100644 test/fuzz/mempool/v1/checktx.go create mode 100644 test/fuzz/mempool/v1/fuzz_test.go create mode 100644 test/fuzz/mempool/v1/testdata/cases/empty create mode 100644 third_party/proto/README.md create mode 100644 third_party/proto/buf.lock create mode 100644 third_party/proto/buf.yaml delete mode 100644 third_party/proto/gogoproto/gogo.proto diff --git a/.github/workflows/check-generated.yml b/.github/workflows/check-generated.yml new file mode 100644 index 000000000..c27e132aa --- /dev/null +++ b/.github/workflows/check-generated.yml @@ -0,0 +1,75 @@ +# Verify that generated code is up-to-date. +# +# Note that we run these checks regardless whether the input files have +# changed, because generated code can change in response to toolchain updates +# even if no files in the repository are modified. +name: Check generated code +on: + pull_request: + branches: + - main + +permissions: + contents: read + +jobs: + check-mocks: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.18' + + - uses: actions/checkout@v3 + + - name: "Check generated mocks" + run: | + set -euo pipefail + + readonly MOCKERY=2.30.18 # N.B. no leading "v" + curl -sL "https://github.com/vektra/mockery/releases/download/v${MOCKERY}/mockery_${MOCKERY}_Linux_x86_64.tar.gz" | tar -C /usr/local/bin -xzf - + make mockery 2>/dev/null + + if ! git diff --stat --exit-code ; then + echo ">> ERROR:" + echo ">>" + echo ">> Generated mocks require update (either Mockery or source files may have changed)." + echo ">> Ensure your tools are up-to-date, re-run 'make mockery' and update this PR." + echo ">>" + exit 1 + fi + + check-proto: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.18' + + - uses: actions/checkout@v3 + with: + fetch-depth: 1 # we need a .git directory to run git diff + + - name: "Check protobuf generated code" + run: | + set -euo pipefail + + # Install buf and gogo tools, so that differences that arise from + # toolchain differences are also caught. + readonly tools="$(mktemp -d)" + export PATH="${PATH}:${tools}/bin" + export GOBIN="${tools}/bin" + + go install github.com/bufbuild/buf/cmd/buf + go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest + + make proto-gen + + if ! git diff --stat --exit-code ; then + echo ">> ERROR:" + echo ">>" + echo ">> Protobuf generated code requires update (either tools or .proto files may have changed)." + echo ">> Ensure your tools are up-to-date, re-run 'make proto-gen' and update this PR." + echo ">>" + exit 1 + fi diff --git a/.github/workflows/proto-docker.yml b/.github/workflows/proto-docker.yml deleted file mode 100644 index 59b4a98ac..000000000 --- a/.github/workflows/proto-docker.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Build & Push OC Proto Builder -on: - pull_request: - paths: - - "tools/proto/*" - push: - branches: - - main - paths: - - "tools/proto/*" - schedule: - # run this job once a month to recieve any go or buf updates - - cron: "* * 1 * *" - -jobs: - build-proto: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Prepare - id: prep - run: | - DOCKER_IMAGE=ostracondev/docker-build-proto - VERSION=noop - if [[ $GITHUB_REF == refs/tags/* ]]; then - VERSION=${GITHUB_REF#refs/tags/} - elif [[ $GITHUB_REF == refs/heads/* ]]; then - VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g') - DEFAULT_BRANCH=$(curl -s -H "Accept: application/vnd.github.v3+json" \ - https://api.github.com/repos/Finschia/ostracon | \ - grep default_branch | \ - cut -d"\"" -f4) - if [ "$DEFAULT_BRANCH" = "$VERSION" ]; then - VERSION=latest - fi - fi - TAGS="${DOCKER_IMAGE}:${VERSION}" - if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then - TAGS="$TAGS,${DOCKER_IMAGE}:${VERSION%.*}" - fi - echo "tags=${TAGS}" >> $GITHUB_OUTPUT - -# - name: Set up Docker Buildx -# uses: docker/setup-buildx-action@v1.3.0 - -# - name: Login to DockerHub -# uses: docker/login-action@v1 -# with: -# username: ${{ secrets.DOCKERHUB_USERNAME }} -# password: ${{ secrets.DOCKERHUB_TOKEN }} - -# - name: Publish to Docker Hub -# uses: docker/build-push-action@v2.4.0 -# with: -# context: ./tools/proto -# file: ./tools/proto/Dockerfile -# push: ${{ github.event_name != 'pull_request' }} -# tags: ${{ steps.prep.outputs.tags }} diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml new file mode 100644 index 000000000..bab9227fc --- /dev/null +++ b/.github/workflows/proto-lint.yml @@ -0,0 +1,19 @@ +name: Protobuf Lint +on: + pull_request: + paths: + - 'proto/**' + push: + paths: + - 'proto/**' + +jobs: + lint: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v3 + - uses: bufbuild/buf-setup-action@v1.5.0 + - uses: bufbuild/buf-lint-action@v1 + with: + input: 'proto' diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml deleted file mode 100644 index f2bcb4c08..000000000 --- a/.github/workflows/proto.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Protobuf -# Protobuf runs buf (https://buf.build/) lint and check-breakage -# This workflow is only run when a .proto file has been modified -on: - pull_request: - paths: - - "**.proto" -jobs: - proto-lint: - runs-on: ubuntu-latest - timeout-minutes: 4 - steps: - - uses: actions/checkout@v3 - - name: lint - run: make proto-lint -# proto-breakage: -# runs-on: ubuntu-latest -# timeout-minutes: 4 -# steps: -# - uses: actions/checkout@v3 -# - name: check-breakage -# run: make proto-check-breaking-ci diff --git a/Makefile b/Makefile index b4ddd1255..1ac98032b 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ VERSION := $(shell git describe --always) LD_FLAGS = -X github.com/Finschia/ostracon/version.OCCoreSemVer=$(VERSION) BUILD_FLAGS = -mod=readonly -ldflags "$(LD_FLAGS)" HTTPS_GIT := https://github.com/Finschia/ostracon.git -DOCKER_BUF := docker run -v $(shell pwd):/workspace --workdir /workspace bufbuild/buf CGO_ENABLED ?= 0 TARGET_OS ?= $(shell go env GOOS) TARGET_ARCH ?= $(shell go env GOARCH) @@ -77,42 +76,48 @@ mockery: ### Protobuf ### ############################################################################### -containerProtoVer=v0.2 -containerProtoImage=tendermintdev/sdk-proto-gen:$(containerProtoVer) - -### -# https://github.com/protocolbuffers/protobuf -# https://developers.google.com/protocol-buffers/docs/gotutorial -# Should install -### go install -# go install google.golang.org/protobuf/cmd/protoc-gen-go -### Docker for Protocol Buffer -# https://hub.docker.com/r/bufbuild/buf +check-proto-deps: +ifeq (,$(shell which protoc-gen-gogofaster)) + @go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest +endif +.PHONY: check-proto-deps -proto-all: proto-gen proto-lint proto-check-breaking -.PHONY: proto-all +check-proto-format-deps: +ifeq (,$(shell which clang-format)) + $(error "clang-format is required for Protobuf formatting. See instructions for your platform on how to install it.") +endif +.PHONY: check-proto-format-deps -proto-gen: - @docker pull -q tendermintdev/docker-build-proto +proto-gen: check-proto-deps @echo "Generating Protobuf files" - @docker run --rm -v $(shell pwd):/workspace --workdir /workspace $(containerProtoImage) sh ./scripts/protocgen.sh + @go run github.com/bufbuild/buf/cmd/buf generate + @mv ./proto/ostracon/abci/types.pb.go ./abci/types/ + @mv ./proto/ostracon/rpc/grpc/types.pb.go ./rpc/grpc/ + @rm -rf ./proto/tendermint .PHONY: proto-gen -proto-lint: - @$(DOCKER_BUF) lint --error-format=json +# These targets are provided for convenience and are intended for local +# execution only. +proto-lint: check-proto-deps + @echo "Linting Protobuf files" + @go run github.com/bufbuild/buf/cmd/buf lint .PHONY: proto-lint -proto-format: +proto-format: check-proto-format-deps @echo "Formatting Protobuf files" - docker run --rm -v $(shell pwd):/workspace --workdir /workspace tendermintdev/docker-build-proto find ./ -not -path "./third_party/*" -name *.proto -exec clang-format -i {} \; + @find . -name '*.proto' -path "./proto/*" -exec clang-format -i {} \; .PHONY: proto-format -proto-check-breaking: - @$(DOCKER_BUF) breaking --against .git#branch=main +proto-check-breaking: check-proto-deps + @echo "Checking for breaking changes in Protobuf files against local branch" + @echo "Note: This is only useful if your changes have not yet been committed." + @echo " Otherwise read up on buf's \"breaking\" command usage:" + @echo " https://docs.buf.build/breaking/usage" + @go run github.com/bufbuild/buf/cmd/buf breaking --against ".git" .PHONY: proto-check-breaking proto-check-breaking-ci: - @$(DOCKER_BUF) breaking --against $(HTTPS_GIT)#branch=main + @go run github.com/bufbuild/buf/cmd/buf breaking --against ".git"#branch=main .PHONY: proto-check-breaking-ci ############################################################################### diff --git a/abci/client/grpc_client.go b/abci/client/grpc_client.go index fca631967..d6f760196 100644 --- a/abci/client/grpc_client.go +++ b/abci/client/grpc_client.go @@ -310,6 +310,7 @@ func (cli *grpcClient) finishAsyncCall(req *ocabci.Request, res *ocabci.Response } // ---------------------------------------- + func (cli *grpcClient) FlushSync() (*types.ResponseFlush, error) { reqres := cli.FlushAsync(nil) reqres.Wait() diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go index 80b379c0e..67094538c 100644 --- a/abci/client/mocks/client.go +++ b/abci/client/mocks/client.go @@ -891,13 +891,12 @@ func (_m *Client) String() string { return r0 } -type mockConstructorTestingTNewClient interface { +// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClient(t interface { mock.TestingT Cleanup(func()) -} - -// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewClient(t mockConstructorTestingTNewClient) *Client { +}) *Client { mock := &Client{} mock.Mock.Test(t) diff --git a/abci/types/mocks/application.go b/abci/types/mocks/application.go index 155f44eef..462f8ac95 100644 --- a/abci/types/mocks/application.go +++ b/abci/types/mocks/application.go @@ -229,13 +229,12 @@ func (_m *Application) SetOption(_a0 types.RequestSetOption) types.ResponseSetOp return r0 } -type mockConstructorTestingTNewApplication interface { +// NewApplication creates a new instance of Application. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewApplication(t interface { mock.TestingT Cleanup(func()) -} - -// NewApplication creates a new instance of Application. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewApplication(t mockConstructorTestingTNewApplication) *Application { +}) *Application { mock := &Application{} mock.Mock.Test(t) diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index d6fd799b9..e0b28e831 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -9,9 +9,7 @@ import ( types2 "github.com/Finschia/ostracon/proto/ostracon/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" - _ "github.com/gogo/protobuf/types" types "github.com/tendermint/tendermint/abci/types" - _ "github.com/tendermint/tendermint/proto/tendermint/crypto" types1 "github.com/tendermint/tendermint/proto/tendermint/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -998,99 +996,95 @@ func init() { func init() { proto.RegisterFile("ostracon/abci/types.proto", fileDescriptor_addf585b2317eb36) } var fileDescriptor_addf585b2317eb36 = []byte{ - // 1457 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x4b, 0x8f, 0xdb, 0x54, - 0x14, 0xc7, 0x33, 0x4d, 0x26, 0x19, 0x9f, 0xc9, 0xa4, 0xd3, 0xd3, 0xa1, 0xb8, 0x66, 0x9a, 0x29, - 0x29, 0x85, 0x52, 0xca, 0x44, 0x9a, 0x8a, 0xaa, 0x08, 0x24, 0x68, 0xc2, 0x8c, 0x32, 0x50, 0x11, - 0xf5, 0x16, 0x81, 0xc4, 0xa3, 0x91, 0x63, 0xdf, 0x24, 0x66, 0x1c, 0x5f, 0xd7, 0xbe, 0x19, 0x1a, - 0xf6, 0xec, 0xf9, 0x26, 0x2c, 0xd9, 0xb1, 0xee, 0xb2, 0x4b, 0x16, 0xa8, 0x42, 0xed, 0x06, 0xf8, - 0x14, 0xe8, 0x5e, 0x3f, 0xea, 0x3c, 0x1c, 0x7b, 0x76, 0xf7, 0x71, 0xce, 0xdf, 0xf7, 0x5c, 0x1f, - 0x9f, 0x5f, 0x4e, 0xe0, 0x32, 0xf3, 0xb9, 0xa7, 0x1b, 0xcc, 0x69, 0xea, 0x7d, 0xc3, 0x6a, 0xf2, - 0xa9, 0x4b, 0xfd, 0x7d, 0xd7, 0x63, 0x9c, 0xe1, 0x56, 0xb4, 0xb5, 0x2f, 0xb6, 0xb4, 0x2b, 0x9c, - 0x3a, 0x26, 0xf5, 0xc6, 0x96, 0xc3, 0x9b, 0x86, 0x37, 0x75, 0x39, 0x6b, 0xba, 0x1e, 0x63, 0x83, - 0xc0, 0x7a, 0x66, 0x5b, 0xaa, 0x34, 0x5d, 0xdd, 0xd3, 0xc7, 0xa1, 0x98, 0xf6, 0x46, 0x62, 0x7b, - 0xfe, 0x49, 0xda, 0xee, 0x82, 0x6f, 0x72, 0x57, 0x8b, 0x8f, 0xb8, 0xb8, 0xb7, 0xbb, 0x78, 0xa8, - 0x13, 0x3a, 0x8d, 0x76, 0xf7, 0x86, 0x8c, 0x0d, 0x6d, 0xda, 0x94, 0xb3, 0xfe, 0x64, 0xd0, 0xe4, - 0xd6, 0x98, 0xfa, 0x5c, 0x1f, 0xbb, 0xa1, 0xc1, 0xce, 0x90, 0x0d, 0x99, 0x1c, 0x36, 0xc5, 0x28, - 0x58, 0x6d, 0xfc, 0xa6, 0x40, 0x85, 0xd0, 0xc7, 0x13, 0xea, 0x73, 0x3c, 0x80, 0x12, 0x35, 0x46, - 0x4c, 0x5d, 0xbb, 0xba, 0x76, 0x63, 0xf3, 0x60, 0x77, 0xff, 0xd5, 0xf3, 0xe4, 0xad, 0xec, 0x87, - 0x76, 0x87, 0xc6, 0x88, 0x75, 0x0a, 0x44, 0xda, 0xe2, 0x07, 0xb0, 0x3e, 0xb0, 0x27, 0xfe, 0x48, - 0x3d, 0x27, 0x9d, 0xae, 0xa4, 0x39, 0x1d, 0x09, 0xa3, 0x4e, 0x81, 0x04, 0xd6, 0xe2, 0x51, 0x96, - 0x33, 0x60, 0x6a, 0x71, 0xf5, 0xa3, 0x8e, 0x9d, 0x81, 0x7c, 0x94, 0xb0, 0xc5, 0x16, 0x80, 0x4f, - 0x79, 0x8f, 0xb9, 0xdc, 0x62, 0x8e, 0x5a, 0x92, 0x9e, 0x6f, 0xa6, 0x79, 0x3e, 0xa4, 0xbc, 0x2b, - 0x0d, 0x3b, 0x05, 0xa2, 0xf8, 0xd1, 0x44, 0x68, 0x58, 0x8e, 0xc5, 0x7b, 0xc6, 0x48, 0xb7, 0x1c, - 0x75, 0x7d, 0xb5, 0xc6, 0xb1, 0x63, 0xf1, 0xb6, 0x30, 0x14, 0x1a, 0x56, 0x34, 0x11, 0x21, 0x3f, - 0x9e, 0x50, 0x6f, 0xaa, 0x96, 0x57, 0x87, 0xfc, 0x40, 0x18, 0x89, 0x90, 0xa5, 0x35, 0xb6, 0x61, - 0xb3, 0x4f, 0x87, 0x96, 0xd3, 0xeb, 0xdb, 0xcc, 0x38, 0x51, 0x2b, 0xd2, 0xf9, 0xea, 0xfe, 0x4c, - 0xe2, 0x45, 0xae, 0x2d, 0x61, 0xd8, 0x12, 0x76, 0x9d, 0x02, 0x81, 0x7e, 0x3c, 0xc3, 0x8f, 0x61, - 0xc3, 0x18, 0x51, 0xe3, 0xa4, 0xc7, 0x9f, 0xa8, 0x1b, 0x52, 0x61, 0x2f, 0xed, 0xf1, 0x6d, 0x61, - 0xf7, 0xd5, 0x93, 0x4e, 0x81, 0x54, 0x8c, 0x60, 0x28, 0xa2, 0x37, 0xa9, 0x6d, 0x9d, 0x52, 0x4f, - 0xf8, 0x2b, 0xab, 0xa3, 0xff, 0x2c, 0xb0, 0x94, 0x0a, 0x8a, 0x19, 0x4d, 0xf0, 0x13, 0x50, 0xa8, - 0x63, 0x86, 0x41, 0x40, 0x18, 0x44, 0x5a, 0xa6, 0x38, 0x66, 0x14, 0xc4, 0x06, 0x0d, 0xc7, 0x78, - 0x17, 0xca, 0x06, 0x1b, 0x8f, 0x2d, 0xae, 0x6e, 0x4a, 0xef, 0x7a, 0x6a, 0x00, 0xd2, 0xaa, 0x53, - 0x20, 0xa1, 0x3d, 0x7e, 0x09, 0x35, 0xdb, 0xf2, 0x79, 0xcf, 0x77, 0x74, 0xd7, 0x1f, 0x31, 0xee, - 0xab, 0x55, 0xa9, 0x70, 0x3d, 0x4d, 0xe1, 0xbe, 0xe5, 0xf3, 0x87, 0x91, 0x71, 0xa7, 0x40, 0xb6, - 0xec, 0xe4, 0x82, 0xd0, 0x63, 0x83, 0x01, 0xf5, 0x62, 0x41, 0x75, 0x6b, 0xb5, 0x5e, 0x57, 0x58, - 0x47, 0xfe, 0x42, 0x8f, 0x25, 0x17, 0xf0, 0x3b, 0xb8, 0x68, 0x33, 0xdd, 0x8c, 0xe5, 0x7a, 0xc6, - 0x68, 0xe2, 0x9c, 0xa8, 0x35, 0x29, 0xfa, 0x6e, 0xea, 0x21, 0x99, 0x6e, 0x46, 0x12, 0x6d, 0xe1, - 0xd0, 0x29, 0x90, 0x0b, 0xf6, 0xfc, 0x22, 0x3e, 0x82, 0x1d, 0xdd, 0x75, 0xed, 0xe9, 0xbc, 0xfa, - 0x79, 0xa9, 0x7e, 0x33, 0x4d, 0xfd, 0x9e, 0xf0, 0x99, 0x97, 0x47, 0x7d, 0x61, 0x15, 0x1f, 0xc0, - 0x76, 0x90, 0x9e, 0x1e, 0x8d, 0x33, 0xec, 0x9f, 0x20, 0x49, 0xdf, 0x5a, 0x91, 0xa4, 0x84, 0x1a, - 0x71, 0x9e, 0xd5, 0xfa, 0x33, 0x2b, 0xf8, 0x05, 0xd4, 0x44, 0xaa, 0x24, 0x04, 0xff, 0x0d, 0x04, - 0x1b, 0xcb, 0x05, 0x0f, 0x1d, 0x33, 0x29, 0x57, 0xa5, 0x89, 0x79, 0xab, 0x02, 0xeb, 0xa7, 0xba, - 0x3d, 0xa1, 0x8d, 0x3f, 0xce, 0xc1, 0x85, 0x85, 0xcf, 0x04, 0x11, 0x4a, 0x23, 0xdd, 0x1f, 0xc9, - 0xda, 0x55, 0x25, 0x72, 0x8c, 0x77, 0xa0, 0x3c, 0xa2, 0xba, 0x49, 0xbd, 0xb0, 0x38, 0xa9, 0xc9, - 0x4b, 0x0a, 0x2a, 0x6b, 0x47, 0xee, 0xb7, 0x4a, 0x4f, 0x9f, 0xef, 0x15, 0x48, 0x68, 0x8d, 0x5d, - 0xd8, 0xb6, 0x75, 0x9f, 0xf7, 0x82, 0xb4, 0xeb, 0x25, 0x0a, 0xd5, 0xe2, 0xc7, 0x76, 0x5f, 0x8f, - 0x12, 0x55, 0xd4, 0xaa, 0x50, 0xa8, 0x66, 0xcf, 0xac, 0x22, 0x81, 0x9d, 0xfe, 0xf4, 0x67, 0xdd, - 0xe1, 0x96, 0x43, 0x7b, 0xa7, 0xba, 0x6d, 0x99, 0x3a, 0x67, 0x9e, 0xaf, 0x96, 0xae, 0x16, 0x6f, - 0x6c, 0x1e, 0x5c, 0x5e, 0x10, 0x3d, 0x3c, 0xb5, 0x4c, 0xea, 0x18, 0x34, 0x94, 0xbb, 0x18, 0x3b, - 0x7f, 0x1d, 0xfb, 0xe2, 0x5d, 0xa8, 0x50, 0x87, 0x7b, 0xcc, 0x9d, 0x46, 0xaf, 0xe9, 0xf5, 0x57, - 0xb7, 0x1a, 0x04, 0x77, 0x18, 0xec, 0x87, 0x2a, 0x91, 0x79, 0xa3, 0x0b, 0xaf, 0x2d, 0x7d, 0x83, - 0x89, 0xfb, 0x5a, 0x3b, 0xcb, 0x7d, 0x35, 0xde, 0x87, 0x8b, 0x4b, 0xde, 0x20, 0x5e, 0x12, 0x72, - 0xd6, 0x70, 0xc4, 0xa5, 0x5c, 0x91, 0x84, 0xb3, 0xc6, 0x2f, 0x00, 0x1b, 0x84, 0xfa, 0x2e, 0x73, - 0x7c, 0x8a, 0x2d, 0x50, 0xe8, 0x13, 0x83, 0x06, 0x35, 0x7d, 0x2d, 0xcc, 0x8e, 0xc5, 0x5c, 0x0e, - 0xac, 0x0f, 0x23, 0x4b, 0x51, 0x92, 0x62, 0x37, 0xbc, 0x1d, 0x72, 0x2b, 0x1d, 0x41, 0xa1, 0x7b, - 0x12, 0x5c, 0x77, 0x22, 0x70, 0x15, 0x53, 0xab, 0x50, 0xe0, 0x35, 0x47, 0xae, 0xdb, 0x21, 0xb9, - 0x4a, 0x19, 0x0f, 0x9b, 0x41, 0x57, 0x7b, 0x06, 0x5d, 0xeb, 0x19, 0x61, 0xa6, 0xb0, 0xab, 0x3d, - 0xc3, 0xae, 0x72, 0x86, 0x48, 0x0a, 0xbc, 0xee, 0x44, 0xf0, 0xaa, 0x64, 0x84, 0x3d, 0x47, 0xaf, - 0xa3, 0x59, 0x7a, 0x05, 0xec, 0xb9, 0x96, 0xea, 0x9d, 0x0a, 0xb0, 0x8f, 0x12, 0x00, 0x53, 0xc2, - 0x23, 0xcc, 0x17, 0x83, 0x40, 0x62, 0x09, 0xbf, 0xda, 0x33, 0xfc, 0x82, 0x8c, 0x1b, 0x48, 0x01, - 0xd8, 0xa7, 0x49, 0x80, 0x6d, 0xa6, 0x32, 0x30, 0x4c, 0x99, 0x65, 0x04, 0xfb, 0x30, 0x26, 0x58, - 0x35, 0x15, 0xc1, 0x61, 0x0c, 0xf3, 0x08, 0xeb, 0x2e, 0x20, 0x2c, 0x40, 0xce, 0xdb, 0xa9, 0x12, - 0x19, 0x0c, 0xeb, 0x2e, 0x30, 0xac, 0x96, 0x21, 0x98, 0x01, 0xb1, 0xef, 0x97, 0x43, 0x2c, 0x1d, - 0x33, 0xe1, 0x31, 0xf3, 0x51, 0xac, 0x97, 0x42, 0xb1, 0x6d, 0x29, 0xff, 0x5e, 0xaa, 0x7c, 0x6e, - 0x8c, 0x91, 0x74, 0x8c, 0x5d, 0x4f, 0x49, 0xb4, 0x4c, 0x8e, 0xdd, 0x4f, 0xe3, 0xd8, 0xb5, 0x14, - 0xc5, 0x7c, 0x20, 0xfb, 0xeb, 0x1c, 0x9c, 0x9f, 0x4b, 0x76, 0x81, 0x31, 0x83, 0x99, 0x54, 0x56, - 0xc2, 0x2d, 0x22, 0xc7, 0x62, 0xcd, 0xd4, 0xb9, 0x2e, 0xcb, 0x5b, 0x95, 0xc8, 0x31, 0x6e, 0x43, - 0xd1, 0x66, 0x43, 0x59, 0xbb, 0x14, 0x22, 0x86, 0xc2, 0x2a, 0xae, 0x4b, 0x4a, 0x58, 0x76, 0xea, - 0x00, 0x43, 0xdd, 0xef, 0xfd, 0xa4, 0x3b, 0x9c, 0x9a, 0xb2, 0xec, 0x14, 0x49, 0x62, 0x05, 0x35, - 0xd8, 0x10, 0xb3, 0x89, 0x4f, 0x4d, 0x59, 0x4f, 0x8a, 0x24, 0x9e, 0x63, 0x07, 0xca, 0xf4, 0x94, - 0x3a, 0xdc, 0x57, 0x2b, 0x92, 0x52, 0x97, 0x96, 0x50, 0x8a, 0x3a, 0xbc, 0xa5, 0x0a, 0x14, 0xfc, - 0xf7, 0x7c, 0x6f, 0x3b, 0xb0, 0xbe, 0xc5, 0xc6, 0x16, 0xa7, 0x63, 0x97, 0x4f, 0x49, 0xe8, 0x8f, - 0xbb, 0xa0, 0x88, 0x38, 0x7c, 0x57, 0x37, 0xa8, 0x2c, 0x1c, 0x0a, 0x79, 0xb5, 0x20, 0x28, 0xe1, - 0x4b, 0x61, 0x59, 0x0e, 0x14, 0x12, 0xce, 0xc4, 0xd9, 0x5c, 0xcf, 0x62, 0x9e, 0xc5, 0xa7, 0xf2, - 0x4b, 0x2f, 0x92, 0x78, 0x8e, 0xd7, 0x60, 0x6b, 0x4c, 0xc7, 0x2e, 0x63, 0x76, 0x8f, 0x7a, 0x1e, - 0xf3, 0xe4, 0x67, 0xac, 0x90, 0x6a, 0xb8, 0x78, 0x28, 0xd6, 0x1a, 0xb7, 0xe0, 0xd2, 0xf2, 0x37, - 0xbc, 0xec, 0x92, 0x1b, 0x37, 0x61, 0x67, 0xd9, 0xdb, 0x5b, 0x66, 0x7b, 0xf0, 0xfb, 0x26, 0x9c, - 0xbf, 0xd7, 0x6a, 0x1f, 0x8b, 0xa4, 0xb4, 0x0c, 0x3d, 0x2c, 0xce, 0x25, 0x81, 0x17, 0x5c, 0xd9, - 0x35, 0x69, 0xab, 0xd9, 0x84, 0x47, 0xb0, 0x2e, 0x69, 0x83, 0xab, 0xdb, 0x28, 0x2d, 0x03, 0x56, - 0xe2, 0x30, 0xf2, 0x77, 0xc7, 0xca, 0xbe, 0x4a, 0x5b, 0xcd, 0x2e, 0x24, 0xa0, 0xc4, 0x20, 0xc2, - 0xec, 0x3e, 0x4b, 0xcb, 0xc1, 0x33, 0xa1, 0x19, 0x57, 0x65, 0xcc, 0xee, 0x3c, 0xb4, 0x1c, 0xc5, - 0x1d, 0x3f, 0x87, 0x4a, 0xf4, 0xf5, 0x64, 0xf5, 0x42, 0x5a, 0x06, 0x6b, 0xc4, 0x0b, 0x90, 0xdc, - 0xc3, 0xd5, 0x4d, 0x9d, 0x96, 0x81, 0x4d, 0x3c, 0x86, 0x72, 0x50, 0xfa, 0x31, 0xa3, 0xbb, 0xd1, - 0xb2, 0xd8, 0x21, 0xae, 0x2c, 0x46, 0x39, 0x66, 0xb7, 0xaa, 0x5a, 0x8e, 0x5f, 0x04, 0xf8, 0x10, - 0x20, 0xf1, 0xd3, 0x39, 0xb3, 0x07, 0xd5, 0xf2, 0x70, 0x1e, 0xbb, 0xb0, 0x11, 0xd1, 0x12, 0x33, - 0x3b, 0x42, 0x2d, 0x1b, 0xb9, 0xf8, 0x08, 0xb6, 0x66, 0xe0, 0x87, 0xf9, 0xfa, 0x3c, 0x2d, 0x27, - 0x4b, 0x85, 0xfe, 0x0c, 0x0b, 0x31, 0x5f, 0xdf, 0xa7, 0xe5, 0x44, 0x2b, 0xfe, 0x08, 0x17, 0x16, - 0xa8, 0x88, 0xf9, 0xdb, 0x40, 0xed, 0x0c, 0xb0, 0xc5, 0x31, 0xe0, 0x22, 0x22, 0xf1, 0x0c, 0x5d, - 0xa1, 0x76, 0x16, 0xf6, 0xe2, 0x0f, 0x50, 0x9b, 0xab, 0xa9, 0xb9, 0x7a, 0x44, 0x2d, 0x1f, 0x82, - 0xf1, 0x1b, 0xa8, 0xce, 0x14, 0xe1, 0x1c, 0xfd, 0xa2, 0x96, 0x87, 0xc5, 0xad, 0x7b, 0x4f, 0x5f, - 0xd4, 0xd7, 0x9e, 0xbd, 0xa8, 0xaf, 0xfd, 0xfd, 0xa2, 0xbe, 0xf6, 0xeb, 0xcb, 0x7a, 0xe1, 0xd9, - 0xcb, 0x7a, 0xe1, 0xcf, 0x97, 0xf5, 0xc2, 0xb7, 0xef, 0x0c, 0x2d, 0x3e, 0x9a, 0xf4, 0xf7, 0x0d, - 0x36, 0x6e, 0x1e, 0x59, 0x8e, 0x6f, 0x8c, 0x2c, 0xbd, 0xb9, 0xe4, 0xff, 0xc2, 0x7e, 0x59, 0xfe, - 0x6f, 0x76, 0xfb, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x38, 0x72, 0x1d, 0x52, 0x4d, 0x14, 0x00, - 0x00, + // 1407 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x98, 0x5d, 0x8f, 0xdb, 0x44, + 0x17, 0xc7, 0xb3, 0x4d, 0x36, 0x59, 0x9f, 0xcd, 0xa6, 0xdb, 0xd3, 0x7d, 0xfa, 0xb8, 0xa6, 0xa4, + 0x25, 0xa5, 0x50, 0x4a, 0xd9, 0x95, 0xb6, 0xa2, 0x2a, 0x02, 0x09, 0x9a, 0xb0, 0xab, 0x2c, 0x54, + 0x44, 0x9d, 0x22, 0x90, 0x78, 0x69, 0xe4, 0xd8, 0xb3, 0xb1, 0xa9, 0xe3, 0x49, 0xed, 0xc9, 0xd2, + 0x70, 0xcf, 0x3d, 0xdf, 0x84, 0x4b, 0xee, 0xb8, 0xee, 0x65, 0x2f, 0xb9, 0x40, 0x15, 0x6a, 0x6f, + 0x80, 0x4f, 0x81, 0x66, 0xfc, 0x52, 0xe7, 0x65, 0x62, 0xef, 0xdd, 0xcc, 0xf8, 0x9c, 0xff, 0xf8, + 0xcc, 0x1c, 0x9f, 0x5f, 0x4e, 0xe0, 0x22, 0x0b, 0x79, 0x60, 0x5a, 0xcc, 0xdf, 0x33, 0x07, 0x96, + 0xbb, 0xc7, 0xa7, 0x63, 0x1a, 0xee, 0x8e, 0x03, 0xc6, 0x19, 0x6e, 0x25, 0x8f, 0x76, 0xc5, 0x23, + 0xe3, 0x35, 0x4e, 0x7d, 0x9b, 0x06, 0x23, 0xd7, 0xe7, 0x0b, 0xb6, 0xc6, 0xa5, 0xcc, 0x43, 0xb9, + 0x3e, 0xf3, 0xd4, 0x48, 0x37, 0x59, 0x7c, 0xb6, 0x33, 0x64, 0x43, 0x26, 0x87, 0x7b, 0x62, 0x14, + 0xad, 0xb6, 0x7e, 0xd5, 0xa0, 0x46, 0xe8, 0xe3, 0x09, 0x0d, 0x39, 0xee, 0x43, 0x85, 0x5a, 0x0e, + 0xd3, 0xd7, 0xae, 0xac, 0x5d, 0xdf, 0xdc, 0xbf, 0xb4, 0xfb, 0x6a, 0x2b, 0xf9, 0x62, 0xbb, 0xb1, + 0xdd, 0x81, 0xe5, 0xb0, 0x6e, 0x89, 0x48, 0x5b, 0x7c, 0x1f, 0xd6, 0x8f, 0xbd, 0x49, 0xe8, 0xe8, + 0x67, 0xa4, 0xd3, 0xeb, 0x2a, 0xa7, 0x43, 0x61, 0xd4, 0x2d, 0x91, 0xc8, 0x5a, 0x6c, 0xe5, 0xfa, + 0xc7, 0x4c, 0x2f, 0xaf, 0xde, 0xea, 0xc8, 0x3f, 0x96, 0x5b, 0x09, 0x5b, 0x6c, 0x03, 0x84, 0x94, + 0xf7, 0xd9, 0x98, 0xbb, 0xcc, 0xd7, 0x2b, 0xd2, 0xf3, 0x0d, 0x95, 0xe7, 0x03, 0xca, 0x7b, 0xd2, + 0xb0, 0x5b, 0x22, 0x5a, 0x98, 0x4c, 0x84, 0x86, 0xeb, 0xbb, 0xbc, 0x6f, 0x39, 0xa6, 0xeb, 0xeb, + 0xeb, 0xab, 0x35, 0x8e, 0x7c, 0x97, 0x77, 0x84, 0xa1, 0xd0, 0x70, 0x93, 0x89, 0x08, 0xf9, 0xf1, + 0x84, 0x06, 0x53, 0xbd, 0xba, 0x3a, 0xe4, 0xfb, 0xc2, 0x48, 0x84, 0x2c, 0xad, 0xb1, 0x03, 0x9b, + 0x03, 0x3a, 0x74, 0xfd, 0xfe, 0xc0, 0x63, 0xd6, 0x23, 0xbd, 0x26, 0x9d, 0xaf, 0xec, 0xce, 0xdc, + 0x7d, 0xe2, 0xda, 0x16, 0x86, 0x6d, 0x61, 0xd7, 0x2d, 0x11, 0x18, 0xa4, 0x33, 0xfc, 0x08, 0x36, + 0x2c, 0x87, 0x5a, 0x8f, 0xfa, 0xfc, 0x89, 0xbe, 0x21, 0x15, 0x2e, 0xab, 0xb6, 0xef, 0x08, 0xbb, + 0x2f, 0x9f, 0x74, 0x4b, 0xa4, 0x66, 0x45, 0x43, 0x11, 0xbd, 0x4d, 0x3d, 0xf7, 0x84, 0x06, 0xc2, + 0x5f, 0x5b, 0x1d, 0xfd, 0xa7, 0x91, 0xa5, 0x54, 0xd0, 0xec, 0x64, 0x82, 0x1f, 0x83, 0x46, 0x7d, + 0x3b, 0x0e, 0x02, 0xe2, 0x20, 0x54, 0x99, 0xe2, 0xdb, 0x49, 0x10, 0x1b, 0x34, 0x1e, 0xe3, 0x1d, + 0xa8, 0x5a, 0x6c, 0x34, 0x72, 0xb9, 0xbe, 0x29, 0xbd, 0x9b, 0xca, 0x00, 0xa4, 0x55, 0xb7, 0x44, + 0x62, 0x7b, 0xfc, 0x02, 0x1a, 0x9e, 0x1b, 0xf2, 0x7e, 0xe8, 0x9b, 0xe3, 0xd0, 0x61, 0x3c, 0xd4, + 0xeb, 0x52, 0xe1, 0x9a, 0x4a, 0xe1, 0x9e, 0x1b, 0xf2, 0x07, 0x89, 0x71, 0xb7, 0x44, 0xb6, 0xbc, + 0xec, 0x82, 0xd0, 0x63, 0xc7, 0xc7, 0x34, 0x48, 0x05, 0xf5, 0xad, 0xd5, 0x7a, 0x3d, 0x61, 0x9d, + 0xf8, 0x0b, 0x3d, 0x96, 0x5d, 0xc0, 0x6f, 0xe1, 0xbc, 0xc7, 0x4c, 0x3b, 0x95, 0xeb, 0x5b, 0xce, + 0xc4, 0x7f, 0xa4, 0x37, 0xa4, 0xe8, 0x3b, 0xca, 0x97, 0x64, 0xa6, 0x9d, 0x48, 0x74, 0x84, 0x43, + 0xb7, 0x44, 0xce, 0x79, 0xf3, 0x8b, 0xf8, 0x10, 0x76, 0xcc, 0xf1, 0xd8, 0x9b, 0xce, 0xab, 0x9f, + 0x95, 0xea, 0x37, 0x54, 0xea, 0x77, 0x85, 0xcf, 0xbc, 0x3c, 0x9a, 0x0b, 0xab, 0x78, 0x1f, 0xb6, + 0xa3, 0xf4, 0x0c, 0x68, 0x9a, 0x61, 0x7f, 0x47, 0x49, 0xfa, 0xe6, 0x8a, 0x24, 0x25, 0xd4, 0x4a, + 0xf3, 0xac, 0x31, 0x98, 0x59, 0xc1, 0xcf, 0xa1, 0x21, 0x52, 0x25, 0x23, 0xf8, 0x4f, 0x24, 0xd8, + 0x5a, 0x2e, 0x78, 0xe0, 0xdb, 0x59, 0xb9, 0x3a, 0xcd, 0xcc, 0xdb, 0x35, 0x58, 0x3f, 0x31, 0xbd, + 0x09, 0x6d, 0xfd, 0x7e, 0x06, 0xce, 0x2d, 0x7c, 0x26, 0x88, 0x50, 0x71, 0xcc, 0xd0, 0x91, 0xb5, + 0xab, 0x4e, 0xe4, 0x18, 0x6f, 0x43, 0xd5, 0xa1, 0xa6, 0x4d, 0x83, 0xb8, 0x38, 0xe9, 0xd9, 0x43, + 0x8a, 0x4a, 0x63, 0x57, 0x3e, 0x6f, 0x57, 0x9e, 0x3e, 0xbf, 0x5c, 0x22, 0xb1, 0x35, 0xf6, 0x60, + 0xdb, 0x33, 0x43, 0xde, 0x8f, 0xd2, 0xae, 0x9f, 0x29, 0x54, 0x8b, 0x1f, 0xdb, 0x3d, 0x33, 0x49, + 0x54, 0x51, 0xab, 0x62, 0xa1, 0x86, 0x37, 0xb3, 0x8a, 0x04, 0x76, 0x06, 0xd3, 0x9f, 0x4c, 0x9f, + 0xbb, 0x3e, 0xed, 0x9f, 0x98, 0x9e, 0x6b, 0x9b, 0x9c, 0x05, 0xa1, 0x5e, 0xb9, 0x52, 0xbe, 0xbe, + 0xb9, 0x7f, 0x71, 0x41, 0xf4, 0xe0, 0xc4, 0xb5, 0xa9, 0x6f, 0xd1, 0x58, 0xee, 0x7c, 0xea, 0xfc, + 0x55, 0xea, 0x8b, 0x77, 0xa0, 0x46, 0x7d, 0x1e, 0xb0, 0xf1, 0x34, 0xb9, 0xa6, 0xff, 0xbf, 0x3a, + 0xd5, 0x28, 0xb8, 0x83, 0xe8, 0x79, 0xac, 0x92, 0x98, 0xb7, 0x7a, 0xf0, 0xbf, 0xa5, 0x37, 0x98, + 0x39, 0xaf, 0xb5, 0xd3, 0x9c, 0x57, 0xeb, 0x3d, 0x38, 0xbf, 0xe4, 0x06, 0xf1, 0x82, 0x90, 0x73, + 0x87, 0x0e, 0x97, 0x72, 0x65, 0x12, 0xcf, 0x5a, 0x3f, 0x03, 0x6c, 0x10, 0x1a, 0x8e, 0x99, 0x1f, + 0x52, 0x6c, 0x83, 0x46, 0x9f, 0x58, 0x34, 0xaa, 0xe9, 0x6b, 0x71, 0x76, 0x2c, 0xe6, 0x72, 0x64, + 0x7d, 0x90, 0x58, 0x8a, 0x92, 0x94, 0xba, 0xe1, 0xad, 0x98, 0x5b, 0x6a, 0x04, 0xc5, 0xee, 0x59, + 0x70, 0xdd, 0x4e, 0xc0, 0x55, 0x56, 0x56, 0xa1, 0xc8, 0x6b, 0x8e, 0x5c, 0xb7, 0x62, 0x72, 0x55, + 0x72, 0x36, 0x9b, 0x41, 0x57, 0x67, 0x06, 0x5d, 0xeb, 0x39, 0x61, 0x2a, 0xd8, 0xd5, 0x99, 0x61, + 0x57, 0x35, 0x47, 0x44, 0x01, 0xaf, 0xdb, 0x09, 0xbc, 0x6a, 0x39, 0x61, 0xcf, 0xd1, 0xeb, 0x70, + 0x96, 0x5e, 0x11, 0x7b, 0xae, 0x2a, 0xbd, 0x95, 0x00, 0xfb, 0x30, 0x03, 0x30, 0x2d, 0x7e, 0x85, + 0xf9, 0x62, 0x10, 0x49, 0x2c, 0xe1, 0x57, 0x67, 0x86, 0x5f, 0x90, 0x73, 0x02, 0x0a, 0x80, 0x7d, + 0x92, 0x05, 0xd8, 0xa6, 0x92, 0x81, 0x71, 0xca, 0x2c, 0x23, 0xd8, 0x07, 0x29, 0xc1, 0xea, 0x4a, + 0x04, 0xc7, 0x31, 0xcc, 0x23, 0xac, 0xb7, 0x80, 0xb0, 0x08, 0x39, 0x6f, 0x29, 0x25, 0x72, 0x18, + 0xd6, 0x5b, 0x60, 0x58, 0x23, 0x47, 0x30, 0x07, 0x62, 0xdf, 0x2d, 0x87, 0x98, 0x1a, 0x33, 0xf1, + 0x6b, 0x16, 0xa3, 0x58, 0x5f, 0x41, 0xb1, 0x6d, 0x29, 0xff, 0xae, 0x52, 0xbe, 0x30, 0xc6, 0x88, + 0x1a, 0x63, 0xd7, 0x14, 0x89, 0x96, 0xcb, 0xb1, 0x7b, 0x2a, 0x8e, 0x5d, 0x55, 0x28, 0x16, 0x03, + 0xd9, 0x9f, 0x67, 0xe0, 0xec, 0x5c, 0xb2, 0x0b, 0x8c, 0x59, 0xcc, 0xa6, 0xb2, 0x12, 0x6e, 0x11, + 0x39, 0x16, 0x6b, 0xb6, 0xc9, 0x4d, 0x59, 0xde, 0xea, 0x44, 0x8e, 0x71, 0x1b, 0xca, 0x1e, 0x1b, + 0xca, 0xda, 0xa5, 0x11, 0x31, 0x14, 0x56, 0x69, 0x5d, 0xd2, 0xe2, 0xb2, 0xd3, 0x04, 0x18, 0x9a, + 0x61, 0xff, 0x47, 0xd3, 0xe7, 0xd4, 0x96, 0x65, 0xa7, 0x4c, 0x32, 0x2b, 0x68, 0xc0, 0x86, 0x98, + 0x4d, 0x42, 0x6a, 0xcb, 0x7a, 0x52, 0x26, 0xe9, 0x1c, 0xbb, 0x50, 0xa5, 0x27, 0xd4, 0xe7, 0xa1, + 0x5e, 0x93, 0x94, 0xba, 0xb0, 0x84, 0x52, 0xd4, 0xe7, 0x6d, 0x5d, 0xa0, 0xe0, 0xdf, 0xe7, 0x97, + 0xb7, 0x23, 0xeb, 0x9b, 0x6c, 0xe4, 0x72, 0x3a, 0x1a, 0xf3, 0x29, 0x89, 0xfd, 0xf1, 0x12, 0x68, + 0x22, 0x8e, 0x70, 0x6c, 0x5a, 0x54, 0x16, 0x0e, 0x8d, 0xbc, 0x5a, 0x10, 0x94, 0x08, 0xa5, 0xb0, + 0x2c, 0x07, 0x1a, 0x89, 0x67, 0xe2, 0xdd, 0xc6, 0x81, 0xcb, 0x02, 0x97, 0x4f, 0xe5, 0x97, 0x5e, + 0x26, 0xe9, 0x1c, 0xaf, 0xc2, 0xd6, 0x88, 0x8e, 0xc6, 0x8c, 0x79, 0x7d, 0x1a, 0x04, 0x2c, 0x90, + 0x9f, 0xb1, 0x46, 0xea, 0xf1, 0xe2, 0x81, 0x58, 0x6b, 0xdd, 0x84, 0x0b, 0xcb, 0x6f, 0x78, 0xd9, + 0x21, 0xb7, 0x6e, 0xc0, 0xce, 0xb2, 0xdb, 0x5b, 0x66, 0xbb, 0xff, 0xdb, 0x26, 0x9c, 0xbd, 0xdb, + 0xee, 0x1c, 0x89, 0xa4, 0x74, 0x2d, 0x33, 0x2e, 0xce, 0x15, 0x81, 0x17, 0x5c, 0xd9, 0x35, 0x19, + 0xab, 0xd9, 0x84, 0x87, 0xb0, 0x2e, 0x69, 0x83, 0xab, 0xdb, 0x28, 0x23, 0x07, 0x56, 0xe2, 0x65, + 0xe4, 0xef, 0x8e, 0x95, 0x7d, 0x95, 0xb1, 0x9a, 0x5d, 0x48, 0x40, 0x4b, 0x41, 0x84, 0xf9, 0x7d, + 0x96, 0x51, 0x80, 0x67, 0x42, 0x33, 0xad, 0xca, 0x98, 0xdf, 0x79, 0x18, 0x05, 0x8a, 0x3b, 0x7e, + 0x06, 0xb5, 0xe4, 0xeb, 0xc9, 0xeb, 0x85, 0x8c, 0x1c, 0xd6, 0x88, 0x0b, 0x90, 0xdc, 0xc3, 0xd5, + 0x4d, 0x9d, 0x91, 0x83, 0x4d, 0x3c, 0x82, 0x6a, 0x54, 0xfa, 0x31, 0xa7, 0xbb, 0x31, 0xf2, 0xd8, + 0x21, 0x8e, 0x2c, 0x45, 0x39, 0xe6, 0xb7, 0xaa, 0x46, 0x81, 0x5f, 0x04, 0xf8, 0x00, 0x20, 0xf3, + 0xd3, 0x39, 0xb7, 0x07, 0x35, 0x8a, 0x70, 0x1e, 0x7b, 0xb0, 0x91, 0xd0, 0x12, 0x73, 0x3b, 0x42, + 0x23, 0x1f, 0xb9, 0xf8, 0x10, 0xb6, 0x66, 0xe0, 0x87, 0xc5, 0xfa, 0x3c, 0xa3, 0x20, 0x4b, 0x85, + 0xfe, 0x0c, 0x0b, 0xb1, 0x58, 0xdf, 0x67, 0x14, 0x44, 0x2b, 0xfe, 0x00, 0xe7, 0x16, 0xa8, 0x88, + 0xc5, 0xdb, 0x40, 0xe3, 0x14, 0xb0, 0xc5, 0x11, 0xe0, 0x22, 0x22, 0xf1, 0x14, 0x5d, 0xa1, 0x71, + 0x1a, 0xf6, 0xe2, 0xf7, 0xd0, 0x98, 0xab, 0xa9, 0x85, 0x7a, 0x44, 0xa3, 0x18, 0x82, 0xf1, 0x6b, + 0xa8, 0xcf, 0x14, 0xe1, 0x02, 0xfd, 0xa2, 0x51, 0x84, 0xc5, 0xed, 0xbb, 0x4f, 0x5f, 0x34, 0xd7, + 0x9e, 0xbd, 0x68, 0xae, 0xfd, 0xf5, 0xa2, 0xb9, 0xf6, 0xcb, 0xcb, 0x66, 0xe9, 0xd9, 0xcb, 0x66, + 0xe9, 0x8f, 0x97, 0xcd, 0xd2, 0x37, 0x6f, 0x0f, 0x5d, 0xee, 0x4c, 0x06, 0xbb, 0x16, 0x1b, 0xed, + 0x1d, 0xba, 0x7e, 0x68, 0x39, 0xae, 0xb9, 0xb7, 0xe4, 0x2f, 0xbb, 0x41, 0x55, 0xfe, 0x6f, 0x76, + 0xeb, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x28, 0x00, 0x44, 0x1c, 0xd0, 0x13, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/blockchain/v0/reactor.go b/blockchain/v0/reactor.go index ed04e0e32..3ecc93b04 100644 --- a/blockchain/v0/reactor.go +++ b/blockchain/v0/reactor.go @@ -400,29 +400,29 @@ FOR_LOOP: bcR.Switch.StopPeerForError(peer2, fmt.Errorf("blockchainReactor validation error: %v", err)) } continue FOR_LOOP - } else { - bcR.pool.PopRequest() + } - // TODO: batch saves so we dont persist to disk every block - bcR.store.SaveBlock(first, firstParts, second.LastCommit) + bcR.pool.PopRequest() - // TODO: same thing for app - but we would need a way to - // get the hash without persisting the state - var err error - state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first, nil) - if err != nil { - // TODO This is bad, are we zombie? - panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) - } - blocksSynced++ + // TODO: batch saves so we dont persist to disk every block + bcR.store.SaveBlock(first, firstParts, second.LastCommit) - if blocksSynced%100 == 0 { - lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds()) - bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height, - "max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate) - lastHundred = time.Now() - } + // TODO: same thing for app - but we would need a way to + // get the hash without persisting the state + state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first, nil) + if err != nil { + // TODO This is bad, are we zombie? + panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) + } + blocksSynced++ + + if blocksSynced%100 == 0 { + lastRate = 0.9*lastRate + 0.1*(100/time.Since(lastHundred).Seconds()) + bcR.Logger.Info("Fast Sync Rate", "height", bcR.pool.height, + "max_peer_height", bcR.pool.MaxPeerHeight(), "blocks/s", lastRate) + lastHundred = time.Now() } + continue FOR_LOOP case <-bcR.Quit(): diff --git a/blockchain/v2/routine.go b/blockchain/v2/routine.go index cba926efa..b0f8c8ec2 100644 --- a/blockchain/v2/routine.go +++ b/blockchain/v2/routine.go @@ -58,7 +58,7 @@ func (rt *Routine) setMetrics(metrics *Metrics) { } func (rt *Routine) start() { - rt.logger.Info(fmt.Sprintf("%s: run", rt.name)) + rt.logger.Info("routine start", "msg", log.NewLazySprintf("%s: run", rt.name)) running := atomic.CompareAndSwapUint32(rt.running, uint32(0), uint32(1)) if !running { panic(fmt.Sprintf("%s is already running", rt.name)) @@ -98,7 +98,7 @@ func (rt *Routine) start() { return } rt.metrics.EventsOut.With("routine", rt.name).Add(1) - rt.logger.Debug(fmt.Sprintf("%s: produced %T %+v", rt.name, oEvent, oEvent)) + rt.logger.Debug("routine start", "msg", log.NewLazySprintf("%s: produced %T %+v", rt.name, oEvent, oEvent)) // Skip rTrySchedule and rProcessBlock events as they clutter the history // due to their frequency. @@ -118,7 +118,7 @@ func (rt *Routine) start() { // XXX: look into returning OpError in the net package func (rt *Routine) send(event Event) bool { - rt.logger.Debug(fmt.Sprintf("%s: received %T %+v", rt.name, event, event)) + rt.logger.Debug("routine send", "msg", log.NewLazySprintf("%s: received %T %+v", rt.name, event, event)) if !rt.isRunning() { return false } @@ -150,7 +150,7 @@ func (rt *Routine) stop() { return } - rt.logger.Info(fmt.Sprintf("%s: stop", rt.name)) + rt.logger.Info("routine stop", "msg", log.NewLazySprintf("%s: stop", rt.name)) rt.queue.Dispose() // this should block until all queue items are free? } diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 000000000..d972360bb --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,9 @@ +version: v1 +plugins: + - name: gogofaster + out: ./proto/ + opt: + - Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types + - Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration + - plugins=grpc + - paths=source_relative diff --git a/buf.work.yaml b/buf.work.yaml new file mode 100644 index 000000000..494296bfa --- /dev/null +++ b/buf.work.yaml @@ -0,0 +1,4 @@ +version: v1 +directories: + - proto + - third_party/proto diff --git a/cmd/ostracon/commands/compact.go b/cmd/ostracon/commands/compact.go new file mode 100644 index 000000000..2155c7207 --- /dev/null +++ b/cmd/ostracon/commands/compact.go @@ -0,0 +1,66 @@ +package commands + +import ( + "errors" + "path/filepath" + "sync" + + "github.com/spf13/cobra" + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/util" + + "github.com/Finschia/ostracon/libs/log" +) + +var CompactGoLevelDBCmd = &cobra.Command{ + Use: "experimental-compact-goleveldb", + Short: "force compacts the ostracon storage engine (only GoLevelDB supported)", + Long: ` +This is a temporary utility command that performs a force compaction on the state +and blockstores to reduce disk space for a pruning node. This should only be run +once the node has stopped. This command will likely be omitted in the future after +the planned refactor to the storage engine. + +Currently, only GoLevelDB is supported. + `, + RunE: func(cmd *cobra.Command, args []string) error { + if config.DBBackend != "goleveldb" { + return errors.New("compaction is currently only supported with goleveldb") + } + + compactGoLevelDBs(config.RootDir, logger) + return nil + }, +} + +func compactGoLevelDBs(rootDir string, logger log.Logger) { + dbNames := []string{"state", "blockstore"} + o := &opt.Options{ + DisableSeeksCompaction: true, + } + wg := sync.WaitGroup{} + + for _, dbName := range dbNames { + dbName := dbName + wg.Add(1) + go func() { + defer wg.Done() + dbPath := filepath.Join(rootDir, "data", dbName+".db") + store, err := leveldb.OpenFile(dbPath, o) + if err != nil { + logger.Error("failed to initialize ostracon db", "path", dbPath, "err", err) + return + } + defer store.Close() + + logger.Info("starting compaction...", "db", dbPath) + + err = store.CompactRange(util.Range{Start: nil, Limit: nil}) + if err != nil { + logger.Error("failed to compact ostracon db", "path", dbPath, "err", err) + } + }() + } + wg.Wait() +} diff --git a/cmd/ostracon/commands/compact_test.go b/cmd/ostracon/commands/compact_test.go new file mode 100644 index 000000000..38e598a2d --- /dev/null +++ b/cmd/ostracon/commands/compact_test.go @@ -0,0 +1,52 @@ +package commands + +import ( + cfg "github.com/Finschia/ostracon/config" + "github.com/Finschia/ostracon/libs/log" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +func Test_RunE(t *testing.T) { + config = cfg.TestConfig() + config.RootDir = os.TempDir() + config.DBBackend = "badgerdb" // not support + logger = log.TestingLogger() + err := CompactGoLevelDBCmd.RunE(nil, nil) + assert.Error(t, err) + config.DBBackend = "goleveldb" + err = CompactGoLevelDBCmd.RunE(nil, nil) + assert.NoError(t, err) +} + +func Test_compactGoLevelDBs(t *testing.T) { + type args struct { + rootDir string + logger log.Logger + } + tests := []struct { + name string + args args + }{ + { + name: "success", + args: args{ + rootDir: os.TempDir(), + logger: log.TestingLogger(), + }, + }, + { + name: "doesn't exist db dir", + args: args{ + rootDir: "/nonexistent", + logger: log.TestingLogger(), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + compactGoLevelDBs(tt.args.rootDir, tt.args.logger) + }) + } +} diff --git a/cmd/ostracon/main.go b/cmd/ostracon/main.go index e40b3695c..a84e2a6ba 100644 --- a/cmd/ostracon/main.go +++ b/cmd/ostracon/main.go @@ -28,6 +28,7 @@ func main() { cmd.GenNodeKeyCmd, cmd.VersionCmd, cmd.RollbackStateCmd, + cmd.CompactGoLevelDBCmd, debug.DebugCmd, cli.NewCompletionCmd(rootCmd, true), ) diff --git a/config/config.go b/config/config.go index 28a5b55ed..7236d9f3a 100644 --- a/config/config.go +++ b/config/config.go @@ -25,6 +25,14 @@ const ( DefaultLogLevel = "info" DefaultDBBackend = "goleveldb" + + // Mempool versions. + // Default is v0. + + // MempoolV0 is regular mempool + MempoolV0 = "v0" + // MempoolV1 is prioritized mempool + MempoolV1 = "v1" ) // NOTE: Most of the structs & relevant comments + the @@ -763,6 +771,13 @@ func DefaultFuzzConnConfig() *FuzzConnConfig { // MempoolConfig defines the configuration options for the Ostracon mempool type MempoolConfig struct { + // Mempool version to use: + // 1) "v0" - (default) FIFO mempool. + // 2) "v1" - prioritized mempool. + // WARNING: There's a known memory leak with the prioritized mempool + // that the team are working on. Read more here: + // https://github.com/tendermint/tendermint/issues/8775 + Version string `mapstructure:"version"` RootDir string `mapstructure:"home"` Recheck bool `mapstructure:"recheck"` Broadcast bool `mapstructure:"broadcast"` @@ -786,20 +801,39 @@ type MempoolConfig struct { // Including space needed by encoding (one varint per transaction). // XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796 MaxBatchBytes int `mapstructure:"max_batch_bytes"` + + // TTLDuration, if non-zero, defines the maximum amount of time a transaction + // can exist for in the mempool. + // + // Note, if TTLNumBlocks is also defined, a transaction will be removed if it + // has existed in the mempool at least TTLNumBlocks number of blocks or if it's + // insertion time into the mempool is beyond TTLDuration. + TTLDuration time.Duration `mapstructure:"ttl-duration"` + + // TTLNumBlocks, if non-zero, defines the maximum number of blocks a transaction + // can exist for in the mempool. + // + // Note, if TTLDuration is also defined, a transaction will be removed if it + // 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"` } // DefaultMempoolConfig returns a default configuration for the Ostracon mempool func DefaultMempoolConfig() *MempoolConfig { return &MempoolConfig{ + Version: MempoolV0, Recheck: true, Broadcast: true, WalPath: "", // Each signature verification takes .5ms, Size reduced until we implement // ABCI Recheck - Size: 5000, - MaxTxsBytes: 1024 * 1024 * 1024, // 1GB - CacheSize: 10000, - MaxTxBytes: 1024 * 1024, // 1MB + Size: 5000, + MaxTxsBytes: 1024 * 1024 * 1024, // 1GB + CacheSize: 10000, + MaxTxBytes: 1024 * 1024, // 1MB + TTLDuration: 0 * time.Second, + TTLNumBlocks: 0, } } diff --git a/config/toml.go b/config/toml.go index 5a1ae5894..e1b82b2ab 100644 --- a/config/toml.go +++ b/config/toml.go @@ -397,6 +397,11 @@ statesync_recv_buf_size = {{ .P2P.StatesyncRecvBufSize }} ####################################################### [mempool] +# Mempool version to use: +# 1) "v0" - (default) FIFO mempool. +# 2) "v1" - prioritized mempool. +version = "{{ .Mempool.Version }}" + recheck = {{ .Mempool.Recheck }} broadcast = {{ .Mempool.Broadcast }} wal_dir = "{{ js .Mempool.WalPath }}" @@ -426,6 +431,22 @@ max_tx_bytes = {{ .Mempool.MaxTxBytes }} # XXX: Unused due to https://github.com/tendermint/tendermint/issues/5796 max_batch_bytes = {{ .Mempool.MaxBatchBytes }} +# ttl-duration, if non-zero, defines the maximum amount of time a transaction +# can exist for in the mempool. +# +# Note, if ttl-num-blocks is also defined, a transaction will be removed if it +# has existed in the mempool at least ttl-num-blocks number of blocks or if it's +# insertion time into the mempool is beyond ttl-duration. +ttl-duration = "{{ .Mempool.TTLDuration }}" + +# ttl-num-blocks, if non-zero, defines the maximum number of blocks a transaction +# can exist for in the mempool. +# +# Note, if ttl-duration is also defined, a transaction will be removed if it +# has existed in the mempool at least ttl-num-blocks number of blocks or if +# it's insertion time into the mempool is beyond ttl-duration. +ttl-num-blocks = {{ .Mempool.TTLNumBlocks }} + ####################################################### ### State Sync Configuration Options ### ####################################################### @@ -531,8 +552,14 @@ peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}" # 1) "null" # 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). # - When "kv" is chosen "tx.height" and "tx.hash" will always be indexed. +# 3) "psql" - the indexer services backed by PostgreSQL. +# When "kv" or "psql" is chosen "tx.height" and "tx.hash" will always be indexed. indexer = "{{ .TxIndex.Indexer }}" +# The PostgreSQL connection configuration, the connection format: +# postgresql://:@:/? +psql-conn = "{{ .TxIndex.PsqlConn }}" + ####################################################### ### Instrumentation Configuration Options ### ####################################################### diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 8ad4a3138..5aadcc274 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -16,14 +16,17 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" - config2 "github.com/Finschia/ostracon/config" - abcicli "github.com/Finschia/ostracon/abci/client" "github.com/Finschia/ostracon/evidence" "github.com/Finschia/ostracon/libs/log" "github.com/Finschia/ostracon/libs/service" tmsync "github.com/Finschia/ostracon/libs/sync" mempl "github.com/Finschia/ostracon/mempool" + + cfg "github.com/Finschia/ostracon/config" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" + + //mempoolv1 "github.com/Finschia/ostracon/mempool/v1" "github.com/Finschia/ostracon/p2p" sm "github.com/Finschia/ostracon/state" "github.com/Finschia/ostracon/store" @@ -60,14 +63,34 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { blockDB := dbm.NewMemDB() blockStore := store.NewBlockStore(blockDB) - // one for mempool, one for consensus mtx := new(tmsync.Mutex) - proxyAppConnMem := abcicli.NewLocalClient(mtx, app) + // one for mempool, one for consensus proxyAppConnCon := abcicli.NewLocalClient(mtx, app) + proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) // Make Mempool - mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0) - mempool.SetLogger(log.TestingLogger().With("module", "mempool")) + var mempool mempl.Mempool + + switch thisConfig.Mempool.Version { + case cfg.MempoolV0: + mempool = mempoolv0.NewCListMempool(config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state))) + case cfg.MempoolV1: // XXX Deprecated + panic("Deprecated MempoolV1") + /* + mempool = mempoolv1.NewTxMempool(logger, + config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + */ + } + if thisConfig.Consensus.WaitForTxs() { mempool.EnableTxsAvailable() } @@ -124,7 +147,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { } } // make connected switches and start all reactors - p2p.MakeConnectedSwitches(config.P2P, nValidators, func(i int, s *p2p.Switch, c *config2.P2PConfig) *p2p.Switch { + p2p.MakeConnectedSwitches(config.P2P, nValidators, func(i int, s *p2p.Switch, c *cfg.P2PConfig) *p2p.Switch { s.AddReactor("CONSENSUS", reactors[i]) s.SetLogger(log.NewNopLogger().With("module", "p2p")) // Switch log is noisy for this test return s @@ -311,7 +334,7 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) { config.P2P, i, "foo", "1.0.0", - func(i int, sw *p2p.Switch, config *config2.P2PConfig) *p2p.Switch { + func(i int, sw *p2p.Switch, config *cfg.P2PConfig) *p2p.Switch { return sw }) switches[i].SetLogger(p2pLogger.With("validator", i)) @@ -373,7 +396,7 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) { } }() - p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch, config *config2.P2PConfig) *p2p.Switch { + p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch, config *cfg.P2PConfig) *p2p.Switch { // ignore new switch s, we already made ours switches[i].AddReactor("CONSENSUS", reactors[i]) return switches[i] diff --git a/consensus/common_test.go b/consensus/common_test.go index c0a2887c8..44c7b9be1 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -33,6 +33,9 @@ import ( tmpubsub "github.com/Finschia/ostracon/libs/pubsub" tmsync "github.com/Finschia/ostracon/libs/sync" mempl "github.com/Finschia/ostracon/mempool" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" + + //mempoolv1 "github.com/Finschia/ostracon/mempool/v1" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/privval" sm "github.com/Finschia/ostracon/state" @@ -420,12 +423,38 @@ func newStateWithConfigAndBlockStoreWithLoggers( // one for mempool, one for consensus mtx := new(tmsync.Mutex) - proxyAppConnMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := abcicli.NewLocalClient(mtx, app) + proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) + // Make Mempool + memplMetrics := mempl.NopMetrics() // Make Mempool - mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0) - mempool.SetLogger(loggers.memLogger.With("module", "mempool")) + var mempool mempl.Mempool + + switch config.Mempool.Version { + case cfg.MempoolV0: + mempool = mempoolv0.NewCListMempool(config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv0.WithMetrics(memplMetrics), + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state))) + mempool.(*mempoolv0.CListMempool).SetLogger(loggers.memLogger.With("module", "mempool")) + case cfg.MempoolV1: // XXX Deprecated + panic("Deprecated MempoolV1") + /* + logger := consensusLogger() + mempool = mempoolv1.NewTxMempool(logger, + config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv1.WithMetrics(memplMetrics), + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + */ + } if thisConfig.Consensus.WaitForTxs() { mempool.EnableTxsAvailable() } diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index 8bcde0b71..9be7d0e87 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -105,7 +105,7 @@ func deliverTxsRange(cs *State, start, end int) { for i := start; i < end; i++ { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - _, err := assertMempool(cs.txNotifier).CheckTxSync(txBytes, mempl.TxInfo{}) + err := assertMempool(cs.txNotifier).CheckTxSync(txBytes, nil, mempl.TxInfo{}) if err != nil { panic(fmt.Sprintf("Error after CheckTx: %v", err)) } diff --git a/consensus/reactor.go b/consensus/reactor.go index 7c6adb9cd..a071cfd19 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -1276,12 +1276,12 @@ func (ps *PeerState) SetHasVote(vote *types.Vote) { } func (ps *PeerState) setHasVote(height int64, round int32, voteType tmproto.SignedMsgType, index int32) { - logger := ps.logger.With( + ps.logger.Debug("setHasVote", "peerH/R", - fmt.Sprintf("%d/%d", ps.PRS.Height, ps.PRS.Round), + log.NewLazySprintf("%d/%d", ps.PRS.Height, ps.PRS.Round), "H/R", - fmt.Sprintf("%d/%d", height, round)) - logger.Debug("setHasVote", "type", voteType, "index", index) + log.NewLazySprintf("%d/%d", height, round), + "type", voteType, "index", index) // NOTE: some may be nil BitArrays -> no side effects. psVotes := ps.getVoteBitArray(height, round, voteType) diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 690fb1489..2c722dccc 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -30,6 +30,9 @@ import ( "github.com/Finschia/ostracon/libs/log" tmsync "github.com/Finschia/ostracon/libs/sync" mempl "github.com/Finschia/ostracon/mempool" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" + + //mempoolv1 "github.com/Finschia/ostracon/mempool/v1" "github.com/Finschia/ostracon/p2p" p2pmock "github.com/Finschia/ostracon/p2p/mock" sm "github.com/Finschia/ostracon/state" @@ -152,14 +155,36 @@ func TestReactorWithEvidence(t *testing.T) { blockDB := dbm.NewMemDB() blockStore := store.NewBlockStore(blockDB) - // one for mempool, one for consensus mtx := new(tmsync.Mutex) - proxyAppConnMem := abcicli.NewLocalClient(mtx, app) + memplMetrics := mempl.NopMetrics() + // one for mempool, one for consensus proxyAppConnCon := abcicli.NewLocalClient(mtx, app) + proxyAppConnConMem := abcicli.NewLocalClient(mtx, app) // Make Mempool - mempool := mempl.NewCListMempool(thisConfig.Mempool, proxyAppConnMem, 0) - mempool.SetLogger(log.TestingLogger().With("module", "mempool")) + var mempool mempl.Mempool + + switch config.Mempool.Version { + case cfg.MempoolV0: + mempool = mempoolv0.NewCListMempool(config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv0.WithMetrics(memplMetrics), + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state))) + case cfg.MempoolV1: // XXX Deprecated MempoolV1 + panic("Deprecated MempoolV1") + /* + mempool = mempoolv1.NewTxMempool(logger, + config.Mempool, + proxyAppConnConMem, + state.LastBlockHeight, + mempoolv1.WithMetrics(memplMetrics), + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + */ + } if thisConfig.Consensus.WaitForTxs() { mempool.EnableTxsAvailable() } @@ -221,7 +246,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) // send a tx - if _, err := assertMempool(css[3].txNotifier).CheckTxSync([]byte{1, 2, 3}, mempl.TxInfo{}); err != nil { + if err := assertMempool(css[3].txNotifier).CheckTxSync([]byte{1, 2, 3}, nil, mempl.TxInfo{}); err != nil { t.Error(err) } @@ -549,7 +574,7 @@ func waitForAndValidateBlock( err := validateBlock(newBlock, activeVals) assert.Nil(t, err) for _, tx := range txs { - _, err := assertMempool(css[j].txNotifier).CheckTxSync(tx, mempl.TxInfo{}) + err := assertMempool(css[j].txNotifier).CheckTxSync(tx, nil, mempl.TxInfo{}) assert.Nil(t, err) } }, css) diff --git a/consensus/replay_stubs.go b/consensus/replay_stubs.go index 13694208e..6f67e3bd0 100644 --- a/consensus/replay_stubs.go +++ b/consensus/replay_stubs.go @@ -17,17 +17,23 @@ type emptyMempool struct{} var _ mempl.Mempool = emptyMempool{} -func (emptyMempool) Lock() {} -func (emptyMempool) Unlock() {} -func (emptyMempool) Size() int { return 0 } -func (emptyMempool) CheckTxSync(_ types.Tx, _ mempl.TxInfo) (*ocabci.Response, error) { - return nil, nil +func (emptyMempool) Lock() {} +func (emptyMempool) Unlock() {} +func (emptyMempool) Size() int { return 0 } +func (emptyMempool) SizeBytes() int64 { return 0 } +func (emptyMempool) CheckTxSync(_ types.Tx, _ func(*ocabci.Response), _ mempl.TxInfo) error { + return nil } func (emptyMempool) CheckTxAsync(_ types.Tx, _ mempl.TxInfo, _ func(error), _ func(*ocabci.Response)) { } func (emptyMempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} } func (emptyMempool) ReapMaxBytesMaxGasMaxTxs(_, _, _ int64) types.Txs { return types.Txs{} } func (emptyMempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} } + +func (txmp emptyMempool) RemoveTxByKey(txKey types.TxKey) error { + return nil +} + func (emptyMempool) Update( _ *types.Block, _ []*abci.ResponseDeliverTx, diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 5582faab2..4b46cb949 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -121,7 +121,7 @@ func sendTxs(ctx context.Context, cs *State) { return default: tx := []byte{byte(i)} - if _, err := assertMempool(cs.txNotifier).CheckTxSync(tx, mempl.TxInfo{}); err != nil { + if err := assertMempool(cs.txNotifier).CheckTxSync(tx, nil, mempl.TxInfo{}); err != nil { panic(err) } i++ @@ -471,7 +471,7 @@ func TestSimulateValidatorsChange(t *testing.T) { valPubKey1ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey1) assert.Nil(t, err) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - _, err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx1, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx1, nil, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -485,7 +485,7 @@ func TestSimulateValidatorsChange(t *testing.T) { updatePubKey1ABCI, err := cryptoenc.PubKeyToProto(updateValidatorPubKey1) require.NoError(t, err) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - _, err = assertMempool(css[0].txNotifier).CheckTxSync(updateValidatorTx1, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTxSync(updateValidatorTx1, nil, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -502,14 +502,14 @@ func TestSimulateValidatorsChange(t *testing.T) { newVal2ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey2) require.NoError(t, err) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) - _, err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx2, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx2, nil, mempl.TxInfo{}) assert.Nil(t, err) newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey() require.NoError(t, err) newVal3ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey3) require.NoError(t, err) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - _, err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx3, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTxSync(newValidatorTx3, nil, mempl.TxInfo{}) assert.Nil(t, err) }) @@ -549,7 +549,7 @@ func TestSimulateValidatorsChange(t *testing.T) { newVal3ABCI, err := cryptoenc.PubKeyToProto(newValidatorPubKey3) require.NoError(t, err) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - _, err = assertMempool(css[0].txNotifier).CheckTxSync(removeValidatorTx3, mempl.TxInfo{}) + err = assertMempool(css[0].txNotifier).CheckTxSync(removeValidatorTx3, nil, mempl.TxInfo{}) assert.Nil(t, err) }) diff --git a/consensus/state.go b/consensus/state.go index 4a0faecce..8700acebb 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1030,7 +1030,7 @@ func (cs *State) enterNewRound(height int64, round int32) { if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { logger.Debug( "entering new round with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } @@ -1040,7 +1040,7 @@ func (cs *State) enterNewRound(height int64, round int32) { logger.Debug("need to set a buffer and log message here for sanity", "start_time", cs.StartTime, "now", now) } - logger.Debug("entering new round", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering new round", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) // Select the current height and round Proposer cs.Proposer = cs.Validators.SelectProposer(cs.state.LastProofHash, height, round) @@ -1108,12 +1108,12 @@ func (cs *State) enterPropose(height int64, round int32) { if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPropose <= cs.Step) { logger.Debug( "entering propose step with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } - logger.Debug("entering propose step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering propose step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) defer func() { // Done enterPropose: @@ -1286,7 +1286,7 @@ func (cs *State) enterPrevote(height int64, round int32) { if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevote <= cs.Step) { logger.Debug( "entering prevote step with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } @@ -1297,7 +1297,7 @@ func (cs *State) enterPrevote(height int64, round int32) { cs.newStep() }() - logger.Debug("entering prevote step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering prevote step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) // Sign and broadcast vote as necessary cs.stepTimes.ToPrevoteStep() @@ -1350,7 +1350,7 @@ func (cs *State) enterPrevoteWait(height int64, round int32) { if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) { logger.Debug( "entering prevote wait step with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } @@ -1362,7 +1362,7 @@ func (cs *State) enterPrevoteWait(height int64, round int32) { )) } - logger.Debug("entering prevote wait step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering prevote wait step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) defer func() { // Done enterPrevoteWait: @@ -1386,12 +1386,12 @@ func (cs *State) enterPrecommit(height int64, round int32) { if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommit <= cs.Step) { logger.Debug( "entering precommit step with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } - logger.Debug("entering precommit step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering precommit step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) defer func() { // Done enterPrecommit: @@ -1512,7 +1512,7 @@ func (cs *State) enterPrecommitWait(height int64, round int32) { logger.Debug( "entering precommit wait step with invalid args", "triggered_timeout", cs.TriggeredTimeoutPrecommit, - "current", fmt.Sprintf("%v/%v", cs.Height, cs.Round), + "current", log.NewLazySprintf("%v/%v", cs.Height, cs.Round), ) return } @@ -1524,7 +1524,7 @@ func (cs *State) enterPrecommitWait(height int64, round int32) { )) } - logger.Debug("entering precommit wait step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering precommit wait step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) defer func() { // Done enterPrecommitWait: @@ -1543,12 +1543,12 @@ func (cs *State) enterCommit(height int64, commitRound int32) { if cs.Height != height || cstypes.RoundStepCommit <= cs.Step { logger.Debug( "entering commit step with invalid args", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } - logger.Debug("entering commit step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) + logger.Debug("entering commit step", "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step)) defer func() { // Done enterCommit: @@ -1581,7 +1581,7 @@ func (cs *State) enterCommit(height int64, commitRound int32) { if !cs.ProposalBlockParts.HasHeader(blockID.PartSetHeader) { logger.Info( "commit is for a block we do not know about; set ProposalBlock=nil", - "proposal", cs.ProposalBlock.Hash(), + "proposal", log.NewLazyBlockHash(cs.ProposalBlock), "commit", blockID.Hash, ) @@ -1618,7 +1618,7 @@ func (cs *State) tryFinalizeCommit(height int64) { // TODO: ^^ wait, why does it matter that we're a validator? logger.Debug( "failed attempt to finalize commit; we do not have the commit block", - "proposal_block", cs.ProposalBlock.Hash(), + "proposal_block", log.NewLazyBlockHash(cs.ProposalBlock), "commit_block", blockID.Hash, ) return @@ -1634,7 +1634,7 @@ func (cs *State) finalizeCommit(height int64) { if cs.Height != height || cs.Step != cstypes.RoundStepCommit { logger.Debug( "entering finalize commit step", - "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), + "current", log.NewLazySprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step), ) return } @@ -1659,11 +1659,11 @@ func (cs *State) finalizeCommit(height int64) { logger.Info( "finalizing commit of block", - "hash", block.Hash(), + "hash", log.NewLazyBlockHash(block), "root", block.AppHash, "num_txs", len(block.Txs), ) - logger.Debug(fmt.Sprintf("%v", block)) + logger.Debug("committed block", "block", log.NewLazySprintf("%v", block)) fail.Fail() // XXX @@ -2018,7 +2018,7 @@ func (cs *State) handleCompleteProposal(blockHeight int64) { cs.Logger.Debug( "updating valid block to new proposal block", "valid_round", cs.Round, - "valid_block_hash", cs.ProposalBlock.Hash(), + "valid_block_hash", log.NewLazyBlockHash(cs.ProposalBlock), ) cs.ValidRound = cs.Round @@ -2193,7 +2193,7 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error } else { cs.Logger.Debug( "valid block we do not know about; set ProposalBlock=nil", - "proposal", cs.ProposalBlock.Hash(), + "proposal", log.NewLazyBlockHash(cs.ProposalBlock), "block_id", blockID.Hash, ) diff --git a/evidence/mocks/block_store.go b/evidence/mocks/block_store.go index a7a47e962..5377b61f2 100644 --- a/evidence/mocks/block_store.go +++ b/evidence/mocks/block_store.go @@ -58,13 +58,12 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta { return r0 } -type mockConstructorTestingTNewBlockStore interface { +// NewBlockStore creates a new instance of BlockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBlockStore(t interface { mock.TestingT Cleanup(func()) -} - -// NewBlockStore creates a new instance of BlockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewBlockStore(t mockConstructorTestingTNewBlockStore) *BlockStore { +}) *BlockStore { mock := &BlockStore{} mock.Mock.Test(t) diff --git a/go.mod b/go.mod index 936676918..0c738651e 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 github.com/tendermint/go-amino v0.16.0 - github.com/tendermint/tendermint v0.34.19 + github.com/tendermint/tendermint v0.34.20 github.com/tendermint/tm-db v0.6.7 github.com/yahoo/coname v0.0.0-20170609175141-84592ddf8673 // indirect golang.org/x/crypto v0.11.0 @@ -48,8 +48,11 @@ require ( github.com/Finschia/r2ishiguro_vrf v0.1.2 github.com/bufbuild/buf v1.25.0 github.com/golangci/golangci-lint v1.53.3 + github.com/klauspost/pgzip v1.2.6 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce + github.com/prometheus/common v0.42.0 // indirect github.com/rs/zerolog v1.29.1 + github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca github.com/vektra/mockery/v2 v2.32.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 ) @@ -81,7 +84,6 @@ require ( github.com/breml/bidichk v0.2.4 // indirect github.com/breml/errchkjson v0.3.1 // indirect github.com/bufbuild/connect-go v1.9.0 // indirect - github.com/bufbuild/connect-opentelemetry-go v0.4.0 // indirect github.com/bufbuild/protocompile v0.5.1 // indirect github.com/butuzov/ireturn v0.2.0 // indirect github.com/butuzov/mirror v1.1.0 // indirect @@ -131,7 +133,7 @@ require ( 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/v5 v5.0.0 // indirect + github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/golang/snappy v0.0.3 // indirect github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect @@ -170,7 +172,6 @@ require ( github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.4 // indirect github.com/klauspost/compress v1.16.7 // indirect - github.com/klauspost/pgzip v1.2.6 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.7 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect @@ -210,7 +211,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polyfloyd/go-errorlint v1.4.2 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/quasilyte/go-ruleguard v0.3.19 // indirect github.com/quasilyte/gogrep v0.5.0 // indirect @@ -238,11 +238,9 @@ 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/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect github.com/tetafro/godot v1.4.11 // indirect - github.com/tetratelabs/wazero v1.3.0 // indirect github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect github.com/timonwong/loggercheck v0.9.4 // indirect github.com/tomarrell/wrapcheck/v2 v2.8.1 // indirect @@ -258,7 +256,6 @@ require ( gitlab.com/bosi/decorder v0.2.3 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opentelemetry.io/otel v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect go.opentelemetry.io/otel/sdk v1.16.0 // indirect go.opentelemetry.io/otel/trace v1.16.0 // indirect go.tmz.dev/musttag v0.7.0 // indirect @@ -283,3 +280,15 @@ require ( mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect ) + +// This is a "replace" directive for "golang-v1.18". If upgrading to golang-v1.19, we can remove +replace ( + github.com/bufbuild/buf => github.com/bufbuild/buf v1.14.0 + github.com/bufbuild/connect-go => github.com/bufbuild/connect-go v1.5.0 + github.com/docker/cli => github.com/docker/cli v24.0.2+incompatible + github.com/docker/docker-credential-helpers => github.com/docker/docker-credential-helpers v0.7.0 + github.com/google/go-containerregistry => github.com/google/go-containerregistry v0.13.0 + go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.12.0 + go.opentelemetry.io/otel/sdk => go.opentelemetry.io/otel/sdk v1.12.0 + go.uber.org/multierr => go.uber.org/multierr v1.8.0 +) diff --git a/go.sum b/go.sum index fdef9eb9a..eb8f2c86c 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,9 @@ 4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= 4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= 4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= 4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= +bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M= 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= @@ -17,6 +18,7 @@ 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= @@ -32,42 +34,65 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 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 v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= 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/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= 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/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +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= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +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/4meepo/tagalign v1.2.2 h1:kQeUTkFTaBRtd/7jm8OKJl9iHk0gAO+TDFPHGSna0aw= github.com/4meepo/tagalign v1.2.2/go.mod h1:Q9c1rYMZJc9dPRkbQPpcBNCLEmY2njbAsXhQOZFE2dE= github.com/Abirdcfly/dupword v0.0.11 h1:z6v8rMETchZXUIuHxYNmlUAuKuB21PeaSymTed16wgU= github.com/Abirdcfly/dupword v0.0.11/go.mod h1:wH8mVGuf3CP5fsBTkfWwwwKTjDnVVCxtU8d8rgeVYXA= +github.com/Antonboom/errname v0.1.6/go.mod h1:7lz79JAnuoMNDAWE9MeeIr1/c/VpSUWatBv2FH9NYpI= github.com/Antonboom/errname v0.1.10 h1:RZ7cYo/GuZqjr1nuJLNe8ZH+a+Jd9DaZzttWzak9Bls= github.com/Antonboom/errname v0.1.10/go.mod h1:xLeiCIrvVNpUtsN0wxAh05bNIZpqE22/qDMnTBTttiA= +github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= github.com/Antonboom/nilnil v0.1.5 h1:X2JAdEVcbPaOom2TUa1FxZ3uyuUlex0XMLGYMemu6l0= github.com/Antonboom/nilnil v0.1.5/go.mod h1:I24toVuBKhfP5teihGWctrRiPbRKHwZIFOvc6v3HZXk= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= @@ -84,20 +109,27 @@ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rW github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Finschia/r2ishiguro_vrf v0.1.2 h1:lDBz6NQMx1pw5I3End6xFmXpM//7KcmTr3Ka983e7v8= github.com/Finschia/r2ishiguro_vrf v0.1.2/go.mod h1:OHRtvzcJnfIrcJ0bvPNktJozRFAyZFuv56E9R3/qB+Y= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0/go.mod h1:LGOGuvEgCfCQsy3JF2tRmpGDpzA53iZfyGEWSPwQ6/4= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +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/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +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/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= 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/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/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -107,7 +139,7 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd5wAKUHEO/k= github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/adlio/schema v1.3.0/go.mod h1:51QzxkpeFs6lRY11kPye26IaFPOV+HqEj01t5aXXKfs= +github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/adlio/schema v1.3.4 h1:8K+41sfQkxfT6a79aLBxx+dBKcid6Raw2JPk5COqeqE= github.com/adlio/schema v1.3.4/go.mod h1:gFMaHYzLkZRfaIqZ5u96LLXPt+DdXSFWUwtr6YBz0kk= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= @@ -124,7 +156,11 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO 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/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= +github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +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/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -132,37 +168,45 @@ github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4 github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= github.com/ashanbrown/forbidigo v1.5.3 h1:jfg+fkm/snMx+V9FBwsl1d340BV/99kZGv5jN9hBoXk= github.com/ashanbrown/forbidigo v1.5.3/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/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +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/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +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/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= 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.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= github.com/breml/bidichk v0.2.4 h1:i3yedFWWQ7YzjdZJHnPo9d/xURinSq3OM+gyM43K4/8= github.com/breml/bidichk v0.2.4/go.mod h1:7Zk0kRFt1LIZxtQdl9W9JwGAcLTTkOs+tN7wuEYGJ3s= +github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= github.com/breml/errchkjson v0.3.1 h1:hlIeXuspTyt8Y/UmP5qy1JocGNR00KQHgfaNtRAjoxQ= github.com/breml/errchkjson v0.3.1/go.mod h1:XroxrzKjdiutFyW3nWhw34VGg7kiMsDQox73yWCGI2U= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= 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/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= @@ -174,14 +218,14 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= -github.com/bufbuild/buf v1.25.0 h1:HFxKrR8wFcZwrBInN50K/oJX/WOtPVq24rHb/ArjfBA= -github.com/bufbuild/buf v1.25.0/go.mod h1:GCKZ5bAP6Ht4MF7KcfaGVgBEXGumwAz2hXjjLVxx8ZU= -github.com/bufbuild/connect-go v1.9.0 h1:JIgAeNuFpo+SUPfU19Yt5TcWlznsN5Bv10/gI/6Pjoc= -github.com/bufbuild/connect-go v1.9.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= -github.com/bufbuild/connect-opentelemetry-go v0.4.0 h1:6JAn10SNqlQ/URhvRNGrIlczKw1wEXknBUUtmWqOiak= -github.com/bufbuild/connect-opentelemetry-go v0.4.0/go.mod h1:nwPXYoDOoc2DGyKE/6pT1Q9MPSi2Et2e6BieMD0l6WU= +github.com/bufbuild/buf v1.14.0 h1:BSpRDgxC8jKwV+XJXyVuB0PM1na/qL80rNAgzb1PZnU= +github.com/bufbuild/buf v1.14.0/go.mod h1:Z5FtbEZtMdog6dGRZdCvIZTc6lPYaCz3AONEPmXNkyk= +github.com/bufbuild/connect-go v1.5.0 h1:IfbgbzzaaZvF+OM3SfxO2EjtvNJarNAz2DIRuuNjAgc= +github.com/bufbuild/connect-go v1.5.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I= +github.com/bufbuild/protocompile v0.2.0/go.mod h1:tleDrpPTlLUVmgnEoN6qBliKWqJaZFJXqZdFjTd+ocU= github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg= github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/ireturn v0.2.0 h1:kCHi+YzC150GE98WFuZQu9yrTn6GEydO2AuPLbTgnO4= github.com/butuzov/ireturn v0.2.0/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/butuzov/mirror v1.1.0 h1:ZqX54gBVMXu78QLoiqdwpl2mgmoOJTk7s4p4o+0avZI= @@ -191,6 +235,7 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= 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/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -199,18 +244,21 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= 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.0.0-20220316182200-5cad0b5181d4/go.mod h1:W8EnPSQ8Nv4fUjc/v1/8tHFqhuOJXnRub0dTfuAQktU= github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8 h1:W9o46d2kbNL06lq7UNDPV0zYLzkrde/bjIqO02eoll0= github.com/chavacava/garif v0.0.0-20230227094218-b8c73b2037b8/go.mod h1:gakxgyXaaPkxvLw1XQxNGK4I37ys9iBRzNUx/B7pUCo= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= 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= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= @@ -226,21 +274,23 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +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/continuity v0.2.1/go.mod h1:wCYX+dRqZdImhGucXOqTQn05AhX6EUDaGEMUzTFFpLg= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/containerd/stargz-snapshotter/estargz v0.12.1/go.mod h1:12VUuCq3qPq4y8yUW+l5w3+oXV3cx2Po3KSe/SmPGqw= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 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-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/go-systemd/v22 v22.5.0/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/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -252,14 +302,19 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/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/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 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.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/daixiang0/gci v0.3.3/go.mod h1:1Xr2bxnQbDxCqqulUOv8qpGqkgRw9RSCGGjEC2LjF8o= github.com/daixiang0/gci v0.10.1 h1:eheNA3ljF6SxnPD/vE4lCBusVHmV3Rs3dkKvFrJ7MR0= github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= +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= @@ -276,21 +331,26 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KP 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/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw= -github.com/docker/cli v24.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM= +github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.20+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v23.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI= github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= -github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= 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/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -306,6 +366,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +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/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= @@ -320,6 +382,7 @@ github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+ne 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.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= @@ -328,6 +391,7 @@ 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/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= +github.com/firefart/nonamedreturns v1.0.1/go.mod h1:D3dpIBojGGNh5UfElmwPu73SwDCm+VKhHYqwlNOk2uQ= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -336,17 +400,24 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/franela/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= 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.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= 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/fzipp/gocyclo v0.5.1/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= 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/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-critic/go-critic v0.6.3/go.mod h1:c6b3ZP1MQ7o6lPR7Rv3lEf7pYQUmAcx8ABHgdZCQt/k= github.com/go-critic/go-critic v0.8.1 h1:16omCF1gN3gTzt4j4J6fKI/HnRojhEp+Eks6EuKw3vw= github.com/go-critic/go-critic v0.8.1/go.mod h1:kpzXl09SIJX1cr9TB/g/sAG+eFEl7ZS9f9cqvZtyNl0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -367,32 +438,46 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/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/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-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +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/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= 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-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= 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.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= 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.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= 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.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= 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.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= 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.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= 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.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= 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 v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= 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/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= @@ -402,10 +487,12 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gofrs/uuid/v5 v5.0.0 h1:p544++a97kEL+svbcFbCQVM9KFu0Yo25UoISXGNNH9M= -github.com/gofrs/uuid/v5 v5.0.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.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-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= @@ -415,7 +502,7 @@ github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQ github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +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= @@ -429,6 +516,7 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +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= @@ -459,16 +547,20 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9 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/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= +github.com/golangci/golangci-lint v1.46.2/go.mod h1:3DkdHnxn9eoTTrpT2gB0TEv8KSziuoqe9FitgQLHvAY= github.com/golangci/golangci-lint v1.53.3 h1:CUcRafczT4t1F+mvdkUm6KuOpxUZTl0yWN/rSU6sSMo= github.com/golangci/golangci-lint v1.53.3/go.mod h1:W4Gg3ONq6p3Jl+0s/h9Gr0j7yEgHJWWZO2bHl2tBUXM= 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/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0= github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= +github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY= 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/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= @@ -476,6 +568,8 @@ github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +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= @@ -488,11 +582,12 @@ 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.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= 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/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE= -github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q= +github.com/google/go-containerregistry v0.13.0 h1:y1C7Z3e149OJbOPDBxLYR8ITPz8dTKqQwjErKVHJC8k= +github.com/google/go-containerregistry v0.13.0/go.mod h1:J9FQ+eSS4a1aC2GNZxvNpbWhgp0487v+cgiilB4FqDo= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -508,36 +603,62 @@ 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-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20230131232505-5a9e8f65f08f/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA= github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA= 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/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +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/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= 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/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= 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/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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/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.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0= 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= @@ -547,11 +668,15 @@ 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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +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/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +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/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= @@ -559,6 +684,7 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= +github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -569,6 +695,7 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -583,6 +710,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= 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= @@ -597,17 +725,26 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= 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/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= 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/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +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.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 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/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -617,21 +754,32 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/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/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +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/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.14.1 h1:N88q7JkxTHWFEqReuTsYH1dPIwXxA0ITNQp7avLY10s= +github.com/jhump/protoreflect v1.14.1/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= 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/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw= 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.9/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= @@ -639,13 +787,17 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +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.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 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= @@ -654,52 +806,73 @@ github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt 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.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/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.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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.2/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= 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.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4= github.com/kunwardeep/paralleltest v1.0.7 h1:2uCk94js0+nVNQoHZNLBkAR1DQJrVzw6T0RMzJn55dQ= github.com/kunwardeep/paralleltest v1.0.7/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= 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/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= 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.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= +github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +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.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 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.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= 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/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU= 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-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= 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= @@ -713,6 +886,7 @@ github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb 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.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +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.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= @@ -721,8 +895,12 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k 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-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -730,31 +908,44 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/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/go.mod h1:+Ro3wqY4vakcYNtkBWdZC7dBg1xSB6sp054wWwmeFm0= github.com/mgechev/revive v1.3.2 h1:Wb8NQKBaALBJ3xrrj4zpwJwqwNA6nDpyJSEQWcCka6U= github.com/mgechev/revive v1.3.2/go.mod h1:UCLtc7o5vg5aXCwdUTU1kEBQ1v+YXPAkYDIDXbrs5I0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +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/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= 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/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 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/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +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/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -763,13 +954,19 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN 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/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +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/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/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q= @@ -782,8 +979,10 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS 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/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.7.11/go.mod h1:gX+MP7DWMKJmNa1HfMozK+u04hQd3na9i0hyqf3/dOI= 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.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ= 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.12.1 h1:vwOqb5Nu05OikTXqhvLdHCGcx5uthIYIl0t79UVrERQ= @@ -793,39 +992,51 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce h1:/pEpMk55wH0X+E5zedGEMOdLuWmV8P4+4W3+LZaM6kg= github.com/oasisprotocol/curve25519-voi v0.0.0-20230110094441-db37f07504ce/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +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.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134= github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 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.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= 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.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= 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/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -834,18 +1045,27 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.0-beta.8/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM= +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/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= 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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -855,19 +1075,23 @@ github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 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/go.mod h1:KZy4xxPJyy88/gldCe5OdW6OQRtNO3EZE7hXzmnebgA= github.com/polyfloyd/go-errorlint v1.4.2 h1:CU+O4181IxFDdPH6t/HT7IiDj1I7zxNi1RIUxYwn8d0= github.com/polyfloyd/go-errorlint v1.4.2/go.mod h1:k6fU/+fQe38ednoZS51T7gSIGQW1y94d6TkSr35OzH8= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -876,18 +1100,16 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= @@ -895,11 +1117,21 @@ 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.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +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/go.mod h1:VMX+OnnSw4LicdiEGtRSD/1X8kW7GuEscjYNr4cOIT4= github.com/quasilyte/go-ruleguard v0.3.19 h1:tfMnabXle/HzOb5Xe9CUZYWXKfkS1KwRmZyPmD9nVcc= github.com/quasilyte/go-ruleguard v0.3.19/go.mod h1:lHSn69Scl48I7Gt9cX3VrbsZYvYiBYszZOZW4A+oTEw= +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/dsl v0.3.19/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/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= 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-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= 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= @@ -907,26 +1139,41 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls= +github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls= +github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= 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.3/go.mod h1:rYbA/4Tg5c54mV1sv4sQTP5WOPBcoLtnBZ7/TEhXAbg= 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.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= +github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= +github.com/sagikazarmark/crypt v0.5.0/go.mod h1:l+nzl7KWh51rpzp2h7t4MZWyiEWdhNpOAnclKvg+mdA= +github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= 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.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= @@ -937,12 +1184,15 @@ github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84d github.com/sashamelentyev/usestdlibvars v1.23.0 h1:01h+/2Kd+NblNItNeux0veSL5cBF1jbEOPrEhDzGYq0= github.com/sashamelentyev/usestdlibvars v1.23.0/go.mod h1:YPwr/Y1LATzHI93CqoPUN/2BzGQ/6N/cl/KwgR0B/aU= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/securego/gosec/v2 v2.16.0 h1:Pi0JKoasQQ3NnoRao/ww/N/XdynIB9NRYYZT5CyOs5U= github.com/securego/gosec/v2 v2.16.0/go.mod h1:xvLcVZqUfo4aAQu56TNv7/Ltz6emAOQAEsrZrt7uGlI= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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/shirou/gopsutil/v3 v3.22.4/go.mod h1:D01hZJ4pVHPpCTZ3m3T2+wDF2YAGfd+H4ifUguaQzHM= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -954,10 +1204,12 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 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.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= 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.5.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/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -965,9 +1217,11 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 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/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= 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/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= 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= @@ -976,26 +1230,34 @@ github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +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.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +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= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU= +github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= +github.com/spf13/viper v1.11.0/go.mod h1:djo0X/bA5+tYVoCn+C7cAYJGcVn/qYLFTG8gdUsX7Zk= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= @@ -1010,6 +1272,7 @@ 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= @@ -1018,6 +1281,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -1025,20 +1289,24 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl 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.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= 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/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/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.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= 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/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.19 h1:y0P1qI5wSa9IRuhKnTDA6IUcOrLi1hXJuALR+R7HFEk= -github.com/tendermint/tendermint v0.34.19/go.mod h1:R5+wgIwSxMdKQcmOaeudL0Cjkr3HDkhpcdum6VeU3R4= +github.com/tendermint/tendermint v0.34.20 h1:/pmvJhO3IqOxhbi8iRXudTjA2YKpaMqrLwFNkyxDSzw= +github.com/tendermint/tendermint v0.34.20/go.mod h1:KtOwCLYJcsS1ymtAfnjjAtXfXClbqcqjdqzFt2Em1Ac= github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= @@ -1048,43 +1316,62 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR 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/tetratelabs/wazero v1.3.0 h1:nqw7zCldxE06B8zSZAY0ACrR9OH5QCcPwYmYlwtcwtE= -github.com/tetratelabs/wazero v1.3.0/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= 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/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +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.1/go.mod h1:Eo+Opt6pyMW1b6cNllOcDSSoHO0aTJ+iF6BfCUbHltA= 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/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4= +github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= 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/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= 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/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/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= +github.com/uudashr/gocognit v1.0.5/go.mod h1:wgYz0mitoKOTysqxTDMOUXg+Jb5SvtihkfmugIZYpEA= github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus= +github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= +github.com/vektra/mockery/v2 v2.14.0/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M= github.com/vektra/mockery/v2 v2.32.0 h1:IXUoQ3s5VxJPpi95DECUmkRUXZ44I1spQ3YatEypIF4= github.com/vektra/mockery/v2 v2.32.0/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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= 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/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw= github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA= 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/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= @@ -1094,26 +1381,42 @@ github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= github.com/ykadowak/zerologlint v0.1.2 h1:Um4P5RMmelfjQqQJKtE8ZW+dLZrXrENeIzWWKw800U4= github.com/ykadowak/zerologlint v0.1.2/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= +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/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.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +gitlab.com/bosi/decorder v0.2.1/go.mod h1:6C/nhLSbF6qZbYD8bRmISBwc6vcWdNsiIBkRvjJFrH0= 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-simpler.org/assert v0.5.0 h1:+5L/lajuQtzmbtEfh69sr5cRf2/xZzyJhFjoOz/PPqs= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= 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.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.5.2/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.2/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= +go.etcd.io/etcd/client/v2 v2.305.2/go.mod h1:2D7ZejHVMIfog1221iLSYlQRzrtECw3kz4I4VAQm3qI= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +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= @@ -1121,36 +1424,37 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel v1.12.0 h1:IgfC7kqQrRccIKuB7Cl+SRUmsKbEwSGPr0Eu+/ht1SQ= +go.opentelemetry.io/otel v1.12.0/go.mod h1:geaoz0L0r1BEOR81k7/n9W4TCXYCJ7bPO7K374jQHG0= +go.opentelemetry.io/otel/sdk v1.12.0 h1:8npliVYV7qc0t1FKdpU08eMnOjgPFMnriPhn0HH4q3o= +go.opentelemetry.io/otel/sdk v1.12.0/go.mod h1:WYcvtgquYvgODEvxOry5owO2y9MyciW7JqMz6cpXShE= +go.opentelemetry.io/otel/trace v1.12.0/go.mod h1:pHlgBynn6s25qJ2szD+Bv+iwKJttjHSI3lUAyf0GNuQ= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.tmz.dev/musttag v0.7.0 h1:QfytzjTWGXZmChoX0L++7uQN+yRCPfyFm+whsM+lfGc= go.tmz.dev/musttag v0.7.0/go.mod h1:oTFPvgOkJmp5kYL02S8+jrH0eLrBIl57rzWeA26zDEM= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= 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.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= -go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +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/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.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= 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-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1166,14 +1470,21 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/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-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 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-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1189,8 +1500,11 @@ 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-20230131160201-f062dba9d201/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= 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-20230224173230-c95f2b4c22f2 h1:J74nGeMgeFnYQJN59eFwh06jX/V8g0lB7LWpjSLxtgU= @@ -1243,13 +1557,14 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 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= @@ -1257,6 +1572,7 @@ 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= @@ -1278,15 +1594,26 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/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-20211208012354-db4efeb81f4b/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.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 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= @@ -1310,10 +1637,19 @@ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/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-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= 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= @@ -1321,6 +1657,8 @@ 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.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= @@ -1346,7 +1684,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-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/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= @@ -1356,7 +1696,6 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w 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= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= @@ -1369,6 +1708,7 @@ 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= @@ -1378,12 +1718,13 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20201204225414-ed752295db88/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= @@ -1398,7 +1739,6 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1408,7 +1748,9 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1422,22 +1764,45 @@ golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/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-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/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-20220403020550-483a9cbc67c0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/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-20220728004956-3c1f35247d10/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-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 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= @@ -1458,6 +1823,7 @@ 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.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= @@ -1467,34 +1833,45 @@ golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= 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/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-20190206041539-40960b6deb8e/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-20190228203856-589c23e65e65/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-20190328211700-ab21143f2384/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= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/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-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= @@ -1507,24 +1884,38 @@ 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-20200422022333-3d57cf2e726e/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-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/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= @@ -1536,8 +1927,12 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +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-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= 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= @@ -1550,6 +1945,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= @@ -1560,6 +1958,7 @@ 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= @@ -1587,16 +1986,31 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 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/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= @@ -1604,6 +2018,7 @@ 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= @@ -1617,12 +2032,15 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 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= @@ -1637,6 +2055,7 @@ google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -1658,20 +2077,48 @@ google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +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.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 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= @@ -1690,8 +2137,12 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.56.2 h1:fVRFRnXvU+x6C4IlHZewvJOVHoOv1TUuQyoRsYnB4bI= google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1708,6 +2159,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1717,10 +2171,15 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 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/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= @@ -1735,17 +2194,22 @@ 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= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I= +gotest.tools/v3 v3.2.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= 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= @@ -1753,18 +2217,22 @@ 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.1/go.mod h1:vlRD9XErLMGT+mDuofSr0mMMquscM/1nQqtRSsh6m70= honnef.co/go/tools v0.4.3 h1:o/n5/K5gXqk8Gozvs2cnL0F2S1/g1vcGCAx2vETjITw= honnef.co/go/tools v0.4.3/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= +mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= 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-20211214103731-d0ef000c54e5/go.mod h1:b8RRCBm0eeiWR8cfN88xeq2G5SG3VKGO+5UPWi5FSOY= 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= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 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= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/libs/os/os.go b/libs/os/os.go index 535c31e50..b21ab1f08 100644 --- a/libs/os/os.go +++ b/libs/os/os.go @@ -7,6 +7,8 @@ import ( "os" "os/signal" "syscall" + + "github.com/Finschia/ostracon/libs/log" ) type logger interface { @@ -20,7 +22,7 @@ func TrapSignal(logger logger, cb func()) { signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { for sig := range c { - logger.Info(fmt.Sprintf("captured %v, exiting...", sig)) + logger.Info("signal trapped", "msg", log.NewLazySprintf("captured %v, exiting...", sig)) if cb != nil { cb() } diff --git a/libs/service/service.go b/libs/service/service.go index 3227852ab..0d31fc864 100644 --- a/libs/service/service.go +++ b/libs/service/service.go @@ -136,7 +136,11 @@ func (bs *BaseService) Start() error { atomic.StoreUint32(&bs.started, 0) return ErrAlreadyStopped } - bs.Logger.Info(fmt.Sprintf("Starting %v service", bs.name), "impl", bs.impl.String()) + bs.Logger.Info("service start", + "msg", + log.NewLazySprintf("Starting %v service", bs.name), + "impl", + bs.impl.String()) err := bs.impl.OnStart() if err != nil { // revert flag @@ -145,7 +149,11 @@ func (bs *BaseService) Start() error { } return nil } - bs.Logger.Debug(fmt.Sprintf("Not starting %v service -- already started", bs.name), "impl", bs.impl) + bs.Logger.Debug("service start", + "msg", + log.NewLazySprintf("Not starting %v service -- already started", bs.name), + "impl", + bs.impl) return ErrAlreadyStarted } @@ -165,12 +173,20 @@ func (bs *BaseService) Stop() error { atomic.StoreUint32(&bs.stopped, 0) return ErrNotStarted } - bs.Logger.Info(fmt.Sprintf("Stopping %v service", bs.name), "impl", bs.impl) + bs.Logger.Info("service stop", + "msg", + log.NewLazySprintf("Stopping %v service", bs.name), + "impl", + bs.impl) bs.impl.OnStop() close(bs.quit) return nil } - bs.Logger.Debug(fmt.Sprintf("Stopping %v service (already stopped)", bs.name), "impl", bs.impl) + bs.Logger.Debug("service stop", + "msg", + log.NewLazySprintf("Stopping %v service (already stopped)", bs.name), + "impl", + bs.impl) return ErrAlreadyStopped } @@ -183,7 +199,11 @@ func (bs *BaseService) OnStop() {} // will be returned if the service is running. func (bs *BaseService) Reset() error { if !atomic.CompareAndSwapUint32(&bs.stopped, 1, 0) { - bs.Logger.Debug(fmt.Sprintf("Can't reset %v service. Not stopped", bs.name), "impl", bs.impl) + bs.Logger.Debug("service reset", + "msg", + log.NewLazySprintf("Can't reset %v service. Not stopped", bs.name), + "impl", + bs.impl) return fmt.Errorf("can't reset running %s", bs.name) } diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go index d7c18e496..e928be743 100644 --- a/light/rpc/mocks/light_client.go +++ b/light/rpc/mocks/light_client.go @@ -109,13 +109,12 @@ func (_m *LightClient) VerifyLightBlockAtHeight(ctx context.Context, height int6 return r0, r1 } -type mockConstructorTestingTNewLightClient interface { +// NewLightClient creates a new instance of LightClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewLightClient(t interface { mock.TestingT Cleanup(func()) -} - -// NewLightClient creates a new instance of LightClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewLightClient(t mockConstructorTestingTNewLightClient) *LightClient { +}) *LightClient { mock := &LightClient{} mock.Mock.Test(t) diff --git a/mempool/bench_test.go b/mempool/bench_test.go deleted file mode 100644 index 4e2fa92dd..000000000 --- a/mempool/bench_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package mempool - -import ( - "encoding/binary" - "testing" - - "github.com/Finschia/ostracon/abci/example/kvstore" - "github.com/Finschia/ostracon/proxy" -) - -func BenchmarkReap(b *testing.B) { - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) - defer cleanup() - - size := 10000 - for i := 0; i < size; i++ { - tx := make([]byte, 8) - binary.BigEndian.PutUint64(tx, uint64(i)) - mempool.CheckTxSync(tx, TxInfo{}) // nolint: errcheck - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - mempool.ReapMaxBytesMaxGas(100000000, 10000000) - } -} - -func BenchmarkReapWithCheckTxAsync(b *testing.B) { - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) - defer cleanup() - - size := 10000 - for i := 0; i < size; i++ { - tx := make([]byte, 8) - binary.BigEndian.PutUint64(tx, uint64(i)) - mempool.CheckTxAsync(tx, TxInfo{}, nil, nil) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - mempool.ReapMaxBytesMaxGas(100000000, 10000000) - } -} - -func BenchmarkCheckTxSync(b *testing.B) { - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) - defer cleanup() - - for i := 0; i < b.N; i++ { - tx := make([]byte, 8) - binary.BigEndian.PutUint64(tx, uint64(i)) - mempool.CheckTxSync(tx, TxInfo{}) // nolint: errcheck - } -} - -func BenchmarkCheckTxAsync(b *testing.B) { - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) - defer cleanup() - - for i := 0; i < b.N; i++ { - tx := make([]byte, 8) - binary.BigEndian.PutUint64(tx, uint64(i)) - mempool.CheckTxAsync(tx, TxInfo{}, nil, nil) - } -} - -func BenchmarkCacheInsertTime(b *testing.B) { - cache := newMapTxCache(b.N) - txs := make([][]byte, b.N) - for i := 0; i < b.N; i++ { - txs[i] = make([]byte, 8) - binary.BigEndian.PutUint64(txs[i], uint64(i)) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - cache.Push(txs[i]) - } -} - -// This benchmark is probably skewed, since we actually will be removing -// txs in parallel, which may cause some overhead due to mutex locking. -func BenchmarkCacheRemoveTime(b *testing.B) { - cache := newMapTxCache(b.N) - txs := make([][]byte, b.N) - for i := 0; i < b.N; i++ { - txs[i] = make([]byte, 8) - binary.BigEndian.PutUint64(txs[i], uint64(i)) - cache.Push(txs[i]) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - cache.Remove(txs[i]) - } -} diff --git a/mempool/cache.go b/mempool/cache.go new file mode 100644 index 000000000..c5b84e412 --- /dev/null +++ b/mempool/cache.go @@ -0,0 +1,120 @@ +package mempool + +import ( + "container/list" + + tmsync "github.com/Finschia/ostracon/libs/sync" + "github.com/Finschia/ostracon/types" +) + +// TxCache defines an interface for raw transaction caching in a mempool. +// Currently, a TxCache does not allow direct reading or getting of transaction +// values. A TxCache is used primarily to push transactions and removing +// transactions. Pushing via Push returns a boolean telling the caller if the +// transaction already exists in the cache or not. +type TxCache interface { + // Reset resets the cache to an empty state. + Reset() + + // Push adds the given raw transaction to the cache and returns true if it was + // newly added. Otherwise, it returns false. + Push(tx types.Tx) bool + + // Remove removes the given raw transaction from the cache. + Remove(tx types.Tx) + + // Has reports whether tx is present in the cache. Checking for presence is + // not treated as an access of the value. + Has(tx types.Tx) bool +} + +var _ TxCache = (*LRUTxCache)(nil) + +// LRUTxCache maintains a thread-safe LRU cache of raw transactions. The cache +// only stores the hash of the raw transaction. +type LRUTxCache struct { + mtx tmsync.Mutex + size int + cacheMap map[types.TxKey]*list.Element + list *list.List +} + +func NewLRUTxCache(cacheSize int) *LRUTxCache { + return &LRUTxCache{ + size: cacheSize, + cacheMap: make(map[types.TxKey]*list.Element, cacheSize), + list: list.New(), + } +} + +// GetList returns the underlying linked-list that backs the LRU cache. Note, +// this should be used for testing purposes only! +func (c *LRUTxCache) GetList() *list.List { + return c.list +} + +func (c *LRUTxCache) Reset() { + c.mtx.Lock() + defer c.mtx.Unlock() + + c.cacheMap = make(map[types.TxKey]*list.Element, c.size) + c.list.Init() +} + +func (c *LRUTxCache) Push(tx types.Tx) bool { + c.mtx.Lock() + defer c.mtx.Unlock() + + key := tx.Key() + + moved, ok := c.cacheMap[key] + if ok { + c.list.MoveToBack(moved) + return false + } + + if c.list.Len() >= c.size { + front := c.list.Front() + if front != nil { + frontKey := front.Value.(types.TxKey) + delete(c.cacheMap, frontKey) + c.list.Remove(front) + } + } + + e := c.list.PushBack(key) + c.cacheMap[key] = e + + return true +} + +func (c *LRUTxCache) Remove(tx types.Tx) { + c.mtx.Lock() + defer c.mtx.Unlock() + + key := tx.Key() + e := c.cacheMap[key] + delete(c.cacheMap, key) + + if e != nil { + c.list.Remove(e) + } +} + +func (c *LRUTxCache) Has(tx types.Tx) bool { + c.mtx.Lock() + defer c.mtx.Unlock() + + _, ok := c.cacheMap[tx.Key()] + return ok +} + +// NopTxCache defines a no-op raw transaction cache. +type NopTxCache struct{} + +var _ TxCache = (*NopTxCache)(nil) + +func (NopTxCache) Reset() {} +func (NopTxCache) Push(types.Tx) bool { return true } +func (NopTxCache) Remove(types.Tx) {} +func (NopTxCache) Has(types.Tx) bool { return false } diff --git a/mempool/cache_bench_test.go b/mempool/cache_bench_test.go new file mode 100644 index 000000000..1c26999d1 --- /dev/null +++ b/mempool/cache_bench_test.go @@ -0,0 +1,41 @@ +package mempool + +import ( + "encoding/binary" + "testing" +) + +func BenchmarkCacheInsertTime(b *testing.B) { + cache := NewLRUTxCache(b.N) + + txs := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + txs[i] = make([]byte, 8) + binary.BigEndian.PutUint64(txs[i], uint64(i)) + } + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + cache.Push(txs[i]) + } +} + +// This benchmark is probably skewed, since we actually will be removing +// txs in parallel, which may cause some overhead due to mutex locking. +func BenchmarkCacheRemoveTime(b *testing.B) { + cache := NewLRUTxCache(b.N) + + txs := make([][]byte, b.N) + for i := 0; i < b.N; i++ { + txs[i] = make([]byte, 8) + binary.BigEndian.PutUint64(txs[i], uint64(i)) + cache.Push(txs[i]) + } + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + cache.Remove(txs[i]) + } +} diff --git a/mempool/cache_test.go b/mempool/cache_test.go index ce72b27a9..513f67ff3 100644 --- a/mempool/cache_test.go +++ b/mempool/cache_test.go @@ -2,32 +2,48 @@ package mempool import ( "crypto/rand" - "crypto/sha256" "testing" - "github.com/stretchr/testify/require" - - "github.com/Finschia/ostracon/abci/example/kvstore" - abci "github.com/Finschia/ostracon/abci/types" - "github.com/Finschia/ostracon/proxy" "github.com/Finschia/ostracon/types" + + "github.com/stretchr/testify/require" ) +func TestCacheBasic(t *testing.T) { + size := 10 + cache := NewLRUTxCache(size) + require.Equal(t, 0, cache.GetList().Len()) + for i := 0; i < size; i++ { + cache.Push(types.Tx{byte(i)}) + } + require.Equal(t, size, cache.GetList().Len()) + cache.Push(types.Tx{byte(0)}) // MoveToBack + require.Equal(t, size, cache.GetList().Len()) + cache.Push(types.Tx{byte(size + 1)}) // Cache out + require.Equal(t, size, cache.GetList().Len()) + cache.Reset() + require.Equal(t, 0, cache.GetList().Len()) +} + func TestCacheRemove(t *testing.T) { - cache := newMapTxCache(100) + cache := NewLRUTxCache(100) numTxs := 10 + txs := make([][]byte, numTxs) for i := 0; i < numTxs; i++ { // probability of collision is 2**-256 txBytes := make([]byte, 32) _, err := rand.Read(txBytes) require.NoError(t, err) + txs[i] = txBytes cache.Push(txBytes) + // make sure its added to both the linked list and the map require.Equal(t, i+1, len(cache.cacheMap)) require.Equal(t, i+1, cache.list.Len()) } + for i := 0; i < numTxs; i++ { cache.Remove(txs[i]) // make sure its removed from both the map and the linked list @@ -35,71 +51,3 @@ func TestCacheRemove(t *testing.T) { require.Equal(t, numTxs-(i+1), cache.list.Len()) } } - -func TestCacheAfterUpdate(t *testing.T) { - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) - defer cleanup() - - // reAddIndices & txsInCache can have elements > numTxsToCreate - // also assumes max index is 255 for convenience - // txs in cache also checks order of elements - tests := []struct { - numTxsToCreate int - updateIndices []int - reAddIndices []int - txsInCache []int - }{ - {1, []int{}, []int{1}, []int{1, 0}}, // adding new txs works - {2, []int{1}, []int{}, []int{1, 0}}, // update doesn't remove tx from cache - {2, []int{2}, []int{}, []int{2, 1, 0}}, // update adds new tx to cache - {2, []int{1}, []int{1}, []int{1, 0}}, // re-adding after update doesn't make dupe - } - for tcIndex, tc := range tests { - for i := 0; i < tc.numTxsToCreate; i++ { - tx := types.Tx{byte(i)} - _, err := mempool.CheckTxSync(tx, TxInfo{}) - require.NoError(t, err) - } - - updateTxs := []types.Tx{} - for _, v := range tc.updateIndices { - tx := types.Tx{byte(v)} - updateTxs = append(updateTxs, tx) - } - err := mempool.Update(newTestBlock(int64(tcIndex), updateTxs), - abciResponses(len(updateTxs), abci.CodeTypeOK), nil, nil) - require.NoError(t, err) - - for _, v := range tc.reAddIndices { - tx := types.Tx{byte(v)} - _, _ = mempool.CheckTxSync(tx, TxInfo{}) - } - - cache := mempool.cache.(*mapTxCache) - node := cache.list.Front() - counter := 0 - for node != nil { - require.NotEqual(t, len(tc.txsInCache), counter, - "cache larger than expected on testcase %d", tcIndex) - - nodeVal := node.Value.([sha256.Size]byte) - expectedBz := sha256.Sum256([]byte{byte(tc.txsInCache[len(tc.txsInCache)-counter-1])}) - // Reference for reading the errors: - // >>> sha256('\x00').hexdigest() - // '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' - // >>> sha256('\x01').hexdigest() - // '4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a' - // >>> sha256('\x02').hexdigest() - // 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' - - require.Equal(t, expectedBz, nodeVal, "Equality failed on index %d, tc %d", counter, tcIndex) - counter++ - node = node.Next() - } - require.Equal(t, len(tc.txsInCache), counter, - "cache smaller than expected on testcase %d", tcIndex) - mempool.Flush() - } -} diff --git a/mempool/errors.go b/mempool/errors.go deleted file mode 100644 index be520742e..000000000 --- a/mempool/errors.go +++ /dev/null @@ -1,54 +0,0 @@ -package mempool - -import ( - "errors" - "fmt" -) - -var ( - // ErrTxInMap is returned to the client if we saw tx earlier in txsMap - ErrTxInMap = errors.New("tx already exists in txsMap") - // ErrTxInCache is returned to the client if we saw tx earlier in cache - ErrTxInCache = errors.New("tx already exists in cache") -) - -// ErrTxTooLarge means the tx is too big to be sent in a message to other peers -type ErrTxTooLarge struct { - max int - actual int -} - -func (e ErrTxTooLarge) Error() string { - return fmt.Sprintf("Tx too large. Max size is %d, but got %d", e.max, e.actual) -} - -// ErrMempoolIsFull means Ostracon & an application can't handle that much load -type ErrMempoolIsFull struct { - numTxs int - maxTxs int - - txsBytes int64 - maxTxsBytes int64 -} - -func (e ErrMempoolIsFull) Error() string { - return fmt.Sprintf( - "mempool is full: number of txs %d (max: %d), total txs bytes %d (max: %d)", - e.numTxs, e.maxTxs, - e.txsBytes, e.maxTxsBytes) -} - -// ErrPreCheck is returned when tx is too big -type ErrPreCheck struct { - Reason error -} - -func (e ErrPreCheck) Error() string { - return e.Reason.Error() -} - -// IsPreCheckError returns true if err is due to pre check failure. -func IsPreCheckError(err error) bool { - _, ok := err.(ErrPreCheck) - return ok -} diff --git a/mempool/ids.go b/mempool/ids.go new file mode 100644 index 000000000..d64a07bda --- /dev/null +++ b/mempool/ids.go @@ -0,0 +1,3 @@ +package mempool + +// These functions were moved into v0/reactor.go and v1/reactor.go diff --git a/mempool/ids_test.go b/mempool/ids_test.go new file mode 100644 index 000000000..2d72076e7 --- /dev/null +++ b/mempool/ids_test.go @@ -0,0 +1,23 @@ +package mempool + +// import ( +// "testing" + +// "github.com/stretchr/testify/require" +// "github.com/tendermint/tendermint/types" +// ) + +// func TestMempoolIDsBasic(t *testing.T) { +// ids := NewMempoolIDs() + +// peerID, err := types.NewNodeID("0011223344556677889900112233445566778899") +// require.NoError(t, err) + +// ids.ReserveForPeer(peerID) +// require.EqualValues(t, 1, ids.GetForPeer(peerID)) +// ids.Reclaim(peerID) + +// ids.ReserveForPeer(peerID) +// require.EqualValues(t, 2, ids.GetForPeer(peerID)) +// ids.Reclaim(peerID) +// } diff --git a/mempool/mempool.go b/mempool/mempool.go index beb3110a1..818039a93 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -1,49 +1,73 @@ package mempool import ( + "crypto/sha256" + "errors" "fmt" + "math" abci "github.com/tendermint/tendermint/abci/types" ocabci "github.com/Finschia/ostracon/abci/types" - "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/types" ) +const ( + MempoolChannel = byte(0x30) + + // PeerCatchupSleepIntervalMS defines how much time to sleep if a peer is behind + PeerCatchupSleepIntervalMS = 100 + + // UnknownPeerID is the peer ID to use when running CheckTx when there is + // no peer (e.g. RPC) + UnknownPeerID uint16 = 0 + + MaxActiveIDs = math.MaxUint16 +) + // Mempool defines the mempool interface. // // Updates to the mempool need to be synchronized with committing a block so -// apps can reset their transient state on Commit. +// applications can reset their transient state on Commit. type Mempool interface { // CheckTx executes a new transaction against the application to determine // its validity and whether it should be added to the mempool. - CheckTxSync(tx types.Tx, txInfo TxInfo) (*ocabci.Response, error) + CheckTxSync(tx types.Tx, checkTxCb func(*ocabci.Response), txInfo TxInfo) error CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), checkTxCb func(*ocabci.Response)) + // RemoveTxByKey removes a transaction, identified by its key, + // from the mempool. + RemoveTxByKey(txKey types.TxKey) error + // ReapMaxBytesMaxGas reaps transactions from the mempool up to maxBytes // bytes total with the condition that the total gasWanted must be less than // maxGas. + // // If both maxes are negative, there is no cap on the size of all returned // transactions (~ all available transactions). ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs - // Puts cap on txs as well on top of ReapMaxBytesMaxGas + // ReapMaxBytesMaxGasMaxTxs puts cap on txs as well on top of ReapMaxBytesMaxGas ReapMaxBytesMaxGasMaxTxs(maxBytes, maxGas, maxTxs int64) types.Txs - // ReapMaxTxs reaps up to max transactions from the mempool. - // If max is negative, there is no cap on the size of all returned - // transactions (~ all available transactions). + // ReapMaxTxs reaps up to max transactions from the mempool. If max is + // negative, there is no cap on the size of all returned transactions + // (~ all available transactions). ReapMaxTxs(max int) types.Txs - // Lock locks the mempool. The consensus must be able to hold lock to safely update. + // Lock locks the mempool. The consensus must be able to hold lock to safely + // update. Lock() // Unlock unlocks the mempool. Unlock() - // Update informs the mempool that the given txs were committed and can be discarded. - // NOTE: this should be called *after* block is committed by consensus. - // NOTE: Lock/Unlock must be managed by caller + // Update informs the mempool that the given txs were committed and can be + // discarded. + // + // NOTE: + // 1. This should be called *after* block is committed by consensus. + // 2. Lock/Unlock must be managed by the caller. Update( block *types.Block, deliverTxResponses []*abci.ResponseDeliverTx, @@ -51,17 +75,21 @@ type Mempool interface { newPostFn PostCheckFunc, ) error - // FlushAppConn flushes the mempool connection to ensure async reqResCb calls are - // done. E.g. from CheckTx. - // NOTE: Lock/Unlock must be managed by caller + // FlushAppConn flushes the mempool connection to ensure async callback calls + // are done, e.g. from CheckTx. + // + // NOTE: + // 1. Lock/Unlock must be managed by caller. FlushAppConn() error - // Flush removes all transactions from the mempool and cache + // Flush removes all transactions from the mempool and caches. Flush() - // TxsAvailable returns a channel which fires once for every height, - // and only when transactions are available in the mempool. - // NOTE: the returned channel may be nil if EnableTxsAvailable was not called. + // TxsAvailable returns a channel which fires once for every height, and only + // when transactions are available in the mempool. + // + // NOTE: + // 1. The returned channel may be nil if EnableTxsAvailable was not called. TxsAvailable() <-chan struct{} // EnableTxsAvailable initializes the TxsAvailable channel, ensuring it will @@ -71,20 +99,10 @@ type Mempool interface { // Size returns the number of transactions in the mempool. Size() int - // TxsBytes returns the total size of all txs in the mempool. - TxsBytes() int64 - - // InitWAL creates a directory for the WAL file and opens a file itself. If - // there is an error, it will be of type *PathError. - InitWAL() error - - // CloseWAL closes and discards the underlying WAL file. - // Any further writes will not be relayed to disk. - CloseWAL() + // SizeBytes returns the total size of all txs in the mempool. + SizeBytes() int64 } -//-------------------------------------------------------------------------------- - // PreCheckFunc is an optional filter executed before CheckTx and rejects // transaction if false is returned. An example would be to ensure that a // transaction doesn't exceeded the block size. @@ -95,27 +113,16 @@ type PreCheckFunc func(types.Tx) error // transaction doesn't require more gas than available for the block. type PostCheckFunc func(types.Tx, *ocabci.ResponseCheckTx) error -// TxInfo are parameters that get passed when attempting to add a tx to the -// mempool. -type TxInfo struct { - // SenderID is the internal peer ID used in the mempool to identify the - // sender, storing 2 bytes with each tx instead of 20 bytes for the p2p.ID. - SenderID uint16 - // SenderP2PID is the actual p2p.ID of the sender, used e.g. for logging. - SenderP2PID p2p.ID -} - -//-------------------------------------------------------------------------------- - -// PreCheckMaxBytes checks that the size of the transaction is smaller or equal to the expected maxBytes. +// PreCheckMaxBytes checks that the size of the transaction is smaller or equal +// to the expected maxBytes. func PreCheckMaxBytes(maxBytes int64) PreCheckFunc { return func(tx types.Tx) error { txSize := types.ComputeProtoSizeForTxs([]types.Tx{tx}) if txSize > maxBytes { - return fmt.Errorf("tx size is too big: %d, max: %d", - txSize, maxBytes) + return fmt.Errorf("tx size is too big: %d, max: %d", txSize, maxBytes) } + return nil } } @@ -135,6 +142,60 @@ func PostCheckMaxGas(maxGas int64) PostCheckFunc { return fmt.Errorf("gas wanted %d is greater than max gas %d", res.GasWanted, maxGas) } + return nil } } + +// ErrTxInMap is returned to the client if we saw tx earlier in txsMap +var ErrTxInMap = errors.New("tx already exists in txsMap") + +// ErrTxInCache is returned to the client if we saw tx earlier +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 + +// ErrTxTooLarge defines an error when a transaction is too big to be sent in a +// message to other peers. +type ErrTxTooLarge struct { + Max int + Actual int +} + +func (e ErrTxTooLarge) Error() string { + return fmt.Sprintf("Tx too large. Max size is %d, but got %d", e.Max, e.Actual) +} + +// ErrMempoolIsFull defines an error where Tendermint and the application cannot +// handle that much load. +type ErrMempoolIsFull struct { + NumTxs int + MaxTxs int + TxsBytes int64 + MaxTxsBytes int64 +} + +func (e ErrMempoolIsFull) Error() string { + return fmt.Sprintf( + "mempool is full: number of txs %d (max: %d), total txs bytes %d (max: %d)", + e.NumTxs, + e.MaxTxs, + e.TxsBytes, + e.MaxTxsBytes, + ) +} + +// ErrPreCheck defines an error where a transaction fails a pre-check. +type ErrPreCheck struct { + Reason error +} + +func (e ErrPreCheck) Error() string { + return e.Reason.Error() +} + +// IsPreCheckError returns true if err is due to pre check failure. +func IsPreCheckError(err error) bool { + return errors.As(err, &ErrPreCheck{}) +} diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 9c5e9f469..b42cae5f4 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -3,8 +3,9 @@ package mempool import ( "testing" - abci "github.com/Finschia/ostracon/abci/types" "github.com/stretchr/testify/require" + + abci "github.com/Finschia/ostracon/abci/types" ) func TestPostCheckMaxGas(t *testing.T) { diff --git a/mempool/metrics.go b/mempool/metrics.go index 39459de69..02affca70 100644 --- a/mempool/metrics.go +++ b/mempool/metrics.go @@ -18,12 +18,27 @@ const ( type Metrics struct { // Size of the mempool. Size metrics.Gauge + // Histogram of transaction sizes, in bytes. TxSizeBytes metrics.Histogram + // Number of failed transactions. FailedTxs metrics.Counter + + // RejectedTxs defines the number of rejected transactions. These are + // transactions that passed CheckTx but failed to make it into the mempool + // due to resource limits, e.g. mempool is full and no lower priority + // transactions exist in the mempool. + RejectedTxs metrics.Counter + + // EvictedTxs defines the number of evicted transactions. These are valid + // transactions that passed CheckTx and existed in the mempool but were later + // evicted to make room for higher priority valid transactions that passed + // CheckTx. + EvictedTxs metrics.Counter + // Number of times transactions are rechecked in the mempool. - RecheckCount metrics.Counter + RecheckTimes metrics.Counter // Time of recheck transactions in the mempool. RecheckTime metrics.Gauge } @@ -43,6 +58,7 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Name: "size", Help: "Size of the mempool (number of uncommitted transactions).", }, labels).With(labelsAndValues...), + TxSizeBytes: prometheus.NewHistogramFrom(stdprometheus.HistogramOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, @@ -50,18 +66,35 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { Help: "Transaction sizes in bytes.", Buckets: stdprometheus.ExponentialBuckets(1, 3, 17), }, labels).With(labelsAndValues...), + FailedTxs: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, Name: "failed_txs", Help: "Number of failed transactions.", }, labels).With(labelsAndValues...), - RecheckCount: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + RejectedTxs: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "rejected_txs", + Help: "Number of rejected transactions.", + }, labels).With(labelsAndValues...), + + EvictedTxs: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ + Namespace: namespace, + Subsystem: MetricsSubsystem, + Name: "evicted_txs", + Help: "Number of evicted transactions.", + }, labels).With(labelsAndValues...), + + RecheckTimes: prometheus.NewCounterFrom(stdprometheus.CounterOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, - Name: "recheck_count", + Name: "recheck_times", Help: "Number of times transactions are rechecked in the mempool.", }, labels).With(labelsAndValues...), + + // Add by Ostracon RecheckTime: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{ Namespace: namespace, Subsystem: MetricsSubsystem, @@ -77,7 +110,9 @@ func NopMetrics() *Metrics { Size: discard.NewGauge(), TxSizeBytes: discard.NewHistogram(), FailedTxs: discard.NewCounter(), - RecheckCount: discard.NewCounter(), + RejectedTxs: discard.NewCounter(), + EvictedTxs: discard.NewCounter(), + RecheckTimes: discard.NewCounter(), RecheckTime: discard.NewGauge(), } } diff --git a/mempool/mock/mempool.go b/mempool/mock/mempool.go index 163646c25..3af779b39 100644 --- a/mempool/mock/mempool.go +++ b/mempool/mock/mempool.go @@ -5,31 +5,32 @@ import ( ocabci "github.com/Finschia/ostracon/abci/types" "github.com/Finschia/ostracon/libs/clist" - mempl "github.com/Finschia/ostracon/mempool" + "github.com/Finschia/ostracon/mempool" "github.com/Finschia/ostracon/types" ) // Mempool is an empty implementation of a Mempool, useful for testing. type Mempool struct{} -var _ mempl.Mempool = Mempool{} +var _ mempool.Mempool = Mempool{} func (Mempool) Lock() {} func (Mempool) Unlock() {} func (Mempool) Size() int { return 0 } -func (Mempool) CheckTxSync(_ types.Tx, _ mempl.TxInfo) (*ocabci.Response, error) { - return nil, nil +func (Mempool) CheckTxSync(_ types.Tx, _ func(*ocabci.Response), _ mempool.TxInfo) error { + return nil } -func (Mempool) CheckTxAsync(_ types.Tx, _ mempl.TxInfo, _ func(error), _ func(*ocabci.Response)) { +func (Mempool) CheckTxAsync(_ types.Tx, _ mempool.TxInfo, _ func(error), _ func(*ocabci.Response)) { } +func (Mempool) RemoveTxByKey(txKey types.TxKey) error { return nil } func (Mempool) ReapMaxBytesMaxGas(_, _ int64) types.Txs { return types.Txs{} } func (Mempool) ReapMaxBytesMaxGasMaxTxs(_, _, _ int64) types.Txs { return types.Txs{} } func (Mempool) ReapMaxTxs(n int) types.Txs { return types.Txs{} } func (Mempool) Update( _ *types.Block, _ []*abci.ResponseDeliverTx, - _ mempl.PreCheckFunc, - _ mempl.PostCheckFunc, + _ mempool.PreCheckFunc, + _ mempool.PostCheckFunc, ) error { return nil } @@ -37,7 +38,7 @@ func (Mempool) Flush() {} func (Mempool) FlushAppConn() error { return nil } func (Mempool) TxsAvailable() <-chan struct{} { return make(chan struct{}) } func (Mempool) EnableTxsAvailable() {} -func (Mempool) TxsBytes() int64 { return 0 } +func (Mempool) SizeBytes() int64 { return 0 } func (Mempool) TxsFront() *clist.CElement { return nil } func (Mempool) TxsWaitChan() <-chan struct{} { return nil } diff --git a/mempool/tx.go b/mempool/tx.go new file mode 100644 index 000000000..e93faa69c --- /dev/null +++ b/mempool/tx.go @@ -0,0 +1,17 @@ +package mempool + +import ( + "github.com/Finschia/ostracon/p2p" +) + +// TxInfo are parameters that get passed when attempting to add a tx to the +// mempool. +type TxInfo struct { + // SenderID is the internal peer ID used in the mempool to identify the + // sender, storing two bytes with each transaction instead of 20 bytes for + // the types.NodeID. + SenderID uint16 + + // SenderP2PID is the actual p2p.ID of the sender, used e.g. for logging. + SenderP2PID p2p.ID +} diff --git a/mempool/v0/bench_test.go b/mempool/v0/bench_test.go new file mode 100644 index 000000000..6da51267f --- /dev/null +++ b/mempool/v0/bench_test.go @@ -0,0 +1,101 @@ +package v0 + +import ( + "encoding/binary" + "sync/atomic" + "testing" + + "github.com/Finschia/ostracon/abci/example/kvstore" + "github.com/Finschia/ostracon/mempool" + "github.com/Finschia/ostracon/proxy" +) + +func BenchmarkReap(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mp, cleanup := newMempoolWithApp(cc) + defer cleanup() + + mp.config.Size = 100000 + + size := 10000 + for i := 0; i < size; i++ { + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, uint64(i)) + if err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}); err != nil { + b.Fatal(err) + } + } + b.ResetTimer() + for i := 0; i < b.N; i++ { + mp.ReapMaxBytesMaxGas(100000000, 10000000) + } +} + +func BenchmarkCheckTx(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mp, cleanup := newMempoolWithApp(cc) + defer cleanup() + + mp.config.Size = 1000000 + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + b.StopTimer() + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, uint64(i)) + b.StartTimer() + + if err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkParallelCheckTx(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mp, cleanup := newMempoolWithApp(cc) + defer cleanup() + + mp.config.Size = 100000000 + + var txcnt uint64 + next := func() uint64 { + return atomic.AddUint64(&txcnt, 1) - 1 + } + + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, next()) + if err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}); err != nil { + b.Fatal(err) + } + } + }) +} + +func BenchmarkCheckDuplicateTx(b *testing.B) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mp, cleanup := newMempoolWithApp(cc) + defer cleanup() + + mp.config.Size = 1000000 + + for i := 0; i < b.N; i++ { + tx := make([]byte, 8) + binary.BigEndian.PutUint64(tx, uint64(i)) + if err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}); err != nil { + b.Fatal(err) + } + + if err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}); err == nil { + b.Fatal("tx should be duplicate") + } + } +} diff --git a/mempool/v0/cache_test.go b/mempool/v0/cache_test.go new file mode 100644 index 000000000..aa58b2da2 --- /dev/null +++ b/mempool/v0/cache_test.go @@ -0,0 +1,81 @@ +package v0 + +import ( + "crypto/sha256" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/Finschia/ostracon/abci/example/kvstore" + abci "github.com/Finschia/ostracon/abci/types" + "github.com/Finschia/ostracon/mempool" + "github.com/Finschia/ostracon/proxy" + "github.com/Finschia/ostracon/types" +) + +func TestCacheAfterUpdate(t *testing.T) { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mp, cleanup := newMempoolWithApp(cc) + defer cleanup() + + // reAddIndices & txsInCache can have elements > numTxsToCreate + // also assumes max index is 255 for convenience + // txs in cache also checks order of elements + tests := []struct { + numTxsToCreate int + updateIndices []int + reAddIndices []int + txsInCache []int + }{ + {1, []int{}, []int{1}, []int{1, 0}}, // adding new txs works + {2, []int{1}, []int{}, []int{1, 0}}, // update doesn't remove tx from cache + {2, []int{2}, []int{}, []int{2, 1, 0}}, // update adds new tx to cache + {2, []int{1}, []int{1}, []int{1, 0}}, // re-adding after update doesn't make dupe + } + for tcIndex, tc := range tests { + for i := 0; i < tc.numTxsToCreate; i++ { + tx := types.Tx{byte(i)} + err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}) + require.NoError(t, err) + } + + updateTxs := []types.Tx{} + for _, v := range tc.updateIndices { + tx := types.Tx{byte(v)} + updateTxs = append(updateTxs, tx) + } + err := mp.Update(newTestBlock(int64(tcIndex), updateTxs), abciResponses(len(updateTxs), abci.CodeTypeOK), nil, nil) + require.NoError(t, err) + + for _, v := range tc.reAddIndices { + tx := types.Tx{byte(v)} + _ = mp.CheckTxSync(tx, nil, mempool.TxInfo{}) + } + + cache := mp.cache.(*mempool.LRUTxCache) + node := cache.GetList().Front() + counter := 0 + for node != nil { + require.NotEqual(t, len(tc.txsInCache), counter, + "cache larger than expected on testcase %d", tcIndex) + + nodeVal := node.Value.(types.TxKey) + expectedBz := sha256.Sum256([]byte{byte(tc.txsInCache[len(tc.txsInCache)-counter-1])}) + // Reference for reading the errors: + // >>> sha256('\x00').hexdigest() + // '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' + // >>> sha256('\x01').hexdigest() + // '4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a' + // >>> sha256('\x02').hexdigest() + // 'dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986' + + require.EqualValues(t, expectedBz, nodeVal, "Equality failed on index %d, tc %d", counter, tcIndex) + counter++ + node = node.Next() + } + require.Equal(t, len(tc.txsInCache), counter, + "cache smaller than expected on testcase %d", tcIndex) + mp.Flush() + } +} diff --git a/mempool/clist_mempool.go b/mempool/v0/clist_mempool.go similarity index 73% rename from mempool/clist_mempool.go rename to mempool/v0/clist_mempool.go index 36fa25edc..e836fad40 100644 --- a/mempool/clist_mempool.go +++ b/mempool/v0/clist_mempool.go @@ -1,36 +1,27 @@ -package mempool +package v0 import ( - "container/list" - "crypto/sha256" - "fmt" + "errors" "sync" "sync/atomic" "time" + "github.com/Finschia/ostracon/config" + "github.com/Finschia/ostracon/mempool" + abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ocabci "github.com/Finschia/ostracon/abci/types" - cfg "github.com/Finschia/ostracon/config" - auto "github.com/Finschia/ostracon/libs/autofile" "github.com/Finschia/ostracon/libs/clist" "github.com/Finschia/ostracon/libs/log" tmmath "github.com/Finschia/ostracon/libs/math" - tmos "github.com/Finschia/ostracon/libs/os" tmsync "github.com/Finschia/ostracon/libs/sync" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/proxy" "github.com/Finschia/ostracon/types" ) -// TxKeySize is the size of the transaction key index -const TxKeySize = sha256.Size - -var newline = []byte("\n") - -//-------------------------------------------------------------------------------- - // CListMempool is an ordered in-memory pool for transactions before they are // proposed in a consensus round. Transaction validity is checked using the // CheckTx abci message before the transaction is added to the pool. The @@ -49,19 +40,17 @@ type CListMempool struct { notifiedTxsAvailable bool txsAvailable chan struct{} // fires once for each height, when the mempool is not empty - config *cfg.MempoolConfig + config *config.MempoolConfig // Exclusive mutex for Update method to prevent concurrent execution of // CheckTx or ReapMaxBytesMaxGas(ReapMaxTxs) methods. updateMtx tmsync.RWMutex - preCheck PreCheckFunc + preCheck mempool.PreCheckFunc + postCheck mempool.PostCheckFunc chReqCheckTx chan *requestCheckTxAsync - postCheck PostCheckFunc - - wal *auto.AutoFile // a log of mempool txs - txs *clist.CList // concurrent linked-list of good txs + txs *clist.CList // concurrent linked-list of good txs proxyAppConn proxy.AppConnMempool // Map for quick access to txs to record sender in CheckTx. @@ -70,52 +59,54 @@ type CListMempool struct { // Keep a cache of already-seen txs. // This reduces the pressure on the proxyApp. - cache txCache + cache mempool.TxCache - logger log.Logger - - metrics *Metrics + logger log.Logger + metrics *mempool.Metrics } type requestCheckTxAsync struct { tx types.Tx - txInfo TxInfo + txInfo mempool.TxInfo prepareCb func(error) checkTxCb func(*ocabci.Response) } -var _ Mempool = &CListMempool{} +var _ mempool.Mempool = &CListMempool{} // CListMempoolOption sets an optional parameter on the mempool. type CListMempoolOption func(*CListMempool) -// NewCListMempool returns a new mempool with the given configuration and connection to an application. +// NewCListMempool returns a new mempool with the given configuration and +// connection to an application. func NewCListMempool( - config *cfg.MempoolConfig, + cfg *config.MempoolConfig, proxyAppConn proxy.AppConnMempool, height int64, options ...CListMempoolOption, ) *CListMempool { - mempool := &CListMempool{ - config: config, + mp := &CListMempool{ + config: cfg, proxyAppConn: proxyAppConn, txs: clist.New(), height: height, - chReqCheckTx: make(chan *requestCheckTxAsync, config.Size), + chReqCheckTx: make(chan *requestCheckTxAsync, cfg.Size), logger: log.NewNopLogger(), - metrics: NopMetrics(), + metrics: mempool.NopMetrics(), } - if config.CacheSize > 0 { - mempool.cache = newMapTxCache(config.CacheSize) + + if cfg.CacheSize > 0 { + mp.cache = mempool.NewLRUTxCache(cfg.CacheSize) } else { - mempool.cache = nopTxCache{} + mp.cache = mempool.NopTxCache{} } - proxyAppConn.SetGlobalCallback(mempool.globalCb) + proxyAppConn.SetGlobalCallback(mp.globalCb) + for _, option := range options { - option(mempool) + option(mp) } - go mempool.checkTxAsyncReactor() - return mempool + go mp.checkTxAsyncReactor() + return mp } // NOTE: not thread safe - should only be called once, on startup @@ -131,49 +122,22 @@ func (mem *CListMempool) SetLogger(l log.Logger) { // WithPreCheck sets a filter for the mempool to reject a tx if f(tx) returns // false. This is ran before CheckTx. Only applies to the first created block. // After that, Update overwrites the existing value. -func WithPreCheck(f PreCheckFunc) CListMempoolOption { +func WithPreCheck(f mempool.PreCheckFunc) CListMempoolOption { return func(mem *CListMempool) { mem.preCheck = f } } // WithPostCheck sets a filter for the mempool to reject a tx if f(tx) returns // false. This is ran after CheckTx. Only applies to the first created block. // After that, Update overwrites the existing value. -func WithPostCheck(f PostCheckFunc) CListMempoolOption { +func WithPostCheck(f mempool.PostCheckFunc) CListMempoolOption { return func(mem *CListMempool) { mem.postCheck = f } } // WithMetrics sets the metrics. -func WithMetrics(metrics *Metrics) CListMempoolOption { +func WithMetrics(metrics *mempool.Metrics) CListMempoolOption { return func(mem *CListMempool) { mem.metrics = metrics } } -func (mem *CListMempool) InitWAL() error { - var ( - walDir = mem.config.WalDir() - walFile = walDir + "/wal" - ) - - const perm = 0700 - if err := tmos.EnsureDir(walDir, perm); err != nil { - return err - } - - af, err := auto.OpenAutoFile(walFile) - if err != nil { - return fmt.Errorf("can't open autofile %s: %w", walFile, err) - } - - mem.wal = af - return nil -} - -func (mem *CListMempool) CloseWAL() { - if err := mem.wal.Close(); err != nil { - mem.logger.Error("Error closing WAL", "err", err) - } - mem.wal = nil -} - // Safe for concurrent use by multiple goroutines. func (mem *CListMempool) Lock() { mem.updateMtx.Lock() @@ -190,7 +154,7 @@ func (mem *CListMempool) Size() int { } // Safe for concurrent use by multiple goroutines. -func (mem *CListMempool) TxsBytes() int64 { +func (mem *CListMempool) SizeBytes() int64 { return atomic.LoadInt64(&mem.txsBytes) } @@ -239,33 +203,43 @@ func (mem *CListMempool) TxsWaitChan() <-chan struct{} { // It blocks if we're waiting on Update() or Reap(). // Safe for concurrent use by multiple goroutines. -func (mem *CListMempool) CheckTxSync(tx types.Tx, txInfo TxInfo) (res *ocabci.Response, err error) { +func (mem *CListMempool) CheckTxSync( + tx types.Tx, + cb func(*ocabci.Response), + txInfo mempool.TxInfo, +) error { + mem.updateMtx.RLock() // use defer to unlock mutex because application (*local client*) might panic defer mem.updateMtx.RUnlock() - if err = mem.prepareCheckTx(tx, txInfo); err != nil { - return res, err + if err := mem.prepareCheckTx(tx, txInfo); err != nil { + return err } // CONTRACT: `app.CheckTxSync()` should check whether `GasWanted` is valid (0 <= GasWanted <= block.masGas) var r *ocabci.ResponseCheckTx - r, err = mem.proxyAppConn.CheckTxSync(abci.RequestCheckTx{Tx: tx}) + r, err := mem.proxyAppConn.CheckTxSync(abci.RequestCheckTx{Tx: tx}) if err != nil { - return res, err + return err } - res = ocabci.ToResponseCheckTx(*r) - mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, res, nil) - return res, err + res := ocabci.ToResponseCheckTx(*r) + mem.reqResCb(tx, txInfo.SenderID, txInfo.SenderP2PID, res, cb) + return err } // cb: A callback from the CheckTx command. -// It gets called from another goroutine. +// +// It gets called from another goroutine. // // Safe for concurrent use by multiple goroutines. -func (mem *CListMempool) CheckTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), - checkTxCb func(*ocabci.Response)) { +func (mem *CListMempool) CheckTxAsync( + tx types.Tx, + txInfo mempool.TxInfo, + prepareCb func(error), + checkTxCb func(*ocabci.Response), +) { mem.chReqCheckTx <- &requestCheckTxAsync{tx: tx, txInfo: txInfo, prepareCb: prepareCb, checkTxCb: checkTxCb} } @@ -276,8 +250,12 @@ func (mem *CListMempool) checkTxAsyncReactor() { } // It blocks if we're waiting on Update() or Reap(). -func (mem *CListMempool) checkTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func(error), - checkTxCb func(*ocabci.Response)) { +func (mem *CListMempool) checkTxAsync( + tx types.Tx, + txInfo mempool.TxInfo, + prepareCb func(error), + checkTxCb func(*ocabci.Response), +) { mem.updateMtx.RLock() defer func() { if r := recover(); r != nil { @@ -307,10 +285,10 @@ func (mem *CListMempool) checkTxAsync(tx types.Tx, txInfo TxInfo, prepareCb func } // CONTRACT: `caller` should held `mem.updateMtx.RLock()` -func (mem *CListMempool) prepareCheckTx(tx types.Tx, txInfo TxInfo) error { +func (mem *CListMempool) prepareCheckTx(tx types.Tx, txInfo mempool.TxInfo) error { // For keeping the consistency between `mem.txs` and `mem.txsMap` - if _, ok := mem.txsMap.Load(TxKey(tx)); ok { - return ErrTxInMap + if _, ok := mem.txsMap.Load(tx.Key()); ok { + return mempool.ErrTxInMap } txSize := len(tx) @@ -320,24 +298,17 @@ func (mem *CListMempool) prepareCheckTx(tx types.Tx, txInfo TxInfo) error { } if txSize > mem.config.MaxTxBytes { - return ErrTxTooLarge{mem.config.MaxTxBytes, txSize} + return mempool.ErrTxTooLarge{ + Max: mem.config.MaxTxBytes, + Actual: txSize, + } } if mem.preCheck != nil { if err := mem.preCheck(tx); err != nil { - return ErrPreCheck{err} - } - } - - // NOTE: writing to the WAL and calling proxy must be done before adding tx - // to the cache. otherwise, if either of them fails, next time CheckTx is - // called with tx, ErrTxInCache will be returned without tx being checked at - // all even once. - if mem.wal != nil { - // TODO: Notify administrators when WAL fails - _, err := mem.wal.Write(append([]byte(tx), newline...)) - if err != nil { - return fmt.Errorf("wal.Write: %w", err) + return mempool.ErrPreCheck{ + Reason: err, + } } } @@ -346,20 +317,19 @@ func (mem *CListMempool) prepareCheckTx(tx types.Tx, txInfo TxInfo) error { return err } - if !mem.cache.Push(tx) { + if !mem.cache.Push(tx) { // if the transaction already exists in the cache // Record a new sender for a tx we've already seen. // Note it's possible a tx is still in the cache but no longer in the mempool // (eg. after committing a block, txs are removed from mempool but not cache), // so we only record the sender for txs still in the mempool. - if e, ok := mem.txsMap.Load(TxKey(tx)); ok { + if e, ok := mem.txsMap.Load(tx.Key()); ok { memTx := e.(*clist.CElement).Value.(*mempoolTx) memTx.senders.LoadOrStore(txInfo.SenderID, true) // TODO: consider punishing peer for dups, // its non-trivial since invalid txs can become valid, // but they can spam the same tx with little cost to them atm. } - - return ErrTxInCache + return mempool.ErrTxInCache } // reserve mempool that should be called just before calling `mem.proxyAppConn.CheckTxAsync()` @@ -388,7 +358,7 @@ func (mem *CListMempool) globalCb(req *ocabci.Request, res *ocabci.Response) { } if checkTxReq.Type == abci.CheckTxType_Recheck { - mem.metrics.RecheckCount.Add(1) + mem.metrics.RecheckTimes.Add(1) mem.resCbRecheck(req, res) // update metrics @@ -424,21 +394,21 @@ func (mem *CListMempool) reqResCb( } // Called from: -// - resCbFirstTime (lock not held) if tx is valid +// - resCbFirstTime (lock not held) if tx is valid func (mem *CListMempool) addTx(memTx *mempoolTx) { e := mem.txs.PushBack(memTx) - mem.txsMap.Store(TxKey(memTx.tx), e) + mem.txsMap.Store(memTx.tx.Key(), e) atomic.AddInt64(&mem.txsBytes, int64(len(memTx.tx))) mem.metrics.TxSizeBytes.Observe(float64(len(memTx.tx))) } // Called from: -// - Update (lock held) if tx was committed -// - resCbRecheck (lock not held) if tx was invalidated +// - Update (lock held) if tx was committed +// - resCbRecheck (lock not held) if tx was invalidated func (mem *CListMempool) removeTx(tx types.Tx, elem *clist.CElement, removeFromCache bool) { mem.txs.Remove(elem) elem.DetachPrev() - mem.txsMap.Delete(TxKey(tx)) + mem.txsMap.Delete(tx.Key()) atomic.AddInt64(&mem.txsBytes, int64(-len(tx))) if removeFromCache { @@ -447,25 +417,30 @@ func (mem *CListMempool) removeTx(tx types.Tx, elem *clist.CElement, removeFromC } // RemoveTxByKey removes a transaction from the mempool by its TxKey index. -func (mem *CListMempool) RemoveTxByKey(txKey [TxKeySize]byte, removeFromCache bool) { +func (mem *CListMempool) RemoveTxByKey(txKey types.TxKey) error { if e, ok := mem.txsMap.Load(txKey); ok { memTx := e.(*clist.CElement).Value.(*mempoolTx) if memTx != nil { - mem.removeTx(memTx.tx, e.(*clist.CElement), removeFromCache) + mem.removeTx(memTx.tx, e.(*clist.CElement), false) + return nil } + return errors.New("transaction not found") } + return errors.New("invalid transaction found") } func (mem *CListMempool) isFull(txSize int) error { var ( memSize = mem.Size() - txsBytes = mem.TxsBytes() + txsBytes = mem.SizeBytes() ) if memSize >= mem.config.Size || int64(txSize)+txsBytes > mem.config.MaxTxsBytes { - return ErrMempoolIsFull{ - memSize, mem.config.Size, - txsBytes, mem.config.MaxTxsBytes, + return mempool.ErrMempoolIsFull{ + NumTxs: memSize, + MaxTxs: mem.config.Size, + TxsBytes: txsBytes, + MaxTxsBytes: mem.config.MaxTxsBytes, } } @@ -478,13 +453,15 @@ func (mem *CListMempool) reserve(txSize int64) error { var ( memSize = mem.Size() - txsBytes = mem.TxsBytes() + txsBytes = mem.SizeBytes() ) if memSize+mem.reserved >= mem.config.Size || txSize+mem.reservedBytes+txsBytes > mem.config.MaxTxsBytes { - return ErrMempoolIsFull{ - memSize + mem.reserved, mem.config.Size, - txsBytes + mem.reservedBytes, mem.config.MaxTxsBytes, + return mempool.ErrMempoolIsFull{ + NumTxs: memSize + mem.reserved, + MaxTxs: mem.config.Size, + TxsBytes: txsBytes + mem.reservedBytes, + MaxTxsBytes: mem.config.MaxTxsBytes, } } @@ -521,8 +498,9 @@ func (mem *CListMempool) resCbFirstTime( } memTx.senders.Store(peerID, true) mem.addTx(memTx) - mem.logger.Debug("added good transaction", - "tx", txID(tx), + mem.logger.Debug( + "added good transaction", + "tx", types.Tx(tx).Hash(), "res", r, "height", memTx.height, "total", mem.Size(), @@ -530,9 +508,14 @@ func (mem *CListMempool) resCbFirstTime( mem.notifyTxsAvailable() } else { // ignore bad transaction - mem.logger.Debug("rejected bad transaction", - "tx", txID(tx), "peerID", peerP2PID, "res", r) + mem.logger.Debug( + "rejected bad transaction", + "tx", types.Tx(tx).Hash(), + "peerID", peerP2PID, + "res", r, + ) mem.metrics.FailedTxs.Add(1) + if !mem.config.KeepInvalidTxsInCache { // remove from cache (it might be good later) mem.cache.Remove(tx) @@ -554,12 +537,12 @@ func (mem *CListMempool) resCbRecheck(req *ocabci.Request, res *ocabci.Response) switch r := res.Value.(type) { case *ocabci.Response_CheckTx: tx := req.GetCheckTx().Tx - txHash := TxKey(tx) - e, ok := mem.txsMap.Load(txHash) + e, ok := mem.txsMap.Load(types.Tx(tx).Key()) if !ok { - mem.logger.Debug("re-CheckTx transaction does not exist", "expected", types.Tx(tx)) + mem.logger.Debug("re-CheckTx transaction does not exist", "expected", types.Tx(tx).Hash()) return } + var postCheckErr error if r.CheckTx.Code == ocabci.CodeTypeOK { if mem.postCheck == nil { @@ -573,7 +556,11 @@ func (mem *CListMempool) resCbRecheck(req *ocabci.Request, res *ocabci.Response) } celem := e.(*clist.CElement) // Tx became invalidated due to newly committed block. - mem.logger.Debug("tx is no longer valid", "tx", txID(tx), "res", r, "err", postCheckErr) + mem.logger.Debug("tx is no longer valid", + "tx", types.Tx(tx).Hash(), + "res", r, + "err", postCheckErr, + ) // NOTE: we remove tx from the cache because it might be good later mem.removeTx(tx, celem, !mem.config.KeepInvalidTxsInCache) default: @@ -605,31 +592,40 @@ func (mem *CListMempool) ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs { mem.updateMtx.RLock() defer mem.updateMtx.RUnlock() - var totalGas int64 + var ( + totalGas int64 + runningSize int64 + ) // TODO: we will get a performance boost if we have a good estimate of avg // size per tx, and set the initial capacity based off of that. // txs := make([]types.Tx, 0, tmmath.MinInt(mem.txs.Len(), max/mem.avgTxSize)) txs := make([]types.Tx, 0, mem.txs.Len()) - protoTxs := tmproto.Data{} for e := mem.txs.Front(); e != nil; e = e.Next() { memTx := e.Value.(*mempoolTx) + txs = append(txs, memTx.tx) + + protoTxs := tmproto.Data{} protoTxs.Txs = append(protoTxs.Txs, memTx.tx) + dataSize := int64(protoTxs.Size()) + // Check total size requirement - if maxBytes > -1 && int64(protoTxs.Size()) > maxBytes { - return txs + if maxBytes > -1 && runningSize+dataSize > maxBytes { + return txs[:len(txs)-1] } + + runningSize += dataSize + // Check total gas requirement. // If maxGas is negative, skip this check. // Since newTotalGas < masGas, which // must be non-negative, it follows that this won't overflow. newTotalGas := totalGas + memTx.gasWanted if maxGas > -1 && newTotalGas > maxGas { - return txs + return txs[:len(txs)-1] } totalGas = newTotalGas - txs = append(txs, memTx.tx) } return txs } @@ -639,35 +635,44 @@ func (mem *CListMempool) ReapMaxBytesMaxGasMaxTxs(maxBytes, maxGas, maxTxs int64 mem.updateMtx.RLock() defer mem.updateMtx.RUnlock() - var totalGas int64 - if maxTxs <= 0 { maxTxs = int64(mem.txs.Len()) } + var ( + totalGas int64 + runningSize int64 + ) + // TODO: we will get a performance boost if we have a good estimate of avg // size per tx, and set the initial capacity based off of that. // txs := make([]types.Tx, 0, tmmath.MinInt(mem.txs.Len(), max/mem.avgTxSize)) txs := make([]types.Tx, 0, mem.txs.Len()) - protoTxs := tmproto.Data{} for e := mem.txs.Front(); e != nil && len(txs) < int(maxTxs); e = e.Next() { memTx := e.Value.(*mempoolTx) + txs = append(txs, memTx.tx) + + protoTxs := tmproto.Data{} protoTxs.Txs = append(protoTxs.Txs, memTx.tx) + dataSize := int64(protoTxs.Size()) + // Check total size requirement - if maxBytes > -1 && int64(protoTxs.Size()) > maxBytes { - return txs + if maxBytes > -1 && runningSize+dataSize > maxBytes { + return txs[:len(txs)-1] } + + runningSize += dataSize + // Check total gas requirement. // If maxGas is negative, skip this check. // Since newTotalGas < masGas, which // must be non-negative, it follows that this won't overflow. newTotalGas := totalGas + memTx.gasWanted if maxGas > -1 && newTotalGas > maxGas { - return txs + return txs[:len(txs)-1] } totalGas = newTotalGas - txs = append(txs, memTx.tx) } return txs } @@ -693,8 +698,8 @@ func (mem *CListMempool) ReapMaxTxs(max int) types.Txs { func (mem *CListMempool) Update( block *types.Block, deliverTxResponses []*abci.ResponseDeliverTx, - preCheck PreCheckFunc, - postCheck PostCheckFunc, + preCheck mempool.PreCheckFunc, + postCheck mempool.PostCheckFunc, ) (err error) { // Set height mem.height = block.Height @@ -726,7 +731,7 @@ func (mem *CListMempool) Update( // Mempool after: // 100 // https://github.com/tendermint/tendermint/issues/3322. - if e, ok := mem.txsMap.Load(TxKey(tx)); ok { + if e, ok := mem.txsMap.Load(tx.Key()); ok { mem.removeTx(tx, e.(*clist.CElement), false) } } @@ -809,98 +814,3 @@ type mempoolTx struct { func (memTx *mempoolTx) Height() int64 { return atomic.LoadInt64(&memTx.height) } - -//-------------------------------------------------------------------------------- - -type txCache interface { - Reset() - Push(tx types.Tx) bool - Remove(tx types.Tx) -} - -// mapTxCache maintains a LRU cache of transactions. This only stores the hash -// of the tx, due to memory concerns. -type mapTxCache struct { - mtx tmsync.Mutex - size int - cacheMap map[[TxKeySize]byte]*list.Element - list *list.List -} - -var _ txCache = (*mapTxCache)(nil) - -// newMapTxCache returns a new mapTxCache. -func newMapTxCache(cacheSize int) *mapTxCache { - return &mapTxCache{ - size: cacheSize, - cacheMap: make(map[[TxKeySize]byte]*list.Element, cacheSize), - list: list.New(), - } -} - -// Reset resets the cache to an empty state. -func (cache *mapTxCache) Reset() { - cache.mtx.Lock() - cache.cacheMap = make(map[[TxKeySize]byte]*list.Element, cache.size) - cache.list.Init() - cache.mtx.Unlock() -} - -// Push adds the given tx to the cache and returns true. It returns -// false if tx is already in the cache. -func (cache *mapTxCache) Push(tx types.Tx) bool { - cache.mtx.Lock() - defer cache.mtx.Unlock() - - // Use the tx hash in the cache - txHash := TxKey(tx) - if moved, exists := cache.cacheMap[txHash]; exists { - cache.list.MoveToBack(moved) - return false - } - - if cache.list.Len() >= cache.size { - popped := cache.list.Front() - if popped != nil { - poppedTxHash := popped.Value.([TxKeySize]byte) - delete(cache.cacheMap, poppedTxHash) - cache.list.Remove(popped) - } - } - e := cache.list.PushBack(txHash) - cache.cacheMap[txHash] = e - return true -} - -// Remove removes the given tx from the cache. -func (cache *mapTxCache) Remove(tx types.Tx) { - cache.mtx.Lock() - txHash := TxKey(tx) - popped := cache.cacheMap[txHash] - delete(cache.cacheMap, txHash) - if popped != nil { - cache.list.Remove(popped) - } - - cache.mtx.Unlock() -} - -type nopTxCache struct{} - -var _ txCache = (*nopTxCache)(nil) - -func (nopTxCache) Reset() {} -func (nopTxCache) Push(types.Tx) bool { return true } -func (nopTxCache) Remove(types.Tx) {} - -//-------------------------------------------------------------------------------- - -// TxKey is the fixed length array hash used as the key in maps. -func TxKey(tx types.Tx) [TxKeySize]byte { - return sha256.Sum256(tx) -} - -// txID is a hash of the Tx. -func txID(tx []byte) []byte { - return types.Tx(tx).Hash() -} diff --git a/mempool/clist_mempool_system_test.go b/mempool/v0/clist_mempool_system_test.go similarity index 96% rename from mempool/clist_mempool_system_test.go rename to mempool/v0/clist_mempool_system_test.go index 8fc04345f..de329466e 100644 --- a/mempool/clist_mempool_system_test.go +++ b/mempool/v0/clist_mempool_system_test.go @@ -1,4 +1,4 @@ -package mempool +package v0 import ( "context" @@ -13,6 +13,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" tmversion "github.com/tendermint/tendermint/proto/tendermint/version" @@ -21,10 +22,10 @@ import ( ocabci "github.com/Finschia/ostracon/abci/types" "github.com/Finschia/ostracon/config" "github.com/Finschia/ostracon/libs/log" + "github.com/Finschia/ostracon/mempool" "github.com/Finschia/ostracon/proxy" "github.com/Finschia/ostracon/types" "github.com/Finschia/ostracon/version" - "github.com/stretchr/testify/require" ) func setupCListMempool(ctx context.Context, t testing.TB, @@ -122,23 +123,23 @@ func commitBlock(ctx context.Context, t *testing.T, func receiveTx(ctx context.Context, t *testing.T, mem *CListMempool, tx []byte, receiveTxCounter *receiveTxCounter) { atomic.AddInt64(&receiveTxCounter.sent, 1) - txInfo := TxInfo{} + txInfo := mempool.TxInfo{} // mempool.lock/unlock in CheckTxAsync mem.CheckTxAsync(tx, txInfo, func(err error) { if err != nil { switch err { - case ErrTxInCache: + case mempool.ErrTxInCache: atomic.AddInt64(&receiveTxCounter.failInCache, 1) - case ErrTxInMap: + case mempool.ErrTxInMap: atomic.AddInt64(&receiveTxCounter.failInMap, 1) } switch err.(type) { - case ErrTxTooLarge: + case mempool.ErrTxTooLarge: atomic.AddInt64(&receiveTxCounter.failTooLarge, 1) - case ErrMempoolIsFull: + case mempool.ErrMempoolIsFull: atomic.AddInt64(&receiveTxCounter.failIsFull, 1) - case ErrPreCheck: + case mempool.ErrPreCheck: atomic.AddInt64(&receiveTxCounter.failPreCheck, 1) } } diff --git a/mempool/clist_mempool_test.go b/mempool/v0/clist_mempool_test.go similarity index 59% rename from mempool/clist_mempool_test.go rename to mempool/v0/clist_mempool_test.go index 81c1c861f..137244adb 100644 --- a/mempool/clist_mempool_test.go +++ b/mempool/v0/clist_mempool_test.go @@ -1,15 +1,12 @@ -package mempool +package v0 import ( "crypto/rand" - "crypto/sha256" "encoding/binary" "errors" "fmt" - "io/ioutil" mrand "math/rand" "os" - "path/filepath" "sync" "testing" "time" @@ -21,14 +18,15 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/Finschia/ostracon/abci/example/counter" + abciclient "github.com/Finschia/ostracon/abci/client" "github.com/Finschia/ostracon/abci/example/kvstore" abciserver "github.com/Finschia/ostracon/abci/server" ocabci "github.com/Finschia/ostracon/abci/types" - cfg "github.com/Finschia/ostracon/config" + "github.com/Finschia/ostracon/config" "github.com/Finschia/ostracon/libs/log" tmrand "github.com/Finschia/ostracon/libs/rand" "github.com/Finschia/ostracon/libs/service" + "github.com/Finschia/ostracon/mempool" "github.com/Finschia/ostracon/proxy" "github.com/Finschia/ostracon/types" ) @@ -37,20 +35,48 @@ import ( // test. type cleanupFunc func() +//func newMempoolWithAppMock(cc proxy.ClientCreator, client abciclient.Client) (*CListMempool, cleanupFunc, error) { +// conf := config.ResetTestRoot("mempool_test") +// +// mp, cu := newMempoolWithAppAndConfigMock(cc, conf, client) +// return mp, cu, nil +//} +// +//func newMempoolWithAppAndConfigMock(cc proxy.ClientCreator, +// cfg *config.Config, +// client abciclient.Client) (*CListMempool, cleanupFunc) { +// appConnMem := client +// appConnMem.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "mempool")) +// err := appConnMem.Start() +// if err != nil { +// panic(err) +// } +// +// mp := NewCListMempool(cfg.Mempool, appConnMem, 0) +// mp.SetLogger(log.TestingLogger()) +// +// return mp, func() { os.RemoveAll(cfg.RootDir) } +//} + func newMempoolWithApp(cc proxy.ClientCreator) (*CListMempool, cleanupFunc) { - return newMempoolWithAppAndConfig(cc, cfg.ResetTestRoot("mempool_test")) + conf := config.ResetTestRoot("mempool_test") + + mp, cu := newMempoolWithAppAndConfig(cc, conf) + return mp, cu } -func newMempoolWithAppAndConfig(cc proxy.ClientCreator, config *cfg.Config) (*CListMempool, cleanupFunc) { +func newMempoolWithAppAndConfig(cc proxy.ClientCreator, cfg *config.Config) (*CListMempool, cleanupFunc) { appConnMem, _ := cc.NewABCIClient() appConnMem.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "mempool")) err := appConnMem.Start() if err != nil { panic(err) } - mempool := NewCListMempool(config.Mempool, appConnMem, 0) - mempool.SetLogger(log.TestingLogger()) - return mempool, func() { os.RemoveAll(config.RootDir) } + + mp := NewCListMempool(cfg.Mempool, appConnMem, 0) + mp.SetLogger(log.TestingLogger()) + + return mp, func() { os.RemoveAll(cfg.RootDir) } } func ensureNoFire(t *testing.T, ch <-chan struct{}, timeoutMS int) { @@ -71,9 +97,9 @@ func ensureFire(t *testing.T, ch <-chan struct{}, timeoutMS int) { } } -func checkTxs(t *testing.T, mempool Mempool, count int, peerID uint16) types.Txs { +func checkTxs(t *testing.T, mp mempool.Mempool, count int, peerID uint16) types.Txs { txs := make(types.Txs, count) - txInfo := TxInfo{SenderID: peerID} + txInfo := mempool.TxInfo{SenderID: peerID} for i := 0; i < count; i++ { txBytes := make([]byte, 20) txs[i] = txBytes @@ -81,11 +107,11 @@ func checkTxs(t *testing.T, mempool Mempool, count int, peerID uint16) types.Txs if err != nil { t.Error(err) } - if _, err := mempool.CheckTxSync(txBytes, txInfo); err != nil { + if err := mp.CheckTxSync(txBytes, nil, txInfo); err != nil { // Skip invalid txs. // TestMempoolFilters will fail otherwise. It asserts a number of txs // returned. - if IsPreCheckError(err) { + if mempool.IsPreCheckError(err) { continue } t.Fatalf("CheckTx failed: %v while checking #%d tx", err, i) @@ -97,19 +123,19 @@ func checkTxs(t *testing.T, mempool Mempool, count int, peerID uint16) types.Txs func TestReapMaxBytesMaxGas(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() // Ensure gas calculation behaves as expected - checkTxs(t, mempool, 1, UnknownPeerID) - tx0 := mempool.TxsFront().Value.(*mempoolTx) + checkTxs(t, mp, 1, mempool.UnknownPeerID) + tx0 := mp.TxsFront().Value.(*mempoolTx) // assert that kv store has gas wanted = 1. require.Equal(t, app.CheckTxSync(abci.RequestCheckTx{Tx: tx0.tx}).GasWanted, int64(1), "KVStore had a gas value neq to 1") require.Equal(t, tx0.gasWanted, int64(1), "transactions gas was set incorrectly") // ensure each tx is 20 bytes long require.Equal(t, len(tx0.tx), 20, "Tx is longer than 20 bytes") - mempool.Flush() + mp.Flush() // each table driven test creates numTxsToCreate txs with checkTx, and at the end clears all remaining txs. // each tx has 20 bytes @@ -140,23 +166,23 @@ func TestReapMaxBytesMaxGas(t *testing.T) { {20, 20000, 30, 20, 100}, } for tcIndex, tt := range tests { - checkTxs(t, mempool, tt.numTxsToCreate, UnknownPeerID) + checkTxs(t, mp, tt.numTxsToCreate, mempool.UnknownPeerID) var got types.Txs if tt.maxTxs <= 0 { - got = mempool.ReapMaxBytesMaxGas(tt.maxBytes, tt.maxGas) + got = mp.ReapMaxBytesMaxGas(tt.maxBytes, tt.maxGas) } else { - got = mempool.ReapMaxBytesMaxGasMaxTxs(tt.maxBytes, tt.maxGas, tt.maxTxs) + got = mp.ReapMaxBytesMaxGasMaxTxs(tt.maxBytes, tt.maxGas, tt.maxTxs) } assert.Equal(t, tt.expectedNumTxs, len(got), "Got %d txs, expected %d, tc #%d", len(got), tt.expectedNumTxs, tcIndex) - mempool.Flush() + mp.Flush() } } func TestMempoolFilters(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() emptyTxArr := []types.Tx{[]byte{}} @@ -166,70 +192,120 @@ func TestMempoolFilters(t *testing.T) { // each tx has 20 bytes tests := []struct { numTxsToCreate int - preFilter PreCheckFunc + preFilter mempool.PreCheckFunc expectedNumTxs int }{ {10, nopPreFilter, 10}, - {10, PreCheckMaxBytes(10), 0}, - {10, PreCheckMaxBytes(20), 0}, - {10, PreCheckMaxBytes(22), 10}, - {10, PreCheckMaxBytes(30), 10}, + {10, mempool.PreCheckMaxBytes(10), 0}, + {10, mempool.PreCheckMaxBytes(20), 0}, + {10, mempool.PreCheckMaxBytes(22), 10}, + {10, mempool.PreCheckMaxBytes(30), 10}, } for tcIndex, tt := range tests { - err := mempool.Update(newTestBlock(1, emptyTxArr), - abciResponses(len(emptyTxArr), ocabci.CodeTypeOK), tt.preFilter, nil) + err := mp.Update(newTestBlock(1, emptyTxArr), abciResponses(len(emptyTxArr), abci.CodeTypeOK), tt.preFilter, nil) require.NoError(t, err) - checkTxs(t, mempool, tt.numTxsToCreate, UnknownPeerID) - require.Equal(t, tt.expectedNumTxs, mempool.Size(), "mempool had the incorrect size, on test case %d", tcIndex) - mempool.Flush() + checkTxs(t, mp, tt.numTxsToCreate, mempool.UnknownPeerID) + require.Equal(t, tt.expectedNumTxs, mp.Size(), "mempool had the incorrect size, on test case %d", tcIndex) + mp.Flush() } } func TestMempoolUpdate(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() // 1. Adds valid txs to the cache { - err := mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), + err := mp.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), abciResponses(1, ocabci.CodeTypeOK), nil, nil) require.NoError(t, err) - _, err = mempool.CheckTxSync([]byte{0x01}, TxInfo{}) + err = mp.CheckTxSync([]byte{0x01}, nil, mempool.TxInfo{}) if assert.Error(t, err) { - assert.Equal(t, ErrTxInCache, err) + assert.Equal(t, mempool.ErrTxInCache, err) } } // 2. Removes valid txs from the mempool { - _, err := mempool.CheckTxSync([]byte{0x02}, TxInfo{}) + err := mp.CheckTxSync([]byte{0x02}, nil, mempool.TxInfo{}) require.NoError(t, err) - err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x02}}), abciResponses(1, ocabci.CodeTypeOK), nil, nil) + err = mp.Update(newTestBlock(1, []types.Tx{[]byte{0x02}}), abciResponses(1, ocabci.CodeTypeOK), nil, nil) require.NoError(t, err) - assert.Zero(t, mempool.Size()) + assert.Zero(t, mp.Size()) } // 3. Removes invalid transactions from the cache and the mempool (if present) { - _, err := mempool.CheckTxSync([]byte{0x03}, TxInfo{}) + err := mp.CheckTxSync([]byte{0x03}, nil, mempool.TxInfo{}) require.NoError(t, err) - err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x03}}), abciResponses(1, 1), nil, nil) + err = mp.Update(newTestBlock(1, []types.Tx{[]byte{0x03}}), abciResponses(1, 1), nil, nil) require.NoError(t, err) - assert.Zero(t, mempool.Size()) + assert.Zero(t, mp.Size()) - _, err = mempool.CheckTxSync([]byte{0x03}, TxInfo{}) + err = mp.CheckTxSync([]byte{0x03}, nil, mempool.TxInfo{}) require.NoError(t, err) } } +// FIXME: need to adjust Ostracon's abci +//func TestMempoolUpdateDoesNotPanicWhenApplicationMissedTx(t *testing.T) { +// var callback abciclient.Callback +// mockClient := new(abciclimocks.Client) +// mockClient.On("Start").Return(nil) +// mockClient.On("SetLogger", mock.Anything) +// +// mockClient.On("Error").Return(nil).Times(4) +// mockClient.On("FlushAsync", mock.Anything).Return(abciclient.NewReqRes(abci.ToRequestFlush()), nil) +// mockClient.On("SetResponseCallback", mock.MatchedBy(func(cb abciclient.Callback) bool { callback = cb; return true })) +// +// app := kvstore.NewApplication() +// cc := proxy.NewLocalClientCreator(app) +// mp, cleanup, err := newMempoolWithAppMock(cc, mockClient) +// require.NoError(t, err) +// defer cleanup() +// +// // Add 4 transactions to the mempool by calling the mempool's `CheckTx` on each of them. +// txs := []types.Tx{[]byte{0x01}, []byte{0x02}, []byte{0x03}, []byte{0x04}} +// for _, tx := range txs { +// reqRes := abciclient.NewReqRes(abci.ToRequestCheckTx(abci.RequestCheckTx{Tx: tx})) +// reqRes.Response = abci.ToResponseCheckTx(abci.ResponseCheckTx{Code: abci.CodeTypeOK}) +// +// mockClient.On("CheckTxAsync", mock.Anything, mock.Anything).Return(reqRes, nil) +// err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}) +// require.NoError(t, err) +// +// // ensure that the callback that the mempool sets on the ReqRes is run. +// reqRes.InvokeCallback() +// } +// +// // Calling update to remove the first transaction from the mempool. +// // This call also triggers the mempool to recheck its remaining transactions. +// err = mp.Update(0, []types.Tx{txs[0]}, abciResponses(1, abci.CodeTypeOK), nil, nil) +// require.Nil(t, err) +// +// // The mempool has now sent its requests off to the client to be rechecked +// // and is waiting for the corresponding callbacks to be called. +// // We now call the mempool-supplied callback on the first and third transaction. +// // This simulates the client dropping the second request. +// // Previous versions of this code panicked when the ABCI application missed +// // a recheck-tx request. +// resp := abci.ResponseCheckTx{Code: abci.CodeTypeOK} +// req := abci.RequestCheckTx{Tx: txs[1]} +// callback(abci.ToRequestCheckTx(req), abci.ToResponseCheckTx(resp)) +// +// req = abci.RequestCheckTx{Tx: txs[3]} +// callback(abci.ToRequestCheckTx(req), abci.ToResponseCheckTx(resp)) +// mockClient.AssertExpectations(t) +//} + func TestMempool_KeepInvalidTxsInCache(t *testing.T) { - app := counter.NewApplication(true) + app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - wcfg := cfg.DefaultConfig() + wcfg := config.DefaultConfig() wcfg.Mempool.KeepInvalidTxsInCache = true - mempool, cleanup := newMempoolWithAppAndConfig(cc, wcfg) + mp, cleanup := newMempoolWithAppAndConfig(cc, wcfg) defer cleanup() // 1. An invalid transaction must remain in the cache after Update @@ -240,43 +316,45 @@ func TestMempool_KeepInvalidTxsInCache(t *testing.T) { b := make([]byte, 8) binary.BigEndian.PutUint64(b, 1) - _, err := mempool.CheckTxSync(b, TxInfo{}) + err := mp.CheckTxSync(b, nil, mempool.TxInfo{}) require.NoError(t, err) // simulate new block _ = app.DeliverTx(abci.RequestDeliverTx{Tx: a}) _ = app.DeliverTx(abci.RequestDeliverTx{Tx: b}) - err = mempool.Update(newTestBlock(1, []types.Tx{a, b}), + err = mp.Update(newTestBlock(1, []types.Tx{a, b}), []*abci.ResponseDeliverTx{{Code: ocabci.CodeTypeOK}, {Code: 2}}, nil, nil) require.NoError(t, err) // a must be added to the cache - _, err = mempool.CheckTxSync(a, TxInfo{}) + err = mp.CheckTxSync(a, nil, mempool.TxInfo{}) if assert.Error(t, err) { - assert.Equal(t, ErrTxInCache, err) + assert.Equal(t, mempool.ErrTxInCache, err) } // b must remain in the cache - _, err = mempool.CheckTxSync(b, TxInfo{}) + err = mp.CheckTxSync(b, nil, mempool.TxInfo{}) if assert.Error(t, err) { - assert.Equal(t, ErrTxInCache, err) + assert.Equal(t, mempool.ErrTxInCache, err) } } - // 2. An invalid transaction must remain in the cache + // 2. An invalid transaction must remain in the Map since checking first in Map on prepareCheckTx { a := make([]byte, 8) binary.BigEndian.PutUint64(a, 0) // remove a from the cache to test (2) - mempool.cache.Remove(a) + mp.cache.Remove(a) - _, err := mempool.CheckTxSync(a, TxInfo{}) + err := mp.CheckTxSync(a, nil, mempool.TxInfo{}) require.NoError(t, err) - _, err = mempool.CheckTxSync(a, TxInfo{}) + err = mp.CheckTxSync(a, nil, mempool.TxInfo{}) if assert.Error(t, err) { - assert.Equal(t, ErrTxInCache, err) + // NOTE: After changing the application KVStore from Counter, + // KVStore doesn't return CodeTypeBadNonce like before Counter + assert.Equal(t, mempool.ErrTxInMap, err) } } } @@ -284,55 +362,54 @@ func TestMempool_KeepInvalidTxsInCache(t *testing.T) { func TestTxsAvailable(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() - mempool.EnableTxsAvailable() + mp.EnableTxsAvailable() timeoutMS := 500 // with no txs, it shouldnt fire - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) // send a bunch of txs, it should only fire once - txs := checkTxs(t, mempool, 100, UnknownPeerID) - ensureFire(t, mempool.TxsAvailable(), timeoutMS) - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + txs := checkTxs(t, mp, 100, mempool.UnknownPeerID) + ensureFire(t, mp.TxsAvailable(), timeoutMS) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) // call update with half the txs. // it should fire once now for the new height // since there are still txs left committedTxs, txs := txs[:50], txs[50:] - if err := mempool.Update(newTestBlock(1, committedTxs), + if err := mp.Update(newTestBlock(1, committedTxs), abciResponses(len(committedTxs), ocabci.CodeTypeOK), nil, nil); err != nil { t.Error(err) } - ensureFire(t, mempool.TxsAvailable(), timeoutMS) - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + ensureFire(t, mp.TxsAvailable(), timeoutMS) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) // send a bunch more txs. we already fired for this height so it shouldnt fire again - moreTxs := checkTxs(t, mempool, 50, UnknownPeerID) - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + moreTxs := checkTxs(t, mp, 50, mempool.UnknownPeerID) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) // now call update with all the txs. it should not fire as there are no txs left committedTxs = append(txs, moreTxs...) // nolint: gocritic - if err := mempool.Update(newTestBlock(2, committedTxs), + if err := mp.Update(newTestBlock(2, committedTxs), abciResponses(len(committedTxs), ocabci.CodeTypeOK), nil, nil); err != nil { t.Error(err) } - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) // send a bunch more txs, it should only fire once - checkTxs(t, mempool, 100, UnknownPeerID) - ensureFire(t, mempool.TxsAvailable(), timeoutMS) - ensureNoFire(t, mempool.TxsAvailable(), timeoutMS) + checkTxs(t, mp, 100, mempool.UnknownPeerID) + ensureFire(t, mp.TxsAvailable(), timeoutMS) + ensureNoFire(t, mp.TxsAvailable(), timeoutMS) } func TestSerialReap(t *testing.T) { - app := counter.NewApplication(true) - app.SetOption(abci.RequestSetOption{Key: "serial", Value: "on"}) + app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() appConnCon, _ := cc.NewABCIClient() @@ -348,7 +425,7 @@ func TestSerialReap(t *testing.T) { // This will succeed txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - _, err := mempool.CheckTxSync(txBytes, TxInfo{}) + err := mp.CheckTxSync(txBytes, nil, mempool.TxInfo{}) _, cached := cacheMap[string(txBytes)] if cached { require.NotNil(t, err, "expected error for cached tx") @@ -358,13 +435,13 @@ func TestSerialReap(t *testing.T) { cacheMap[string(txBytes)] = struct{}{} // Duplicates are cached and should return error - _, err = mempool.CheckTxSync(txBytes, TxInfo{}) + err = mp.CheckTxSync(txBytes, nil, mempool.TxInfo{}) require.NotNil(t, err, "Expected error after CheckTx on duplicated tx") } } reapCheck := func(exp int) { - txs := mempool.ReapMaxBytesMaxGas(-1, -1) + txs := mp.ReapMaxBytesMaxGas(-1, -1) require.Equal(t, len(txs), exp, fmt.Sprintf("Expected to reap %v txs but got %v", exp, len(txs))) } @@ -375,7 +452,7 @@ func TestSerialReap(t *testing.T) { binary.BigEndian.PutUint64(txBytes, uint64(i)) txs = append(txs, txBytes) } - if err := mempool.Update(newTestBlock(0, txs), + if err := mp.Update(newTestBlock(0, txs), abciResponses(len(txs), ocabci.CodeTypeOK), nil, nil); err != nil { t.Error(err) } @@ -439,58 +516,10 @@ func TestSerialReap(t *testing.T) { reapCheck(600) } -func TestMempoolCloseWAL(t *testing.T) { - // 1. Create the temporary directory for mempool and WAL testing. - rootDir, err := ioutil.TempDir("", "mempool-test") - require.Nil(t, err, "expecting successful tmpdir creation") - - // 2. Ensure that it doesn't contain any elements -- Sanity check - m1, err := filepath.Glob(filepath.Join(rootDir, "*")) - require.Nil(t, err, "successful globbing expected") - require.Equal(t, 0, len(m1), "no matches yet") - - // 3. Create the mempool - wcfg := cfg.DefaultConfig() - wcfg.Mempool.RootDir = rootDir - app := kvstore.NewApplication() - cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithAppAndConfig(cc, wcfg) - defer cleanup() - mempool.height = 10 - err = mempool.InitWAL() - require.NoError(t, err) - - // 4. Ensure that the directory contains the WAL file - m2, err := filepath.Glob(filepath.Join(rootDir, "*")) - require.Nil(t, err, "successful globbing expected") - require.Equal(t, 1, len(m2), "expecting the wal match in") - - // 5. Write some contents to the WAL - _, err = mempool.CheckTxSync(types.Tx([]byte("foo")), TxInfo{}) - require.NoError(t, err) - walFilepath := mempool.wal.Path - sum1 := checksumFile(walFilepath, t) - - // 6. Sanity check to ensure that the written TX matches the expectation. - require.Equal(t, sum1, checksumIt([]byte("foo\n")), "foo with a newline should be written") - - // 7. Invoke CloseWAL() and ensure it discards the - // WAL thus any other write won't go through. - mempool.CloseWAL() - _, err = mempool.CheckTxSync(types.Tx([]byte("bar")), TxInfo{}) - require.NoError(t, err) - sum2 := checksumFile(walFilepath, t) - require.Equal(t, sum1, sum2, "expected no change to the WAL after invoking CloseWAL() since it was discarded") - - // 8. Sanity check to ensure that the WAL file still exists - m3, err := filepath.Glob(filepath.Join(rootDir, "*")) - require.Nil(t, err, "successful globbing expected") - require.Equal(t, 1, len(m3), "expecting the wal match in") -} - func TestMempool_CheckTxChecksTxSize(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) + mempl, cleanup := newMempoolWithApp(cc) defer cleanup() @@ -516,7 +545,7 @@ func TestMempool_CheckTxChecksTxSize(t *testing.T) { tx := tmrand.Bytes(testCase.len) - _, err := mempl.CheckTxSync(tx, TxInfo{}) + err := mempl.CheckTxSync(tx, nil, mempool.TxInfo{}) bv := gogotypes.BytesValue{Value: tx} bz, err2 := bv.Marshal() require.NoError(t, err2) @@ -525,7 +554,10 @@ func TestMempool_CheckTxChecksTxSize(t *testing.T) { if !testCase.err { require.NoError(t, err, caseString) } else { - require.Equal(t, err, ErrTxTooLarge{maxTxSize, testCase.len}, caseString) + require.Equal(t, err, mempool.ErrTxTooLarge{ + Max: maxTxSize, + Actual: testCase.len, + }, caseString) } } } @@ -533,53 +565,60 @@ func TestMempool_CheckTxChecksTxSize(t *testing.T) { func TestMempoolTxsBytes(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - config := cfg.ResetTestRoot("mempool_test") - config.Mempool.MaxTxsBytes = 10 - mempool, cleanup := newMempoolWithAppAndConfig(cc, config) + + cfg := config.ResetTestRoot("mempool_test") + + cfg.Mempool.MaxTxsBytes = 10 + mp, cleanup := newMempoolWithAppAndConfig(cc, cfg) defer cleanup() // 1. zero by default - assert.EqualValues(t, 0, mempool.TxsBytes()) + assert.EqualValues(t, 0, mp.SizeBytes()) // 2. len(tx) after CheckTx - _, err := mempool.CheckTxSync([]byte{0x01}, TxInfo{}) + err := mp.CheckTxSync([]byte{0x01}, nil, mempool.TxInfo{}) require.NoError(t, err) - assert.EqualValues(t, 1, mempool.TxsBytes()) + assert.EqualValues(t, 1, mp.SizeBytes()) // 3. zero again after tx is removed by Update - err = mempool.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), + err = mp.Update(newTestBlock(1, []types.Tx{[]byte{0x01}}), abciResponses(1, ocabci.CodeTypeOK), nil, nil) require.NoError(t, err) - assert.EqualValues(t, 0, mempool.TxsBytes()) + assert.EqualValues(t, 0, mp.SizeBytes()) // 4. zero after Flush - _, err = mempool.CheckTxSync([]byte{0x02, 0x03}, TxInfo{}) + err = mp.CheckTxSync([]byte{0x02, 0x03}, nil, mempool.TxInfo{}) require.NoError(t, err) - assert.EqualValues(t, 2, mempool.TxsBytes()) + assert.EqualValues(t, 2, mp.SizeBytes()) - mempool.Flush() - assert.EqualValues(t, 0, mempool.TxsBytes()) + mp.Flush() + assert.EqualValues(t, 0, mp.SizeBytes()) // 5. ErrMempoolIsFull is returned when/if MaxTxsBytes limit is reached. - _, err = mempool.CheckTxSync([]byte{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, TxInfo{}) + err = mp.CheckTxSync( + []byte{0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}, + nil, + mempool.TxInfo{}, + ) require.NoError(t, err) - _, err = mempool.CheckTxSync([]byte{0x05}, TxInfo{}) + err = mp.CheckTxSync([]byte{0x05}, nil, mempool.TxInfo{}) if assert.Error(t, err) { - assert.IsType(t, ErrMempoolIsFull{}, err) + assert.IsType(t, mempool.ErrMempoolIsFull{}, err) } // 6. zero after tx is rechecked and removed due to not being valid anymore - app2 := counter.NewApplication(true) + app2 := kvstore.NewApplication() cc = proxy.NewLocalClientCreator(app2) - mempool, cleanup = newMempoolWithApp(cc) + + mp, cleanup = newMempoolWithApp(cc) defer cleanup() txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(0)) - _, err = mempool.CheckTxSync(txBytes, TxInfo{}) + err = mp.CheckTxSync(txBytes, nil, mempool.TxInfo{}) require.NoError(t, err) - assert.EqualValues(t, 8, mempool.TxsBytes()) + assert.EqualValues(t, 8, mp.SizeBytes()) appConnCon, _ := cc.NewABCIClient() appConnCon.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "consensus")) @@ -590,26 +629,28 @@ func TestMempoolTxsBytes(t *testing.T) { t.Error(err) } }) + res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes}) require.NoError(t, err) require.EqualValues(t, 0, res.Code) + res2, err := appConnCon.CommitSync() require.NoError(t, err) require.NotEmpty(t, res2.Data) // Pretend like we committed nothing so txBytes gets rechecked and removed. - err = mempool.Update(newTestBlock(1, []types.Tx{}), abciResponses(0, ocabci.CodeTypeOK), nil, nil) + err = mp.Update(newTestBlock(1, []types.Tx{}), abciResponses(0, ocabci.CodeTypeOK), nil, nil) require.NoError(t, err) - assert.EqualValues(t, 0, mempool.TxsBytes()) + assert.EqualValues(t, 8, mp.SizeBytes()) // 7. Test RemoveTxByKey function - _, err = mempool.CheckTxSync([]byte{0x06}, TxInfo{}) + err = mp.CheckTxSync([]byte{0x06}, nil, mempool.TxInfo{}) require.NoError(t, err) - assert.EqualValues(t, 1, mempool.TxsBytes()) - mempool.RemoveTxByKey(TxKey([]byte{0x07}), true) - assert.EqualValues(t, 1, mempool.TxsBytes()) - mempool.RemoveTxByKey(TxKey([]byte{0x06}), true) - assert.EqualValues(t, 0, mempool.TxsBytes()) + assert.EqualValues(t, 9, mp.SizeBytes()) + assert.Error(t, mp.RemoveTxByKey(types.Tx([]byte{0x07}).Key())) + assert.EqualValues(t, 9, mp.SizeBytes()) + assert.NoError(t, mp.RemoveTxByKey(types.Tx([]byte{0x06}).Key())) + assert.EqualValues(t, 8, mp.SizeBytes()) } @@ -620,14 +661,16 @@ func TestMempoolTxsBytes(t *testing.T) { func TestMempoolRemoteAppConcurrency(t *testing.T) { sockPath := fmt.Sprintf("unix:///tmp/echo_%v.sock", tmrand.Str(6)) app := kvstore.NewApplication() - cc, server := newRemoteApp(t, sockPath, app) + _, server := newRemoteApp(t, sockPath, app) t.Cleanup(func() { if err := server.Stop(); err != nil { t.Error(err) } }) - config := cfg.ResetTestRoot("mempool_test") - mempool, cleanup := newMempoolWithAppAndConfig(cc, config) + + cfg := config.ResetTestRoot("mempool_test") + + mp, cleanup := newMempoolWithAppAndConfig(proxy.NewRemoteClientCreator(sockPath, "socket", true), cfg) defer cleanup() // generate small number of txs @@ -639,7 +682,7 @@ func TestMempoolRemoteAppConcurrency(t *testing.T) { } // simulate a group of peers sending them over and over - N := config.Mempool.Size + N := cfg.Mempool.Size maxPeers := 5 for i := 0; i < N; i++ { peerID := mrand.Intn(maxPeers) @@ -647,10 +690,10 @@ func TestMempoolRemoteAppConcurrency(t *testing.T) { tx := txs[txNum] // this will err with ErrTxInCache many times ... - mempool.CheckTxSync(tx, TxInfo{SenderID: uint16(peerID)}) // nolint: errcheck + mp.CheckTxSync(tx, nil, mempool.TxInfo{SenderID: uint16(peerID)}) // nolint: errcheck } - err := mempool.FlushAppConn() - require.NoError(t, err) + + require.NoError(t, mp.FlushAppConn()) } func newTestBlock(height int64, txs types.Txs) *types.Block { @@ -665,35 +708,18 @@ func newTestBlock(height int64, txs types.Txs) *types.Block { } // caller must close server -func newRemoteApp( - t *testing.T, - addr string, - app ocabci.Application, -) ( - clientCreator proxy.ClientCreator, - server service.Service, -) { - clientCreator = proxy.NewRemoteClientCreator(addr, "socket", true) +func newRemoteApp(t *testing.T, addr string, app ocabci.Application) (abciclient.Client, service.Service) { + clientCreator, err := abciclient.NewClient(addr, "socket", true) + require.NoError(t, err) // Start server - server = abciserver.NewSocketServer(addr, app) + server := abciserver.NewSocketServer(addr, app) server.SetLogger(log.TestingLogger().With("module", "abci-server")) if err := server.Start(); err != nil { t.Fatalf("Error starting socket server: %v", err.Error()) } - return clientCreator, server -} - -func checksumIt(data []byte) string { - h := sha256.New() - h.Write(data) - return fmt.Sprintf("%x", h.Sum(nil)) -} -func checksumFile(p string, t *testing.T) string { - data, err := ioutil.ReadFile(p) - require.Nil(t, err, "expecting successful read of %q", p) - return checksumIt(data) + return clientCreator, server } func abciResponses(n int, code uint32) []*abci.ResponseDeliverTx { @@ -723,15 +749,15 @@ func TestTxMempoolPostCheckError(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { app := kvstore.NewApplication() cc := proxy.NewLocalClientCreator(app) - mempool, cleanup := newMempoolWithApp(cc) + mp, cleanup := newMempoolWithApp(cc) defer cleanup() - mempool.postCheck = func(_ types.Tx, _ *ocabci.ResponseCheckTx) error { + mp.postCheck = func(_ types.Tx, _ *ocabci.ResponseCheckTx) error { return testCase.err } tx := types.Tx{1} - _, err := mempool.CheckTxSync(tx, TxInfo{}) + err := mp.CheckTxSync(tx, nil, mempool.TxInfo{}) require.NoError(t, err) req := abci.RequestCheckTx{ @@ -742,7 +768,7 @@ func TestTxMempoolPostCheckError(t *testing.T) { m := sync.Mutex{} m.Lock() - mempool.proxyAppConn.CheckTxAsync(req, func(r *ocabci.Response) { + mp.proxyAppConn.CheckTxAsync(req, func(r *ocabci.Response) { res = r m.Unlock() }) diff --git a/mempool/doc.go b/mempool/v0/doc.go similarity index 98% rename from mempool/doc.go rename to mempool/v0/doc.go index 7e6363e12..3b5d0d20d 100644 --- a/mempool/doc.go +++ b/mempool/v0/doc.go @@ -20,4 +20,4 @@ // broadcastTxRoutine(). // TODO: Better handle abci client errors. (make it automatically handle connection errors) -package mempool +package v0 diff --git a/mempool/reactor.go b/mempool/v0/reactor.go similarity index 88% rename from mempool/reactor.go rename to mempool/v0/reactor.go index 350cfc99a..d90f34122 100644 --- a/mempool/reactor.go +++ b/mempool/v0/reactor.go @@ -1,9 +1,8 @@ -package mempool +package v0 import ( "errors" "fmt" - "math" "time" protomem "github.com/tendermint/tendermint/proto/tendermint/mempool" @@ -12,22 +11,11 @@ import ( "github.com/Finschia/ostracon/libs/clist" "github.com/Finschia/ostracon/libs/log" tmsync "github.com/Finschia/ostracon/libs/sync" + "github.com/Finschia/ostracon/mempool" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/types" ) -const ( - MempoolChannel = byte(0x30) - - peerCatchupSleepIntervalMS = 100 // If peer is behind, sleep this amount - - // UnknownPeerID is the peer ID to use when running CheckTx when there is - // no peer (e.g. RPC) - UnknownPeerID uint16 = 0 - - maxActiveIDs = math.MaxUint16 -) - // Reactor handles mempool tx broadcasting amongst peers. // It maintains a map from peer ID to counter, to prevent gossiping txs to the // peers you received it from. @@ -59,8 +47,8 @@ func (ids *mempoolIDs) ReserveForPeer(peer p2p.Peer) { // nextPeerID returns the next unused peer ID to use. // This assumes that ids's mutex is already locked. func (ids *mempoolIDs) nextPeerID() uint16 { - if len(ids.activeIDs) == maxActiveIDs { - panic(fmt.Sprintf("node has maximum %d active IDs and wanted to get one more", maxActiveIDs)) + if len(ids.activeIDs) == mempool.MaxActiveIDs { + panic(fmt.Sprintf("node has maximum %d active IDs and wanted to get one more", mempool.MaxActiveIDs)) } _, idExists := ids.activeIDs[ids.nextID] @@ -150,7 +138,7 @@ func (memR *Reactor) GetChannels() []*p2p.ChannelDescriptor { return []*p2p.ChannelDescriptor{ { - ID: MempoolChannel, + ID: mempool.MempoolChannel, Priority: 5, RecvMessageCapacity: batchMsg.Size(), }, @@ -182,20 +170,22 @@ func (memR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { } memR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg) - txInfo := TxInfo{SenderID: memR.ids.GetForPeer(src)} + txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(src)} if src != nil { txInfo.SenderP2PID = src.ID() } + for _, tx := range msg.Txs { tx := tx // pin! workaround for `scopelint` error memR.mempool.CheckTxAsync(tx, txInfo, func(err error) { - if err == ErrTxInCache { - memR.Logger.Debug("Tx already exists in cache", "tx", txID(tx)) + if errors.Is(err, mempool.ErrTxInCache) { + memR.Logger.Debug("Tx already exists in cache", "tx", tx.String()) } else if err != nil { - memR.Logger.Info("Could not check tx", "tx", txID(tx), "err", err) + memR.Logger.Info("Could not check tx", "tx", tx.String(), "err", err) } }, nil) } + // broadcasting happens from go routines per peer } @@ -238,14 +228,14 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) { // different every time due to us using a map. Sometimes other reactors // will be initialized before the consensus reactor. We should wait a few // milliseconds and retry. - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) continue } // Allow for a lag of 1 block. memTx := next.Value.(*mempoolTx) if peerState.GetHeight() < memTx.Height()-1 { - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) continue } @@ -258,13 +248,15 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) { Txs: &protomem.Txs{Txs: [][]byte{memTx.tx}}, }, } + bz, err := msg.Marshal() if err != nil { panic(err) } - success := peer.Send(MempoolChannel, bz) + + success := peer.Send(mempool.MempoolChannel, bz) if !success { - time.Sleep(peerCatchupSleepIntervalMS * time.Millisecond) + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) continue } } @@ -281,9 +273,6 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) { } } -//----------------------------------------------------------------------------- -// Messages - func (memR *Reactor) decodeMsg(bz []byte) (TxsMessage, error) { msg := protomem.Message{} err := msg.Unmarshal(bz) @@ -313,8 +302,6 @@ func (memR *Reactor) decodeMsg(bz []byte) (TxsMessage, error) { return message, fmt.Errorf("msg type: %T is not supported", msg) } -//------------------------------------- - // TxsMessage is a Message containing transactions. type TxsMessage struct { Txs []types.Tx diff --git a/mempool/reactor_test.go b/mempool/v0/reactor_test.go similarity index 93% rename from mempool/reactor_test.go rename to mempool/v0/reactor_test.go index 63d2ab438..a5f2f4989 100644 --- a/mempool/reactor_test.go +++ b/mempool/v0/reactor_test.go @@ -1,4 +1,4 @@ -package mempool +package v0 import ( "encoding/hex" @@ -20,6 +20,7 @@ import ( cfg "github.com/Finschia/ostracon/config" "github.com/Finschia/ostracon/libs/log" tmrand "github.com/Finschia/ostracon/libs/rand" + "github.com/Finschia/ostracon/mempool" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/p2p/mock" "github.com/Finschia/ostracon/proxy" @@ -67,7 +68,7 @@ func TestReactorBroadcastTxsMessage(t *testing.T) { } } - txs := checkTxs(t, reactors[0].mempool, numTxs, UnknownPeerID) + txs := checkTxs(t, reactors[0].mempool, numTxs, mempool.UnknownPeerID) waitForTxsOnReactors(t, txs, reactors) } @@ -97,7 +98,7 @@ func TestReactorConcurrency(t *testing.T) { // 1. submit a bunch of txs // 2. update the whole mempool - txs := checkTxs(t, reactors[0].mempool, numTxs, UnknownPeerID) + txs := checkTxs(t, reactors[0].mempool, numTxs, mempool.UnknownPeerID) go func() { defer wg.Done() @@ -114,7 +115,7 @@ func TestReactorConcurrency(t *testing.T) { // 1. submit a bunch of txs // 2. update none - _ = checkTxs(t, reactors[1].mempool, numTxs, UnknownPeerID) + _ = checkTxs(t, reactors[1].mempool, numTxs, mempool.UnknownPeerID) go func() { defer wg.Done() @@ -177,7 +178,7 @@ func TestReactor_MaxTxBytes(t *testing.T) { // Broadcast a tx, which has the max size // => ensure it's received by the second reactor. tx1 := tmrand.Bytes(config.Mempool.MaxTxBytes) - _, err := reactors[0].mempool.CheckTxSync(tx1, TxInfo{SenderID: UnknownPeerID}) + err := reactors[0].mempool.CheckTxSync(tx1, nil, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) require.NoError(t, err) waitForTxsOnReactors(t, []types.Tx{tx1}, reactors) @@ -187,7 +188,7 @@ func TestReactor_MaxTxBytes(t *testing.T) { // Broadcast a tx, which is beyond the max size // => ensure it's not sent tx2 := tmrand.Bytes(config.Mempool.MaxTxBytes + 1) - _, err = reactors[0].mempool.CheckTxSync(tx2, TxInfo{SenderID: UnknownPeerID}) + err = reactors[0].mempool.CheckTxSync(tx2, nil, mempool.TxInfo{SenderID: mempool.UnknownPeerID}) require.Error(t, err) } @@ -259,7 +260,7 @@ func TestMempoolIDsPanicsIfNodeRequestsOvermaxActiveIDs(t *testing.T) { // 0 is already reserved for UnknownPeerID ids := newMempoolIDs() - for i := 0; i < maxActiveIDs-1; i++ { + for i := 0; i < mempool.MaxActiveIDs-1; i++ { peer := mock.NewPeer(net.IP{127, 0, 0, 1}) ids.ReserveForPeer(peer) } @@ -283,9 +284,9 @@ func TestDontExhaustMaxActiveIDs(t *testing.T) { }() reactor := reactors[0] - for i := 0; i < maxActiveIDs+1; i++ { + for i := 0; i < mempool.MaxActiveIDs+1; i++ { peer := mock.NewPeer(nil) - reactor.Receive(MempoolChannel, peer, []byte{0x1, 0x2, 0x3}) + reactor.Receive(mempool.MempoolChannel, peer, []byte{0x1, 0x2, 0x3}) reactor.AddPeer(peer) } } diff --git a/mempool/v1/mempool.go b/mempool/v1/mempool.go new file mode 100644 index 000000000..96925e219 --- /dev/null +++ b/mempool/v1/mempool.go @@ -0,0 +1,803 @@ +//go:build deprecated + +package v1 + +import ( + "fmt" + "reflect" + "sort" + "sync" + "sync/atomic" + "time" + + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/clist" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" + "github.com/tendermint/tendermint/types" +) + +var _ mempool.Mempool = (*TxMempool)(nil) + +// TxMempoolOption sets an optional parameter on the TxMempool. +type TxMempoolOption func(*TxMempool) + +// TxMempool implemements the Mempool interface and allows the application to +// set priority values on transactions in the CheckTx response. When selecting +// transactions to include in a block, higher-priority transactions are chosen +// first. When evicting transactions from the mempool for size constraints, +// lower-priority transactions are evicted sooner. +// +// Within the mempool, transactions are ordered by time of arrival, and are +// gossiped to the rest of the network based on that order (gossip order does +// not take priority into account). +type TxMempool struct { + // Immutable fields + logger log.Logger + config *config.MempoolConfig + proxyAppConn proxy.AppConnMempool + metrics *mempool.Metrics + cache mempool.TxCache // seen transactions + + // Atomically-updated fields + txsBytes int64 // atomic: the total size of all transactions in the mempool, in bytes + txRecheck int64 // atomic: the number of pending recheck calls + + // Synchronized fields, protected by mtx. + mtx *sync.RWMutex + notifiedTxsAvailable bool + txsAvailable chan struct{} // one value sent per height when mempool is not empty + preCheck mempool.PreCheckFunc + postCheck mempool.PostCheckFunc + height int64 // the latest height passed to Update + + txs *clist.CList // valid transactions (passed CheckTx) + txByKey map[types.TxKey]*clist.CElement + txBySender map[string]*clist.CElement // for sender != "" +} + +// NewTxMempool constructs a new, empty priority mempool at the specified +// initial height and using the given config and options. +func NewTxMempool( + logger log.Logger, + cfg *config.MempoolConfig, + proxyAppConn proxy.AppConnMempool, + height int64, + options ...TxMempoolOption, +) *TxMempool { + + txmp := &TxMempool{ + logger: logger, + config: cfg, + proxyAppConn: proxyAppConn, + metrics: mempool.NopMetrics(), + cache: mempool.NopTxCache{}, + txs: clist.New(), + mtx: new(sync.RWMutex), + height: height, + txByKey: make(map[types.TxKey]*clist.CElement), + txBySender: make(map[string]*clist.CElement), + } + if cfg.CacheSize > 0 { + txmp.cache = mempool.NewLRUTxCache(cfg.CacheSize) + } + + proxyAppConn.SetResponseCallback(txmp.recheckTxCallback) + + for _, opt := range options { + opt(txmp) + } + + return txmp +} + +// WithPreCheck sets a filter for the mempool to reject a transaction if f(tx) +// returns an error. This is executed before CheckTx. It only applies to the +// first created block. After that, Update() overwrites the existing value. +func WithPreCheck(f mempool.PreCheckFunc) TxMempoolOption { + return func(txmp *TxMempool) { txmp.preCheck = f } +} + +// WithPostCheck sets a filter for the mempool to reject a transaction if +// f(tx, resp) returns an error. This is executed after CheckTx. It only applies +// to the first created block. After that, Update overwrites the existing value. +func WithPostCheck(f mempool.PostCheckFunc) TxMempoolOption { + return func(txmp *TxMempool) { txmp.postCheck = f } +} + +// WithMetrics sets the mempool's metrics collector. +func WithMetrics(metrics *mempool.Metrics) TxMempoolOption { + return func(txmp *TxMempool) { txmp.metrics = metrics } +} + +// Lock obtains a write-lock on the mempool. A caller must be sure to explicitly +// release the lock when finished. +func (txmp *TxMempool) Lock() { txmp.mtx.Lock() } + +// Unlock releases a write-lock on the mempool. +func (txmp *TxMempool) Unlock() { txmp.mtx.Unlock() } + +// Size returns the number of valid transactions in the mempool. It is +// thread-safe. +func (txmp *TxMempool) Size() int { return txmp.txs.Len() } + +// SizeBytes return the total sum in bytes of all the valid transactions in the +// mempool. It is thread-safe. +func (txmp *TxMempool) SizeBytes() int64 { return atomic.LoadInt64(&txmp.txsBytes) } + +// FlushAppConn executes FlushSync on the mempool's proxyAppConn. +// +// The caller must hold an exclusive mempool lock (by calling txmp.Lock) before +// calling FlushAppConn. +func (txmp *TxMempool) FlushAppConn() error { + // N.B.: We have to issue the call outside the lock so that its callback can + // fire. It's safe to do this, the flush will block until complete. + // + // We could just not require the caller to hold the lock at all, but the + // semantics of the Mempool interface require the caller to hold it, and we + // can't change that without disrupting existing use. + txmp.mtx.Unlock() + defer txmp.mtx.Lock() + + return txmp.proxyAppConn.FlushSync() +} + +// EnableTxsAvailable enables the mempool to trigger events when transactions +// are available on a block by block basis. +func (txmp *TxMempool) EnableTxsAvailable() { + txmp.mtx.Lock() + defer txmp.mtx.Unlock() + + txmp.txsAvailable = make(chan struct{}, 1) +} + +// 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 } + +// CheckTx adds the given transaction to the mempool if it fits and passes the +// application's ABCI CheckTx method. +// +// CheckTx reports an error without adding tx if: +// +// - The size of tx exceeds the configured maximum transaction size. +// - The pre-check hook is defined and reports an error for tx. +// - The transaction already exists in the cache. +// - The proxy connection to the application fails. +// +// If tx passes all of the above conditions, it is passed (asynchronously) to +// the application's ABCI CheckTx method and this CheckTx method returns nil. +// If cb != nil, it is called when the ABCI request completes to report the +// application response. +// +// If the application accepts the transaction and the mempool is full, the +// mempool evicts one or more of the lowest-priority transaction whose priority +// is (strictly) lower than the priority of tx and whose size together exceeds +// the size of tx, and adds tx instead. If no such transactions exist, tx is +// discarded. +func (txmp *TxMempool) CheckTx(tx types.Tx, cb func(*abci.Response), txInfo mempool.TxInfo) error { + + // During the initial phase of CheckTx, we do not need to modify any state. + // A transaction will not actually be added to the mempool until it survives + // a call to the ABCI CheckTx method and size constraint checks. + height, err := func() (int64, error) { + txmp.mtx.RLock() + defer txmp.mtx.RUnlock() + + // Reject transactions in excess of the configured maximum transaction size. + if len(tx) > txmp.config.MaxTxBytes { + return 0, mempool.ErrTxTooLarge{Max: txmp.config.MaxTxBytes, Actual: len(tx)} + } + + // If a precheck hook is defined, call it before invoking the application. + if txmp.preCheck != nil { + if err := txmp.preCheck(tx); err != nil { + return 0, mempool.ErrPreCheck{Reason: err} + } + } + + // Early exit if the proxy connection has an error. + if err := txmp.proxyAppConn.Error(); err != nil { + return 0, err + } + + txKey := tx.Key() + + // Check for the transaction in the cache. + if !txmp.cache.Push(tx) { + // If the cached transaction is also in the pool, record its sender. + if elt, ok := txmp.txByKey[txKey]; ok { + w := elt.Value.(*WrappedTx) + w.SetPeer(txInfo.SenderID) + } + return 0, mempool.ErrTxInCache + } + return txmp.height, nil + }() + if err != nil { + return err + } + + // Initiate an ABCI CheckTx for this transaction. The callback is + // responsible for adding the transaction to the pool if it survives. + // + // N.B.: We have to issue the call outside the lock. In a local client, + // even an "async" call invokes its callback immediately which will make + // the callback deadlock trying to acquire the same lock. This isn't a + // problem with out-of-process calls, but this has to work for both. + reqRes := txmp.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx}) + if err := txmp.proxyAppConn.FlushSync(); err != nil { + return err + } + reqRes.SetCallback(func(res *abci.Response) { + wtx := &WrappedTx{ + tx: tx, + hash: tx.Key(), + timestamp: time.Now().UTC(), + height: height, + } + wtx.SetPeer(txInfo.SenderID) + txmp.initialTxCallback(wtx, res) + if cb != nil { + cb(res) + } + }) + return nil +} + +// RemoveTxByKey removes the transaction with the specified key from the +// mempool. It reports an error if no such transaction exists. This operation +// does not remove the transaction from the cache. +func (txmp *TxMempool) RemoveTxByKey(txKey types.TxKey) error { + txmp.mtx.Lock() + defer txmp.mtx.Unlock() + return txmp.removeTxByKey(txKey) +} + +// removeTxByKey removes the specified transaction key from the mempool. +// The caller must hold txmp.mtx excluxively. +func (txmp *TxMempool) removeTxByKey(key types.TxKey) error { + if elt, ok := txmp.txByKey[key]; ok { + w := elt.Value.(*WrappedTx) + delete(txmp.txByKey, key) + delete(txmp.txBySender, w.sender) + txmp.txs.Remove(elt) + elt.DetachPrev() + elt.DetachNext() + atomic.AddInt64(&txmp.txsBytes, -w.Size()) + return nil + } + return fmt.Errorf("transaction %x not found", key) +} + +// removeTxByElement removes the specified transaction element from the mempool. +// The caller must hold txmp.mtx exclusively. +func (txmp *TxMempool) removeTxByElement(elt *clist.CElement) { + w := elt.Value.(*WrappedTx) + delete(txmp.txByKey, w.tx.Key()) + delete(txmp.txBySender, w.sender) + txmp.txs.Remove(elt) + elt.DetachPrev() + elt.DetachNext() + atomic.AddInt64(&txmp.txsBytes, -w.Size()) +} + +// Flush purges the contents of the mempool and the cache, leaving both empty. +// The current height is not modified by this operation. +func (txmp *TxMempool) Flush() { + txmp.mtx.Lock() + defer txmp.mtx.Unlock() + + // Remove all the transactions in the list explicitly, so that the sizes + // and indexes get updated properly. + cur := txmp.txs.Front() + for cur != nil { + next := cur.Next() + txmp.removeTxByElement(cur) + cur = next + } + txmp.cache.Reset() + + // Discard any pending recheck calls that may be in flight. The calls will + // still complete, but will have no effect on the mempool. + atomic.StoreInt64(&txmp.txRecheck, 0) +} + +// allEntriesSorted returns a slice of all the transactions currently in the +// mempool, sorted in nonincreasing order by priority with ties broken by +// increasing order of arrival time. +func (txmp *TxMempool) allEntriesSorted() []*WrappedTx { + txmp.mtx.RLock() + defer txmp.mtx.RUnlock() + + all := make([]*WrappedTx, 0, len(txmp.txByKey)) + for _, tx := range txmp.txByKey { + all = append(all, tx.Value.(*WrappedTx)) + } + sort.Slice(all, func(i, j int) bool { + if all[i].priority == all[j].priority { + return all[i].timestamp.Before(all[j].timestamp) + } + return all[i].priority > all[j].priority // N.B. higher priorities first + }) + return all +} + +// ReapMaxBytesMaxGas returns a slice of valid transactions that fit within the +// size and gas constraints. The results are ordered by nonincreasing priority, +// with ties broken by increasing order of arrival. Reaping transactions does +// not remove them from the mempool. +// +// If maxBytes < 0, no limit is set on the total size in bytes. +// If maxGas < 0, no limit is set on the total gas cost. +// +// If the mempool is empty or has no transactions fitting within the given +// constraints, the result will also be empty. +func (txmp *TxMempool) ReapMaxBytesMaxGas(maxBytes, maxGas int64) types.Txs { + var totalGas, totalBytes int64 + + var keep []types.Tx //nolint:prealloc + for _, w := range txmp.allEntriesSorted() { + // N.B. When computing byte size, we need to include the overhead for + // encoding as protobuf to send to the application. + totalGas += w.gasWanted + totalBytes += types.ComputeProtoSizeForTxs([]types.Tx{w.tx}) + if (maxGas >= 0 && totalGas > maxGas) || (maxBytes >= 0 && totalBytes > maxBytes) { + break + } + keep = append(keep, w.tx) + } + return keep +} + +// TxsWaitChan returns a channel that is closed when there is at least one +// transaction available to be gossiped. +func (txmp *TxMempool) TxsWaitChan() <-chan struct{} { return txmp.txs.WaitChan() } + +// TxsFront returns the frontmost element of the pending transaction list. +// It will be nil if the mempool is empty. +func (txmp *TxMempool) TxsFront() *clist.CElement { return txmp.txs.Front() } + +// ReapMaxTxs returns up to max transactions from the mempool. The results are +// ordered by nonincreasing priority with ties broken by increasing order of +// arrival. Reaping transactions does not remove them from the mempool. +// +// If max < 0, all transactions in the mempool are reaped. +// +// The result may have fewer than max elements (possibly zero) if the mempool +// does not have that many transactions available. +func (txmp *TxMempool) ReapMaxTxs(max int) types.Txs { + var keep []types.Tx //nolint:prealloc + + for _, w := range txmp.allEntriesSorted() { + if max >= 0 && len(keep) >= max { + break + } + keep = append(keep, w.tx) + } + return keep +} + +// Update removes all the given transactions from the mempool and the cache, +// and updates the current block height. The blockTxs and deliverTxResponses +// must have the same length with each response corresponding to the tx at the +// same offset. +// +// If the configuration enables recheck, Update sends each remaining +// transaction after removing blockTxs to the ABCI CheckTx method. Any +// transactions marked as invalid during recheck are also removed. +// +// The caller must hold an exclusive mempool lock (by calling txmp.Lock) before +// calling Update. +func (txmp *TxMempool) Update( + blockHeight int64, + blockTxs types.Txs, + deliverTxResponses []*abci.ResponseDeliverTx, + newPreFn mempool.PreCheckFunc, + newPostFn mempool.PostCheckFunc, +) error { + // TODO(creachadair): This would be a nice safety check but requires Go 1.18. + // // Safety check: The caller is required to hold the lock. + // if txmp.mtx.TryLock() { + // txmp.mtx.Unlock() + // panic("mempool: Update caller does not hold the lock") + // } + // Safety check: Transactions and responses must match in number. + if len(blockTxs) != len(deliverTxResponses) { + panic(fmt.Sprintf("mempool: got %d transactions but %d DeliverTx responses", + len(blockTxs), len(deliverTxResponses))) + } + + txmp.height = blockHeight + txmp.notifiedTxsAvailable = false + + if newPreFn != nil { + txmp.preCheck = newPreFn + } + if newPostFn != nil { + txmp.postCheck = newPostFn + } + + for i, tx := range blockTxs { + // Add successful committed transactions to the cache (if they are not + // already present). Transactions that failed to commit are removed from + // the cache unless the operator has explicitly requested we keep them. + if deliverTxResponses[i].Code == abci.CodeTypeOK { + _ = txmp.cache.Push(tx) + } else if !txmp.config.KeepInvalidTxsInCache { + txmp.cache.Remove(tx) + } + + // Regardless of success, remove the transaction from the mempool. + _ = txmp.removeTxByKey(tx.Key()) + } + + txmp.purgeExpiredTxs(blockHeight) + + // If there any uncommitted transactions left in the mempool, we either + // initiate re-CheckTx per remaining transaction or notify that remaining + // transactions are left. + size := txmp.Size() + txmp.metrics.Size.Set(float64(size)) + if size > 0 { + if txmp.config.Recheck { + txmp.recheckTransactions() + } else { + txmp.notifyTxsAvailable() + } + } + return nil +} + +// initialTxCallback handles the ABCI CheckTx response for the first time a +// transaction is added to the mempool. A recheck after a block is committed +// goes to the default callback (see recheckTxCallback). +// +// If either the application rejected the transaction or a post-check hook is +// defined and rejects the transaction, it is discarded. +// +// Otherwise, if the mempool is full, check for lower-priority transactions +// that can be evicted to make room for the new one. If no such transactions +// exist, this transaction is logged and dropped; otherwise the selected +// transactions are evicted. +// +// Finally, the new transaction is added and size stats updated. +func (txmp *TxMempool) initialTxCallback(wtx *WrappedTx, res *abci.Response) { + checkTxRes, ok := res.Value.(*abci.Response_CheckTx) + if !ok { + txmp.logger.Error("mempool: received incorrect result type in CheckTx callback", + "expected", reflect.TypeOf(&abci.Response_CheckTx{}).Name(), + "got", reflect.TypeOf(res.Value).Name(), + ) + return + } + + txmp.mtx.Lock() + defer txmp.mtx.Unlock() + + var err error + if txmp.postCheck != nil { + err = txmp.postCheck(wtx.tx, checkTxRes.CheckTx) + } + + if err != nil || checkTxRes.CheckTx.Code != abci.CodeTypeOK { + txmp.logger.Info( + "rejected bad transaction", + "priority", wtx.Priority(), + "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "peer_id", wtx.peers, + "code", checkTxRes.CheckTx.Code, + "post_check_err", err, + ) + + txmp.metrics.FailedTxs.Add(1) + + // Remove the invalid transaction from the cache, unless the operator has + // instructed us to keep invalid transactions. + if !txmp.config.KeepInvalidTxsInCache { + txmp.cache.Remove(wtx.tx) + } + + // If there was a post-check error, record its text in the result for + // debugging purposes. + if err != nil { + checkTxRes.CheckTx.MempoolError = err.Error() + } + return + } + + priority := checkTxRes.CheckTx.Priority + sender := checkTxRes.CheckTx.Sender + + // Disallow multiple concurrent transactions from the same sender assigned + // by the ABCI application. As a special case, an empty sender is not + // restricted. + if sender != "" { + elt, ok := txmp.txBySender[sender] + if ok { + w := elt.Value.(*WrappedTx) + txmp.logger.Debug( + "rejected valid incoming transaction; tx already exists for sender", + "tx", fmt.Sprintf("%X", w.tx.Hash()), + "sender", sender, + ) + checkTxRes.CheckTx.MempoolError = + fmt.Sprintf("rejected valid incoming transaction; tx already exists for sender %q (%X)", + sender, w.tx.Hash()) + txmp.metrics.RejectedTxs.Add(1) + return + } + } + + // At this point the application has ruled the transaction valid, but the + // mempool might be full. If so, find the lowest-priority items with lower + // priority than the application assigned to this new one, and evict as many + // of them as necessary to make room for tx. If no such items exist, we + // discard tx. + + if err := txmp.canAddTx(wtx); err != nil { + 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() { + cw := cur.Value.(*WrappedTx) + if cw.priority < priority { + victims = append(victims, cur) + victimBytes += cw.Size() + } + } + + // 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() { + txmp.cache.Remove(wtx.tx) + txmp.logger.Error( + "rejected valid incoming transaction; mempool is full", + "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "err", err.Error(), + ) + checkTxRes.CheckTx.MempoolError = + fmt.Sprintf("rejected valid incoming transaction; mempool is full (%X)", + wtx.tx.Hash()) + txmp.metrics.RejectedTxs.Add(1) + return + } + + txmp.logger.Debug("evicting lower-priority transactions", + "new_tx", fmt.Sprintf("%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", fmt.Sprintf("%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.CheckTx.GasWanted) + wtx.SetPriority(priority) + wtx.SetSender(sender) + txmp.insertTx(wtx) + + txmp.metrics.TxSizeBytes.Observe(float64(wtx.Size())) + txmp.metrics.Size.Set(float64(txmp.Size())) + txmp.logger.Debug( + "inserted new valid transaction", + "priority", wtx.Priority(), + "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "height", txmp.height, + "num_txs", txmp.Size(), + ) + txmp.notifyTxsAvailable() +} + +func (txmp *TxMempool) insertTx(wtx *WrappedTx) { + elt := txmp.txs.PushBack(wtx) + txmp.txByKey[wtx.tx.Key()] = elt + if s := wtx.Sender(); s != "" { + txmp.txBySender[s] = elt + } + + atomic.AddInt64(&txmp.txsBytes, wtx.Size()) +} + +// recheckTxCallback handles the responses from ABCI CheckTx calls issued +// during the recheck phase of a block Update. It updates the recheck counter +// and removes any transactions invalidated by the application. +// +// This callback is NOT executed for the initial CheckTx on a new transaction; +// that case is handled by initialTxCallback instead. +func (txmp *TxMempool) recheckTxCallback(req *abci.Request, res *abci.Response) { + checkTxRes, ok := res.Value.(*abci.Response_CheckTx) + if !ok { + // Don't log this; this is the default callback and other response types + // can safely be ignored. + return + } + + // Check whether we are expecting recheck responses at this point. + // If not, we will ignore the response, this usually means the mempool was Flushed. + // If this is the "last" pending recheck, trigger a notification when it's been processed. + numLeft := atomic.AddInt64(&txmp.txRecheck, -1) + if numLeft == 0 { + defer txmp.notifyTxsAvailable() // notify waiters on return, if mempool is non-empty + } else if numLeft < 0 { + return + } + + txmp.metrics.RecheckTimes.Add(1) + tx := types.Tx(req.GetCheckTx().Tx) + + txmp.mtx.Lock() + defer txmp.mtx.Unlock() + + // Find the transaction reported by the ABCI callback. It is possible the + // transaction was evicted during the recheck, in which case the transaction + // will be gone. + elt, ok := txmp.txByKey[tx.Key()] + if !ok { + return + } + wtx := elt.Value.(*WrappedTx) + + // If a postcheck hook is defined, call it before checking the result. + var err error + if txmp.postCheck != nil { + err = txmp.postCheck(tx, checkTxRes.CheckTx) + } + + if checkTxRes.CheckTx.Code == abci.CodeTypeOK && err == nil { + wtx.SetPriority(checkTxRes.CheckTx.Priority) + return // N.B. Size of mempool did not change + } + + txmp.logger.Debug( + "existing transaction no longer valid; failed re-CheckTx callback", + "priority", wtx.Priority(), + "tx", fmt.Sprintf("%X", wtx.tx.Hash()), + "err", err, + "code", checkTxRes.CheckTx.Code, + ) + txmp.removeTxByElement(elt) + txmp.metrics.FailedTxs.Add(1) + if !txmp.config.KeepInvalidTxsInCache { + txmp.cache.Remove(wtx.tx) + } + txmp.metrics.Size.Set(float64(txmp.Size())) +} + +// recheckTransactions initiates re-CheckTx ABCI calls for all the transactions +// currently in the mempool. It reports the number of recheck calls that were +// successfully initiated. +// +// Precondition: The mempool is not empty. +// The caller must hold txmp.mtx exclusively. +func (txmp *TxMempool) recheckTransactions() { + if txmp.Size() == 0 { + panic("mempool: cannot run recheck on an empty mempool") + } + txmp.logger.Debug( + "executing re-CheckTx for all remaining transactions", + "num_txs", txmp.Size(), + "height", txmp.height, + ) + // N.B.: We have to issue the calls outside the lock. In a local client, + // even an "async" call invokes its callback immediately which will make the + // callback deadlock trying to acquire the same lock. This isn't a problem + // with out-of-process calls, but this has to work for both. + txmp.mtx.Unlock() + defer txmp.mtx.Lock() + + atomic.StoreInt64(&txmp.txRecheck, int64(txmp.txs.Len())) + for e := txmp.txs.Front(); e != nil; e = e.Next() { + wtx := e.Value.(*WrappedTx) + + // The response for this CheckTx is handled by the default recheckTxCallback. + _ = txmp.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{ + Tx: wtx.tx, + Type: abci.CheckTxType_Recheck, + }) + if err := txmp.proxyAppConn.FlushSync(); err != nil { + atomic.AddInt64(&txmp.txRecheck, -1) + txmp.logger.Error("mempool: error flushing re-CheckTx", "key", wtx.tx.Key(), "err", err) + } + } + + txmp.proxyAppConn.FlushAsync() +} + +// canAddTx returns an error if we cannot insert the provided *WrappedTx into +// the mempool due to mempool configured constraints. Otherwise, nil is +// returned and the transaction can be inserted into the mempool. +func (txmp *TxMempool) canAddTx(wtx *WrappedTx) error { + numTxs := txmp.Size() + txBytes := txmp.SizeBytes() + + if numTxs >= txmp.config.Size || wtx.Size()+txBytes > txmp.config.MaxTxsBytes { + return mempool.ErrMempoolIsFull{ + NumTxs: numTxs, + MaxTxs: txmp.config.Size, + TxsBytes: txBytes, + MaxTxsBytes: txmp.config.MaxTxsBytes, + } + } + + return nil +} + +// purgeExpiredTxs removes all transactions from the mempool that have exceeded +// their respective height or time-based limits as of the given blockHeight. +// Transactions removed by this operation are not removed from the cache. +// +// The caller must hold txmp.mtx exclusively. +func (txmp *TxMempool) purgeExpiredTxs(blockHeight int64) { + if txmp.config.TTLNumBlocks == 0 && txmp.config.TTLDuration == 0 { + return // nothing to do + } + + now := time.Now() + cur := txmp.txs.Front() + for cur != nil { + // N.B. Grab the next element first, since if we remove cur its successor + // will be invalidated. + next := cur.Next() + + w := cur.Value.(*WrappedTx) + if txmp.config.TTLNumBlocks > 0 && (blockHeight-w.height) > txmp.config.TTLNumBlocks { + txmp.removeTxByElement(cur) + txmp.cache.Remove(w.tx) + txmp.metrics.EvictedTxs.Add(1) + } else if txmp.config.TTLDuration > 0 && now.Sub(w.timestamp) > txmp.config.TTLDuration { + txmp.removeTxByElement(cur) + txmp.cache.Remove(w.tx) + txmp.metrics.EvictedTxs.Add(1) + } + cur = next + } +} + +func (txmp *TxMempool) notifyTxsAvailable() { + if txmp.Size() == 0 { + return // nothing to do + } + + if txmp.txsAvailable != nil && !txmp.notifiedTxsAvailable { + // channel cap is 1, so this will send once + txmp.notifiedTxsAvailable = true + + select { + case txmp.txsAvailable <- struct{}{}: + default: + } + } +} diff --git a/mempool/v1/mempool_bench_test.go b/mempool/v1/mempool_bench_test.go new file mode 100644 index 000000000..8a407ce17 --- /dev/null +++ b/mempool/v1/mempool_bench_test.go @@ -0,0 +1,33 @@ +//go:build deprecated + +package v1 + +import ( + "fmt" + "math/rand" + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/mempool" +) + +func BenchmarkTxMempool_CheckTx(b *testing.B) { + txmp := setup(b, 10000) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + b.ResetTimer() + + for n := 0; n < b.N; n++ { + b.StopTimer() + prefix := make([]byte, 20) + _, err := rng.Read(prefix) + require.NoError(b, err) + + priority := int64(rng.Intn(9999-1000) + 1000) + tx := []byte(fmt.Sprintf("%X=%d", prefix, priority)) + b.StartTimer() + + require.NoError(b, txmp.CheckTx(tx, nil, mempool.TxInfo{})) + } +} diff --git a/mempool/v1/mempool_test.go b/mempool/v1/mempool_test.go new file mode 100644 index 000000000..7be1dd2fe --- /dev/null +++ b/mempool/v1/mempool_test.go @@ -0,0 +1,656 @@ +//go:build deprecated + +package v1 + +import ( + "bytes" + "errors" + "fmt" + "math/rand" + "os" + "sort" + "strconv" + "strings" + "sync" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/abci/example/code" + "github.com/tendermint/tendermint/abci/example/kvstore" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" + "github.com/tendermint/tendermint/types" +) + +// application extends the KV store application by overriding CheckTx to provide +// transaction priority based on the value in the key/value pair. +type application struct { + *kvstore.Application +} + +type testTx struct { + tx types.Tx + priority int64 +} + +func (app *application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { + var ( + priority int64 + sender string + ) + + // infer the priority from the raw transaction value (sender=key=value) + parts := bytes.Split(req.Tx, []byte("=")) + if len(parts) == 3 { + v, err := strconv.ParseInt(string(parts[2]), 10, 64) + if err != nil { + return abci.ResponseCheckTx{ + Priority: priority, + Code: 100, + GasWanted: 1, + } + } + + priority = v + sender = string(parts[0]) + } else { + return abci.ResponseCheckTx{ + Priority: priority, + Code: 101, + GasWanted: 1, + } + } + + return abci.ResponseCheckTx{ + Priority: priority, + Sender: sender, + Code: code.CodeTypeOK, + GasWanted: 1, + } +} + +func setup(t testing.TB, cacheSize int, options ...TxMempoolOption) *TxMempool { + t.Helper() + + app := &application{kvstore.NewApplication()} + cc := proxy.NewLocalClientCreator(app) + + cfg := config.ResetTestRoot(strings.ReplaceAll(t.Name(), "/", "|")) + cfg.Mempool.CacheSize = cacheSize + + appConnMem, err := cc.NewABCIClient() + require.NoError(t, err) + require.NoError(t, appConnMem.Start()) + + t.Cleanup(func() { + os.RemoveAll(cfg.RootDir) + require.NoError(t, appConnMem.Stop()) + }) + + return NewTxMempool(log.TestingLogger().With("test", t.Name()), cfg.Mempool, appConnMem, 0, options...) +} + +// mustCheckTx invokes txmp.CheckTx for the given transaction and waits until +// its callback has finished executing. It fails t if CheckTx fails. +func mustCheckTx(t *testing.T, txmp *TxMempool, spec string) { + done := make(chan struct{}) + if err := txmp.CheckTx([]byte(spec), func(*abci.Response) { + close(done) + }, mempool.TxInfo{}); err != nil { + t.Fatalf("CheckTx for %q failed: %v", spec, err) + } + <-done +} + +func checkTxs(t *testing.T, txmp *TxMempool, numTxs int, peerID uint16) []testTx { + txs := make([]testTx, numTxs) + txInfo := mempool.TxInfo{SenderID: peerID} + + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + for i := 0; i < numTxs; i++ { + prefix := make([]byte, 20) + _, err := rng.Read(prefix) + require.NoError(t, err) + + priority := int64(rng.Intn(9999-1000) + 1000) + + txs[i] = testTx{ + tx: []byte(fmt.Sprintf("sender-%d-%d=%X=%d", i, peerID, prefix, priority)), + priority: priority, + } + require.NoError(t, txmp.CheckTx(txs[i].tx, nil, txInfo)) + } + + return txs +} + +func TestTxMempool_TxsAvailable(t *testing.T) { + txmp := setup(t, 0) + txmp.EnableTxsAvailable() + + ensureNoTxFire := func() { + timer := time.NewTimer(500 * time.Millisecond) + select { + case <-txmp.TxsAvailable(): + require.Fail(t, "unexpected transactions event") + case <-timer.C: + } + } + + ensureTxFire := func() { + timer := time.NewTimer(500 * time.Millisecond) + select { + case <-txmp.TxsAvailable(): + case <-timer.C: + require.Fail(t, "expected transactions event") + } + } + + // ensure no event as we have not executed any transactions yet + ensureNoTxFire() + + // Execute CheckTx for some transactions and ensure TxsAvailable only fires + // once. + txs := checkTxs(t, txmp, 100, 0) + ensureTxFire() + ensureNoTxFire() + + rawTxs := make([]types.Tx, len(txs)) + for i, tx := range txs { + rawTxs[i] = tx.tx + } + + responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + for i := 0; i < len(responses); i++ { + responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + } + + // commit half the transactions and ensure we fire an event + txmp.Lock() + require.NoError(t, txmp.Update(1, rawTxs[:50], responses, nil, nil)) + txmp.Unlock() + ensureTxFire() + ensureNoTxFire() + + // Execute CheckTx for more transactions and ensure we do not fire another + // event as we're still on the same height (1). + _ = checkTxs(t, txmp, 100, 0) + ensureNoTxFire() +} + +func TestTxMempool_Size(t *testing.T) { + txmp := setup(t, 0) + txs := checkTxs(t, txmp, 100, 0) + require.Equal(t, len(txs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + + rawTxs := make([]types.Tx, len(txs)) + for i, tx := range txs { + rawTxs[i] = tx.tx + } + + responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + for i := 0; i < len(responses); i++ { + responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + } + + txmp.Lock() + require.NoError(t, txmp.Update(1, rawTxs[:50], responses, nil, nil)) + txmp.Unlock() + + require.Equal(t, len(rawTxs)/2, txmp.Size()) + require.Equal(t, int64(2850), txmp.SizeBytes()) +} + +func TestTxMempool_Eviction(t *testing.T) { + txmp := setup(t, 1000) + txmp.config.Size = 5 + txmp.config.MaxTxsBytes = 60 + txExists := func(spec string) bool { + txmp.Lock() + defer txmp.Unlock() + key := types.Tx(spec).Key() + _, ok := txmp.txByKey[key] + return ok + } + + // A transaction bigger than the mempool should be rejected even when there + // are slots available. + mustCheckTx(t, txmp, "big=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef=1") + require.Equal(t, 0, txmp.Size()) + + // Nearly-fill the mempool with a low-priority transaction, to show that it + // is evicted even when slots are available for a higher-priority tx. + const bigTx = "big=0123456789abcdef0123456789abcdef0123456789abcdef01234=2" + mustCheckTx(t, txmp, bigTx) + require.Equal(t, 1, txmp.Size()) // bigTx is the only element + require.True(t, txExists(bigTx)) + require.Equal(t, int64(len(bigTx)), txmp.SizeBytes()) + + // The next transaction should evict bigTx, because it is higher priority + // but does not fit on size. + mustCheckTx(t, txmp, "key1=0000=25") + require.True(t, txExists("key1=0000=25")) + require.False(t, txExists(bigTx)) + require.False(t, txmp.cache.Has([]byte(bigTx))) + require.Equal(t, int64(len("key1=0000=25")), txmp.SizeBytes()) + + // Now fill up the rest of the slots with other transactions. + mustCheckTx(t, txmp, "key2=0001=5") + mustCheckTx(t, txmp, "key3=0002=10") + mustCheckTx(t, txmp, "key4=0003=3") + mustCheckTx(t, txmp, "key5=0004=3") + + // A new transaction with low priority should be discarded. + mustCheckTx(t, txmp, "key6=0005=1") + require.False(t, txExists("key6=0005=1")) + + // A new transaction with higher priority should evict key5, which is the + // newest of the two transactions with lowest priority. + mustCheckTx(t, txmp, "key7=0006=7") + require.True(t, txExists("key7=0006=7")) // new transaction added + require.False(t, txExists("key5=0004=3")) // newest low-priority tx evicted + require.True(t, txExists("key4=0003=3")) // older low-priority tx retained + + // Another new transaction evicts the other low-priority element. + mustCheckTx(t, txmp, "key8=0007=20") + require.True(t, txExists("key8=0007=20")) + require.False(t, txExists("key4=0003=3")) + + // Now the lowest-priority tx is 5, so that should be the next to go. + mustCheckTx(t, txmp, "key9=0008=9") + require.True(t, txExists("key9=0008=9")) + require.False(t, txExists("k3y2=0001=5")) + + // Add a transaction that requires eviction of multiple lower-priority + // entries, in order to fit the size of the element. + mustCheckTx(t, txmp, "key10=0123456789abcdef=11") // evict 10, 9, 7; keep 25, 20, 11 + require.True(t, txExists("key1=0000=25")) + require.True(t, txExists("key8=0007=20")) + require.True(t, txExists("key10=0123456789abcdef=11")) + require.False(t, txExists("key3=0002=10")) + require.False(t, txExists("key9=0008=9")) + require.False(t, txExists("key7=0006=7")) +} + +func TestTxMempool_Flush(t *testing.T) { + txmp := setup(t, 0) + txs := checkTxs(t, txmp, 100, 0) + require.Equal(t, len(txs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + + rawTxs := make([]types.Tx, len(txs)) + for i, tx := range txs { + rawTxs[i] = tx.tx + } + + responses := make([]*abci.ResponseDeliverTx, len(rawTxs[:50])) + for i := 0; i < len(responses); i++ { + responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + } + + txmp.Lock() + require.NoError(t, txmp.Update(1, rawTxs[:50], responses, nil, nil)) + txmp.Unlock() + + txmp.Flush() + require.Zero(t, txmp.Size()) + require.Equal(t, int64(0), txmp.SizeBytes()) +} + +func TestTxMempool_ReapMaxBytesMaxGas(t *testing.T) { + txmp := setup(t, 0) + tTxs := checkTxs(t, txmp, 100, 0) // all txs request 1 gas unit + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + + txMap := make(map[types.TxKey]testTx) + priorities := make([]int64, len(tTxs)) + for i, tTx := range tTxs { + txMap[tTx.tx.Key()] = tTx + priorities[i] = tTx.priority + } + + sort.Slice(priorities, func(i, j int) bool { + // sort by priority, i.e. decreasing order + return priorities[i] > priorities[j] + }) + + ensurePrioritized := func(reapedTxs types.Txs) { + reapedPriorities := make([]int64, len(reapedTxs)) + for i, rTx := range reapedTxs { + reapedPriorities[i] = txMap[rTx.Key()].priority + } + + require.Equal(t, priorities[:len(reapedPriorities)], reapedPriorities) + } + + // reap by gas capacity only + reapedTxs := txmp.ReapMaxBytesMaxGas(-1, 50) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.Len(t, reapedTxs, 50) + + // reap by transaction bytes only + reapedTxs = txmp.ReapMaxBytesMaxGas(1000, -1) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.GreaterOrEqual(t, len(reapedTxs), 16) + + // Reap by both transaction bytes and gas, where the size yields 31 reaped + // transactions and the gas limit reaps 25 transactions. + reapedTxs = txmp.ReapMaxBytesMaxGas(1500, 30) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.Len(t, reapedTxs, 25) +} + +func TestTxMempool_ReapMaxTxs(t *testing.T) { + txmp := setup(t, 0) + tTxs := checkTxs(t, txmp, 100, 0) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + + txMap := make(map[types.TxKey]testTx) + priorities := make([]int64, len(tTxs)) + for i, tTx := range tTxs { + txMap[tTx.tx.Key()] = tTx + priorities[i] = tTx.priority + } + + sort.Slice(priorities, func(i, j int) bool { + // sort by priority, i.e. decreasing order + return priorities[i] > priorities[j] + }) + + ensurePrioritized := func(reapedTxs types.Txs) { + reapedPriorities := make([]int64, len(reapedTxs)) + for i, rTx := range reapedTxs { + reapedPriorities[i] = txMap[rTx.Key()].priority + } + + require.Equal(t, priorities[:len(reapedPriorities)], reapedPriorities) + } + + // reap all transactions + reapedTxs := txmp.ReapMaxTxs(-1) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.Len(t, reapedTxs, len(tTxs)) + + // reap a single transaction + reapedTxs = txmp.ReapMaxTxs(1) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.Len(t, reapedTxs, 1) + + // reap half of the transactions + reapedTxs = txmp.ReapMaxTxs(len(tTxs) / 2) + ensurePrioritized(reapedTxs) + require.Equal(t, len(tTxs), txmp.Size()) + require.Equal(t, int64(5690), txmp.SizeBytes()) + require.Len(t, reapedTxs, len(tTxs)/2) +} + +func TestTxMempool_CheckTxExceedsMaxSize(t *testing.T) { + txmp := setup(t, 0) + + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + tx := make([]byte, txmp.config.MaxTxBytes+1) + _, err := rng.Read(tx) + require.NoError(t, err) + + require.Error(t, txmp.CheckTx(tx, nil, mempool.TxInfo{SenderID: 0})) + + tx = make([]byte, txmp.config.MaxTxBytes-1) + _, err = rng.Read(tx) + require.NoError(t, err) + + require.NoError(t, txmp.CheckTx(tx, nil, mempool.TxInfo{SenderID: 0})) +} + +func TestTxMempool_CheckTxSamePeer(t *testing.T) { + txmp := setup(t, 100) + peerID := uint16(1) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + prefix := make([]byte, 20) + _, err := rng.Read(prefix) + require.NoError(t, err) + + tx := []byte(fmt.Sprintf("sender-0=%X=%d", prefix, 50)) + + require.NoError(t, txmp.CheckTx(tx, nil, mempool.TxInfo{SenderID: peerID})) + require.Error(t, txmp.CheckTx(tx, nil, mempool.TxInfo{SenderID: peerID})) +} + +func TestTxMempool_CheckTxSameSender(t *testing.T) { + txmp := setup(t, 100) + peerID := uint16(1) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + + prefix1 := make([]byte, 20) + _, err := rng.Read(prefix1) + require.NoError(t, err) + + prefix2 := make([]byte, 20) + _, err = rng.Read(prefix2) + require.NoError(t, err) + + tx1 := []byte(fmt.Sprintf("sender-0=%X=%d", prefix1, 50)) + tx2 := []byte(fmt.Sprintf("sender-0=%X=%d", prefix2, 50)) + + require.NoError(t, txmp.CheckTx(tx1, nil, mempool.TxInfo{SenderID: peerID})) + require.Equal(t, 1, txmp.Size()) + require.NoError(t, txmp.CheckTx(tx2, nil, mempool.TxInfo{SenderID: peerID})) + require.Equal(t, 1, txmp.Size()) +} + +func TestTxMempool_ConcurrentTxs(t *testing.T) { + txmp := setup(t, 100) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + checkTxDone := make(chan struct{}) + + var wg sync.WaitGroup + + wg.Add(1) + go func() { + for i := 0; i < 20; i++ { + _ = checkTxs(t, txmp, 100, 0) + dur := rng.Intn(1000-500) + 500 + time.Sleep(time.Duration(dur) * time.Millisecond) + } + + wg.Done() + close(checkTxDone) + }() + + wg.Add(1) + go func() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + defer wg.Done() + + var height int64 = 1 + + for range ticker.C { + reapedTxs := txmp.ReapMaxTxs(200) + if len(reapedTxs) > 0 { + responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + for i := 0; i < len(responses); i++ { + var code uint32 + + if i%10 == 0 { + code = 100 + } else { + code = abci.CodeTypeOK + } + + responses[i] = &abci.ResponseDeliverTx{Code: code} + } + + txmp.Lock() + require.NoError(t, txmp.Update(height, reapedTxs, responses, nil, nil)) + txmp.Unlock() + + height++ + } else { + // only return once we know we finished the CheckTx loop + select { + case <-checkTxDone: + return + default: + } + } + } + }() + + wg.Wait() + require.Zero(t, txmp.Size()) + require.Zero(t, txmp.SizeBytes()) +} + +func TestTxMempool_ExpiredTxs_Timestamp(t *testing.T) { + txmp := setup(t, 5000) + txmp.config.TTLDuration = 5 * time.Millisecond + + added1 := checkTxs(t, txmp, 10, 0) + require.Equal(t, len(added1), txmp.Size()) + + // Wait a while, then add some more transactions that should not be expired + // when the first batch TTLs out. + // + // ms: 0 1 2 3 4 5 6 + // ^ ^ ^ ^ + // | | | +-- Update (triggers pruning) + // | | +------ first batch expires + // | +-------------- second batch added + // +-------------------------- first batch added + // + // The exact intervals are not important except that the delta should be + // large relative to the cost of CheckTx (ms vs. ns is fine here). + time.Sleep(3 * time.Millisecond) + added2 := checkTxs(t, txmp, 10, 1) + + // Wait a while longer, so that the first batch will expire. + time.Sleep(3 * time.Millisecond) + + // Trigger an update so that pruning will occur. + txmp.Lock() + defer txmp.Unlock() + require.NoError(t, txmp.Update(txmp.height+1, nil, nil, nil, nil)) + + // All the transactions in the original set should have been purged. + for _, tx := range added1 { + if _, ok := txmp.txByKey[tx.tx.Key()]; ok { + t.Errorf("Transaction %X should have been purged for TTL", tx.tx.Key()) + } + if txmp.cache.Has(tx.tx) { + t.Errorf("Transaction %X should have been removed from the cache", tx.tx.Key()) + } + } + + // All the transactions added later should still be around. + for _, tx := range added2 { + if _, ok := txmp.txByKey[tx.tx.Key()]; !ok { + t.Errorf("Transaction %X should still be in the mempool, but is not", tx.tx.Key()) + } + } +} + +func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) { + txmp := setup(t, 500) + txmp.height = 100 + txmp.config.TTLNumBlocks = 10 + + tTxs := checkTxs(t, txmp, 100, 0) + require.Equal(t, len(tTxs), txmp.Size()) + + // reap 5 txs at the next height -- no txs should expire + reapedTxs := txmp.ReapMaxTxs(5) + responses := make([]*abci.ResponseDeliverTx, len(reapedTxs)) + for i := 0; i < len(responses); i++ { + responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + } + + txmp.Lock() + require.NoError(t, txmp.Update(txmp.height+1, reapedTxs, responses, nil, nil)) + txmp.Unlock() + + require.Equal(t, 95, txmp.Size()) + + // check more txs at height 101 + _ = checkTxs(t, txmp, 50, 1) + require.Equal(t, 145, txmp.Size()) + + // Reap 5 txs at a height that would expire all the transactions from before + // the previous Update (height 100). + // + // NOTE: When we reap txs below, we do not know if we're picking txs from the + // initial CheckTx calls or from the second round of CheckTx calls. Thus, we + // cannot guarantee that all 95 txs are remaining that should be expired and + // removed. However, we do know that that at most 95 txs can be expired and + // removed. + reapedTxs = txmp.ReapMaxTxs(5) + responses = make([]*abci.ResponseDeliverTx, len(reapedTxs)) + for i := 0; i < len(responses); i++ { + responses[i] = &abci.ResponseDeliverTx{Code: abci.CodeTypeOK} + } + + txmp.Lock() + require.NoError(t, txmp.Update(txmp.height+10, reapedTxs, responses, nil, nil)) + txmp.Unlock() + + require.GreaterOrEqual(t, txmp.Size(), 45) +} + +func TestTxMempool_CheckTxPostCheckError(t *testing.T) { + cases := []struct { + name string + err error + }{ + { + name: "error", + err: errors.New("test error"), + }, + { + name: "no error", + err: nil, + }, + } + for _, tc := range cases { + testCase := tc + t.Run(testCase.name, func(t *testing.T) { + postCheckFn := func(_ types.Tx, _ *abci.ResponseCheckTx) error { + return testCase.err + } + txmp := setup(t, 0, WithPostCheck(postCheckFn)) + rng := rand.New(rand.NewSource(time.Now().UnixNano())) + tx := make([]byte, txmp.config.MaxTxBytes-1) + _, err := rng.Read(tx) + require.NoError(t, err) + + callback := func(res *abci.Response) { + checkTxRes, ok := res.Value.(*abci.Response_CheckTx) + require.True(t, ok) + expectedErrString := "" + if testCase.err != nil { + expectedErrString = testCase.err.Error() + } + require.Equal(t, expectedErrString, checkTxRes.CheckTx.MempoolError) + } + require.NoError(t, txmp.CheckTx(tx, callback, mempool.TxInfo{SenderID: 0})) + }) + } +} diff --git a/mempool/v1/reactor.go b/mempool/v1/reactor.go new file mode 100644 index 000000000..8b78a7f41 --- /dev/null +++ b/mempool/v1/reactor.go @@ -0,0 +1,312 @@ +//go:build deprecated + +package v1 + +import ( + "errors" + "fmt" + "time" + + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/clist" + "github.com/tendermint/tendermint/libs/log" + tmsync "github.com/tendermint/tendermint/libs/sync" + "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/p2p" + protomem "github.com/tendermint/tendermint/proto/tendermint/mempool" + "github.com/tendermint/tendermint/types" +) + +// Reactor handles mempool tx broadcasting amongst peers. +// It maintains a map from peer ID to counter, to prevent gossiping txs to the +// peers you received it from. +type Reactor struct { + p2p.BaseReactor + config *cfg.MempoolConfig + mempool *TxMempool + ids *mempoolIDs +} + +type mempoolIDs struct { + mtx tmsync.RWMutex + peerMap map[p2p.ID]uint16 + nextID uint16 // assumes that a node will never have over 65536 active peers + activeIDs map[uint16]struct{} // used to check if a given peerID key is used, the value doesn't matter +} + +// Reserve searches for the next unused ID and assigns it to the +// peer. +func (ids *mempoolIDs) ReserveForPeer(peer p2p.Peer) { + ids.mtx.Lock() + defer ids.mtx.Unlock() + + curID := ids.nextPeerID() + ids.peerMap[peer.ID()] = curID + ids.activeIDs[curID] = struct{}{} +} + +// nextPeerID returns the next unused peer ID to use. +// This assumes that ids's mutex is already locked. +func (ids *mempoolIDs) nextPeerID() uint16 { + if len(ids.activeIDs) == mempool.MaxActiveIDs { + panic(fmt.Sprintf("node has maximum %d active IDs and wanted to get one more", mempool.MaxActiveIDs)) + } + + _, idExists := ids.activeIDs[ids.nextID] + for idExists { + ids.nextID++ + _, idExists = ids.activeIDs[ids.nextID] + } + curID := ids.nextID + ids.nextID++ + return curID +} + +// Reclaim returns the ID reserved for the peer back to unused pool. +func (ids *mempoolIDs) Reclaim(peer p2p.Peer) { + ids.mtx.Lock() + defer ids.mtx.Unlock() + + removedID, ok := ids.peerMap[peer.ID()] + if ok { + delete(ids.activeIDs, removedID) + delete(ids.peerMap, peer.ID()) + } +} + +// GetForPeer returns an ID reserved for the peer. +func (ids *mempoolIDs) GetForPeer(peer p2p.Peer) uint16 { + ids.mtx.RLock() + defer ids.mtx.RUnlock() + + return ids.peerMap[peer.ID()] +} + +func newMempoolIDs() *mempoolIDs { + return &mempoolIDs{ + peerMap: make(map[p2p.ID]uint16), + activeIDs: map[uint16]struct{}{0: {}}, + nextID: 1, // reserve unknownPeerID(0) for mempoolReactor.BroadcastTx + } +} + +// NewReactor returns a new Reactor with the given config and mempool. +func NewReactor(config *cfg.MempoolConfig, mempool *TxMempool) *Reactor { + memR := &Reactor{ + config: config, + mempool: mempool, + ids: newMempoolIDs(), + } + memR.BaseReactor = *p2p.NewBaseReactor("Mempool", memR) + return memR +} + +// InitPeer implements Reactor by creating a state for the peer. +func (memR *Reactor) InitPeer(peer p2p.Peer) p2p.Peer { + memR.ids.ReserveForPeer(peer) + return peer +} + +// SetLogger sets the Logger on the reactor and the underlying mempool. +func (memR *Reactor) SetLogger(l log.Logger) { + memR.Logger = l +} + +// OnStart implements p2p.BaseReactor. +func (memR *Reactor) OnStart() error { + if !memR.config.Broadcast { + memR.Logger.Info("Tx broadcasting is disabled") + } + return nil +} + +// GetChannels implements Reactor by returning the list of channels for this +// reactor. +func (memR *Reactor) GetChannels() []*p2p.ChannelDescriptor { + largestTx := make([]byte, memR.config.MaxTxBytes) + batchMsg := protomem.Message{ + Sum: &protomem.Message_Txs{ + Txs: &protomem.Txs{Txs: [][]byte{largestTx}}, + }, + } + + return []*p2p.ChannelDescriptor{ + { + ID: mempool.MempoolChannel, + Priority: 5, + RecvMessageCapacity: batchMsg.Size(), + }, + } +} + +// AddPeer implements Reactor. +// It starts a broadcast routine ensuring all txs are forwarded to the given peer. +func (memR *Reactor) AddPeer(peer p2p.Peer) { + if memR.config.Broadcast { + go memR.broadcastTxRoutine(peer) + } +} + +// RemovePeer implements Reactor. +func (memR *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) { + memR.ids.Reclaim(peer) + // broadcast routine checks if peer is gone and returns +} + +// Receive implements Reactor. +// It adds any received transactions to the mempool. +func (memR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) { + msg, err := memR.decodeMsg(msgBytes) + if err != nil { + memR.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err) + memR.Switch.StopPeerForError(src, err) + return + } + memR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg) + + txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(src)} + if src != nil { + txInfo.SenderP2PID = src.ID() + } + for _, tx := range msg.Txs { + err = memR.mempool.CheckTx(tx, nil, txInfo) + if err == mempool.ErrTxInCache { + memR.Logger.Debug("Tx already exists in cache", "tx", tx.String()) + } else if err != nil { + memR.Logger.Info("Could not check tx", "tx", tx.String(), "err", err) + } + } + // broadcasting happens from go routines per peer +} + +// PeerState describes the state of a peer. +type PeerState interface { + GetHeight() int64 +} + +// Send new mempool txs to peer. +func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) { + peerID := memR.ids.GetForPeer(peer) + var next *clist.CElement + + for { + // In case of both next.NextWaitChan() and peer.Quit() are variable at the same time + if !memR.IsRunning() || !peer.IsRunning() { + return + } + + // This happens because the CElement we were looking at got garbage + // collected (removed). That is, .NextWait() returned nil. Go ahead and + // start from the beginning. + if next == nil { + select { + case <-memR.mempool.TxsWaitChan(): // Wait until a tx is available + if next = memR.mempool.TxsFront(); next == nil { + continue + } + + case <-peer.Quit(): + return + + case <-memR.Quit(): + return + } + } + + // Make sure the peer is up to date. + peerState, ok := peer.Get(types.PeerStateKey).(PeerState) + if !ok { + // Peer does not have a state yet. We set it in the consensus reactor, but + // when we add peer in Switch, the order we call reactors#AddPeer is + // different every time due to us using a map. Sometimes other reactors + // will be initialized before the consensus reactor. We should wait a few + // milliseconds and retry. + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) + continue + } + + // Allow for a lag of 1 block. + memTx := next.Value.(*WrappedTx) + if peerState.GetHeight() < memTx.height-1 { + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) + continue + } + + // NOTE: Transaction batching was disabled due to + // https://github.com/tendermint/tendermint/issues/5796 + if !memTx.HasPeer(peerID) { + msg := protomem.Message{ + Sum: &protomem.Message_Txs{ + Txs: &protomem.Txs{Txs: [][]byte{memTx.tx}}, + }, + } + + bz, err := msg.Marshal() + if err != nil { + panic(err) + } + + success := peer.Send(mempool.MempoolChannel, bz) + if !success { + time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond) + continue + } + } + + select { + case <-next.NextWaitChan(): + // see the start of the for loop for nil check + next = next.Next() + + case <-peer.Quit(): + return + + case <-memR.Quit(): + return + } + } +} + +//----------------------------------------------------------------------------- +// Messages + +func (memR *Reactor) decodeMsg(bz []byte) (TxsMessage, error) { + msg := protomem.Message{} + err := msg.Unmarshal(bz) + if err != nil { + return TxsMessage{}, err + } + + var message TxsMessage + + if i, ok := msg.Sum.(*protomem.Message_Txs); ok { + txs := i.Txs.GetTxs() + + if len(txs) == 0 { + return message, errors.New("empty TxsMessage") + } + + decoded := make([]types.Tx, len(txs)) + for j, tx := range txs { + decoded[j] = types.Tx(tx) + } + + message = TxsMessage{ + Txs: decoded, + } + return message, nil + } + return message, fmt.Errorf("msg type: %T is not supported", msg) +} + +//------------------------------------- + +// TxsMessage is a Message containing transactions. +type TxsMessage struct { + Txs []types.Tx +} + +// String returns a string representation of the TxsMessage. +func (m *TxsMessage) String() string { + return fmt.Sprintf("[TxsMessage %v]", m.Txs) +} diff --git a/mempool/v1/reactor_test.go b/mempool/v1/reactor_test.go new file mode 100644 index 000000000..5d5ef92c9 --- /dev/null +++ b/mempool/v1/reactor_test.go @@ -0,0 +1,188 @@ +//go:build deprecated + +package v1 + +import ( + "encoding/hex" + "os" + "sync" + "testing" + "time" + + "github.com/go-kit/log/term" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/abci/example/kvstore" + + cfg "github.com/tendermint/tendermint/config" + + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/p2p" + memproto "github.com/tendermint/tendermint/proto/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" + "github.com/tendermint/tendermint/types" +) + +const ( + numTxs = 1000 + timeout = 120 * time.Second // ridiculously high because CircleCI is slow +) + +type peerState struct { + height int64 +} + +func (ps peerState) GetHeight() int64 { + return ps.height +} + +// Send a bunch of txs to the first reactor's mempool and wait for them all to +// be received in the others. +func TestReactorBroadcastTxsMessage(t *testing.T) { + config := cfg.TestConfig() + // if there were more than two reactors, the order of transactions could not be + // asserted in waitForTxsOnReactors (due to transactions gossiping). If we + // replace Connect2Switches (full mesh) with a func, which connects first + // reactor to others and nothing else, this test should also pass with >2 reactors. + const N = 2 + reactors := makeAndConnectReactors(config, N) + defer func() { + for _, r := range reactors { + if err := r.Stop(); err != nil { + assert.NoError(t, err) + } + } + }() + for _, r := range reactors { + for _, peer := range r.Switch.Peers().List() { + peer.Set(types.PeerStateKey, peerState{1}) + } + } + + txs := checkTxs(t, reactors[0].mempool, numTxs, mempool.UnknownPeerID) + transactions := make(types.Txs, len(txs)) + for idx, tx := range txs { + transactions[idx] = tx.tx + } + + waitForTxsOnReactors(t, transactions, reactors) +} + +func TestMempoolVectors(t *testing.T) { + testCases := []struct { + testName string + tx []byte + expBytes string + }{ + {"tx 1", []byte{123}, "0a030a017b"}, + {"tx 2", []byte("proto encoding in mempool"), "0a1b0a1970726f746f20656e636f64696e6720696e206d656d706f6f6c"}, + } + + for _, tc := range testCases { + tc := tc + + msg := memproto.Message{ + Sum: &memproto.Message_Txs{ + Txs: &memproto.Txs{Txs: [][]byte{tc.tx}}, + }, + } + bz, err := msg.Marshal() + require.NoError(t, err, tc.testName) + + require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName) + } +} + +func makeAndConnectReactors(config *cfg.Config, n int) []*Reactor { + reactors := make([]*Reactor, n) + logger := mempoolLogger() + for i := 0; i < n; i++ { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + mempool, cleanup := newMempoolWithApp(cc) + defer cleanup() + + reactors[i] = NewReactor(config.Mempool, mempool) // so we dont start the consensus states + reactors[i].SetLogger(logger.With("validator", i)) + } + + p2p.MakeConnectedSwitches(config.P2P, n, func(i int, s *p2p.Switch) *p2p.Switch { + s.AddReactor("MEMPOOL", reactors[i]) + return s + + }, p2p.Connect2Switches) + return reactors +} + +// mempoolLogger is a TestingLogger which uses a different +// color for each validator ("validator" key must exist). +func mempoolLogger() log.Logger { + return log.TestingLoggerWithColorFn(func(keyvals ...interface{}) term.FgBgColor { + for i := 0; i < len(keyvals)-1; i += 2 { + if keyvals[i] == "validator" { + return term.FgBgColor{Fg: term.Color(uint8(keyvals[i+1].(int) + 1))} + } + } + return term.FgBgColor{} + }) +} + +func newMempoolWithApp(cc proxy.ClientCreator) (*TxMempool, func()) { + conf := cfg.ResetTestRoot("mempool_test") + + mp, cu := newMempoolWithAppAndConfig(cc, conf) + return mp, cu +} + +func newMempoolWithAppAndConfig(cc proxy.ClientCreator, conf *cfg.Config) (*TxMempool, func()) { + appConnMem, _ := cc.NewABCIClient() + appConnMem.SetLogger(log.TestingLogger().With("module", "abci-client", "connection", "mempool")) + err := appConnMem.Start() + if err != nil { + panic(err) + } + + mp := NewTxMempool(log.TestingLogger(), conf.Mempool, appConnMem, 0) + + return mp, func() { os.RemoveAll(conf.RootDir) } +} + +func waitForTxsOnReactors(t *testing.T, txs types.Txs, reactors []*Reactor) { + // wait for the txs in all mempools + wg := new(sync.WaitGroup) + for i, reactor := range reactors { + wg.Add(1) + go func(r *Reactor, reactorIndex int) { + defer wg.Done() + waitForTxsOnReactor(t, txs, r, reactorIndex) + }(reactor, i) + } + + done := make(chan struct{}) + go func() { + wg.Wait() + close(done) + }() + + timer := time.After(timeout) + select { + case <-timer: + t.Fatal("Timed out waiting for txs") + case <-done: + } +} + +func waitForTxsOnReactor(t *testing.T, txs types.Txs, reactor *Reactor, reactorIndex int) { + mempool := reactor.mempool + for mempool.Size() < len(txs) { + time.Sleep(time.Millisecond * 100) + } + + reapedTxs := mempool.ReapMaxTxs(len(txs)) + for i, tx := range txs { + assert.Equalf(t, tx, reapedTxs[i], + "txs at index %d on reactor %d don't match: %v vs %v", i, reactorIndex, tx, reapedTxs[i]) + } +} diff --git a/mempool/v1/tx.go b/mempool/v1/tx.go new file mode 100644 index 000000000..1cb24b7eb --- /dev/null +++ b/mempool/v1/tx.go @@ -0,0 +1,89 @@ +//go:build deprecated + +package v1 + +import ( + "sync" + "time" + + "github.com/tendermint/tendermint/types" +) + +// WrappedTx defines a wrapper around a raw transaction with additional metadata +// that is used for indexing. +type WrappedTx struct { + tx types.Tx // the original transaction data + hash types.TxKey // the transaction hash + height int64 // height when this transaction was initially checked (for expiry) + timestamp time.Time // time when transaction was entered (for TTL) + + mtx sync.Mutex + gasWanted int64 // app: gas required to execute this transaction + priority int64 // app: priority value for this transaction + sender string // app: assigned sender label + peers map[uint16]bool // peer IDs who have sent us this transaction +} + +// Size reports the size of the raw transaction in bytes. +func (w *WrappedTx) Size() int64 { return int64(len(w.tx)) } + +// SetPeer adds the specified peer ID as a sender of w. +func (w *WrappedTx) SetPeer(id uint16) { + w.mtx.Lock() + defer w.mtx.Unlock() + if w.peers == nil { + w.peers = map[uint16]bool{id: true} + } else { + w.peers[id] = true + } +} + +// HasPeer reports whether the specified peer ID is a sender of w. +func (w *WrappedTx) HasPeer(id uint16) bool { + w.mtx.Lock() + defer w.mtx.Unlock() + _, ok := w.peers[id] + return ok +} + +// SetGasWanted sets the application-assigned gas requirement of w. +func (w *WrappedTx) SetGasWanted(gas int64) { + w.mtx.Lock() + defer w.mtx.Unlock() + w.gasWanted = gas +} + +// GasWanted reports the application-assigned gas requirement of w. +func (w *WrappedTx) GasWanted() int64 { + w.mtx.Lock() + defer w.mtx.Unlock() + return w.gasWanted +} + +// SetSender sets the application-assigned sender of w. +func (w *WrappedTx) SetSender(sender string) { + w.mtx.Lock() + defer w.mtx.Unlock() + w.sender = sender +} + +// Sender reports the application-assigned sender of w. +func (w *WrappedTx) Sender() string { + w.mtx.Lock() + defer w.mtx.Unlock() + return w.sender +} + +// SetPriority sets the application-assigned priority of w. +func (w *WrappedTx) SetPriority(p int64) { + w.mtx.Lock() + defer w.mtx.Unlock() + w.priority = p +} + +// Priority reports the application-assigned priority of w. +func (w *WrappedTx) Priority() int64 { + w.mtx.Lock() + defer w.mtx.Unlock() + return w.priority +} diff --git a/node/node.go b/node/node.go index d2c2fae1a..48c42dd52 100644 --- a/node/node.go +++ b/node/node.go @@ -29,6 +29,9 @@ import ( "github.com/Finschia/ostracon/libs/service" "github.com/Finschia/ostracon/light" mempl "github.com/Finschia/ostracon/mempool" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" + + //mempoolv1 "github.com/Finschia/ostracon/mempool/v1" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/p2p/pex" "github.com/Finschia/ostracon/privval" @@ -230,7 +233,7 @@ type Node struct { stateStore sm.Store blockStore *store.BlockStore // store the blockchain to disk bcReactor p2p.Reactor // for fast-syncing - mempoolReactor *mempl.Reactor // for gossipping transactions + mempoolReactor p2p.Reactor // for gossipping transactions mempool mempl.Mempool stateSync bool // whether the node should state sync on startup stateSyncReactor *statesync.Reactor // for hosting and restoring state sync snapshots @@ -384,25 +387,68 @@ func onlyValidatorIsUs(state sm.State, pubKey crypto.PubKey) bool { return bytes.Equal(pubKey.Address(), addr) } -func createMempoolAndMempoolReactor(config *cfg.Config, proxyApp proxy.AppConns, - state sm.State, memplMetrics *mempl.Metrics, logger log.Logger) (*mempl.Reactor, *mempl.CListMempool) { +func createMempoolAndMempoolReactor( + config *cfg.Config, + proxyApp proxy.AppConns, + state sm.State, + memplMetrics *mempl.Metrics, + logger log.Logger, +) (mempl.Mempool, p2p.Reactor) { + + switch config.Mempool.Version { + case cfg.MempoolV1: // XXX Deprecated MempoolV1 + panic("Deprecated MempoolV1") + /* + // TODO(thane): Remove log once https://github.com/tendermint/tendermint/issues/8775 is resolved. + logger.Error("While the prioritized mempool API is stable, there is a critical bug in it that is currently under investigation. See https://github.com/tendermint/tendermint/issues/8775 for details") + mp := mempoolv1.NewTxMempool( + logger, + config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv1.WithMetrics(memplMetrics), + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + + reactor := mempoolv1.NewReactor( + config.Mempool, + mp, + ) + if config.Consensus.WaitForTxs() { + mp.EnableTxsAvailable() + } - mempool := mempl.NewCListMempool( - config.Mempool, - proxyApp.Mempool(), - state.LastBlockHeight, - mempl.WithMetrics(memplMetrics), - mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), - ) - mempoolLogger := logger.With("module", "mempool") - mempoolReactor := mempl.NewReactor(config.Mempool, config.P2P.RecvAsync, config.P2P.MempoolRecvBufSize, mempool) - mempoolReactor.SetLogger(mempoolLogger) + return mp, reactor + */ + case cfg.MempoolV0: + mp := mempoolv0.NewCListMempool( + config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv0.WithMetrics(memplMetrics), + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state)), + ) + + mp.SetLogger(logger) + + reactor := mempoolv0.NewReactor( + config.Mempool, + config.P2P.RecvAsync, + config.P2P.MempoolRecvBufSize, + mp, + ) - if config.Consensus.WaitForTxs() { - mempool.EnableTxsAvailable() + if config.Consensus.WaitForTxs() { + mp.EnableTxsAvailable() + } + + return mp, reactor + + default: + return nil, nil } - return mempoolReactor, mempool } func createEvidenceReactor(config *cfg.Config, dbProvider DBProvider, @@ -450,7 +496,7 @@ func createConsensusReactor(config *cfg.Config, state sm.State, blockExec *sm.BlockExecutor, blockStore sm.BlockStore, - mempool *mempl.CListMempool, + mempool mempl.Mempool, evidencePool *evidence.Pool, privValidator types.PrivValidator, csMetrics *cs.Metrics, @@ -553,7 +599,7 @@ func createSwitch(config *cfg.Config, transport p2p.Transport, p2pMetrics *p2p.Metrics, peerFilters []p2p.PeerFilterFunc, - mempoolReactor *mempl.Reactor, + mempoolReactor p2p.Reactor, bcReactor p2p.Reactor, stateSyncReactor *statesync.Reactor, consensusReactor *cs.Reactor, @@ -787,7 +833,7 @@ func NewNode(config *cfg.Config, csMetrics, p2pMetrics, memplMetrics, smMetrics := metricsProvider(genDoc.ChainID) // Make MempoolReactor - mempoolReactor, mempool := createMempoolAndMempoolReactor(config, proxyApp, state, memplMetrics, logger) + mempool, mempoolReactor := createMempoolAndMempoolReactor(config, proxyApp, state, memplMetrics, logger) // Make Evidence Reactor evidenceReactor, evidencePool, err := createEvidenceReactor(config, dbProvider, stateDB, blockStore, logger) @@ -965,13 +1011,6 @@ func (n *Node) OnStart() error { n.isListening = true - if n.config.Mempool.WalEnabled() { - err = n.mempool.InitWAL() - if err != nil { - return fmt.Errorf("init mempool WAL: %w", err) - } - } - // Start the switch (the P2P server). err = n.sw.Start() if err != nil { @@ -1019,11 +1058,6 @@ func (n *Node) OnStop() { n.Logger.Error("Error closing switch", "err", err) } - // stop mempool WAL - if n.config.Mempool.WalEnabled() { - n.mempool.CloseWAL() - } - if err := n.transport.Close(); err != nil { n.Logger.Error("Error closing transport", "err", err) } @@ -1262,7 +1296,7 @@ func (n *Node) ConsensusReactor() *cs.Reactor { } // MempoolReactor returns the Node's mempool reactor. -func (n *Node) MempoolReactor() *mempl.Reactor { +func (n *Node) MempoolReactor() p2p.Reactor { return n.mempoolReactor } diff --git a/node/node_test.go b/node/node_test.go index 2ca318cc5..3a8217f88 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -25,6 +25,9 @@ import ( "github.com/Finschia/ostracon/libs/log" tmrand "github.com/Finschia/ostracon/libs/rand" mempl "github.com/Finschia/ostracon/mempool" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" + + //mempoolv1 "github.com/Finschia/ostracon/mempool/v1" "github.com/Finschia/ostracon/p2p" "github.com/Finschia/ostracon/p2p/conn" p2pmock "github.com/Finschia/ostracon/p2p/mock" @@ -266,16 +269,30 @@ func TestCreateProposalBlock(t *testing.T) { proposerAddr, _ := state.Validators.GetByIndex(0) // Make Mempool - memplMetrics := mempl.PrometheusMetrics("node_test_1") - mempool := mempl.NewCListMempool( - config.Mempool, - proxyApp.Mempool(), - state.LastBlockHeight, - mempl.WithMetrics(memplMetrics), - mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), - ) - mempool.SetLogger(logger) + memplMetrics := mempl.NopMetrics() + var mempool mempl.Mempool + + switch config.Mempool.Version { + case cfg.MempoolV0: + mempool = mempoolv0.NewCListMempool(config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv0.WithMetrics(memplMetrics), + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state))) + case cfg.MempoolV1: // XXX Deprecated MempoolV1 + panic("Deprecated MempoolV1") + /* + mempool = mempoolv1.NewTxMempool(logger, + config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv1.WithMetrics(memplMetrics), + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + */ + } // Make EvidencePool evidenceDB := dbm.NewMemDB() @@ -303,7 +320,7 @@ func TestCreateProposalBlock(t *testing.T) { txLength := 100 for i := 0; i <= maxBytes/txLength; i++ { tx := tmrand.Bytes(txLength) - _, err := mempool.CheckTxSync(tx, mempl.TxInfo{}) + err := mempool.CheckTxSync(tx, nil, mempl.TxInfo{}) assert.NoError(t, err) } @@ -363,21 +380,33 @@ func TestMaxProposalBlockSize(t *testing.T) { proposerAddr, _ := state.Validators.GetByIndex(0) // Make Mempool - memplMetrics := mempl.PrometheusMetrics("node_test_2") - mempool := mempl.NewCListMempool( - config.Mempool, - proxyApp.Mempool(), - state.LastBlockHeight, - mempl.WithMetrics(memplMetrics), - mempl.WithPreCheck(sm.TxPreCheck(state)), - mempl.WithPostCheck(sm.TxPostCheck(state)), - ) - mempool.SetLogger(logger) + memplMetrics := mempl.NopMetrics() + var mempool mempl.Mempool + switch config.Mempool.Version { + case cfg.MempoolV0: + mempool = mempoolv0.NewCListMempool(config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv0.WithMetrics(memplMetrics), + mempoolv0.WithPreCheck(sm.TxPreCheck(state)), + mempoolv0.WithPostCheck(sm.TxPostCheck(state))) + case cfg.MempoolV1: // XXX Deprecated + /* + mempool = mempoolv1.NewTxMempool(logger, + config.Mempool, + proxyApp.Mempool(), + state.LastBlockHeight, + mempoolv1.WithMetrics(memplMetrics), + mempoolv1.WithPreCheck(sm.TxPreCheck(state)), + mempoolv1.WithPostCheck(sm.TxPostCheck(state)), + ) + */ + } // fill the mempool with one txs just below the maximum size txLength := int(types.MaxDataBytesNoEvidence(maxBytes, 1)) tx := tmrand.Bytes(txLength - 4) // to account for the varint - _, err = mempool.CheckTxSync(tx, mempl.TxInfo{}) + err = mempool.CheckTxSync(tx, nil, mempl.TxInfo{}) assert.NoError(t, err) blockExec := sm.NewBlockExecutor( diff --git a/p2p/conn/connection.go b/p2p/conn/connection.go index a9ace878e..d4f684a11 100644 --- a/p2p/conn/connection.go +++ b/p2p/conn/connection.go @@ -359,7 +359,7 @@ func (c *MConnection) Send(chID byte, msgBytes []byte) bool { return false } - c.Logger.Debug("Send", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes)) + c.Logger.Debug("Send", "channel", chID, "conn", c, "msgBytes", log.NewLazySprintf("%X", msgBytes)) // Send message to channel. channel, ok := c.channelsIdx[chID] @@ -376,7 +376,7 @@ func (c *MConnection) Send(chID byte, msgBytes []byte) bool { default: } } else { - c.Logger.Debug("Send failed", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes)) + c.Logger.Debug("Send failed", "channel", chID, "conn", c, "msgBytes", log.NewLazySprintf("%X", msgBytes)) } return success } @@ -388,7 +388,7 @@ func (c *MConnection) TrySend(chID byte, msgBytes []byte) bool { return false } - c.Logger.Debug("TrySend", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes)) + c.Logger.Debug("TrySend", "channel", chID, "conn", c, "msgBytes", log.NewLazySprintf("%X", msgBytes)) // Send message to channel. channel, ok := c.channelsIdx[chID] diff --git a/p2p/mocks/node_info.go b/p2p/mocks/node_info.go index 1e2b2039d..2009bee9a 100644 --- a/p2p/mocks/node_info.go +++ b/p2p/mocks/node_info.go @@ -80,13 +80,12 @@ func (_m *NodeInfo) Validate() error { return r0 } -type mockConstructorTestingTNewNodeInfo interface { +// NewNodeInfo creates a new instance of NodeInfo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewNodeInfo(t interface { mock.TestingT Cleanup(func()) -} - -// NewNodeInfo creates a new instance of NodeInfo. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewNodeInfo(t mockConstructorTestingTNewNodeInfo) *NodeInfo { +}) *NodeInfo { mock := &NodeInfo{} mock.Mock.Test(t) diff --git a/p2p/mocks/peer.go b/p2p/mocks/peer.go index 509f7d5b9..4f79499f0 100644 --- a/p2p/mocks/peer.go +++ b/p2p/mocks/peer.go @@ -330,13 +330,12 @@ func (_m *Peer) TrySend(_a0 byte, _a1 []byte) bool { return r0 } -type mockConstructorTestingTNewPeer interface { +// NewPeer creates a new instance of Peer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPeer(t interface { mock.TestingT Cleanup(func()) -} - -// NewPeer creates a new instance of Peer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewPeer(t mockConstructorTestingTNewPeer) *Peer { +}) *Peer { mock := &Peer{} mock.Mock.Test(t) diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index 11272d0a6..51813500d 100644 --- a/p2p/pex/addrbook.go +++ b/p2p/pex/addrbook.go @@ -16,6 +16,7 @@ import ( "github.com/minio/highwayhash" "github.com/Finschia/ostracon/crypto" + "github.com/Finschia/ostracon/libs/log" tmmath "github.com/Finschia/ostracon/libs/math" tmrand "github.com/Finschia/ostracon/libs/rand" "github.com/Finschia/ostracon/libs/service" @@ -740,7 +741,7 @@ func (a *addrBook) expireNew(bucketIdx int) { for addrStr, ka := range a.bucketsNew[bucketIdx] { // If an entry is bad, throw it away if ka.isBad() { - a.Logger.Info(fmt.Sprintf("expiring bad address %v", addrStr)) + a.Logger.Info("expire new", "msg", log.NewLazySprintf("expiring bad address %v", addrStr)) a.removeFromBucket(ka, bucketTypeNew, bucketIdx) return } diff --git a/p2p/switch.go b/p2p/switch.go index 40f70e456..679699367 100644 --- a/p2p/switch.go +++ b/p2p/switch.go @@ -8,6 +8,7 @@ import ( "github.com/Finschia/ostracon/config" "github.com/Finschia/ostracon/libs/cmap" + "github.com/Finschia/ostracon/libs/log" "github.com/Finschia/ostracon/libs/rand" "github.com/Finschia/ostracon/libs/service" "github.com/Finschia/ostracon/p2p/conn" @@ -262,7 +263,7 @@ func (sw *Switch) OnStop() { // // NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved. func (sw *Switch) Broadcast(chID byte, msgBytes []byte) chan bool { - sw.Logger.Debug("Broadcast", "channel", chID, "msgBytes", fmt.Sprintf("%X", msgBytes)) + sw.Logger.Debug("Broadcast", "channel", chID, "msgBytes", log.NewLazySprintf("%X", msgBytes)) peers := sw.peers.List() var wg sync.WaitGroup diff --git a/p2p/upnp/probe.go b/p2p/upnp/probe.go index f48db735e..23473babf 100644 --- a/p2p/upnp/probe.go +++ b/p2p/upnp/probe.go @@ -18,19 +18,19 @@ func makeUPNPListener(intPort int, extPort int, logger log.Logger) (NAT, net.Lis if err != nil { return nil, nil, nil, fmt.Errorf("nat upnp could not be discovered: %v", err) } - logger.Info(fmt.Sprintf("ourIP: %v", nat.(*upnpNAT).ourIP)) + logger.Info("make upnp listener", "msg", log.NewLazySprintf("ourIP: %v", nat.(*upnpNAT).ourIP)) ext, err := nat.GetExternalAddress() if err != nil { return nat, nil, nil, fmt.Errorf("external address error: %v", err) } - logger.Info(fmt.Sprintf("External address: %v", ext)) + logger.Info("make upnp listener", "msg", log.NewLazySprintf("External address: %v", ext)) port, err := nat.AddPortMapping("tcp", extPort, intPort, "Ostracon UPnP Probe", 0) if err != nil { return nat, nil, ext, fmt.Errorf("port mapping error: %v", err) } - logger.Info(fmt.Sprintf("Port mapping mapped: %v", port)) + logger.Info("make upnp listener", "msg", log.NewLazySprintf("Port mapping mapped: %v", port)) // also run the listener, open for all remote addresses. listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort)) @@ -45,17 +45,23 @@ func testHairpin(listener net.Listener, extAddr string, logger log.Logger) (supp go func() { inConn, err := listener.Accept() if err != nil { - logger.Info(fmt.Sprintf("Listener.Accept() error: %v", err)) + logger.Info("test hair pin", "msg", log.NewLazySprintf("Listener.Accept() error: %v", err)) return } - logger.Info(fmt.Sprintf("Accepted incoming connection: %v -> %v", inConn.LocalAddr(), inConn.RemoteAddr())) + logger.Info("test hair pin", + "msg", + log.NewLazySprintf("Accepted incoming connection: %v -> %v", inConn.LocalAddr(), inConn.RemoteAddr())) buf := make([]byte, 1024) n, err := inConn.Read(buf) if err != nil { - logger.Info(fmt.Sprintf("Incoming connection read error: %v", err)) + logger.Info("test hair pin", + "msg", + log.NewLazySprintf("Incoming connection read error: %v", err)) return } - logger.Info(fmt.Sprintf("Incoming connection read %v bytes: %X", n, buf)) + logger.Info("test hair pin", + "msg", + log.NewLazySprintf("Incoming connection read %v bytes: %X", n, buf)) if string(buf) == "test data" { supportsHairpin = true return @@ -65,16 +71,16 @@ func testHairpin(listener net.Listener, extAddr string, logger log.Logger) (supp // Establish outgoing outConn, err := net.Dial("tcp", extAddr) if err != nil { - logger.Info(fmt.Sprintf("Outgoing connection dial error: %v", err)) + logger.Info("test hair pin", "msg", log.NewLazySprintf("Outgoing connection dial error: %v", err)) return } n, err := outConn.Write([]byte("test data")) if err != nil { - logger.Info(fmt.Sprintf("Outgoing connection write error: %v", err)) + logger.Info("test hair pin", "msg", log.NewLazySprintf("Outgoing connection write error: %v", err)) return } - logger.Info(fmt.Sprintf("Outgoing connection wrote %v bytes", n)) + logger.Info("test hair pin", "msg", log.NewLazySprintf("Outgoing connection wrote %v bytes", n)) // Wait for data receipt time.Sleep(1 * time.Second) diff --git a/proto/README.md b/proto/README.md new file mode 100644 index 000000000..1317ee761 --- /dev/null +++ b/proto/README.md @@ -0,0 +1,16 @@ +# Using buf build +https://buf.build/ + +```script +go run github.com/bufbuild/buf/cmd/buf help +``` + +## buf.yaml +See: +- https://buf.build/docs/lint/overview/ +- https://buf.build/docs/lint/rules/ + +## if you update `buf.yaml`, should also update `buf.lock` +```script +cd proto && go run github.com/bufbuild/buf/cmd/buf mod update && cd .. +``` diff --git a/proto/buf.lock b/proto/buf.lock new file mode 100644 index 000000000..768ad21ce --- /dev/null +++ b/proto/buf.lock @@ -0,0 +1,8 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: gogo + repository: protobuf + commit: 5461a3dfa9d941da82028ab185dc2a0e + digest: shake256:37c7c75224982038cb1abf45b481ef06716c1f806ffaa162018d0df092bd11a2a9b62c2d0dc0a2ae43beff86b6014fc0eb8c594ffd84d52ade4b08fca901eadc diff --git a/proto/buf.yaml b/proto/buf.yaml new file mode 100644 index 000000000..af1671e6b --- /dev/null +++ b/proto/buf.yaml @@ -0,0 +1,11 @@ +version: v1 +deps: + - buf.build/gogo/protobuf +# - buf.build/tendermint/tendermint # don't use since can't specify tendermint-v0.34.19 +breaking: + use: + - FILE +lint: + use: + - BASIC + - UNARY_RPC diff --git a/proto/ostracon/abci/types.proto b/proto/ostracon/abci/types.proto index 145b1ad72..158fb4b6b 100644 --- a/proto/ostracon/abci/types.proto +++ b/proto/ostracon/abci/types.proto @@ -5,13 +5,9 @@ option go_package = "github.com/Finschia/ostracon/abci/types"; // For more information on gogo.proto, see: // https://github.com/gogo/protobuf/blob/master/extensions.md -import "tendermint/crypto/proof.proto"; -import "tendermint/types/params.proto"; import "tendermint/abci/types.proto"; import "tendermint/types/types.proto"; import "ostracon/types/types.proto"; -import "tendermint/crypto/keys.proto"; -import "google/protobuf/timestamp.proto"; import "gogoproto/gogo.proto"; // This file is copied from http://github.com/tendermint/abci diff --git a/proto/ostracon/privval/types.pb.go b/proto/ostracon/privval/types.pb.go index 0e0d33721..8bc5614ee 100644 --- a/proto/ostracon/privval/types.pb.go +++ b/proto/ostracon/privval/types.pb.go @@ -5,11 +5,8 @@ package privval import ( fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" - _ "github.com/tendermint/tendermint/proto/tendermint/crypto" privval "github.com/tendermint/tendermint/proto/tendermint/privval" - _ "github.com/tendermint/tendermint/proto/tendermint/types" io "io" math "math" math_bits "math/bits" @@ -322,41 +319,39 @@ func init() { func init() { proto.RegisterFile("ostracon/privval/types.proto", fileDescriptor_abbbbe5131a55005) } var fileDescriptor_abbbbe5131a55005 = []byte{ - // 538 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xc1, 0x6e, 0xd3, 0x30, - 0x18, 0xc7, 0x13, 0x46, 0x1b, 0xe4, 0x76, 0xb4, 0x33, 0x05, 0x55, 0xd5, 0x14, 0x4a, 0x11, 0x30, + // 508 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x13, 0x46, 0x17, 0xf4, 0xda, 0xd1, 0xce, 0x0c, 0x54, 0x21, 0x14, 0x4a, 0x11, 0x30, 0x81, 0x94, 0x48, 0xdb, 0x91, 0xdb, 0x04, 0x63, 0xd2, 0x34, 0x54, 0x32, 0x69, 0x87, 0x49, 0xa8, - 0x4a, 0xdb, 0xaf, 0x59, 0xb4, 0x25, 0x36, 0xb6, 0x13, 0x29, 0x6f, 0xc1, 0x63, 0x71, 0xdc, 0x11, - 0x6e, 0xa8, 0xbd, 0xc0, 0x5b, 0x4c, 0x71, 0xdc, 0x24, 0xed, 0xd2, 0xde, 0xe2, 0xbf, 0x3f, 0xff, - 0xbe, 0x9f, 0x15, 0xdb, 0x68, 0x9f, 0x70, 0xc1, 0xdc, 0x09, 0x09, 0x6d, 0xca, 0xfc, 0x38, 0x76, - 0x6f, 0x6d, 0x91, 0x50, 0xe0, 0x16, 0x65, 0x44, 0x10, 0xdc, 0x5e, 0xce, 0x5a, 0x6a, 0xb6, 0xb7, - 0x2f, 0x20, 0x9c, 0x02, 0x0b, 0xfc, 0x50, 0xd8, 0x13, 0x96, 0x50, 0x41, 0xec, 0x1b, 0x48, 0x54, - 0x7d, 0xaf, 0xe3, 0x11, 0x8f, 0xc8, 0x4f, 0x3b, 0xfd, 0x52, 0x69, 0x79, 0x8d, 0xa4, 0x97, 0x7b, - 0xf4, 0xcc, 0xd2, 0x6c, 0x85, 0xc3, 0xe0, 0x03, 0x6a, 0x5d, 0x3a, 0x27, 0x43, 0x46, 0xc8, 0xcc, - 0x81, 0x1f, 0x11, 0x70, 0x81, 0xbb, 0xc8, 0x08, 0x80, 0x73, 0xd7, 0x83, 0xae, 0xde, 0xd7, 0x0f, - 0x9a, 0xce, 0x72, 0x38, 0x00, 0xd4, 0x2e, 0x8a, 0x39, 0x25, 0x21, 0x07, 0xdc, 0x41, 0x35, 0x9a, - 0x06, 0xaa, 0x36, 0x1b, 0xe0, 0x8f, 0xa8, 0x06, 0x8c, 0x11, 0xd6, 0x7d, 0xd4, 0xd7, 0x0f, 0x1a, - 0x87, 0x6f, 0xac, 0x42, 0x63, 0xb9, 0x59, 0xcb, 0x81, 0x80, 0x08, 0xb8, 0xf0, 0xbd, 0x10, 0xd8, - 0xe7, 0xb4, 0xd8, 0xc9, 0xd6, 0x0c, 0xfe, 0xd4, 0x91, 0x71, 0x9e, 0xb5, 0xc4, 0x67, 0xa8, 0x45, - 0xa3, 0xf1, 0xe8, 0x06, 0x92, 0x11, 0xcb, 0xfc, 0x64, 0xa3, 0xc6, 0xe1, 0xab, 0x2a, 0xe4, 0x30, - 0x1a, 0x9f, 0x41, 0xa2, 0x36, 0x72, 0xaa, 0x39, 0xbb, 0xb4, 0x1c, 0xe0, 0xaf, 0xa8, 0x5d, 0xc0, - 0x32, 0x7f, 0x25, 0x38, 0xd8, 0x46, 0xcb, 0x2a, 0x4f, 0x35, 0xe7, 0x29, 0x5d, 0x49, 0xf0, 0x37, - 0xb4, 0xc7, 0x7d, 0x2f, 0x1c, 0xc5, 0x44, 0x40, 0xae, 0xb7, 0x23, 0x81, 0xaf, 0xab, 0x80, 0xe9, - 0x5e, 0x2f, 0x89, 0x80, 0x42, 0xb0, 0xc5, 0x57, 0x23, 0x7c, 0x85, 0x3a, 0x69, 0x04, 0xd3, 0x25, - 0x54, 0x69, 0x3e, 0x96, 0xd4, 0xb7, 0x9b, 0xa8, 0x30, 0xcd, 0x20, 0xb9, 0x2a, 0xe6, 0x0f, 0x52, - 0xfc, 0x1d, 0x3d, 0x97, 0xba, 0x94, 0x11, 0x4a, 0xb8, 0x7b, 0x9b, 0x2b, 0xd7, 0x24, 0xfc, 0xdd, - 0x26, 0xf8, 0x50, 0xd5, 0x17, 0xda, 0xcf, 0xf8, 0xc3, 0x18, 0xcf, 0x50, 0x57, 0xa9, 0x97, 0x1a, - 0x28, 0xfd, 0xba, 0xec, 0xf0, 0x7e, 0xb3, 0x7e, 0x01, 0xcb, 0xb7, 0xf0, 0x82, 0x57, 0xce, 0xe0, - 0x4f, 0xa8, 0x49, 0xfd, 0xd0, 0xcb, 0xed, 0x0d, 0xc9, 0x7e, 0x59, 0xf9, 0x07, 0xfd, 0xd0, 0x2b, - 0xac, 0x1b, 0xb4, 0x18, 0xe2, 0x2f, 0x68, 0x57, 0x51, 0x94, 0xe2, 0x13, 0x89, 0xe9, 0x6f, 0xc6, - 0xe4, 0x62, 0x4d, 0x5a, 0x1a, 0xe3, 0x21, 0xda, 0x8b, 0xd9, 0x6c, 0x24, 0xcf, 0x7d, 0xee, 0xf4, - 0xcf, 0x50, 0x87, 0x74, 0xfd, 0x8a, 0x5b, 0x6b, 0xb7, 0x2d, 0x3d, 0x03, 0x31, 0x9b, 0xad, 0x5c, - 0xc0, 0x0b, 0x84, 0xcb, 0x44, 0xe5, 0xf7, 0xdf, 0x50, 0x27, 0x75, 0x0b, 0x32, 0x57, 0x6c, 0x17, - 0xcc, 0x2c, 0x3b, 0xae, 0xa1, 0x1d, 0x1e, 0x05, 0xc7, 0xe7, 0xbf, 0xe6, 0xa6, 0x7e, 0x37, 0x37, - 0xf5, 0xbf, 0x73, 0x53, 0xff, 0xb9, 0x30, 0xb5, 0xbb, 0x85, 0xa9, 0xfd, 0x5e, 0x98, 0xda, 0xd5, - 0x91, 0xe7, 0x8b, 0xeb, 0x68, 0x6c, 0x4d, 0x48, 0x60, 0x9f, 0xf8, 0x21, 0x9f, 0x5c, 0xfb, 0xae, - 0x5d, 0x7a, 0xbf, 0xd2, 0x67, 0x67, 0xfd, 0x39, 0x1b, 0xd7, 0x65, 0x7e, 0x74, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0x04, 0x18, 0x8f, 0xf9, 0xe9, 0x04, 0x00, 0x00, + 0x4a, 0xdb, 0xd7, 0x2c, 0x62, 0x89, 0x8d, 0xed, 0x44, 0xea, 0xb7, 0xe0, 0x63, 0x71, 0xdc, 0x11, + 0x6e, 0xa8, 0xbd, 0xc0, 0xb7, 0x40, 0x71, 0xdc, 0x24, 0xed, 0xd2, 0x1d, 0xfd, 0xf7, 0xcb, 0xef, + 0xfd, 0xac, 0x3c, 0x1b, 0x9e, 0x51, 0x21, 0xb9, 0x3f, 0xa6, 0xb1, 0xcb, 0x78, 0x98, 0xa6, 0xfe, + 0xb5, 0x2b, 0x67, 0x0c, 0x85, 0xc3, 0x38, 0x95, 0x94, 0x74, 0x96, 0xbb, 0x8e, 0xde, 0x7d, 0x6a, + 0x4b, 0x8c, 0x27, 0xc8, 0xa3, 0x30, 0x96, 0x75, 0x5f, 0xf4, 0xdf, 0x41, 0xfb, 0xc2, 0x3b, 0x1e, + 0x70, 0x4a, 0xa7, 0x1e, 0x7e, 0x4f, 0x50, 0x48, 0xd2, 0x05, 0x2b, 0x42, 0x21, 0xfc, 0x00, 0xbb, + 0x66, 0xcf, 0xdc, 0x6f, 0x79, 0xcb, 0x65, 0x1f, 0xa1, 0x53, 0x16, 0x0b, 0x46, 0x63, 0x81, 0x64, + 0x0f, 0x1a, 0x2c, 0x0b, 0x74, 0x6d, 0xbe, 0x20, 0xef, 0xa1, 0x81, 0x9c, 0x53, 0xde, 0xbd, 0xd7, + 0x33, 0xf7, 0x9b, 0x07, 0xaf, 0x9c, 0x52, 0x63, 0xa9, 0xe6, 0x78, 0x18, 0x51, 0x89, 0xe7, 0x61, + 0x10, 0x23, 0xff, 0x98, 0x15, 0x7b, 0xf9, 0x37, 0xfd, 0xdf, 0xdb, 0x60, 0x9d, 0xe5, 0x2d, 0xc9, + 0x29, 0xb4, 0x59, 0x32, 0x1a, 0x7e, 0xc3, 0xd9, 0x90, 0xe7, 0x7e, 0xaa, 0x51, 0xf3, 0xe0, 0x45, + 0x1d, 0x72, 0x90, 0x8c, 0x4e, 0x71, 0xa6, 0x0f, 0x72, 0x62, 0x78, 0x3b, 0xac, 0x1a, 0x90, 0xcf, + 0xd0, 0x29, 0x61, 0xb9, 0xbf, 0x16, 0xec, 0xdf, 0x45, 0xcb, 0x2b, 0x4f, 0x0c, 0xef, 0x21, 0x5b, + 0x49, 0xc8, 0x17, 0xd8, 0x15, 0x61, 0x10, 0x0f, 0x53, 0x2a, 0xb1, 0xd0, 0xdb, 0x52, 0xc0, 0x97, + 0x75, 0xc0, 0xec, 0xac, 0x17, 0x54, 0x62, 0x29, 0xd8, 0x16, 0xab, 0x11, 0xb9, 0x84, 0xbd, 0x2c, + 0xc2, 0xc9, 0x12, 0xaa, 0x35, 0xef, 0x2b, 0xea, 0xeb, 0x4d, 0x54, 0x9c, 0xe4, 0x90, 0x42, 0x95, + 0x88, 0x5b, 0x29, 0xf9, 0x0a, 0x8f, 0x95, 0x2e, 0xe3, 0x94, 0x51, 0xe1, 0x5f, 0x17, 0xca, 0x0d, + 0x05, 0x7f, 0xb3, 0x09, 0x3e, 0xd0, 0xf5, 0xa5, 0xf6, 0x23, 0x71, 0x3b, 0x26, 0x53, 0xe8, 0x6a, + 0xf5, 0x4a, 0x03, 0xad, 0xbf, 0xad, 0x3a, 0xbc, 0xdd, 0xac, 0x5f, 0xc2, 0x8a, 0x23, 0x3c, 0x11, + 0xb5, 0x3b, 0xe4, 0x03, 0xb4, 0x58, 0x18, 0x07, 0x85, 0xbd, 0xa5, 0xd8, 0xcf, 0x6b, 0xff, 0x60, + 0x18, 0x07, 0xa5, 0x75, 0x93, 0x95, 0x4b, 0xf2, 0x09, 0x76, 0x34, 0x45, 0x2b, 0x3e, 0x50, 0x98, + 0xde, 0x66, 0x4c, 0x21, 0xd6, 0x62, 0x95, 0x35, 0x19, 0xc0, 0x6e, 0xca, 0xa7, 0x43, 0x35, 0xf7, + 0x85, 0xd3, 0x5f, 0x4b, 0x0f, 0xe9, 0xfa, 0x85, 0x74, 0xd6, 0x6e, 0x5b, 0x36, 0x03, 0x29, 0x9f, + 0xae, 0x5c, 0xc0, 0x73, 0x20, 0x55, 0xa2, 0xf6, 0xfb, 0x67, 0xe9, 0x49, 0xbd, 0x03, 0x59, 0x28, + 0x76, 0x4a, 0x66, 0x9e, 0x1d, 0x35, 0x60, 0x4b, 0x24, 0xd1, 0xd1, 0xd9, 0xcf, 0xb9, 0x6d, 0xde, + 0xcc, 0x6d, 0xf3, 0xcf, 0xdc, 0x36, 0x7f, 0x2c, 0x6c, 0xe3, 0x66, 0x61, 0x1b, 0xbf, 0x16, 0xb6, + 0x71, 0x79, 0x18, 0x84, 0xf2, 0x2a, 0x19, 0x39, 0x63, 0x1a, 0xb9, 0xc7, 0x61, 0x2c, 0xc6, 0x57, + 0xa1, 0xef, 0x56, 0x5e, 0x1b, 0x2a, 0xa9, 0xbb, 0xfe, 0xf8, 0x8c, 0xb6, 0x55, 0x7e, 0xf8, 0x3f, + 0x00, 0x00, 0xff, 0xff, 0x26, 0x1b, 0x30, 0x10, 0x97, 0x04, 0x00, 0x00, } func (m *VRFProofRequest) Marshal() (dAtA []byte, err error) { diff --git a/proto/ostracon/privval/types.proto b/proto/ostracon/privval/types.proto index f377a2fe1..45a5aa74b 100644 --- a/proto/ostracon/privval/types.proto +++ b/proto/ostracon/privval/types.proto @@ -1,9 +1,6 @@ syntax = "proto3"; package ostracon.privval; -import "tendermint/crypto/keys.proto"; -import "gogoproto/gogo.proto"; -import "tendermint/types/types.proto"; import "tendermint/privval/types.proto"; option go_package = "github.com/Finschia/ostracon/proto/ostracon/privval"; diff --git a/proto/ostracon/state/types.pb.go b/proto/ostracon/state/types.pb.go index 3be0b0934..273381acb 100644 --- a/proto/ostracon/state/types.pb.go +++ b/proto/ostracon/state/types.pb.go @@ -5,8 +5,6 @@ package state import ( fmt "fmt" - _ "github.com/Finschia/ostracon/abci/types" - _ "github.com/Finschia/ostracon/proto/ostracon/types" _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" _ "github.com/gogo/protobuf/types" @@ -14,7 +12,6 @@ import ( types "github.com/tendermint/tendermint/abci/types" state "github.com/tendermint/tendermint/proto/tendermint/state" types1 "github.com/tendermint/tendermint/proto/tendermint/types" - _ "github.com/tendermint/tendermint/proto/tendermint/version" io "io" math "math" math_bits "math/bits" @@ -273,52 +270,51 @@ func init() { func init() { proto.RegisterFile("ostracon/state/types.proto", fileDescriptor_898987a4421067cd) } var fileDescriptor_898987a4421067cd = []byte{ - // 708 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0x4f, 0x6f, 0xd3, 0x3e, - 0x18, 0xc7, 0x9b, 0x5f, 0xb7, 0xb5, 0x73, 0xd6, 0xf6, 0x47, 0xe0, 0x90, 0x75, 0x90, 0x96, 0xf1, - 0xaf, 0xe2, 0x90, 0x8a, 0x71, 0xe2, 0x82, 0x44, 0x5a, 0x60, 0x15, 0x13, 0x9a, 0xb2, 0x69, 0x07, - 0x2e, 0x91, 0x93, 0x78, 0x89, 0x45, 0x1a, 0x47, 0xb1, 0x3b, 0x8d, 0xb7, 0xc0, 0x69, 0x2f, 0x6b, - 0xc7, 0x1d, 0x11, 0x87, 0x81, 0xba, 0x0b, 0x2f, 0x03, 0xd9, 0x8e, 0xd3, 0x6c, 0x65, 0xd2, 0x6e, - 0xce, 0xf3, 0xfd, 0x3e, 0x1f, 0x7d, 0x6d, 0x3f, 0x31, 0xe8, 0x12, 0xca, 0x72, 0x18, 0x90, 0x74, - 0x48, 0x19, 0x64, 0x68, 0xc8, 0xbe, 0x65, 0x88, 0xda, 0x59, 0x4e, 0x18, 0x31, 0xda, 0x4a, 0xb3, - 0x85, 0xd6, 0x7d, 0x10, 0x91, 0x88, 0x08, 0x69, 0xc8, 0x57, 0xd2, 0xd5, 0xdd, 0x2c, 0x09, 0xd0, - 0x0f, 0x70, 0x15, 0xd0, 0x5d, 0xc0, 0x45, 0xf5, 0x9a, 0xd6, 0x67, 0x28, 0x0d, 0x51, 0x3e, 0xc5, - 0x29, 0x2b, 0xd4, 0x13, 0x98, 0xe0, 0x10, 0x32, 0x92, 0x17, 0x8e, 0x47, 0x4b, 0x8e, 0x0c, 0xe6, - 0x70, 0xaa, 0x00, 0x0f, 0x97, 0xe4, 0x2a, 0xde, 0xaa, 0xa8, 0x27, 0x28, 0xa7, 0x58, 0x85, 0x28, - 0xf4, 0x5e, 0x44, 0x48, 0x94, 0xa0, 0xa1, 0xf8, 0xf2, 0x67, 0xc7, 0x43, 0x86, 0xa7, 0x88, 0x32, - 0x38, 0xcd, 0xfe, 0x81, 0x5f, 0x3a, 0x9a, 0xee, 0x56, 0x45, 0xbd, 0xb9, 0xed, 0xed, 0x9f, 0x1a, - 0x68, 0xbd, 0x73, 0x46, 0x13, 0x17, 0xd1, 0x8c, 0xa4, 0x14, 0x51, 0x63, 0x04, 0xf4, 0x10, 0x25, - 0xf8, 0x04, 0xe5, 0x1e, 0x3b, 0xa5, 0xa6, 0xd6, 0xaf, 0x0f, 0xf4, 0x9d, 0x6d, 0x7b, 0x01, 0xb1, - 0x39, 0xc4, 0x56, 0x0d, 0x63, 0xe9, 0x3d, 0x3c, 0x75, 0x41, 0xa8, 0x96, 0xd4, 0x78, 0x0b, 0xd6, - 0x51, 0x1a, 0x7a, 0x7e, 0x42, 0x82, 0xaf, 0xe6, 0x7f, 0x7d, 0x6d, 0xa0, 0xef, 0x3c, 0xbe, 0x15, - 0xf1, 0x3e, 0x0d, 0x1d, 0x6e, 0x74, 0x9b, 0xa8, 0x58, 0x19, 0x63, 0xa0, 0xfb, 0x28, 0xc2, 0x69, - 0x41, 0xa8, 0x0b, 0xc2, 0x93, 0x5b, 0x09, 0x0e, 0xf7, 0x4a, 0x06, 0xf0, 0xcb, 0xf5, 0xf6, 0xf7, - 0x06, 0x58, 0x3d, 0xe0, 0xe7, 0x61, 0xbc, 0x01, 0x8d, 0xe2, 0x64, 0x4d, 0x4d, 0xb0, 0x36, 0xab, - 0x2c, 0x71, 0x66, 0xf6, 0x91, 0x34, 0x38, 0x2b, 0xe7, 0x97, 0xbd, 0x9a, 0xab, 0xfc, 0xc6, 0x73, - 0xd0, 0x0c, 0x62, 0x88, 0x53, 0x0f, 0x87, 0x62, 0x27, 0xeb, 0x8e, 0x3e, 0xbf, 0xec, 0x35, 0x46, - 0xbc, 0x36, 0x19, 0xbb, 0x0d, 0x21, 0x4e, 0x42, 0xe3, 0x19, 0x68, 0xe3, 0x14, 0x33, 0x0c, 0x13, - 0x2f, 0x46, 0x38, 0x8a, 0x99, 0xd9, 0xee, 0x6b, 0x83, 0xba, 0xdb, 0x2a, 0xaa, 0xbb, 0xa2, 0x68, - 0xbc, 0x04, 0xf7, 0x12, 0x48, 0x99, 0xdc, 0x98, 0x72, 0xd6, 0x85, 0xb3, 0xc3, 0x05, 0x91, 0xbc, - 0xf0, 0xba, 0xa0, 0x55, 0xf1, 0xe2, 0xd0, 0x5c, 0x59, 0xce, 0x2e, 0x2f, 0x53, 0x74, 0x4d, 0xc6, - 0xce, 0x7d, 0x9e, 0x7d, 0x7e, 0xd9, 0xd3, 0xf7, 0x14, 0x6a, 0x32, 0x76, 0xf5, 0x92, 0x3b, 0x09, - 0x8d, 0x3d, 0xd0, 0xa9, 0x30, 0xf9, 0x24, 0x99, 0xab, 0x82, 0xda, 0xb5, 0xe5, 0x98, 0xd9, 0x6a, - 0xcc, 0xec, 0x43, 0x35, 0x66, 0x4e, 0x93, 0x63, 0xcf, 0x7e, 0xf5, 0x34, 0xb7, 0x55, 0xb2, 0xb8, - 0x6a, 0x7c, 0x04, 0x9d, 0x14, 0x9d, 0x32, 0xaf, 0xfc, 0x1f, 0xa8, 0xb9, 0x26, 0x68, 0xd6, 0x72, - 0xc6, 0x23, 0xe5, 0x39, 0x40, 0xcc, 0x6d, 0xf3, 0xb6, 0xb2, 0xc2, 0x07, 0x06, 0x54, 0x18, 0x8d, - 0x3b, 0x31, 0x2a, 0x1d, 0x3c, 0x88, 0xd8, 0x56, 0x05, 0xd2, 0xbc, 0x5b, 0x10, 0xde, 0x56, 0x09, - 0x32, 0x02, 0x96, 0x00, 0xc9, 0x9b, 0xa9, 0xf0, 0xbc, 0x20, 0x86, 0x69, 0x84, 0x42, 0x73, 0x5d, - 0x5c, 0xd6, 0x16, 0x77, 0xc9, 0x7b, 0x5a, 0x74, 0x8f, 0xa4, 0xc5, 0x70, 0xc1, 0xff, 0x01, 0x9f, - 0xcb, 0x94, 0xce, 0xa8, 0x27, 0x5f, 0x02, 0x13, 0x2c, 0xff, 0x05, 0x32, 0xce, 0x48, 0x39, 0xf7, - 0x85, 0xb1, 0x98, 0xbf, 0x4e, 0x70, 0xbd, 0x6c, 0x7c, 0x06, 0x4f, 0xab, 0xc1, 0x6e, 0xf2, 0xcb, - 0x78, 0xba, 0x88, 0xd7, 0x5f, 0xc4, 0xbb, 0xc1, 0x57, 0x19, 0xd5, 0x20, 0xe6, 0x88, 0xce, 0x12, - 0x46, 0xbd, 0x18, 0xd2, 0xd8, 0xdc, 0xe8, 0x6b, 0x83, 0x0d, 0x39, 0x88, 0xae, 0xac, 0xef, 0x42, - 0x1a, 0x1b, 0x9b, 0xa0, 0x09, 0xb3, 0x4c, 0x5a, 0x5a, 0xc2, 0xd2, 0x80, 0x59, 0x26, 0xa4, 0x17, - 0xc5, 0xc1, 0x67, 0x39, 0x21, 0xc7, 0xd2, 0xf1, 0xa7, 0x21, 0x2c, 0x62, 0x54, 0xf6, 0x79, 0x99, - 0x1b, 0x9d, 0x4f, 0xe7, 0x73, 0x4b, 0xbb, 0x98, 0x5b, 0xda, 0xef, 0xb9, 0xa5, 0x9d, 0x5d, 0x59, - 0xb5, 0x8b, 0x2b, 0xab, 0xf6, 0xe3, 0xca, 0xaa, 0x7d, 0x79, 0x15, 0x61, 0x16, 0xcf, 0x7c, 0x3b, - 0x20, 0xd3, 0xe1, 0x07, 0x9c, 0xd2, 0x20, 0xc6, 0x70, 0x58, 0x3e, 0xc7, 0xf2, 0x11, 0xbf, 0xfe, - 0xf4, 0xfb, 0x6b, 0xa2, 0xfa, 0xfa, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0xe8, 0x57, 0xa5, - 0x13, 0x06, 0x00, 0x00, + // 694 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x94, 0x4f, 0x4f, 0xdb, 0x48, + 0x18, 0xc6, 0xe3, 0x0d, 0x90, 0x30, 0x26, 0xc9, 0xae, 0x77, 0x0f, 0x26, 0x6c, 0x9d, 0x94, 0xfe, + 0x8b, 0x7a, 0xb0, 0x55, 0x7a, 0xea, 0xa5, 0x52, 0x9d, 0xb4, 0x25, 0x2a, 0xaa, 0x90, 0x41, 0x1c, + 0x7a, 0xb1, 0xc6, 0xf6, 0x60, 0x8f, 0xea, 0xcc, 0x58, 0x9e, 0x09, 0xa2, 0x5f, 0xa1, 0x27, 0x3e, + 0x16, 0x47, 0x8e, 0x55, 0x0f, 0xb4, 0x0a, 0x97, 0x7e, 0x8c, 0x6a, 0x66, 0x6c, 0x63, 0x48, 0x91, + 0xb8, 0x4d, 0xde, 0xf7, 0x79, 0x7f, 0x79, 0x66, 0xe6, 0xf1, 0x80, 0x3e, 0x65, 0x3c, 0x87, 0x21, + 0x25, 0x0e, 0xe3, 0x90, 0x23, 0x87, 0x7f, 0xc9, 0x10, 0xb3, 0xb3, 0x9c, 0x72, 0x6a, 0x74, 0xcb, + 0x9e, 0x2d, 0x7b, 0xfd, 0xff, 0x62, 0x1a, 0x53, 0xd9, 0x72, 0xc4, 0x4a, 0xa9, 0xfa, 0x43, 0x8e, + 0x48, 0x84, 0xf2, 0x19, 0x26, 0x5c, 0x4d, 0x3b, 0x27, 0x30, 0xc5, 0x11, 0xe4, 0x34, 0x2f, 0x14, + 0x0f, 0x96, 0x14, 0x19, 0xcc, 0xe1, 0xac, 0xf8, 0x9b, 0xfe, 0xff, 0x4b, 0xed, 0x9a, 0x89, 0xfe, + 0x20, 0xa6, 0x34, 0x4e, 0x91, 0x23, 0x7f, 0x05, 0xf3, 0x63, 0x87, 0xe3, 0x19, 0x62, 0x1c, 0xce, + 0xb2, 0x3f, 0x8c, 0x2f, 0xed, 0xa1, 0xbf, 0x55, 0xeb, 0xc2, 0x20, 0xc4, 0xf5, 0xe6, 0xf6, 0x77, + 0x0d, 0x74, 0xde, 0xb8, 0xe3, 0xa9, 0x87, 0x58, 0x46, 0x09, 0x43, 0xcc, 0x18, 0x03, 0x3d, 0x42, + 0x29, 0x3e, 0x41, 0xb9, 0xcf, 0x4f, 0x99, 0xa9, 0x0d, 0x9b, 0x23, 0x7d, 0x67, 0xdb, 0xbe, 0x86, + 0xd8, 0x02, 0x62, 0x97, 0x03, 0x13, 0xa5, 0x3d, 0x3c, 0xf5, 0x40, 0x54, 0x2e, 0x99, 0xf1, 0x1a, + 0xac, 0x23, 0x12, 0xf9, 0x41, 0x4a, 0xc3, 0xcf, 0xe6, 0x5f, 0x43, 0x6d, 0xa4, 0xef, 0x3c, 0xbc, + 0x13, 0xf1, 0x96, 0x44, 0xae, 0x10, 0x7a, 0x6d, 0x54, 0xac, 0x8c, 0x09, 0xd0, 0x03, 0x14, 0x63, + 0x52, 0x10, 0x9a, 0x92, 0xf0, 0xe8, 0x4e, 0x82, 0x2b, 0xb4, 0x8a, 0x01, 0x82, 0x6a, 0xbd, 0xfd, + 0xb5, 0x05, 0x56, 0x0f, 0xc4, 0x79, 0x18, 0xaf, 0x40, 0xeb, 0x04, 0xe5, 0x0c, 0x53, 0x62, 0x6a, + 0x92, 0xb5, 0x59, 0x67, 0xc9, 0x33, 0xb3, 0x8f, 0x94, 0xc0, 0x5d, 0x39, 0xbf, 0x1c, 0x34, 0xbc, + 0x52, 0x6f, 0x3c, 0x05, 0xed, 0x30, 0x81, 0x98, 0xf8, 0x38, 0x92, 0x3b, 0x59, 0x77, 0xf5, 0xc5, + 0xe5, 0xa0, 0x35, 0x16, 0xb5, 0xe9, 0xc4, 0x6b, 0xc9, 0xe6, 0x34, 0x32, 0x9e, 0x80, 0x2e, 0x26, + 0x98, 0x63, 0x98, 0xfa, 0x09, 0xc2, 0x71, 0xc2, 0xcd, 0xee, 0x50, 0x1b, 0x35, 0xbd, 0x4e, 0x51, + 0xdd, 0x95, 0x45, 0xe3, 0x39, 0xf8, 0x27, 0x85, 0x8c, 0xab, 0x8d, 0x95, 0xca, 0xa6, 0x54, 0xf6, + 0x44, 0x43, 0x3a, 0x2f, 0xb4, 0x1e, 0xe8, 0xd4, 0xb4, 0x38, 0x32, 0x57, 0x96, 0xbd, 0xab, 0xcb, + 0x94, 0x53, 0xd3, 0x89, 0xfb, 0xaf, 0xf0, 0xbe, 0xb8, 0x1c, 0xe8, 0x7b, 0x25, 0x6a, 0x3a, 0xf1, + 0xf4, 0x8a, 0x3b, 0x8d, 0x8c, 0x3d, 0xd0, 0xab, 0x31, 0x45, 0x92, 0xcc, 0x55, 0x49, 0xed, 0xdb, + 0x2a, 0x66, 0x76, 0x19, 0x33, 0xfb, 0xb0, 0x8c, 0x99, 0xdb, 0x16, 0xd8, 0xb3, 0x1f, 0x03, 0xcd, + 0xeb, 0x54, 0x2c, 0xd1, 0x35, 0xde, 0x83, 0x1e, 0x41, 0xa7, 0xdc, 0xaf, 0xf2, 0xce, 0xcc, 0x35, + 0x49, 0xb3, 0x96, 0x3d, 0x1e, 0x95, 0x9a, 0x03, 0xc4, 0xbd, 0xae, 0x18, 0xab, 0x2a, 0x22, 0x30, + 0xa0, 0xc6, 0x68, 0xdd, 0x8b, 0x51, 0x9b, 0x10, 0x46, 0xe4, 0xb6, 0x6a, 0x90, 0xf6, 0xfd, 0x8c, + 0x88, 0xb1, 0x9a, 0x91, 0x31, 0xb0, 0x24, 0x48, 0xdd, 0x4c, 0x8d, 0xe7, 0x87, 0x09, 0x24, 0x31, + 0x8a, 0xcc, 0x75, 0x79, 0x59, 0x5b, 0x42, 0xa5, 0xee, 0xe9, 0x7a, 0x7a, 0xac, 0x24, 0x86, 0x07, + 0xfe, 0x0e, 0x45, 0x2e, 0x09, 0x9b, 0x33, 0x5f, 0x7d, 0xe9, 0x26, 0x58, 0xfe, 0x0a, 0x94, 0x9d, + 0x71, 0xa9, 0xdc, 0x97, 0xc2, 0x22, 0x7f, 0xbd, 0xf0, 0x66, 0xd9, 0xf8, 0x08, 0x1e, 0xd7, 0x8d, + 0xdd, 0xe6, 0x57, 0xf6, 0x74, 0x69, 0x6f, 0x78, 0x6d, 0xef, 0x16, 0xbf, 0xf4, 0x58, 0x06, 0x31, + 0x47, 0x6c, 0x9e, 0x72, 0xe6, 0x27, 0x90, 0x25, 0xe6, 0xc6, 0x50, 0x1b, 0x6d, 0xa8, 0x20, 0x7a, + 0xaa, 0xbe, 0x0b, 0x59, 0x62, 0x6c, 0x82, 0x36, 0xcc, 0x32, 0x25, 0xe9, 0x48, 0x49, 0x0b, 0x66, + 0x99, 0x6c, 0x3d, 0x2b, 0x0e, 0x3e, 0xcb, 0x29, 0x3d, 0x56, 0x8a, 0x5f, 0x2d, 0x29, 0x91, 0x51, + 0xd9, 0x17, 0x65, 0x21, 0x74, 0x3f, 0x9c, 0x2f, 0x2c, 0xed, 0x62, 0x61, 0x69, 0x3f, 0x17, 0x96, + 0x76, 0x76, 0x65, 0x35, 0x2e, 0xae, 0xac, 0xc6, 0xb7, 0x2b, 0xab, 0xf1, 0xe9, 0x45, 0x8c, 0x79, + 0x32, 0x0f, 0xec, 0x90, 0xce, 0x9c, 0x77, 0x98, 0xb0, 0x30, 0xc1, 0xd0, 0xa9, 0x1e, 0x65, 0xf5, + 0xda, 0xde, 0x7c, 0xa3, 0x83, 0x35, 0x59, 0x7d, 0xf9, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x20, 0x46, + 0x0f, 0x5a, 0xbc, 0x05, 0x00, 0x00, } func (m *ABCIResponses) Marshal() (dAtA []byte, err error) { diff --git a/proto/ostracon/state/types.proto b/proto/ostracon/state/types.proto index 123588a3b..b192aed5f 100644 --- a/proto/ostracon/state/types.proto +++ b/proto/ostracon/state/types.proto @@ -4,12 +4,9 @@ package ostracon.state; option go_package = "github.com/Finschia/ostracon/proto/ostracon/state"; import "gogoproto/gogo.proto"; -import "ostracon/abci/types.proto"; -import "ostracon/types/types.proto"; import "tendermint/types/validator.proto"; import "tendermint/types/params.proto"; import "tendermint/types/types.proto"; -import "tendermint/version/types.proto"; import "google/protobuf/timestamp.proto"; import "tendermint/state/types.proto"; import "tendermint/abci/types.proto"; diff --git a/proxy/mocks/app_conn_consensus.go b/proxy/mocks/app_conn_consensus.go index 25b97a4ac..9e21d7154 100644 --- a/proxy/mocks/app_conn_consensus.go +++ b/proxy/mocks/app_conn_consensus.go @@ -155,13 +155,12 @@ func (_m *AppConnConsensus) SetGlobalCallback(_a0 abcicli.GlobalCallback) { _m.Called(_a0) } -type mockConstructorTestingTNewAppConnConsensus interface { +// NewAppConnConsensus creates a new instance of AppConnConsensus. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAppConnConsensus(t interface { mock.TestingT Cleanup(func()) -} - -// NewAppConnConsensus creates a new instance of AppConnConsensus. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAppConnConsensus(t mockConstructorTestingTNewAppConnConsensus) *AppConnConsensus { +}) *AppConnConsensus { mock := &AppConnConsensus{} mock.Mock.Test(t) diff --git a/proxy/mocks/app_conn_mempool.go b/proxy/mocks/app_conn_mempool.go index 42e8c2832..0e3d3958e 100644 --- a/proxy/mocks/app_conn_mempool.go +++ b/proxy/mocks/app_conn_mempool.go @@ -171,13 +171,12 @@ func (_m *AppConnMempool) SetGlobalCallback(_a0 abcicli.GlobalCallback) { _m.Called(_a0) } -type mockConstructorTestingTNewAppConnMempool interface { +// NewAppConnMempool creates a new instance of AppConnMempool. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAppConnMempool(t interface { mock.TestingT Cleanup(func()) -} - -// NewAppConnMempool creates a new instance of AppConnMempool. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAppConnMempool(t mockConstructorTestingTNewAppConnMempool) *AppConnMempool { +}) *AppConnMempool { mock := &AppConnMempool{} mock.Mock.Test(t) diff --git a/proxy/mocks/app_conn_query.go b/proxy/mocks/app_conn_query.go index 88ba96f8d..2fcd62802 100644 --- a/proxy/mocks/app_conn_query.go +++ b/proxy/mocks/app_conn_query.go @@ -105,13 +105,12 @@ func (_m *AppConnQuery) QuerySync(_a0 types.RequestQuery) (*types.ResponseQuery, return r0, r1 } -type mockConstructorTestingTNewAppConnQuery interface { +// NewAppConnQuery creates a new instance of AppConnQuery. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAppConnQuery(t interface { mock.TestingT Cleanup(func()) -} - -// NewAppConnQuery creates a new instance of AppConnQuery. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAppConnQuery(t mockConstructorTestingTNewAppConnQuery) *AppConnQuery { +}) *AppConnQuery { mock := &AppConnQuery{} mock.Mock.Test(t) diff --git a/proxy/mocks/app_conn_snapshot.go b/proxy/mocks/app_conn_snapshot.go index fab90afd4..5faa02689 100644 --- a/proxy/mocks/app_conn_snapshot.go +++ b/proxy/mocks/app_conn_snapshot.go @@ -131,13 +131,12 @@ func (_m *AppConnSnapshot) OfferSnapshotSync(_a0 types.RequestOfferSnapshot) (*t return r0, r1 } -type mockConstructorTestingTNewAppConnSnapshot interface { +// NewAppConnSnapshot creates a new instance of AppConnSnapshot. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewAppConnSnapshot(t interface { mock.TestingT Cleanup(func()) -} - -// NewAppConnSnapshot creates a new instance of AppConnSnapshot. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAppConnSnapshot(t mockConstructorTestingTNewAppConnSnapshot) *AppConnSnapshot { +}) *AppConnSnapshot { mock := &AppConnSnapshot{} mock.Mock.Test(t) diff --git a/proxy/mocks/client_creator.go b/proxy/mocks/client_creator.go index 3c762a228..3e3869699 100644 --- a/proxy/mocks/client_creator.go +++ b/proxy/mocks/client_creator.go @@ -38,13 +38,12 @@ func (_m *ClientCreator) NewABCIClient() (abcicli.Client, error) { return r0, r1 } -type mockConstructorTestingTNewClientCreator interface { +// NewClientCreator creates a new instance of ClientCreator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClientCreator(t interface { mock.TestingT Cleanup(func()) -} - -// NewClientCreator creates a new instance of ClientCreator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewClientCreator(t mockConstructorTestingTNewClientCreator) *ClientCreator { +}) *ClientCreator { mock := &ClientCreator{} mock.Mock.Test(t) diff --git a/rpc/client/mocks/client.go b/rpc/client/mocks/client.go index 6b49fc4e7..82ffc9de6 100644 --- a/rpc/client/mocks/client.go +++ b/rpc/client/mocks/client.go @@ -909,13 +909,12 @@ func (_m *Client) Validators(ctx context.Context, height *int64, page *int, perP return r0, r1 } -type mockConstructorTestingTNewClient interface { +// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewClient(t interface { mock.TestingT Cleanup(func()) -} - -// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewClient(t mockConstructorTestingTNewClient) *Client { +}) *Client { mock := &Client{} mock.Mock.Test(t) diff --git a/rpc/client/mocks/remote_client.go b/rpc/client/mocks/remote_client.go index 656202116..6fde92349 100644 --- a/rpc/client/mocks/remote_client.go +++ b/rpc/client/mocks/remote_client.go @@ -923,13 +923,12 @@ func (_m *RemoteClient) Validators(ctx context.Context, height *int64, page *int return r0, r1 } -type mockConstructorTestingTNewRemoteClient interface { +// NewRemoteClient creates a new instance of RemoteClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRemoteClient(t interface { mock.TestingT Cleanup(func()) -} - -// NewRemoteClient creates a new instance of RemoteClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewRemoteClient(t mockConstructorTestingTNewRemoteClient) *RemoteClient { +}) *RemoteClient { mock := &RemoteClient{} mock.Mock.Test(t) diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index a0512296c..91c701d0e 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -391,7 +391,7 @@ func TestUnconfirmedTxs(t *testing.T) { assert.Equal(t, 1, res.Count) assert.Equal(t, 1, res.Total) - assert.Equal(t, mempool.TxsBytes(), res.TotalBytes) + assert.Equal(t, mempool.SizeBytes(), res.TotalBytes) assert.Exactly(t, types.Txs{tx}, types.Txs(res.Txs)) } @@ -425,7 +425,7 @@ func TestNumUnconfirmedTxs(t *testing.T) { assert.Equal(t, mempoolSize, res.Count) assert.Equal(t, mempoolSize, res.Total) - assert.Equal(t, mempool.TxsBytes(), res.TotalBytes) + assert.Equal(t, mempool.SizeBytes(), res.TotalBytes) } mempool.Flush() diff --git a/rpc/core/events.go b/rpc/core/events.go index 2a3cdcd07..ce70ef82c 100644 --- a/rpc/core/events.go +++ b/rpc/core/events.go @@ -12,6 +12,12 @@ import ( rpctypes "github.com/Finschia/ostracon/rpc/jsonrpc/types" ) +const ( + // maxQueryLength is the maximum length of a query string that will be + // accepted. This is just a safety check to avoid outlandish queries. + maxQueryLength = 512 +) + // Subscribe for events via WebSocket. // More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, error) { @@ -21,6 +27,8 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er return nil, fmt.Errorf("max_subscription_clients %d reached", env.Config.MaxSubscriptionClients) } else if env.EventBus.NumClientSubscriptions(addr) >= env.Config.MaxSubscriptionsPerClient { return nil, fmt.Errorf("max_subscriptions_per_client %d reached", env.Config.MaxSubscriptionsPerClient) + } else if len(query) > maxQueryLength { + return nil, errors.New("maximum query length exceeded") } env.Logger.Info("Subscribe to query", "remote", addr, "query", query) diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 0555389f8..10ae27f24 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -38,19 +38,31 @@ func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadca // DeliverTx result. // More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - res, err := env.Mempool.CheckTxSync(tx, mempl.TxInfo{}) + resCh := make(chan *ocabci.Response, 1) + err := env.Mempool.CheckTxSync(tx, func(res *ocabci.Response) { + select { + case <-ctx.Context().Done(): + case resCh <- res: + } + + }, mempl.TxInfo{}) if err != nil { return nil, err } - r := res.GetCheckTx() - return &ctypes.ResultBroadcastTx{ - Code: r.Code, - Data: r.Data, - Log: r.Log, - Codespace: r.Codespace, - MempoolError: r.MempoolError, - Hash: tx.Hash(), - }, nil + + select { + case <-ctx.Context().Done(): + return nil, fmt.Errorf("broadcast confirmation not received: %w", ctx.Context().Err()) + case res := <-resCh: + r := res.GetCheckTx() + return &ctypes.ResultBroadcastTx{ + Code: r.Code, + Data: r.Data, + Log: r.Log, + Codespace: r.Codespace, + Hash: tx.Hash(), + }, nil + } } // BroadcastTxCommit returns with the responses from CheckTx and DeliverTx. @@ -80,53 +92,64 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc } }() - // Broadcast tx and check tx - checkTxResMsg, err := env.Mempool.CheckTxSync(tx, mempl.TxInfo{}) + // Broadcast tx and wait for CheckTx result + checkTxResCh := make(chan *ocabci.Response, 1) + err = env.Mempool.CheckTxSync(tx, func(res *ocabci.Response) { + select { + case <-ctx.Context().Done(): + case checkTxResCh <- res: + } + }, mempl.TxInfo{}) if err != nil { env.Logger.Error("Error on broadcastTxCommit", "err", err) return nil, fmt.Errorf("error on broadcastTxCommit: %v", err) } - checkTxRes := checkTxResMsg.GetCheckTx() - if checkTxRes.Code != ocabci.CodeTypeOK { - return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), - }, nil - } - - // Wait for the tx to be included in a block or timeout. select { - case msg := <-deliverTxSub.Out(): // The tx was included in a block. - deliverTxRes := msg.Data().(types.EventDataTx) - return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: deliverTxRes.Result, - Hash: tx.Hash(), - Height: deliverTxRes.Height, - }, nil - case <-deliverTxSub.Cancelled(): - var reason string - if deliverTxSub.Err() == nil { - reason = "Ostracon exited" - } else { - reason = deliverTxSub.Err().Error() + case <-ctx.Context().Done(): + return nil, fmt.Errorf("broadcast confirmation not received: %w", ctx.Context().Err()) + case checkTxResMsg := <-checkTxResCh: + checkTxRes := checkTxResMsg.GetCheckTx() + if checkTxRes.Code != abci.CodeTypeOK { + return &ctypes.ResultBroadcastTxCommit{ + CheckTx: *checkTxRes, + DeliverTx: abci.ResponseDeliverTx{}, + Hash: tx.Hash(), + }, nil + } + + // Wait for the tx to be included in a block or timeout. + select { + case msg := <-deliverTxSub.Out(): // The tx was included in a block. + deliverTxRes := msg.Data().(types.EventDataTx) + return &ctypes.ResultBroadcastTxCommit{ + CheckTx: *checkTxRes, + DeliverTx: deliverTxRes.Result, + Hash: tx.Hash(), + Height: deliverTxRes.Height, + }, nil + case <-deliverTxSub.Cancelled(): + var reason string + if deliverTxSub.Err() == nil { + reason = "Tendermint exited" + } else { + reason = deliverTxSub.Err().Error() + } + err = fmt.Errorf("deliverTxSub was cancelled (reason: %s)", reason) + env.Logger.Error("Error on broadcastTxCommit", "err", err) + return &ctypes.ResultBroadcastTxCommit{ + CheckTx: *checkTxRes, + DeliverTx: abci.ResponseDeliverTx{}, + Hash: tx.Hash(), + }, err + case <-time.After(env.Config.TimeoutBroadcastTxCommit): + err = errors.New("timed out waiting for tx to be included in a block") + env.Logger.Error("Error on broadcastTxCommit", "err", err) + return &ctypes.ResultBroadcastTxCommit{ + CheckTx: *checkTxRes, + DeliverTx: abci.ResponseDeliverTx{}, + Hash: tx.Hash(), + }, err } - err = fmt.Errorf("deliverTxSub was cancelled (reason: %s)", reason) - env.Logger.Error("Error on broadcastTxCommit", "err", err) - return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), - }, err - case <-time.After(env.Config.TimeoutBroadcastTxCommit): - err = errors.New("timed out waiting for tx to be included in a block") - env.Logger.Error("Error on broadcastTxCommit", "err", err) - return &ctypes.ResultBroadcastTxCommit{ - CheckTx: *checkTxRes, - DeliverTx: abci.ResponseDeliverTx{}, - Hash: tx.Hash(), - }, err } } @@ -141,7 +164,7 @@ func UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfi return &ctypes.ResultUnconfirmedTxs{ Count: len(txs), Total: env.Mempool.Size(), - TotalBytes: env.Mempool.TxsBytes(), + TotalBytes: env.Mempool.SizeBytes(), Txs: txs}, nil } @@ -151,7 +174,7 @@ func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, err return &ctypes.ResultUnconfirmedTxs{ Count: env.Mempool.Size(), Total: env.Mempool.Size(), - TotalBytes: env.Mempool.TxsBytes()}, nil + TotalBytes: env.Mempool.SizeBytes()}, nil } // CheckTx checks the transaction without executing it. The transaction won't diff --git a/rpc/core/mempool_test.go b/rpc/core/mempool_test.go new file mode 100644 index 000000000..fd7a9bf4e --- /dev/null +++ b/rpc/core/mempool_test.go @@ -0,0 +1,439 @@ +package core + +import ( + "context" + "errors" + "fmt" + ocabcicli "github.com/Finschia/ostracon/abci/client" + ocabci "github.com/Finschia/ostracon/abci/types" + "github.com/Finschia/ostracon/config" + "github.com/Finschia/ostracon/libs/log" + "github.com/Finschia/ostracon/mempool" + memv0 "github.com/Finschia/ostracon/mempool/v0" + "github.com/Finschia/ostracon/proxy/mocks" + ctypes "github.com/Finschia/ostracon/rpc/core/types" + rpctypes "github.com/Finschia/ostracon/rpc/jsonrpc/types" + "github.com/Finschia/ostracon/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + abci "github.com/tendermint/tendermint/abci/types" + "net/http" + "sync" + "testing" + "time" +) + +type ErrorAssertionFunc func(t assert.TestingT, theError error, contains string, msgAndArgs ...interface{}) bool + +func TestBroadcastTxAsync(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + tx := types.Tx{} + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTx + wantErr assert.ErrorAssertionFunc + err error + }{ + { + name: "success", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: &ctypes.ResultBroadcastTx{ + Code: abci.CodeTypeOK, + Data: nil, + Log: "", + Codespace: "", + MempoolError: "", + Hash: tx.Hash(), + }, + wantErr: assert.NoError, + err: nil, + }, + { + name: "failure: tx is same the one before", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: nil, + wantErr: assert.Error, + err: mempool.ErrTxInCache, + }, + } + env = &Environment{} + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("CheckTxAsync", mock.Anything, mock.Anything).Return(&ocabcicli.ReqRes{}) + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAppConnMempool.On("Error").Return(tt.err).Once() + got, err := BroadcastTxAsync(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, fmt.Sprintf("BroadcastTxAsync(%v, %v)", tt.args.ctx, tt.args.tx)) { + return + } + assert.Equal(t, tt.err, err) + assert.Equalf(t, tt.want, got, "BroadcastTxAsync(%v, %v)", tt.args.ctx, tt.args.tx) + }) + } +} + +func TestBroadcastTxSync(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + tx := types.Tx{} + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTx + wantErr assert.ErrorAssertionFunc + err error + }{ + { + name: "success", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: &ctypes.ResultBroadcastTx{ + Code: ocabci.CodeTypeOK, + Data: nil, + Log: "", + Codespace: "", + MempoolError: "", + Hash: tx.Hash(), + }, + wantErr: assert.NoError, + err: nil, + }, + { + name: "failure: tx is same the one before", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: nil, + wantErr: assert.Error, + err: mempool.ErrTxInMap, + }, + } + env = &Environment{} + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("CheckTxSync", mock.Anything).Return(&ocabci.ResponseCheckTx{}, nil) + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAppConnMempool.On("Error").Return(tt.err).Once() + got, err := BroadcastTxSync(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, fmt.Sprintf("BroadcastTxSync(%v, %v)", tt.args.ctx, tt.args.tx)) { + return + } + assert.Equal(t, tt.err, err) + assert.Equalf(t, tt.want, got, "BroadcastTxSync(%v, %v)", tt.args.ctx, tt.args.tx) + }) + } +} + +// TestBroadcastTxSyncWithCancelContextForCheckTxSync test in isolation from TestBroadcastTxSync since avoiding coexistence +func TestBroadcastTxSyncWithCancelContextForCheckTxSync(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + errContext, cancel := context.WithCancel(context.Background()) + defer cancel() // for safety to avoid memory leaks + req := &http.Request{} + req = req.WithContext(errContext) + errRpcContext := rpctypes.Context{HTTPReq: req} + tx := types.Tx{} + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTx + wantErr ErrorAssertionFunc + err error + }{ + { + name: "failure(non-deterministic test, retry please): interrupted by context", + args: args{ + ctx: &errRpcContext, + tx: tx, + }, + want: nil, + wantErr: assert.ErrorContains, + err: fmt.Errorf("broadcast confirmation not received: context canceled"), + }, + } + env = &Environment{} + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("CheckTxSync", mock.Anything).Return( + &ocabci.ResponseCheckTx{Code: abci.CodeTypeOK}, nil).WaitUntil( + time.After(1000 * time.Millisecond)) // Wait calling the context cancel + mockAppConnMempool.On("Error").Return(nil) // Not to use tt.err + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // cancel context for while doing `env.Mempool.CheckTxSync` + cancel() + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + got, err := BroadcastTxSync(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, tt.err.Error(), fmt.Sprintf("BroadcastTxSync(%v, %v)", tt.args.ctx, tt.args.tx)) { + wg.Done() + return + } + assert.Equalf(t, tt.want, got, "BroadcastTxSync(%v, %v)", tt.args.ctx, tt.args.tx) + wg.Done() + }() + wg.Wait() + }) + } +} + +func TestBroadcastTxCommit(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + height := int64(1) + tx := types.Tx{} + tx1 := types.Tx{1} + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTxCommit + wantErr assert.ErrorAssertionFunc + }{ + { + name: "success", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: &ctypes.ResultBroadcastTxCommit{ + CheckTx: ocabci.ResponseCheckTx{ + Code: abci.CodeTypeOK, + }, + DeliverTx: abci.ResponseDeliverTx{ + Code: abci.CodeTypeOK, + Data: tx, + }, + Hash: tx.Hash(), + Height: height, + }, + wantErr: assert.NoError, + }, + { + name: "success but CheckTxResponse is not OK", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx1, + }, + want: &ctypes.ResultBroadcastTxCommit{ + CheckTx: ocabci.ResponseCheckTx{ + Code: abci.CodeTypeOK + 1, // Not OK + }, + DeliverTx: abci.ResponseDeliverTx{}, // return empty response + Hash: tx1.Hash(), + Height: 0, // return empty height + }, + wantErr: assert.NoError, + }, + } + env = &Environment{} + env.Logger = log.TestingLogger() + env.Config = *config.TestConfig().RPC + env.EventBus = types.NewEventBus() + err := env.EventBus.OnStart() + defer env.EventBus.OnStop() + assert.NoError(t, err) + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("Error").Return(nil) + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAppConnMempool.On("CheckTxSync", mock.Anything).Return(&tt.want.CheckTx, nil).Once() + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + got, err := BroadcastTxCommit(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, fmt.Sprintf("BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx)) { + wg.Done() + return + } + assert.Equalf(t, tt.want, got, "BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx) + wg.Done() + }() + // Wait the time for `env.EventBus.Subscribe` in BroadcastTxCommit + time.Sleep(10 * time.Millisecond) + err := env.EventBus.PublishEventTx(types.EventDataTx{ + TxResult: abci.TxResult{ + Height: height, + Index: 0, + Tx: tt.args.tx, + Result: tt.want.DeliverTx, + }, + }) + assert.NoError(t, err) + wg.Wait() + }) + } +} + +func TestBroadcastTxCommitWithCancelContextForCheckTxSync(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + errContext, cancel := context.WithCancel(context.Background()) + defer cancel() // for safety to avoid memory leaks + req := &http.Request{} + req = req.WithContext(errContext) + errRpcContext := rpctypes.Context{HTTPReq: req} + height := int64(1) + tx := types.Tx{} + resCheckTx := ocabci.ResponseCheckTx{ + Code: abci.CodeTypeOK, + } + resDeliverTx := abci.ResponseDeliverTx{ + Code: abci.CodeTypeOK, + Data: tx, + } + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTxCommit + wantErr ErrorAssertionFunc + err error + }{ + { + name: "failure(non-deterministic test, retry please): interrupted by context", + args: args{ + ctx: &errRpcContext, + tx: tx, + }, + want: nil, + wantErr: assert.ErrorContains, + err: fmt.Errorf("broadcast confirmation not received: context canceled"), + }, + } + env = &Environment{} + env.Logger = log.TestingLogger() + env.Config = *config.TestConfig().RPC + env.EventBus = types.NewEventBus() + err := env.EventBus.OnStart() + defer env.EventBus.OnStop() + assert.NoError(t, err) + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("Error").Return(nil) + mockAppConnMempool.On("CheckTxSync", mock.Anything).Return(&resCheckTx, nil).WaitUntil( + time.After(1 * time.Second)) // Wait calling the context cancel + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + wg := &sync.WaitGroup{} + wg.Add(2) + go func() { + // Wait the time for `env.EventBus.Subscribe` in BroadcastTxCommit + time.Sleep(10 * time.Millisecond) + err := env.EventBus.PublishEventTx(types.EventDataTx{ + TxResult: abci.TxResult{ + Height: height, + Index: 0, + Tx: tx, + Result: resDeliverTx, + }, + }) + assert.NoError(t, err) + // cancel context for while doing `env.Mempool.CheckTxSync` + cancel() + wg.Done() + }() + go func() { + got, err := BroadcastTxCommit(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, tt.err.Error(), fmt.Sprintf("BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx)) { + wg.Done() + return + } + assert.Equalf(t, tt.want, got, "BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx) + wg.Done() + }() + wg.Wait() + }) + } +} + +func TestBroadcastTxCommitTimeout(t *testing.T) { + type args struct { + ctx *rpctypes.Context + tx types.Tx + } + tx := types.Tx{} + tests := []struct { + name string + args args + want *ctypes.ResultBroadcastTxCommit + wantErr ErrorAssertionFunc + err error + }{ + { + name: "failure: timeout", + args: args{ + ctx: &rpctypes.Context{}, + tx: tx, + }, + want: &ctypes.ResultBroadcastTxCommit{ + CheckTx: ocabci.ResponseCheckTx{ + Code: abci.CodeTypeOK, + }, + DeliverTx: abci.ResponseDeliverTx{}, // return empty response + Hash: tx.Hash(), + Height: 0, // return empty height + }, + wantErr: assert.ErrorContains, + err: errors.New("timed out waiting for tx to be included in a block"), + }, + } + env = &Environment{} + env.Logger = log.TestingLogger() + env.Config = *config.TestConfig().RPC + env.Config.TimeoutBroadcastTxCommit = 1 // For test + env.EventBus = types.NewEventBus() + err := env.EventBus.OnStart() + defer env.EventBus.OnStop() + assert.NoError(t, err) + mockAppConnMempool := &mocks.AppConnMempool{} + mockAppConnMempool.On("SetGlobalCallback", mock.Anything) + mockAppConnMempool.On("Error").Return(nil) + env.Mempool = memv0.NewCListMempool(config.TestConfig().Mempool, mockAppConnMempool, 0) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAppConnMempool.On("CheckTxSync", mock.Anything).Return(&tt.want.CheckTx, nil).Once() + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + got, err := BroadcastTxCommit(tt.args.ctx, tt.args.tx) + if !tt.wantErr(t, err, tt.err.Error(), fmt.Sprintf("BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx)) { + wg.Done() + return + } + assert.Equalf(t, tt.want, got, "BroadcastTxCommit(%v, %v)", tt.args.ctx, tt.args.tx) + wg.Done() + }() + wg.Wait() + }) + } +} diff --git a/rpc/core/tx.go b/rpc/core/tx.go index a80f24e5e..c30c2bb0a 100644 --- a/rpc/core/tx.go +++ b/rpc/core/tx.go @@ -65,6 +65,8 @@ func TxSearch( // if index is disabled, return error if _, ok := env.TxIndexer.(*null.TxIndex); ok { return nil, errors.New("transaction indexing is disabled") + } else if len(query) > maxQueryLength { + return nil, errors.New("maximum query length exceeded") } q, err := tmquery.New(query) diff --git a/rpc/jsonrpc/client/ws_client.go b/rpc/jsonrpc/client/ws_client.go index 03a3c40b6..11e44f065 100644 --- a/rpc/jsonrpc/client/ws_client.go +++ b/rpc/jsonrpc/client/ws_client.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/websocket" metrics "github.com/rcrowley/go-metrics" + "github.com/Finschia/ostracon/libs/log" tmrand "github.com/Finschia/ostracon/libs/rand" "github.com/Finschia/ostracon/libs/service" tmsync "github.com/Finschia/ostracon/libs/sync" @@ -511,7 +512,7 @@ func (c *WSClient) readRoutine() { // c.wg.Wait() in c.Stop(). Note we rely on Quit being closed so that it sends unlimited Quit signals to stop // both readRoutine and writeRoutine - c.Logger.Info("got response", "id", response.ID, "result", fmt.Sprintf("%X", response.Result)) + c.Logger.Info("got response", "id", response.ID, "result", log.NewLazySprintf("%X", response.Result)) select { case <-c.Quit(): diff --git a/rpc/jsonrpc/server/http_server.go b/rpc/jsonrpc/server/http_server.go index acbc7c67d..926f56a65 100644 --- a/rpc/jsonrpc/server/http_server.go +++ b/rpc/jsonrpc/server/http_server.go @@ -54,7 +54,7 @@ func DefaultConfig() *Config { // // NOTE: This function blocks - you may want to call it in a go-routine. func Serve(listener net.Listener, handler http.Handler, logger log.Logger, config *Config) error { - logger.Info(fmt.Sprintf("Starting RPC HTTP server on %s", listener.Addr())) + logger.Info("serve", "msg", log.NewLazySprintf("Starting RPC HTTP server on %s", listener.Addr())) s := &http.Server{ Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger), ReadTimeout: config.ReadTimeout, @@ -79,7 +79,7 @@ func ServeTLS( logger log.Logger, config *Config, ) error { - logger.Info(fmt.Sprintf("Starting RPC HTTPS server on %s (cert: %q, key: %q)", + logger.Info("serve tls", "msg", log.NewLazySprintf("Starting RPC HTTPS server on %s (cert: %q, key: %q)", listener.Addr(), certFile, keyFile)) s := &http.Server{ Handler: RecoverAndLogHandler(maxBytesHandler{h: handler, n: config.MaxBodyBytes}, logger), diff --git a/scripts/proto-gen.sh b/scripts/proto-gen.sh new file mode 100755 index 000000000..06fa07dd9 --- /dev/null +++ b/scripts/proto-gen.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Update the generated code for protocol buffers in the Tendermint repository. +# This must be run from inside a Tendermint working directory. +# +set -euo pipefail + +# Work from the root of the repository. +cd "$(git rev-parse --show-toplevel)" + +# Run inside Docker to install the correct versions of the required tools +# without polluting the local system. +docker run --rm -i -v "$PWD":/w --workdir=/w golang:1.18-alpine sh <<"EOF" +apk add git make + +go install github.com/bufbuild/buf/cmd/buf +go install github.com/gogo/protobuf/protoc-gen-gogofaster@latest +make proto-gen +EOF diff --git a/scripts/protocgen.sh b/scripts/protocgen.sh deleted file mode 100755 index 50e0c8f8c..000000000 --- a/scripts/protocgen.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -set -eo pipefail - -proto_dirs=$(find ./proto -path -prune -o -name '*.proto' -print0 | xargs -0 -n1 dirname | sort | uniq) -for dir in $proto_dirs; do - buf protoc \ - -I "proto" \ - -I "third_party/proto" \ - --gogofaster_out=\ -Mgoogle/protobuf/timestamp.proto=github.com/gogo/protobuf/types,\ -Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,\ -plugins=grpc,paths=source_relative:. \ - $(find "${dir}" -maxdepth 1 -name '*.proto') -done - -cp -r ./ostracon/* ./proto/* -rm -rf ostracon - -mv ./proto/ostracon/abci/types.pb.go ./abci/types - -mv ./proto/ostracon/rpc/grpc/types.pb.go ./rpc/grpc diff --git a/state/mocks/block_store.go b/state/mocks/block_store.go index 8c05d338f..892d26818 100644 --- a/state/mocks/block_store.go +++ b/state/mocks/block_store.go @@ -196,13 +196,12 @@ func (_m *BlockStore) Size() int64 { return r0 } -type mockConstructorTestingTNewBlockStore interface { +// NewBlockStore creates a new instance of BlockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewBlockStore(t interface { mock.TestingT Cleanup(func()) -} - -// NewBlockStore creates a new instance of BlockStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewBlockStore(t mockConstructorTestingTNewBlockStore) *BlockStore { +}) *BlockStore { mock := &BlockStore{} mock.Mock.Test(t) diff --git a/state/mocks/evidence_pool.go b/state/mocks/evidence_pool.go index 423dfcfbd..5c562c45c 100644 --- a/state/mocks/evidence_pool.go +++ b/state/mocks/evidence_pool.go @@ -73,13 +73,12 @@ func (_m *EvidencePool) Update(_a0 state.State, _a1 types.EvidenceList) { _m.Called(_a0, _a1) } -type mockConstructorTestingTNewEvidencePool interface { +// NewEvidencePool creates a new instance of EvidencePool. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewEvidencePool(t interface { mock.TestingT Cleanup(func()) -} - -// NewEvidencePool creates a new instance of EvidencePool. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewEvidencePool(t mockConstructorTestingTNewEvidencePool) *EvidencePool { +}) *EvidencePool { mock := &EvidencePool{} mock.Mock.Test(t) diff --git a/state/mocks/store.go b/state/mocks/store.go index 584988898..3f29ed535 100644 --- a/state/mocks/store.go +++ b/state/mocks/store.go @@ -261,13 +261,12 @@ func (_m *Store) SaveABCIResponses(_a0 int64, _a1 *ostraconstate.ABCIResponses) return r0 } -type mockConstructorTestingTNewStore interface { +// NewStore creates a new instance of Store. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewStore(t interface { mock.TestingT Cleanup(func()) -} - -// NewStore creates a new instance of Store. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewStore(t mockConstructorTestingTNewStore) *Store { +}) *Store { mock := &Store{} mock.Mock.Test(t) diff --git a/state/txindex/mocks/tx_indexer.go b/state/txindex/mocks/tx_indexer.go index 0217b5c37..8ec713101 100644 --- a/state/txindex/mocks/tx_indexer.go +++ b/state/txindex/mocks/tx_indexer.go @@ -98,13 +98,12 @@ func (_m *TxIndexer) Search(ctx context.Context, q *query.Query) ([]*types.TxRes return r0, r1 } -type mockConstructorTestingTNewTxIndexer interface { +// NewTxIndexer creates a new instance of TxIndexer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewTxIndexer(t interface { mock.TestingT Cleanup(func()) -} - -// NewTxIndexer creates a new instance of TxIndexer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewTxIndexer(t mockConstructorTestingTNewTxIndexer) *TxIndexer { +}) *TxIndexer { mock := &TxIndexer{} mock.Mock.Test(t) diff --git a/statesync/mocks/state_provider.go b/statesync/mocks/state_provider.go index 7a3aedd80..ad29a5e5f 100644 --- a/statesync/mocks/state_provider.go +++ b/statesync/mocks/state_provider.go @@ -92,13 +92,12 @@ func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State, return r0, r1 } -type mockConstructorTestingTNewStateProvider interface { +// NewStateProvider creates a new instance of StateProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewStateProvider(t interface { mock.TestingT Cleanup(func()) -} - -// NewStateProvider creates a new instance of StateProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewStateProvider(t mockConstructorTestingTNewStateProvider) *StateProvider { +}) *StateProvider { mock := &StateProvider{} mock.Mock.Test(t) diff --git a/statesync/syncer.go b/statesync/syncer.go index d87e32be2..36e298e59 100644 --- a/statesync/syncer.go +++ b/statesync/syncer.go @@ -145,7 +145,7 @@ func (s *syncer) SyncAny(discoveryTime time.Duration, retryHook func()) (sm.Stat } if discoveryTime > 0 { - s.logger.Info(fmt.Sprintf("Discovering snapshots for %v", discoveryTime)) + s.logger.Info("sync any", "msg", log.NewLazySprintf("Discovering snapshots for %v", discoveryTime)) time.Sleep(discoveryTime) } @@ -167,7 +167,7 @@ func (s *syncer) SyncAny(discoveryTime time.Duration, retryHook func()) (sm.Stat return sm.State{}, sm.State{}, nil, errNoSnapshots } retryHook() - s.logger.Info(fmt.Sprintf("Discovering snapshots for %v", discoveryTime)) + s.logger.Info("sync any", "msg", log.NewLazySprintf("Discovering snapshots for %v", discoveryTime)) time.Sleep(discoveryTime) continue } diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index 6baa3287f..bcdc8a5ee 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -34,6 +34,7 @@ var ( // FIXME: v2 disabled due to flake nodeFastSyncs = uniformChoice{"v0"} // "v2" nodeStateSyncs = uniformChoice{false, true} + nodeMempools = uniformChoice{"v0", "v1"} nodePersistIntervals = uniformChoice{0, 1, 5} nodeSnapshotIntervals = uniformChoice{0, 3} nodeRetainBlocks = uniformChoice{ @@ -225,6 +226,7 @@ func generateNode( Database: nodeDatabases.Choose(r).(string), PrivvalProtocol: nodePrivvalProtocols.Choose(r).(string), FastSync: nodeFastSyncs.Choose(r).(string), + Mempool: nodeMempools.Choose(r).(string), StateSync: nodeStateSyncs.Choose(r).(bool) && startAt > 0, PersistInterval: ptrUint64(uint64(nodePersistIntervals.Choose(r).(int))), SnapshotInterval: uint64(nodeSnapshotIntervals.Choose(r).(int)), diff --git a/test/e2e/networks/ci.toml b/test/e2e/networks/ci.toml index 0301b7893..5ad599fc8 100644 --- a/test/e2e/networks/ci.toml +++ b/test/e2e/networks/ci.toml @@ -64,7 +64,7 @@ start_at = 1005 # Becomes part of the validator set at 1010 persistent_peers = ["validator01", "full01"] database = "cleveldb" fast_sync = "v0" -mempool_version = "v1" +mempool_version = "v0" # Deprecated mempool-v1 privval_protocol = "tcp" perturb = ["kill", "pause", "disconnect", "restart"] diff --git a/test/e2e/pkg/manifest.go b/test/e2e/pkg/manifest.go index 6dfb7642b..0dab0d708 100644 --- a/test/e2e/pkg/manifest.go +++ b/test/e2e/pkg/manifest.go @@ -111,6 +111,10 @@ type ManifestNode struct { // Defaults to disabled. FastSync string `toml:"fast_sync"` + // Mempool specifies which version of mempool to use. Either "v0" or "v1" + // This defaults to v0. + Mempool string `toml:"mempool_version"` + // StateSync enables state sync. The runner automatically configures trusted // block hashes and RPC servers. At least one node in the network must have // SnapshotInterval set to non-zero, and the state syncing node must have diff --git a/test/e2e/pkg/testnet.go b/test/e2e/pkg/testnet.go index 22dac9de2..d0a7104f9 100644 --- a/test/e2e/pkg/testnet.go +++ b/test/e2e/pkg/testnet.go @@ -88,6 +88,7 @@ type Node struct { StartAt int64 FastSync string StateSync bool + Mempool string Database string ABCIProtocol Protocol PrivvalProtocol Protocol @@ -184,6 +185,7 @@ func LoadTestnet(manifest Manifest, fname string, ifd InfrastructureData) (*Test PrivvalProtocol: ProtocolFile, StartAt: nodeManifest.StartAt, FastSync: nodeManifest.FastSync, + Mempool: nodeManifest.Mempool, StateSync: nodeManifest.StateSync, PersistInterval: 1, SnapshotInterval: nodeManifest.SnapshotInterval, @@ -329,6 +331,12 @@ func (n Node) Validate(testnet Testnet) error { case "", "v0", "v1", "v2": default: return fmt.Errorf("invalid fast sync setting %q", n.FastSync) + + } + switch n.Mempool { + case "", "v0", "v1": + default: + return fmt.Errorf("invalid mempool version %q", n.Mempool) } switch n.Database { case "goleveldb", "cleveldb", "boltdb", "rocksdb", "badgerdb": diff --git a/test/e2e/runner/load.go b/test/e2e/runner/load.go index fff08c924..acd2a8673 100644 --- a/test/e2e/runner/load.go +++ b/test/e2e/runner/load.go @@ -36,7 +36,7 @@ func Load(ctx context.Context, testnet *e2e.Testnet, multiplier int) error { defer cancel() // Spawn job generator and processors. - logger.Info(fmt.Sprintf("Starting transaction load (%v workers)...", concurrency)) + logger.Info("load", "msg", log.NewLazySprintf("Starting transaction load (%v workers)...", concurrency)) started := time.Now() go loadGenerate(ctx, chTx, multiplier) diff --git a/test/e2e/runner/setup.go b/test/e2e/runner/setup.go index d44a9e00f..d50012283 100644 --- a/test/e2e/runner/setup.go +++ b/test/e2e/runner/setup.go @@ -209,6 +209,9 @@ func MakeConfig(node *e2e.Node) (*config.Config, error) { default: return nil, fmt.Errorf("unexpected mode %q", node.Mode) } + if node.Mempool != "" { + cfg.Mempool.Version = node.Mempool + } if node.FastSync == "" { cfg.FastSyncMode = false diff --git a/test/fuzz/mempool/checktx.go b/test/fuzz/mempool/v0/checktx.go similarity index 75% rename from test/fuzz/mempool/checktx.go rename to test/fuzz/mempool/v0/checktx.go index 31c139ee7..eb871b87d 100644 --- a/test/fuzz/mempool/checktx.go +++ b/test/fuzz/mempool/v0/checktx.go @@ -1,9 +1,10 @@ -package checktx +package v0 import ( "github.com/Finschia/ostracon/abci/example/kvstore" "github.com/Finschia/ostracon/config" mempl "github.com/Finschia/ostracon/mempool" + mempoolv0 "github.com/Finschia/ostracon/mempool/v0" "github.com/Finschia/ostracon/proxy" ) @@ -20,12 +21,11 @@ func init() { cfg := config.DefaultMempoolConfig() cfg.Broadcast = false - - mempool = mempl.NewCListMempool(cfg, appConnMem, 0) + mempool = mempoolv0.NewCListMempool(cfg, appConnMem, 0) } func Fuzz(data []byte) int { - _, err := mempool.CheckTxSync(data, mempl.TxInfo{}) + err := mempool.CheckTxSync(data, nil, mempl.TxInfo{}) if err != nil { return 0 } diff --git a/test/fuzz/mempool/v0/fuzz_test.go b/test/fuzz/mempool/v0/fuzz_test.go new file mode 100644 index 000000000..9a32bbf04 --- /dev/null +++ b/test/fuzz/mempool/v0/fuzz_test.go @@ -0,0 +1,34 @@ +package v0_test + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + mempoolv0 "github.com/Finschia/ostracon/test/fuzz/mempool/v0" +) + +const testdataCasesDir = "testdata/cases" + +func TestMempoolTestdataCases(t *testing.T) { + entries, err := os.ReadDir(testdataCasesDir) + require.NoError(t, err) + + for _, e := range entries { + entry := e + t.Run(entry.Name(), func(t *testing.T) { + defer func() { + r := recover() + require.Nilf(t, r, "testdata/cases test panic") + }() + f, err := os.Open(filepath.Join(testdataCasesDir, entry.Name())) + require.NoError(t, err) + input, err := ioutil.ReadAll(f) + require.NoError(t, err) + mempoolv0.Fuzz(input) + }) + } +} diff --git a/test/fuzz/mempool/v0/testdata/cases/empty b/test/fuzz/mempool/v0/testdata/cases/empty new file mode 100644 index 000000000..e69de29bb diff --git a/test/fuzz/mempool/v1/checktx.go b/test/fuzz/mempool/v1/checktx.go new file mode 100644 index 000000000..0e4a66fca --- /dev/null +++ b/test/fuzz/mempool/v1/checktx.go @@ -0,0 +1,39 @@ +//go:build deprecated + +package v1 + +import ( + "github.com/tendermint/tendermint/abci/example/kvstore" + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/log" + mempl "github.com/tendermint/tendermint/mempool" + "github.com/tendermint/tendermint/proxy" + + mempoolv1 "github.com/tendermint/tendermint/mempool/v1" +) + +var mempool mempl.Mempool + +func init() { + app := kvstore.NewApplication() + cc := proxy.NewLocalClientCreator(app) + appConnMem, _ := cc.NewABCIClient() + err := appConnMem.Start() + if err != nil { + panic(err) + } + cfg := config.DefaultMempoolConfig() + cfg.Broadcast = false + log := log.NewNopLogger() + mempool = mempoolv1.NewTxMempool(log, cfg, appConnMem, 0) +} + +func Fuzz(data []byte) int { + + err := mempool.CheckTx(data, nil, mempl.TxInfo{}) + if err != nil { + return 0 + } + + return 1 +} diff --git a/test/fuzz/mempool/v1/fuzz_test.go b/test/fuzz/mempool/v1/fuzz_test.go new file mode 100644 index 000000000..6371f09a9 --- /dev/null +++ b/test/fuzz/mempool/v1/fuzz_test.go @@ -0,0 +1,35 @@ +//go:build deprecated + +package v1_test + +import ( + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + mempoolv1 "github.com/tendermint/tendermint/test/fuzz/mempool/v1" +) + +const testdataCasesDir = "testdata/cases" + +func TestMempoolTestdataCases(t *testing.T) { + entries, err := os.ReadDir(testdataCasesDir) + require.NoError(t, err) + + for _, e := range entries { + entry := e + t.Run(entry.Name(), func(t *testing.T) { + defer func() { + r := recover() + require.Nilf(t, r, "testdata/cases test panic") + }() + f, err := os.Open(filepath.Join(testdataCasesDir, entry.Name())) + require.NoError(t, err) + input, err := ioutil.ReadAll(f) + require.NoError(t, err) + mempoolv1.Fuzz(input) + }) + } +} diff --git a/test/fuzz/mempool/v1/testdata/cases/empty b/test/fuzz/mempool/v1/testdata/cases/empty new file mode 100644 index 000000000..e69de29bb diff --git a/third_party/proto/README.md b/third_party/proto/README.md new file mode 100644 index 000000000..ae2419cdb --- /dev/null +++ b/third_party/proto/README.md @@ -0,0 +1,16 @@ +# Using buf build +https://buf.build/ + +```script +go run github.com/bufbuild/buf/cmd/buf help +``` + +## if you update `buf.yaml`, should also update `buf.lock` +```script +cd third_party/proto && go run github.com/bufbuild/buf/cmd/buf mod update && cd ../.. +``` + +## NOTE +If tendermint use `BSR: Buf Schema Registry`, can remove `tendermint` +Currently, coping `tendermint-v0.34.19` proto files +See: `go.mod` diff --git a/third_party/proto/buf.lock b/third_party/proto/buf.lock new file mode 100644 index 000000000..768ad21ce --- /dev/null +++ b/third_party/proto/buf.lock @@ -0,0 +1,8 @@ +# Generated by buf. DO NOT EDIT. +version: v1 +deps: + - remote: buf.build + owner: gogo + repository: protobuf + commit: 5461a3dfa9d941da82028ab185dc2a0e + digest: shake256:37c7c75224982038cb1abf45b481ef06716c1f806ffaa162018d0df092bd11a2a9b62c2d0dc0a2ae43beff86b6014fc0eb8c594ffd84d52ade4b08fca901eadc diff --git a/third_party/proto/buf.yaml b/third_party/proto/buf.yaml new file mode 100644 index 000000000..816db10f7 --- /dev/null +++ b/third_party/proto/buf.yaml @@ -0,0 +1,11 @@ +version: v1 +deps: + - buf.build/gogo/protobuf +breaking: + use: + - FILE +lint: + use: + - BASIC + - FILE_LOWER_SNAKE_CASE + - UNARY_RPC diff --git a/third_party/proto/gogoproto/gogo.proto b/third_party/proto/gogoproto/gogo.proto deleted file mode 100644 index 27960ecfb..000000000 --- a/third_party/proto/gogoproto/gogo.proto +++ /dev/null @@ -1,147 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copied from https://github.com/gogo/protobuf/blob/master/gogoproto/gogo.proto -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto2"; -package gogoproto; - -import "google/protobuf/descriptor.proto"; - -option java_package = "com.google.protobuf"; -option java_outer_classname = "GoGoProtos"; -option go_package = "github.com/gogo/protobuf/gogoproto"; - -extend google.protobuf.EnumOptions { - optional bool goproto_enum_prefix = 62001; - optional bool goproto_enum_stringer = 62021; - optional bool enum_stringer = 62022; - optional string enum_customname = 62023; - optional bool enumdecl = 62024; -} - -extend google.protobuf.EnumValueOptions { - optional string enumvalue_customname = 66001; -} - -extend google.protobuf.FileOptions { - optional bool goproto_getters_all = 63001; - optional bool goproto_enum_prefix_all = 63002; - optional bool goproto_stringer_all = 63003; - optional bool verbose_equal_all = 63004; - optional bool face_all = 63005; - optional bool gostring_all = 63006; - optional bool populate_all = 63007; - optional bool stringer_all = 63008; - optional bool onlyone_all = 63009; - - optional bool equal_all = 63013; - optional bool description_all = 63014; - optional bool testgen_all = 63015; - optional bool benchgen_all = 63016; - optional bool marshaler_all = 63017; - optional bool unmarshaler_all = 63018; - optional bool stable_marshaler_all = 63019; - - optional bool sizer_all = 63020; - - optional bool goproto_enum_stringer_all = 63021; - optional bool enum_stringer_all = 63022; - - optional bool unsafe_marshaler_all = 63023; - optional bool unsafe_unmarshaler_all = 63024; - - optional bool goproto_extensions_map_all = 63025; - optional bool goproto_unrecognized_all = 63026; - optional bool gogoproto_import = 63027; - optional bool protosizer_all = 63028; - optional bool compare_all = 63029; - optional bool typedecl_all = 63030; - optional bool enumdecl_all = 63031; - - optional bool goproto_registration = 63032; - optional bool messagename_all = 63033; - - optional bool goproto_sizecache_all = 63034; - optional bool goproto_unkeyed_all = 63035; -} - -extend google.protobuf.MessageOptions { - optional bool goproto_getters = 64001; - optional bool goproto_stringer = 64003; - optional bool verbose_equal = 64004; - optional bool face = 64005; - optional bool gostring = 64006; - optional bool populate = 64007; - optional bool stringer = 67008; - optional bool onlyone = 64009; - - optional bool equal = 64013; - optional bool description = 64014; - optional bool testgen = 64015; - optional bool benchgen = 64016; - optional bool marshaler = 64017; - optional bool unmarshaler = 64018; - optional bool stable_marshaler = 64019; - - optional bool sizer = 64020; - - optional bool unsafe_marshaler = 64023; - optional bool unsafe_unmarshaler = 64024; - - optional bool goproto_extensions_map = 64025; - optional bool goproto_unrecognized = 64026; - - optional bool protosizer = 64028; - optional bool compare = 64029; - - optional bool typedecl = 64030; - - optional bool messagename = 64033; - - optional bool goproto_sizecache = 64034; - optional bool goproto_unkeyed = 64035; -} - -extend google.protobuf.FieldOptions { - optional bool nullable = 65001; - optional bool embed = 65002; - optional string customtype = 65003; - optional string customname = 65004; - optional string jsontag = 65005; - optional string moretags = 65006; - optional string casttype = 65007; - optional string castkey = 65008; - optional string castvalue = 65009; - - optional bool stdtime = 65010; - optional bool stdduration = 65011; - optional bool wktpointer = 65012; - - optional string castrepeated = 65013; -} \ No newline at end of file diff --git a/third_party/proto/tendermint/abci/types.proto b/third_party/proto/tendermint/abci/types.proto index 8e3a90936..23a6ec2e3 100644 --- a/third_party/proto/tendermint/abci/types.proto +++ b/third_party/proto/tendermint/abci/types.proto @@ -75,10 +75,10 @@ message RequestQuery { } message RequestBeginBlock { - bytes hash = 1; - tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; - LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; - repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; + bytes hash = 1; + tendermint.types.Header header = 2 [(gogoproto.nullable) = false]; + LastCommitInfo last_commit_info = 3 [(gogoproto.nullable) = false]; + repeated Evidence byzantine_validators = 4 [(gogoproto.nullable) = false]; } enum CheckTxType { @@ -102,8 +102,7 @@ message RequestEndBlock { message RequestCommit {} // lists available snapshots -message RequestListSnapshots { -} +message RequestListSnapshots {} // offers a snapshot to the application message RequestOfferSnapshot { @@ -212,6 +211,12 @@ message ResponseCheckTx { repeated Event events = 7 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; string codespace = 8; + string sender = 9; + int64 priority = 10; + + // mempool_error is set by Tendermint. + // ABCI applictions creating a ResponseCheckTX should not set mempool_error. + string mempool_error = 11; } message ResponseDeliverTx { @@ -221,16 +226,17 @@ message ResponseDeliverTx { string info = 4; // nondeterministic int64 gas_wanted = 5 [json_name = "gas_wanted"]; int64 gas_used = 6 [json_name = "gas_used"]; - repeated Event events = 7 - [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; // nondeterministic + repeated Event events = 7 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "events,omitempty" + ]; // nondeterministic string codespace = 8; } message ResponseEndBlock { - repeated ValidatorUpdate validator_updates = 1 - [(gogoproto.nullable) = false]; - ConsensusParams consensus_param_updates = 2; - repeated Event events = 3 + repeated ValidatorUpdate validator_updates = 1 [(gogoproto.nullable) = false]; + ConsensusParams consensus_param_updates = 2; + repeated Event events = 3 [(gogoproto.nullable) = false, (gogoproto.jsontag) = "events,omitempty"]; } @@ -364,10 +370,8 @@ message Evidence { // The height when the offense occurred int64 height = 3; // The corresponding time where the offense occurred - google.protobuf.Timestamp time = 4 [ - (gogoproto.nullable) = false, - (gogoproto.stdtime) = true - ]; + google.protobuf.Timestamp time = 4 + [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; // Total voting power of the validator set in case the ABCI application does // not store historical validators. // https://github.com/tendermint/tendermint/issues/4581 @@ -402,6 +406,8 @@ service ABCIApplication { rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); rpc ListSnapshots(RequestListSnapshots) returns (ResponseListSnapshots); rpc OfferSnapshot(RequestOfferSnapshot) returns (ResponseOfferSnapshot); - rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) returns (ResponseLoadSnapshotChunk); - rpc ApplySnapshotChunk(RequestApplySnapshotChunk) returns (ResponseApplySnapshotChunk); + rpc LoadSnapshotChunk(RequestLoadSnapshotChunk) + returns (ResponseLoadSnapshotChunk); + rpc ApplySnapshotChunk(RequestApplySnapshotChunk) + returns (ResponseApplySnapshotChunk); } diff --git a/types/tx.go b/types/tx.go index b6d767b9a..308a999cd 100644 --- a/types/tx.go +++ b/types/tx.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "crypto/sha256" "errors" "fmt" @@ -12,16 +13,28 @@ import ( tmbytes "github.com/Finschia/ostracon/libs/bytes" ) -// Tx is an arbitrary byte array. -// NOTE: Tx has no types at this level, so when wire encoded it's just length-prefixed. -// Might we want types here ? -type Tx []byte +// TxKeySize is the size of the transaction key index +const TxKeySize = sha256.Size + +type ( + // Tx is an arbitrary byte array. + // NOTE: Tx has no types at this level, so when wire encoded it's just length-prefixed. + // Might we want types here ? + Tx []byte + + // TxKey is the fixed length array key used as an index. + TxKey [TxKeySize]byte +) // Hash computes the OCHASH hash of the wire encoded transaction. func (tx Tx) Hash() []byte { return tmhash.Sum(tx) } +func (tx Tx) Key() TxKey { + return sha256.Sum256(tx) +} + // String returns the hex-encoded transaction as a string. func (tx Tx) String() string { return fmt.Sprintf("Tx{%X}", []byte(tx))