diff --git a/.github/auto_request_review.yml b/.github/auto_request_review.yml index fcaed3c592..a00957c0e3 100644 --- a/.github/auto_request_review.yml +++ b/.github/auto_request_review.yml @@ -12,7 +12,3 @@ options: ignored_keywords: - DO NOT REVIEW enable_group_assignment: false - - # Randomly pick reviewers up to this number. - # Do not set this option if you'd like to assign all matching reviewers. - number_of_reviewers: 2 diff --git a/.github/mergify.yml b/.github/mergify.yml index 1e60d88bb2..f32c3fafcf 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -15,3 +15,19 @@ pull_request_rules: backport: branches: - v2.x + - name: forward-port patches to main branch (v1.x) + conditions: + - base=v1.x + - label=forwardport:main + actions: + backport: + branches: + - main + - name: forward-port patches to main branch (v2.x) + conditions: + - base=v2.x + - label=forwardport:main + actions: + backport: + branches: + - main diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index f4bbe29713..5fe828d636 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -6,12 +6,9 @@ on: push: branches: - main - - "v[0-9]+.x" + - "v*" tags: - - "v[0-9]+.[0-9]+.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" + - "v*" pull_request: jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 84f229e2e6..6ef0382d21 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,9 +13,9 @@ name: "CodeQL" on: push: - branches: ["main", "v[0-9].[0-9].x", "v[0-9].[0-9][0-9].x", "v[0-9].x"] + branches: ["main", "v*"] schedule: - - cron: '24 20 * * 4' + - cron: "24 20 * * 4" jobs: analyze: @@ -25,7 +25,7 @@ jobs: # - https://gh.io/supported-runners-and-hardware-resources # - https://gh.io/using-larger-runners # Consider using larger runners for possible analysis time improvements. - runs-on: 'ubuntu-latest' + runs-on: "ubuntu-latest" timeout-minutes: 360 permissions: actions: read @@ -35,7 +35,7 @@ jobs: strategy: fail-fast: false matrix: - language: ['go'] + language: ["go"] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: @@ -56,7 +56,7 @@ jobs: - uses: actions/setup-go@v5 with: - go-version-file: 'go.mod' + go-version-file: "go.mod" - name: Build binary run: | diff --git a/.github/workflows/create_release_tracking_epic.yml b/.github/workflows/create_release_tracking_epic.yml index 2fa90be14a..b14fb0406a 100644 --- a/.github/workflows/create_release_tracking_epic.yml +++ b/.github/workflows/create_release_tracking_epic.yml @@ -7,7 +7,7 @@ on: types: [released] jobs: trigger_issue: - uses: celestiaorg/.github/.github/workflows/reusable_create_release_tracking_epic.yml@v0.4.3 + uses: celestiaorg/.github/.github/workflows/reusable_create_release_tracking_epic.yml@v0.4.5 secrets: inherit with: release-repo: ${{ github.repository }} diff --git a/.github/workflows/docker-build-publish.yml b/.github/workflows/docker-build-publish.yml index f805f343dd..c25e21aa2e 100644 --- a/.github/workflows/docker-build-publish.yml +++ b/.github/workflows/docker-build-publish.yml @@ -5,32 +5,35 @@ on: push: branches: - "main" - - "v[0-9].[0-9].x" - - "v[0-9].[0-9][0-9].x" - - "v[0-9].x" + - "v*" tags: - - "v[0-9]+.[0-9]+.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" + - "v*" pull_request: + workflow_dispatch: + inputs: + ref: + description: "The checkout reference (ie tag, branch, sha)" + required: true + type: string jobs: docker-security-build: permissions: contents: write packages: write - uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.4.3 + uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.4.5 with: - dockerfile: Dockerfile + dockerfile: docker/Dockerfile + checkout_ref: ${{ github.event.inputs.ref }} secrets: inherit docker-txsim-build: permissions: contents: write packages: write - uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.4.3 + uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.4.5 with: - dockerfile: docker/Dockerfile_txsim + dockerfile: docker/txsim/Dockerfile packageName: txsim + checkout_ref: ${{ github.event.inputs.ref }} secrets: inherit diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index f25d738a65..dd265479e9 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -9,12 +9,18 @@ jobs: goreleaser-check: runs-on: ubuntu-latest steps: - - name: checkout - uses: actions/checkout@v4 - - uses: goreleaser/goreleaser-action@v6 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - run: git fetch --force --tags + - uses: actions/setup-go@v5 with: - version: latest - args: check + go-version-file: 'go.mod' + - name: Create .release-env file + run: |- + echo 'GITHUB_TOKEN=${{secrets.GORELEASER_ACCESS_TOKEN}}' >> .release-env + - name: Check the .goreleaser.yaml config file + run: make goreleaser-check goreleaser: needs: goreleaser-check diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 4716adabf1..87d07b6ae3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,20 +20,21 @@ jobs: **/**.go go.mod go.sum - - uses: golangci/golangci-lint-action@v6.1.0 + - uses: golangci/golangci-lint-action@v6.1.1 with: - version: v1.59.1 + version: v1.61.0 args: --timeout 10m github-token: ${{ secrets.github_token }} - skip-pkg-cache: true if: env.GIT_DIFF # hadolint lints the Dockerfile hadolint: - uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_lint.yml@v0.4.3 + uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_lint.yml@v0.4.5 + with: + dockerfile: "docker/Dockerfile" yamllint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: celestiaorg/.github/.github/actions/yamllint@v0.4.3 + - uses: celestiaorg/.github/.github/actions/yamllint@v0.4.5 diff --git a/.github/workflows/pr-review-requester.yml b/.github/workflows/pr-review-requester.yml index a46df08794..8396723699 100644 --- a/.github/workflows/pr-review-requester.yml +++ b/.github/workflows/pr-review-requester.yml @@ -11,7 +11,7 @@ on: jobs: auto-request-review: name: Auto request reviews - uses: celestiaorg/.github/.github/workflows/reusable_housekeeping.yml@v0.4.3 + uses: celestiaorg/.github/.github/workflows/reusable_housekeeping.yml@v0.4.5 secrets: inherit # write access for issues and pull requests is needed because the called # workflow requires write access to issues and pull requests and the diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 21185f78c8..b135a91611 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,7 +41,7 @@ jobs: run: make test-coverage - name: Upload coverage.txt - uses: codecov/codecov-action@v4.5.0 + uses: codecov/codecov-action@v4.6.0 with: file: ./coverage.txt diff --git a/.golangci.yml b/.golangci.yml index d14fe1963a..59be9b021d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -4,7 +4,7 @@ run: linters: enable: - - exportloopref + - copyloopvar - gofumpt - misspell - nakedret diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 950143a3f1..4f08a63b64 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -108,7 +108,7 @@ archives: checksum: name_template: "checksums.txt" snapshot: - name_template: "{{ incpatch .Version }}-next" + version_template: "{{ incpatch .Version }}-next" changelog: sort: asc filters: @@ -118,4 +118,4 @@ changelog: release: prerelease: auto git: - prerelease_suffix: "-rc*" + prerelease_suffix: "-" diff --git a/Makefile b/Makefile index 2eb251bd24..9bd79ac302 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,20 @@ -VERSION := $(shell echo $(shell git describe --tags 2>/dev/null || git log -1 --format='%h') | sed 's/^v//') +# GIT_TAG is an environment variable that is set to the latest git tag on the +# current commit with the following example priority: v2.2.0, v2.2.0-mocha, +# v2.2.0-arabica, v2.2.0-rc0, v2.2.0-beta, v2.2.0-alpha. If no tag points to the +# current commit, git describe is used. The priority in this command is +# necessary because `git tag --sort=-creatordate` only works for annotated tags +# with metadata. Git tags created via GitHub releases are not annotated and do +# not have metadata like creatordate. Therefore, this command is a hacky attempt +# to get the most recent tag on the current commit according to Celestia's +# testnet versioning scheme + SemVer. +GIT_TAG := $(shell git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$$' \ + || git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-mocha$$' \ + || git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-arabica$$' \ + || git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]*$$' \ + || git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-(beta)$$' \ + || git tag --points-at HEAD --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+-(alpha)$$' \ + || git describe --tags) +VERSION := $(shell echo $(GIT_TAG) | sed 's/^v//') COMMIT := $(shell git rev-parse --short HEAD) DOCKER := $(shell which docker) DOCKER_BUF := $(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace bufbuild/buf @@ -7,13 +23,21 @@ DOCKER_PROTO_BUILDER := docker run -v $(shell pwd):/workspace --workdir /workspa PROJECTNAME=$(shell basename "$(PWD)") HTTPS_GIT := https://github.com/celestiaorg/celestia-app.git PACKAGE_NAME := github.com/celestiaorg/celestia-app/v3 -GOLANG_CROSS_VERSION ?= v1.22.6 +# Before upgrading the GOLANG_CROSS_VERSION, please verify that a Docker image exists with the new tag. +# See https://github.com/goreleaser/goreleaser-cross/pkgs/container/goreleaser-cross +GOLANG_CROSS_VERSION ?= v1.23.1 +# Set this to override the max square size of the binary +OVERRIDE_MAX_SQUARE_SIZE ?= +# Set this to override the upgrade height delay of the binary +OVERRIDE_UPGRADE_HEIGHT_DELAY ?= # process linker flags ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=celestia-app \ -X github.com/cosmos/cosmos-sdk/version.AppName=celestia-appd \ -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ + -X github.com/celestiaorg/celestia-app/v3/pkg/appconsts.OverrideSquareSizeUpperBoundStr=$(OVERRIDE_MAX_SQUARE_SIZE) \ + -X github.com/celestiaorg/celestia-app/v3/pkg/appconsts.OverrideUpgradeHeightDelayStr=$(OVERRIDE_UPGRADE_HEIGHT_DELAY) BUILD_FLAGS := -tags "ledger" -ldflags '$(ldflags)' @@ -31,7 +55,7 @@ build: mod .PHONY: build ## install: Build and install the celestia-appd binary into the $GOPATH/bin directory. -install: go.sum +install: check-bbr @echo "--> Installing celestia-appd" @go install $(BUILD_FLAGS) ./cmd/celestia-appd .PHONY: install @@ -77,13 +101,13 @@ proto-format: ## build-docker: Build the celestia-appd docker image from the current branch. Requires docker. build-docker: @echo "--> Building Docker image" - $(DOCKER) build -t celestiaorg/celestia-app -f Dockerfile . + $(DOCKER) build -t celestiaorg/celestia-app -f docker/Dockerfile . .PHONY: build-docker ## build-ghcr-docker: Build the celestia-appd docker image from the last commit. Requires docker. build-ghcr-docker: @echo "--> Building Docker image" - $(DOCKER) build -t ghcr.io/celestiaorg/celestia-app:$(COMMIT) -f Dockerfile . + $(DOCKER) build -t ghcr.io/celestiaorg/celestia-app:$(COMMIT) -f docker/Dockerfile . .PHONY: build-ghcr-docker ## publish-ghcr-docker: Publish the celestia-appd docker image. Requires docker. @@ -100,7 +124,8 @@ lint: @echo "--> Running markdownlint" @markdownlint --config .markdownlint.yaml '**/*.md' @echo "--> Running hadolint" - @hadolint Dockerfile + @hadolint docker/Dockerfile + @hadolint docker/txsim/Dockerfile @echo "--> Running yamllint" @yamllint --no-warnings . -c .yamllint.yml .PHONY: lint @@ -143,7 +168,7 @@ test-race: # TODO: Remove the -skip flag once the following tests no longer contain data races. # https://github.com/celestiaorg/celestia-app/issues/1369 @echo "--> Running tests in race mode" - @go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestBlobstreamRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestBlobstreamCLI|TestUpgrade|TestMaliciousTestNode|TestBigBlobSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext|TestBlobstream|TestCLITestSuite|TestLegacyUpgrade|TestSignerTwins|TestConcurrentTxSubmission|TestTxClientTestSuite|Test_testnode" + @go test -timeout 15m ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestBlobstreamRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestBlobstreamCLI|TestUpgrade|TestMaliciousTestNode|TestBigBlobSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext|TestBlobstream|TestCLITestSuite|TestLegacyUpgrade|TestSignerTwins|TestConcurrentTxSubmission|TestTxClientTestSuite|Test_testnode|TestEvictions" .PHONY: test-race ## test-bench: Run unit tests in bench mode. @@ -163,13 +188,6 @@ test-fuzz: bash -x scripts/test_fuzz.sh .PHONY: test-fuzz -## test-interchain: Run interchain tests in verbose mode. Requires Docker. -test-interchain: - @echo "Reminder: this test uses the latest celestia-app Docker image. If you would like to test recent code changes, re-build the Docker image by running: make build-docker" - @echo "--> Running interchain tests" - @cd ./test/interchain && go test . -v -.PHONY: test-interchain - ## txsim-install: Install the tx simulator. txsim-install: @echo "--> Installing tx simulator" @@ -187,7 +205,7 @@ txsim-build: ## txsim-build-docker: Build the tx simulator Docker image. Requires Docker. txsim-build-docker: - docker build -t ghcr.io/celestiaorg/txsim -f docker/Dockerfile_txsim . + docker build -t ghcr.io/celestiaorg/txsim -f docker/txsim/Dockerfile . .PHONY: txsim-build-docker ## adr-gen: Download the ADR template from the celestiaorg/.github repo. @@ -196,6 +214,23 @@ adr-gen: @curl -sSL https://raw.githubusercontent.com/celestiaorg/.github/main/adr-template.md > docs/architecture/adr-template.md .PHONY: adr-gen +## goreleaser-check: Check the .goreleaser.yaml config file. +goreleaser-check: + @if [ ! -f ".release-env" ]; then \ + echo "A .release-env file was not found but is required to create prebuilt binaries. This command is expected to be run in CI where a .release-env file exists. If you need to run this command locally to attach binaries to a release, you need to create a .release-env file with a Github token (classic) that has repo:public_repo scope."; \ + exit 1;\ + fi + docker run \ + --rm \ + -e CGO_ENABLED=1 \ + --env-file .release-env \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/goreleaser/goreleaser-cross:${GOLANG_CROSS_VERSION} \ + check +.PHONY: goreleaser-check + ## prebuilt-binary: Create prebuilt binaries and attach them to GitHub release. Requires Docker. prebuilt-binary: @if [ ! -f ".release-env" ]; then \ @@ -220,3 +255,34 @@ build-node: @cd ./node && go build -o ../build/node . @go mod tidy .PHONY: build-node + +## check-bbr: Check if your system uses BBR congestion control algorithm. Only works on Linux. +check-bbr: + @echo "Checking if BBR is enabled..." + @if [ "$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')" != "bbr" ]; then \ + echo "WARNING: BBR is not enabled. Please enable BBR for optimal performance. Call make enable-bbr or see Usage section in the README."; \ + else \ + echo "BBR is enabled."; \ + fi +.PHONY: check-bbr + +## enable-bbr: Enable BBR congestion control algorithm. Only works on Linux. +enable-bbr: + @echo "Configuring system to use BBR..." + @if [ "$(sysctl net.ipv4.tcp_congestion_control | awk '{print $3}')" != "bbr" ]; then \ + echo "BBR is not enabled. Configuring BBR..."; \ + sudo modprobe tcp_bbr; \ + echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf; \ + echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf; \ + sudo sysctl -p; \ + echo "BBR has been enabled."; \ + else \ + echo "BBR is already enabled."; \ + fi +.PHONY: enable-bbr + +## debug-version: Print the git tag and version. +debug-version: + @echo "GIT_TAG: $(GIT_TAG)" + @echo "VERSION: $(VERSION)" +.PHONY: debug-version diff --git a/README.md b/README.md index 58ac9da858..7854890901 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ node | | | | ### Source -1. [Install Go](https://go.dev/doc/install) 1.22.6 +1. [Install Go](https://go.dev/doc/install) 1.23.1 1. Clone this repo 1. Install the celestia-app CLI @@ -77,6 +77,22 @@ See for more information. ## Usage +First, make sure that the [BBR](https://www.ietf.org/archive/id/draft-cardwell-iccrg-bbr-congestion-control-01.html) ("Bottleneck Bandwidth and Round-trip propagation time") congestion control algorithm is enabled in the +system's kernel. The result should contain `bbr`: + +```sh +sysctl net.ipv4.tcp_congestion_control +``` + +If not, enable it on Linux by calling the `make use-bbr` or by running: + +```sh +sudo modprobe tcp_bbr +net.core.default_qdisc=fq +net.ipv4.tcp_congestion_control=bbr +sudo sysctl -p +``` + ```sh # Print help celestia-appd --help @@ -118,7 +134,7 @@ This repo contains multiple go modules. When using it, rename `go.work.example` ### Tools -1. Install [golangci-lint](https://golangci-lint.run/welcome/install) 1.59.1 +1. Install [golangci-lint](https://golangci-lint.run/welcome/install) 1.61.0 1. Install [markdownlint](https://github.com/DavidAnson/markdownlint) 0.39.0 1. Install [hadolint](https://github.com/hadolint/hadolint) 1. Install [yamllint](https://yamllint.readthedocs.io/en/stable/quickstart.html) @@ -153,8 +169,9 @@ Package-specific READMEs aim to explain implementation details for developers th ## Audits -| Date | Auditor | Version | Report | -|------------|-----------------------------------------------|-------------------------------------------------------------------------------------|---------------------------------------------------------------| -| 2023/9/15 | [Informal Systems](https://informal.systems/) | [v1.0.0-rc6](https://github.com/celestiaorg/celestia-app/releases/tag/v1.0.0-rc6) | [informal-systems.pdf](docs/audit/informal-systems.pdf) | -| 2023/10/17 | [Binary Builders](https://binary.builders/) | [v1.0.0-rc10](https://github.com/celestiaorg/celestia-app/releases/tag/v1.0.0-rc10) | [binary-builders.pdf](docs/audit/binary-builders.pdf) | -| 2024/7/1 | [Informal Systems](https://informal.systems/) | [v2.0.0-rc1](https://github.com/celestiaorg/celestia-app/releases/tag/v2.0.0-rc1) | [informal-systems-v2.pdf](docs/audit/informal-systems-v2.pdf) | +| Date | Auditor | Version | Report | +|------------|-----------------------------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------| +| 2023/9/15 | [Informal Systems](https://informal.systems/) | [v1.0.0-rc6](https://github.com/celestiaorg/celestia-app/releases/tag/v1.0.0-rc6) | [informal-systems.pdf](docs/audit/informal-systems.pdf) | +| 2023/10/17 | [Binary Builders](https://binary.builders/) | [v1.0.0-rc10](https://github.com/celestiaorg/celestia-app/releases/tag/v1.0.0-rc10) | [binary-builders.pdf](docs/audit/binary-builders.pdf) | +| 2024/7/1 | [Informal Systems](https://informal.systems/) | [v2.0.0-rc1](https://github.com/celestiaorg/celestia-app/releases/tag/v2.0.0-rc1) | [informal-systems-v2.pdf](docs/audit/informal-systems-v2.pdf) | +| 2024/9/20 | [Informal Systems](https://informal.systems/) | [306c587](https://github.com/celestiaorg/celestia-app/commit/306c58745d135d31c3777a1af2f58d50adbd32c8) | [informal-systems-authored-blobs.pdf](docs/audit/informal-systems-authored-blobs.pdf) | diff --git a/app/ante/ante.go b/app/ante/ante.go index dd65fdd120..c82313b65e 100644 --- a/app/ante/ante.go +++ b/app/ante/ante.go @@ -32,6 +32,8 @@ func NewAnteHandler( // Set up the context with a gas meter. // Must be called before gas consumption occurs in any other decorator. ante.NewSetUpContextDecorator(), + // Ensure the tx is not larger than the configured threshold. + NewMaxTxSizeDecorator(), // Ensure the tx does not contain any extension options. ante.NewExtensionOptionsDecorator(nil), // Ensure the tx passes ValidateBasic. @@ -42,7 +44,7 @@ func NewAnteHandler( ante.NewValidateMemoDecorator(accountKeeper), // Ensure the tx's gas limit is > the gas consumed based on the tx size. // Side effect: consumes gas from the gas meter. - ante.NewConsumeGasForTxSizeDecorator(accountKeeper), + NewConsumeGasForTxSizeDecorator(accountKeeper), // Ensure the feepayer (fee granter or first signer) has enough funds to pay for the tx. // Ensure the gas price >= network min gas price if app version >= 2. // Side effect: deducts fees from the fee payer. Sets the tx priority in context. diff --git a/app/ante/max_tx_size.go b/app/ante/max_tx_size.go new file mode 100644 index 0000000000..a9525777e2 --- /dev/null +++ b/app/ante/max_tx_size.go @@ -0,0 +1,33 @@ +package ante + +import ( + "fmt" + + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MaxTxSizeDecorator ensures that a tx can not be larger than +// application's configured versioned constant. +type MaxTxSizeDecorator struct{} + +func NewMaxTxSizeDecorator() MaxTxSizeDecorator { + return MaxTxSizeDecorator{} +} + +// AnteHandle implements the AnteHandler interface. It ensures that tx size is under application's configured threshold. +func (d MaxTxSizeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + // Tx size rule applies to app versions v3 and onwards. + if ctx.BlockHeader().Version.App < v3.Version { + return next(ctx, tx, simulate) + } + + currentTxSize := len(ctx.TxBytes()) + maxTxSize := appconsts.MaxTxSize(ctx.BlockHeader().Version.App) + if currentTxSize > maxTxSize { + bytesOverLimit := currentTxSize - maxTxSize + return ctx, fmt.Errorf("tx size %d bytes is larger than the application's configured threshold of %d bytes. Please reduce the size by %d bytes", currentTxSize, maxTxSize, bytesOverLimit) + } + return next(ctx, tx, simulate) +} diff --git a/app/ante/max_tx_size_test.go b/app/ante/max_tx_size_test.go new file mode 100644 index 0000000000..b52ceeb084 --- /dev/null +++ b/app/ante/max_tx_size_test.go @@ -0,0 +1,78 @@ +package ante_test + +import ( + "testing" + + "github.com/celestiaorg/celestia-app/v3/app/ante" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + version "github.com/tendermint/tendermint/proto/tendermint/version" +) + +func TestMaxTxSizeDecorator(t *testing.T) { + decorator := ante.NewMaxTxSizeDecorator() + anteHandler := sdk.ChainAnteDecorators(decorator) + + testCases := []struct { + name string + txSize int + expectError bool + appVersion uint64 + isCheckTx []bool + }{ + { + name: "good tx; under max tx size threshold", + txSize: v3.MaxTxSize - 1, + appVersion: v3.Version, + expectError: false, + isCheckTx: []bool{true, false}, + }, + { + name: "bad tx; over max tx size threshold", + txSize: v3.MaxTxSize + 1, + appVersion: v3.Version, + expectError: true, + isCheckTx: []bool{true, false}, + }, + { + name: "good tx; equal to max tx size threshold", + txSize: v3.MaxTxSize, + appVersion: v3.Version, + expectError: false, + isCheckTx: []bool{true, false}, + }, + { + name: "good tx; limit only applies to v3 and above", + txSize: v3.MaxTxSize + 10, + appVersion: v2.Version, + expectError: false, + isCheckTx: []bool{true, false}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + for _, isCheckTx := range tc.isCheckTx { + + ctx := sdk.NewContext(nil, tmproto.Header{ + Version: version.Consensus{ + App: tc.appVersion, + }, + }, isCheckTx, nil) + + txBytes := make([]byte, tc.txSize) + + ctx = ctx.WithTxBytes(txBytes) + _, err := anteHandler(ctx, nil, false) + if tc.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + } + }) + } +} diff --git a/app/ante/min_fee_test.go b/app/ante/min_fee_test.go index 30912813c4..fc66e11a67 100644 --- a/app/ante/min_fee_test.go +++ b/app/ante/min_fee_test.go @@ -9,7 +9,6 @@ import ( "github.com/celestiaorg/celestia-app/v3/app/ante" "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" - v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" "github.com/celestiaorg/celestia-app/v3/x/minfee" "github.com/cosmos/cosmos-sdk/codec" @@ -58,7 +57,7 @@ func TestValidateTxFee(t *testing.T) { { name: "bad tx; fee below required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount-1)), - gasLimit: uint64(float64(feeAmount) / v2.NetworkMinGasPrice), + gasLimit: uint64(float64(feeAmount) / appconsts.DefaultNetworkMinGasPrice), appVersion: uint64(2), isCheckTx: false, expErr: true, @@ -66,7 +65,7 @@ func TestValidateTxFee(t *testing.T) { { name: "good tx; fee equal to required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount)), - gasLimit: uint64(float64(feeAmount) / v2.NetworkMinGasPrice), + gasLimit: uint64(float64(feeAmount) / appconsts.DefaultNetworkMinGasPrice), appVersion: uint64(2), isCheckTx: false, expErr: false, @@ -74,7 +73,7 @@ func TestValidateTxFee(t *testing.T) { { name: "good tx; fee above required minimum", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount+1)), - gasLimit: uint64(float64(feeAmount) / v2.NetworkMinGasPrice), + gasLimit: uint64(float64(feeAmount) / appconsts.DefaultNetworkMinGasPrice), appVersion: uint64(2), isCheckTx: false, expErr: false, @@ -82,7 +81,7 @@ func TestValidateTxFee(t *testing.T) { { name: "good tx; with no fee (v1)", fee: sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, feeAmount)), - gasLimit: uint64(float64(feeAmount) / v2.NetworkMinGasPrice), + gasLimit: uint64(float64(feeAmount) / appconsts.DefaultNetworkMinGasPrice), appVersion: uint64(1), isCheckTx: false, expErr: false, @@ -143,7 +142,7 @@ func TestValidateTxFee(t *testing.T) { ctx = ctx.WithMinGasPrices(sdk.DecCoins{validatorMinGasPriceCoin}) - networkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", v2.NetworkMinGasPrice)) + networkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", appconsts.DefaultNetworkMinGasPrice)) require.NoError(t, err) subspace, _ := paramsKeeper.GetSubspace(minfee.ModuleName) diff --git a/app/ante/tx_size_gas.go b/app/ante/tx_size_gas.go new file mode 100644 index 0000000000..356f6f2646 --- /dev/null +++ b/app/ante/tx_size_gas.go @@ -0,0 +1,151 @@ +package ante + +import ( + "encoding/hex" + + "cosmossdk.io/errors" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + "github.com/cosmos/cosmos-sdk/codec/legacy" + "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/ante" + "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + auth "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +var ( + // Simulation signature values used to estimate gas consumption. + key = make([]byte, secp256k1.PubKeySize) + simSecp256k1Pubkey = &secp256k1.PubKey{Key: key} + simSecp256k1Sig [64]byte +) + +func init() { + // Decodes a valid hex string into a sepc256k1Pubkey for use in transaction simulation + bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A") + copy(key, bz) + simSecp256k1Pubkey.Key = key +} + +// ConsumeTxSizeGasDecorator will take in parameters and consume gas proportional +// to the size of tx before calling next AnteHandler. Note, the gas costs will be +// slightly over estimated due to the fact that any given signing account may need +// to be retrieved from state. +// +// CONTRACT: If simulate=true, then signatures must either be completely filled +// in or empty. +// CONTRACT: To use this decorator, signatures of transaction must be represented +// as legacytx.StdSignature otherwise simulate mode will incorrectly estimate gas cost. + +// The code was copied from celestia's fork of the cosmos-sdk: +// https://github.com/celestiaorg/cosmos-sdk/blob/release/v0.46.x-celestia/x/auth/ante/basic.go +// In app versions v2 and below, the txSizeCostPerByte used for gas cost estimation is taken from the auth module. +// In app v3 and above, the versioned constant appconsts.TxSizeCostPerByte is used. +type ConsumeTxSizeGasDecorator struct { + ak ante.AccountKeeper +} + +func NewConsumeGasForTxSizeDecorator(ak ante.AccountKeeper) ConsumeTxSizeGasDecorator { + return ConsumeTxSizeGasDecorator{ + ak: ak, + } +} + +func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return ctx, errors.Wrap(sdkerrors.ErrTxDecode, "invalid tx type") + } + params := cgts.ak.GetParams(ctx) + + consumeGasForTxSize(ctx, sdk.Gas(len(ctx.TxBytes())), params) + + // simulate gas cost for signatures in simulate mode + if simulate { + // in simulate mode, each element should be a nil signature + sigs, err := sigTx.GetSignaturesV2() + if err != nil { + return ctx, err + } + n := len(sigs) + + for i, signer := range sigTx.GetSigners() { + // if signature is already filled in, no need to simulate gas cost + if i < n && !isIncompleteSignature(sigs[i].Data) { + continue + } + + var pubkey cryptotypes.PubKey + + acc := cgts.ak.GetAccount(ctx, signer) + + // use placeholder simSecp256k1Pubkey if sig is nil + if acc == nil || acc.GetPubKey() == nil { + pubkey = simSecp256k1Pubkey + } else { + pubkey = acc.GetPubKey() + } + + // use stdsignature to mock the size of a full signature + simSig := legacytx.StdSignature{ //nolint:staticcheck // this will be removed when proto is ready + Signature: simSecp256k1Sig[:], + PubKey: pubkey, + } + + sigBz := legacy.Cdc.MustMarshal(simSig) + txBytes := sdk.Gas(len(sigBz) + 6) + + // If the pubkey is a multi-signature pubkey, then we estimate for the maximum + // number of signers. + if _, ok := pubkey.(*multisig.LegacyAminoPubKey); ok { + txBytes *= params.TxSigLimit + } + + consumeGasForTxSize(ctx, txBytes, params) + } + } + + return next(ctx, tx, simulate) +} + +// isIncompleteSignature tests whether SignatureData is fully filled in for simulation purposes +func isIncompleteSignature(data signing.SignatureData) bool { + if data == nil { + return true + } + + switch data := data.(type) { + case *signing.SingleSignatureData: + return len(data.Signature) == 0 + case *signing.MultiSignatureData: + if len(data.Signatures) == 0 { + return true + } + for _, s := range data.Signatures { + if isIncompleteSignature(s) { + return true + } + } + } + + return false +} + +// consumeGasForTxSize consumes gas based on the size of the transaction. +// It uses different parameters depending on the app version. +func consumeGasForTxSize(ctx sdk.Context, txBytes uint64, params auth.Params) { + // For app v2 and below we should get txSizeCostPerByte from auth module + if ctx.BlockHeader().Version.App <= v2.Version { + ctx.GasMeter().ConsumeGas(params.TxSizeCostPerByte*txBytes, "txSize") + } else { + // From v3 onwards, we should get txSizeCostPerByte from appconsts + txSizeCostPerByte := appconsts.TxSizeCostPerByte(ctx.BlockHeader().Version.App) + ctx.GasMeter().ConsumeGas(txSizeCostPerByte*txBytes, "txSize") + } +} diff --git a/app/ante/tx_size_gas_test.go b/app/ante/tx_size_gas_test.go new file mode 100644 index 0000000000..6b6bdbd80b --- /dev/null +++ b/app/ante/tx_size_gas_test.go @@ -0,0 +1,197 @@ +package ante_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/ante" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + testutil "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/crypto/types/multisig" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proto/tendermint/version" +) + +const TxSizeCostPerByte = 8 + +func setup() (*app.App, sdk.Context, client.Context, error) { + app, _, _ := testutil.NewTestAppWithGenesisSet(app.DefaultConsensusParams()) + ctx := app.NewContext(false, tmproto.Header{}) + params := authtypes.DefaultParams() + // Override default with a different TxSizeCostPerByte value for testing + params.TxSizeCostPerByte = TxSizeCostPerByte + app.AccountKeeper.SetParams(ctx, params) + ctx = ctx.WithBlockHeight(1) + + // Set up TxConfig. + encodingConfig := simapp.MakeTestEncodingConfig() + // We're using TestMsg encoding in the test, so register it here. + encodingConfig.Amino.RegisterConcrete(&testdata.TestMsg{}, "testdata.TestMsg", nil) + testdata.RegisterInterfaces(encodingConfig.InterfaceRegistry) + + clientCtx := client.Context{}. + WithTxConfig(encodingConfig.TxConfig) + + return app, ctx, clientCtx, nil +} + +func TestConsumeGasForTxSize(t *testing.T) { + app, ctx, clientCtx, err := setup() + require.NoError(t, err) + var txBuilder client.TxBuilder + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + msg := testdata.NewTestMsg(addr1) + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + + cgtsd := ante.NewConsumeGasForTxSizeDecorator(app.AccountKeeper) + antehandler := sdk.ChainAnteDecorators(cgtsd) + + testCases := []struct { + version uint64 + name string + sigV2 signing.SignatureV2 + }{ + {v2.Version, "SingleSignatureData v2", signing.SignatureV2{PubKey: priv1.PubKey()}}, + {v2.Version, "MultiSignatureData v2", signing.SignatureV2{PubKey: priv1.PubKey(), Data: multisig.NewMultisig(2)}}, + {appconsts.LatestVersion, fmt.Sprintf("SingleSignatureData v%d", appconsts.LatestVersion), signing.SignatureV2{PubKey: priv1.PubKey()}}, + {appconsts.LatestVersion, fmt.Sprintf("MultiSignatureData v%d", appconsts.LatestVersion), signing.SignatureV2{PubKey: priv1.PubKey(), Data: multisig.NewMultisig(2)}}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // set the version + ctx = app.NewContext(false, tmproto.Header{Version: version.Consensus{ + App: tc.version, + }}) + + txBuilder = clientCtx.TxConfig.NewTxBuilder() + require.NoError(t, txBuilder.SetMsgs(msg)) + txBuilder.SetFeeAmount(feeAmount) + txBuilder.SetGasLimit(gasLimit) + txBuilder.SetMemo(strings.Repeat("01234567890", 10)) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := createTestTx(txBuilder, clientCtx, privs, accNums, accSeqs, ctx.ChainID()) + require.NoError(t, err) + + txBytes, err := clientCtx.TxConfig.TxJSONEncoder()(tx) + require.Nil(t, err, "Cannot marshal tx: %v", err) + + // expected TxSizeCostPerByte is different for each version + var txSizeCostPerByte uint64 + if tc.version == v2.Version { + txSizeCostPerByte = TxSizeCostPerByte + } else { + txSizeCostPerByte = appconsts.TxSizeCostPerByte(tc.version) + } + + expectedGas := sdk.Gas(len(txBytes)) * txSizeCostPerByte + + // set suite.ctx with TxBytes manually + ctx = ctx.WithTxBytes(txBytes) + + // track how much gas is necessary to retrieve parameters + beforeGas := ctx.GasMeter().GasConsumed() + app.AccountKeeper.GetParams(ctx) + afterGas := ctx.GasMeter().GasConsumed() + expectedGas += afterGas - beforeGas + + beforeGas = ctx.GasMeter().GasConsumed() + ctx, err = antehandler(ctx, tx, false) + require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err) + + // require that decorator consumes expected amount of gas + consumedGas := ctx.GasMeter().GasConsumed() - beforeGas + require.Equal(t, expectedGas, consumedGas, "Decorator did not consume the correct amount of gas") + + // simulation must not underestimate gas of this decorator even with nil signatures + txBuilder, err := clientCtx.TxConfig.WrapTxBuilder(tx) + require.NoError(t, err) + require.NoError(t, txBuilder.SetSignatures(tc.sigV2)) + tx = txBuilder.GetTx() + + simTxBytes, err := clientCtx.TxConfig.TxJSONEncoder()(tx) + require.Nil(t, err, "Cannot marshal tx: %v", err) + // require that simulated tx is smaller than tx with signatures + require.True(t, len(simTxBytes) < len(txBytes), "simulated tx still has signatures") + + // Set suite.ctx with smaller simulated TxBytes manually + ctx = ctx.WithTxBytes(simTxBytes) + + beforeSimGas := ctx.GasMeter().GasConsumed() + + // run antehandler with simulate=true + ctx, err = antehandler(ctx, tx, true) + consumedSimGas := ctx.GasMeter().GasConsumed() - beforeSimGas + + // require that antehandler passes and does not underestimate decorator cost + require.Nil(t, err, "ConsumeTxSizeGasDecorator returned error: %v", err) + require.True(t, consumedSimGas >= expectedGas, "Simulate mode underestimates gas on AnteDecorator. Simulated cost: %d, expected cost: %d", consumedSimGas, expectedGas) + }) + } +} + +// createTestTx creates a test tx given multiple inputs. +func createTestTx(txBuilder client.TxBuilder, clientCtx client.Context, privs []cryptotypes.PrivKey, accNums []uint64, accSeqs []uint64, chainID string) (xauthsigning.Tx, error) { + // First round: we gather all the signer infos. We use the "set empty + // signature" hack to do that. + sigsV2 := make([]signing.SignatureV2, 0, len(privs)) + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: clientCtx.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + err := txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + // Second round: all signer infos are set, so each signer can sign. + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + } + sigV2, err := tx.SignWithPrivKey( + clientCtx.TxConfig.SignModeHandler().DefaultMode(), signerData, + txBuilder, priv, clientCtx.TxConfig, accSeqs[i]) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + err = txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + return txBuilder.GetTx(), nil +} diff --git a/app/app.go b/app/app.go index 88c3722ab0..9a2996fc3b 100644 --- a/app/app.go +++ b/app/app.go @@ -10,8 +10,10 @@ import ( celestiatx "github.com/celestiaorg/celestia-app/v3/app/grpc/tx" "github.com/celestiaorg/celestia-app/v3/app/module" "github.com/celestiaorg/celestia-app/v3/app/posthandler" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" appv1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" appv2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + appv3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" "github.com/celestiaorg/celestia-app/v3/pkg/proof" blobkeeper "github.com/celestiaorg/celestia-app/v3/x/blob/keeper" blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" @@ -21,9 +23,9 @@ import ( mintkeeper "github.com/celestiaorg/celestia-app/v3/x/mint/keeper" minttypes "github.com/celestiaorg/celestia-app/v3/x/mint/types" "github.com/celestiaorg/celestia-app/v3/x/paramfilter" + "github.com/celestiaorg/celestia-app/v3/x/signal" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/celestiaorg/celestia-app/v3/x/tokenfilter" - "github.com/celestiaorg/celestia-app/x/signal" - signaltypes "github.com/celestiaorg/celestia-app/x/signal/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" @@ -108,6 +110,7 @@ var maccPerms = map[string][]string{ const ( v1 = appv1.Version v2 = appv2.Version + v3 = appv3.Version DefaultInitialVersion = v1 ) @@ -339,11 +342,11 @@ func New( packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, // forward timeout packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp, // refund timeout ) - // PacketForwardMiddleware is used only for version 2. - transferStack = module.NewVersionedIBCModule(packetForwardMiddleware, transferStack, v2, v2) + // PacketForwardMiddleware is used only for version >= 2. + transferStack = module.NewVersionedIBCModule(packetForwardMiddleware, transferStack, v2, v3) // Token filter wraps packet forward middleware and is thus the first module in the transfer stack. tokenFilterMiddelware := tokenfilter.NewIBCMiddleware(transferStack) - transferStack = module.NewVersionedIBCModule(tokenFilterMiddelware, transferStack, v1, v2) + transferStack = module.NewVersionedIBCModule(tokenFilterMiddelware, transferStack, v1, v3) app.EvidenceKeeper = *evidencekeeper.NewKeeper( appCodec, @@ -463,14 +466,23 @@ func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.Respo res := app.manager.EndBlock(ctx, req) currentVersion := app.AppVersion() - // from v3 onwards we use a signalling mechanism - if shouldUpgrade, newVersion := app.SignalKeeper.ShouldUpgrade(ctx); shouldUpgrade { - // Version changes must be increasing. Downgrades are not permitted + if currentVersion == v1 { + if req.Height == app.upgradeHeightV2-1 { + app.BaseApp.Logger().Info(fmt.Sprintf("upgrading from app version %v to 2", currentVersion)) + app.SetInitialAppVersionInConsensusParams(ctx, v2) + app.SetAppVersion(ctx, v2) + } + } else if shouldUpgrade, newVersion := app.SignalKeeper.ShouldUpgrade(ctx); shouldUpgrade { + // Version changes must be increasing. Downgrades are not permitted. if newVersion > currentVersion { app.SetAppVersion(ctx, newVersion) app.SignalKeeper.ResetTally(ctx) } } + + // Question why do we do this every block instead of just during the v2 to v3 upgrade? + res.Timeouts.TimeoutCommit = appconsts.GetTimeoutCommit(currentVersion) + res.Timeouts.TimeoutPropose = appconsts.GetTimeoutPropose(currentVersion) return res } @@ -506,27 +518,40 @@ func (app *App) migrateModules(ctx sdk.Context, fromVersion, toVersion uint64) e // Info command so that it can take the app version and setup the multicommit // store. func (app *App) Info(req abci.RequestInfo) abci.ResponseInfo { - return app.BaseApp.Info(req) + if height := app.LastBlockHeight(); height > 0 { + ctx, err := app.CreateQueryContext(height, false) + if err != nil { + panic(err) + } + appVersion := app.GetAppVersionFromParamStore(ctx) + if appVersion > 0 { + app.SetAppVersion(ctx, appVersion) + } else { + app.SetAppVersion(ctx, v1) + } + } + + resp := app.BaseApp.Info(req) + // mount the stores for the provided app version + if resp.AppVersion > 0 && !app.IsSealed() { + app.mountKeysAndInit(resp.AppVersion) + } + + resp.Timeouts.TimeoutPropose = appconsts.GetTimeoutPropose(resp.AppVersion) + resp.Timeouts.TimeoutCommit = appconsts.GetTimeoutCommit(resp.AppVersion) + + return resp } // InitChain implements the ABCI interface. This method is a wrapper around -// baseapp's InitChain so we can take the app version and setup the multicommit +// baseapp's InitChain so that we can take the app version and setup the multicommit // store. // // Side-effect: calls baseapp.Init() // TODO: refactor this method because it no longer needs to support initializing a chain with an app version that isn't 3. func (app *App) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain) { - // genesis must always contain the consensus params. The validator set however is derived from the - // initial genesis state. The genesis must always contain a non zero app version which is the initial - // version that the chain starts on - if req.ConsensusParams == nil || req.ConsensusParams.Version == nil { - panic("no consensus params set") - } - if req.ConsensusParams.Version.AppVersion == 0 { - panic("app version 0 is not accepted. Please set an app version in the genesis") - } + req = setDefaultAppVersion(req) appVersion := req.ConsensusParams.Version.AppVersion - // mount the stores for the provided app version if it has not already been mounted if app.AppVersion() == 0 && !app.IsSealed() { app.mountKeysAndInit(appVersion) @@ -539,12 +564,31 @@ func (app *App) InitChain(req abci.RequestInitChain) (res abci.ResponseInitChain app.SetInitialAppVersionInConsensusParams(ctx, appVersion) app.SetAppVersion(ctx, appVersion) } + res.Timeouts.TimeoutCommit = appconsts.GetTimeoutCommit(appVersion) + res.Timeouts.TimeoutPropose = appconsts.GetTimeoutPropose(appVersion) return res } +// setDefaultAppVersion sets the default app version in the consensus params if +// it was 0. This is needed because chains (e.x. mocha-4) did not explicitly set +// an app version in genesis.json. +func setDefaultAppVersion(req abci.RequestInitChain) abci.RequestInitChain { + if req.ConsensusParams == nil { + panic("no consensus params set") + } + if req.ConsensusParams.Version == nil { + panic("no version set in consensus params") + } + if req.ConsensusParams.Version.AppVersion == 0 { + req.ConsensusParams.Version.AppVersion = v1 + } + return req +} + // mountKeysAndInit mounts the keys for the provided app version and then // invokes baseapp.Init(). func (app *App) mountKeysAndInit(appVersion uint64) { + app.Logger().Info(fmt.Sprintf("mounting KV stores for app version %v", appVersion)) app.MountKVStores(app.versionedKeys(appVersion)) // Invoke load latest version for its side-effect of invoking baseapp.Init() @@ -559,9 +603,9 @@ func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.Res if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil { panic(err) } - - app.UpgradeKeeper.SetModuleVersionMap(ctx, app.manager.GetVersionMap(req.ConsensusParams.Version.AppVersion)) - return app.manager.InitGenesis(ctx, app.appCodec, genesisState, req.ConsensusParams.Version.AppVersion) + appVersion := req.ConsensusParams.Version.AppVersion + app.UpgradeKeeper.SetModuleVersionMap(ctx, app.manager.GetVersionMap(appVersion)) + return app.manager.InitGenesis(ctx, app.appCodec, genesisState, appVersion) } // LoadHeight loads a particular height @@ -763,3 +807,48 @@ func (app *App) InitializeAppVersion(ctx sdk.Context) { func (app *App) RunMigrations() []byte { return []byte{} } + +// OfferSnapshot is a wrapper around the baseapp's OfferSnapshot method. It is +// needed to mount stores for the appropriate app version. +func (app *App) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { + if app.IsSealed() { + // If the app is sealed, keys have already been mounted so this can + // delegate to the baseapp's OfferSnapshot. + return app.BaseApp.OfferSnapshot(req) + } + + app.Logger().Info("offering snapshot", "height", req.Snapshot.Height, "app_version", req.AppVersion) + if req.AppVersion != 0 { + if !isSupportedAppVersion(req.AppVersion) { + app.Logger().Info("rejecting snapshot because unsupported app version", "app_version", req.AppVersion) + return abci.ResponseOfferSnapshot{ + Result: abci.ResponseOfferSnapshot_REJECT, + } + } + + app.Logger().Info("mounting keys for snapshot", "app_version", req.AppVersion) + app.mountKeysAndInit(req.AppVersion) + return app.BaseApp.OfferSnapshot(req) + } + + // If the app version is not set in the snapshot, this falls back to inferring the app version based on the upgrade height. + if app.upgradeHeightV2 == 0 { + app.Logger().Info("v2 upgrade height not set, assuming app version 2") + app.mountKeysAndInit(v2) + return app.BaseApp.OfferSnapshot(req) + } + + if req.Snapshot.Height >= uint64(app.upgradeHeightV2) { + app.Logger().Info("snapshot height is greater than or equal to upgrade height, assuming app version 2") + app.mountKeysAndInit(v2) + return app.BaseApp.OfferSnapshot(req) + } + + app.Logger().Info("snapshot height is less than upgrade height, assuming app version 1") + app.mountKeysAndInit(v1) + return app.BaseApp.OfferSnapshot(req) +} + +func isSupportedAppVersion(appVersion uint64) bool { + return appVersion == v1 || appVersion == v2 || appVersion == v3 +} diff --git a/app/app_test.go b/app/app_test.go index e1189e5599..ae1c6089f5 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -1,13 +1,24 @@ package app_test import ( + "encoding/json" + "os" + "path/filepath" "testing" "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" "github.com/celestiaorg/celestia-app/v3/x/minfee" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/snapshots" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmdb "github.com/tendermint/tm-db" ) @@ -47,6 +58,145 @@ func TestNew(t *testing.T) { }) } +func TestInitChain(t *testing.T) { + logger := log.NewNopLogger() + db := tmdb.NewMemDB() + traceStore := &NoopWriter{} + invCheckPeriod := uint(1) + encodingConfig := encoding.MakeConfig(app.ModuleEncodingRegisters...) + upgradeHeight := int64(0) + appOptions := NoopAppOptions{} + testApp := app.New(logger, db, traceStore, invCheckPeriod, encodingConfig, upgradeHeight, appOptions) + genesisState, _, _ := util.GenesisStateWithSingleValidator(testApp, "account") + appStateBytes, err := json.MarshalIndent(genesisState, "", " ") + require.NoError(t, err) + genesis := testnode.DefaultConfig().Genesis + + type testCase struct { + name string + request abci.RequestInitChain + wantPanic bool + } + testCases := []testCase{ + { + name: "should panic if consensus params not set", + request: abci.RequestInitChain{}, + wantPanic: true, + }, + { + name: "should not panic on a genesis that does not contain an app version", + request: abci.RequestInitChain{ + Time: genesis.GenesisTime, + ChainId: genesis.ChainID, + ConsensusParams: &abci.ConsensusParams{ + Block: &abci.BlockParams{}, + Evidence: &genesis.ConsensusParams.Evidence, + Validator: &genesis.ConsensusParams.Validator, + Version: &tmproto.VersionParams{}, // explicitly set to empty to remove app version., + }, + AppStateBytes: appStateBytes, + InitialHeight: 0, + }, + wantPanic: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + application := app.New(logger, db, traceStore, invCheckPeriod, encodingConfig, upgradeHeight, appOptions) + if tc.wantPanic { + assert.Panics(t, func() { application.InitChain(tc.request) }) + } else { + assert.NotPanics(t, func() { application.InitChain(tc.request) }) + } + }) + } +} + +func TestOfferSnapshot(t *testing.T) { + t.Run("should ACCEPT a snapshot with app version 0", func(t *testing.T) { + // Snapshots taken before the app version field was introduced to RequestOfferSnapshot should still be accepted. + app := createTestApp(t) + request := createRequest() + want := abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + got := app.OfferSnapshot(request) + assert.Equal(t, want, got) + }) + t.Run("should ACCEPT a snapshot with app version 1", func(t *testing.T) { + app := createTestApp(t) + request := createRequest() + request.AppVersion = 1 + want := abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + got := app.OfferSnapshot(request) + assert.Equal(t, want, got) + }) + t.Run("should ACCEPT a snapshot with app version 2", func(t *testing.T) { + app := createTestApp(t) + request := createRequest() + request.AppVersion = 2 + want := abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + got := app.OfferSnapshot(request) + assert.Equal(t, want, got) + }) + t.Run("should ACCEPT a snapshot with app version 3", func(t *testing.T) { + app := createTestApp(t) + request := createRequest() + request.AppVersion = 3 + want := abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT} + got := app.OfferSnapshot(request) + assert.Equal(t, want, got) + }) + t.Run("should REJECT a snapshot with unsupported app version", func(t *testing.T) { + app := createTestApp(t) + request := createRequest() + request.AppVersion = 4 // unsupported app version + want := abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT} + got := app.OfferSnapshot(request) + assert.Equal(t, want, got) + }) +} + +func createTestApp(t *testing.T) *app.App { + db := tmdb.NewMemDB() + config := encoding.MakeConfig(app.ModuleEncodingRegisters...) + upgradeHeight := int64(3) + snapshotDir := filepath.Join(t.TempDir(), "data", "snapshots") + t.Cleanup(func() { + err := os.RemoveAll(snapshotDir) + require.NoError(t, err) + }) + snapshotDB, err := tmdb.NewDB("metadata", tmdb.GoLevelDBBackend, snapshotDir) + t.Cleanup(func() { + err := snapshotDB.Close() + require.NoError(t, err) + }) + require.NoError(t, err) + snapshotStore, err := snapshots.NewStore(snapshotDB, snapshotDir) + require.NoError(t, err) + baseAppOption := baseapp.SetSnapshot(snapshotStore, snapshottypes.NewSnapshotOptions(10, 10)) + testApp := app.New(log.NewNopLogger(), db, nil, 0, config, upgradeHeight, util.EmptyAppOptions{}, baseAppOption) + require.NoError(t, err) + response := testApp.Info(abci.RequestInfo{}) + require.Equal(t, uint64(0), response.AppVersion) + return testApp +} + +func createRequest() abci.RequestOfferSnapshot { + return abci.RequestOfferSnapshot{ + // Snapshot was created by logging the contents of OfferSnapshot on a + // node that was syncing via state sync. + Snapshot: &abci.Snapshot{ + Height: 0x1b07ec, + Format: 0x2, + Chunks: 0x1, + Hash: []uint8{0xaf, 0xa5, 0xe, 0x16, 0x45, 0x4, 0x2e, 0x45, 0xd3, 0x49, 0xdf, 0x83, 0x2a, 0x57, 0x9d, 0x64, 0xc8, 0xad, 0xa5, 0xb, 0x65, 0x1b, 0x46, 0xd6, 0xc3, 0x85, 0x6, 0x51, 0xd7, 0x45, 0x8e, 0xb8}, + Metadata: []uint8{0xa, 0x20, 0xaf, 0xa5, 0xe, 0x16, 0x45, 0x4, 0x2e, 0x45, 0xd3, 0x49, 0xdf, 0x83, 0x2a, 0x57, 0x9d, 0x64, 0xc8, 0xad, 0xa5, 0xb, 0x65, 0x1b, 0x46, 0xd6, 0xc3, 0x85, 0x6, 0x51, 0xd7, 0x45, 0x8e, 0xb8}, + }, + AppHash: []byte("apphash"), + AppVersion: 0, // unit tests will override this + } +} + // NoopWriter is a no-op implementation of a writer. type NoopWriter struct{} diff --git a/app/benchmarks/README.md b/app/benchmarks/README.md new file mode 100644 index 0000000000..f7f720741b --- /dev/null +++ b/app/benchmarks/README.md @@ -0,0 +1,27 @@ +# Benchmarks + +This package contains benchmarks for the ABCI methods with the following transaction types: + +- Message send +- IBC update client +- PayForBlobs + +## How to run + +To run the benchmarks, run the following in the root directory: + +```shell +go test -tags=bench_abci_methods -bench= app/benchmarks/benchmark_* +``` + +## Results + +The results are outlined in the [results](results.md) document. + +## Key takeaways + +We decided to softly limit the number of messages contained in a block, via introducing the `MaxPFBMessages` and `MaxNonPFBMessages`, and checking against them in prepare proposal. + +This way, the default block construction mechanism will only propose blocks that respect these limitations. And if a block that doesn't respect them reached consensus, it will still be accepted since this rule is not consensus breaking. + +As specified in [results](results.md) document, those results were generated on 16 core 48GB RAM machine, and gave us certain thresholds. However, when we run the same experiments on the recommended validator setup, 4 cores 16GB RAM, the numbers were lower. These low numbers are what we used in the limits. diff --git a/app/benchmarks/benchmark_ibc_update_client_test.go b/app/benchmarks/benchmark_ibc_update_client_test.go new file mode 100644 index 0000000000..873c560a95 --- /dev/null +++ b/app/benchmarks/benchmark_ibc_update_client_test.go @@ -0,0 +1,518 @@ +//go:build bench_abci_methods + +package benchmarks_test + +import ( + "fmt" + "math" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + testutil "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" + dbm "github.com/cometbft/cometbft-db" + sdk "github.com/cosmos/cosmos-sdk/types" + types3 "github.com/cosmos/ibc-go/v6/modules/core/02-client/types" + types2 "github.com/cosmos/ibc-go/v6/modules/core/23-commitment/types" + types4 "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/tmhash" + crypto2 "github.com/tendermint/tendermint/proto/tendermint/crypto" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmprotoversion "github.com/tendermint/tendermint/proto/tendermint/version" + "github.com/tendermint/tendermint/version" + + "github.com/tendermint/tendermint/crypto/ed25519" + sm "github.com/tendermint/tendermint/state" + types0 "github.com/tendermint/tendermint/types" +) + +func BenchmarkIBC_CheckTx_Update_Client_Multi(b *testing.B) { + testCases := []struct { + numberOfValidators int + }{ + {numberOfValidators: 2}, + {numberOfValidators: 10}, + {numberOfValidators: 25}, + {numberOfValidators: 50}, + {numberOfValidators: 75}, + {numberOfValidators: 100}, + {numberOfValidators: 125}, + {numberOfValidators: 150}, + {numberOfValidators: 175}, + {numberOfValidators: 200}, + {numberOfValidators: 225}, + {numberOfValidators: 250}, + {numberOfValidators: 300}, + {numberOfValidators: 400}, + {numberOfValidators: 500}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("number of validators: %d", testCase.numberOfValidators), func(b *testing.B) { + benchmarkIBCCheckTxUpdateClient(b, testCase.numberOfValidators) + }) + } +} + +func benchmarkIBCCheckTxUpdateClient(b *testing.B, numberOfValidators int) { + testApp, rawTxs := generateIBCUpdateClientTransaction(b, numberOfValidators, 1, 1) + testApp.Commit() + + checkTxRequest := types.RequestCheckTx{ + Type: types.CheckTxType_New, + Tx: rawTxs[0], + } + + b.ResetTimer() + resp := testApp.CheckTx(checkTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") + b.ReportMetric(float64(len(rawTxs[0])), "transaction_size(byte)") + b.ReportMetric(float64(numberOfValidators), "number_of_validators") + b.ReportMetric(float64(2*numberOfValidators/3), "number_of_verified_signatures") +} + +func BenchmarkIBC_DeliverTx_Update_Client_Multi(b *testing.B) { + testCases := []struct { + numberOfValidators int + }{ + {numberOfValidators: 2}, + {numberOfValidators: 10}, + {numberOfValidators: 25}, + {numberOfValidators: 50}, + {numberOfValidators: 75}, + {numberOfValidators: 100}, + {numberOfValidators: 125}, + {numberOfValidators: 150}, + {numberOfValidators: 175}, + {numberOfValidators: 200}, + {numberOfValidators: 225}, + {numberOfValidators: 250}, + {numberOfValidators: 300}, + {numberOfValidators: 400}, + {numberOfValidators: 500}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("number of validators: %d", testCase.numberOfValidators), func(b *testing.B) { + benchmarkIBCDeliverTxUpdateClient(b, testCase.numberOfValidators) + }) + } +} + +func benchmarkIBCDeliverTxUpdateClient(b *testing.B, numberOfValidators int) { + testApp, rawTxs := generateIBCUpdateClientTransaction(b, numberOfValidators, 1, 1) + + deliverTxRequest := types.RequestDeliverTx{ + Tx: rawTxs[0], + } + + b.ResetTimer() + resp := testApp.DeliverTx(deliverTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") + b.ReportMetric(float64(len(rawTxs[0])), "transaction_size(byte)") + b.ReportMetric(float64(numberOfValidators), "number_of_validators") + b.ReportMetric(float64(2*numberOfValidators/3), "number_of_verified_signatures") +} + +func BenchmarkIBC_PrepareProposal_Update_Client_Multi(b *testing.B) { + testCases := []struct { + numberOfTransactions, numberOfValidators int + }{ + {numberOfTransactions: 6_000, numberOfValidators: 2}, + {numberOfTransactions: 3_000, numberOfValidators: 10}, + {numberOfTransactions: 2_000, numberOfValidators: 25}, + {numberOfTransactions: 1_000, numberOfValidators: 50}, + {numberOfTransactions: 500, numberOfValidators: 75}, + {numberOfTransactions: 500, numberOfValidators: 100}, + {numberOfTransactions: 500, numberOfValidators: 125}, + {numberOfTransactions: 500, numberOfValidators: 150}, + {numberOfTransactions: 500, numberOfValidators: 175}, + {numberOfTransactions: 500, numberOfValidators: 200}, + {numberOfTransactions: 500, numberOfValidators: 225}, + {numberOfTransactions: 500, numberOfValidators: 250}, + {numberOfTransactions: 500, numberOfValidators: 300}, + {numberOfTransactions: 500, numberOfValidators: 400}, + {numberOfTransactions: 500, numberOfValidators: 500}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("number of validators: %d", testCase.numberOfValidators), func(b *testing.B) { + benchmarkIBCPrepareProposalUpdateClient(b, testCase.numberOfValidators, testCase.numberOfTransactions) + }) + } +} + +func benchmarkIBCPrepareProposalUpdateClient(b *testing.B, numberOfValidators, count int) { + testApp, rawTxs := generateIBCUpdateClientTransaction(b, numberOfValidators, count, 0) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + + b.ResetTimer() + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + b.StopTimer() + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + b.ReportMetric(float64(b.Elapsed().Nanoseconds()), "prepare_proposal_time(ns)") + b.ReportMetric(float64(len(prepareProposalResponse.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(float64(len(rawTxs[0])), "transactions_size(byte)") + b.ReportMetric(calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs), "block_size(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, prepareProposalResponse.BlockData.Txs)), "total_gas_used") + b.ReportMetric(float64(numberOfValidators), "number_of_validators") + b.ReportMetric(float64(2*numberOfValidators/3), "number_of_verified_signatures") +} + +func BenchmarkIBC_ProcessProposal_Update_Client_Multi(b *testing.B) { + testCases := []struct { + numberOfTransactions, numberOfValidators int + }{ + {numberOfTransactions: 6_000, numberOfValidators: 2}, + {numberOfTransactions: 3_000, numberOfValidators: 10}, + {numberOfTransactions: 2_000, numberOfValidators: 25}, + {numberOfTransactions: 1_000, numberOfValidators: 50}, + {numberOfTransactions: 500, numberOfValidators: 75}, + {numberOfTransactions: 500, numberOfValidators: 100}, + {numberOfTransactions: 500, numberOfValidators: 125}, + {numberOfTransactions: 500, numberOfValidators: 150}, + {numberOfTransactions: 500, numberOfValidators: 175}, + {numberOfTransactions: 500, numberOfValidators: 200}, + {numberOfTransactions: 500, numberOfValidators: 225}, + {numberOfTransactions: 500, numberOfValidators: 250}, + {numberOfTransactions: 500, numberOfValidators: 300}, + {numberOfTransactions: 500, numberOfValidators: 400}, + {numberOfTransactions: 500, numberOfValidators: 500}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("number of validators: %d", testCase.numberOfValidators), func(b *testing.B) { + benchmarkIBCProcessProposalUpdateClient(b, testCase.numberOfValidators, testCase.numberOfTransactions) + }) + } +} + +func benchmarkIBCProcessProposalUpdateClient(b *testing.B, numberOfValidators, count int) { + testApp, rawTxs := generateIBCUpdateClientTransaction(b, numberOfValidators, count, 0) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 10, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: tmprotoversion.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + b.ResetTimer() + resp := testApp.ProcessProposal(processProposalRequest) + b.StopTimer() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + b.ReportMetric(float64(b.Elapsed().Nanoseconds()), "process_proposal_time(ns)") + b.ReportMetric(float64(len(prepareProposalResponse.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(float64(len(rawTxs[0])), "transactions_size(byte)") + b.ReportMetric(calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs), "block_size(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, prepareProposalResponse.BlockData.Txs)), "total_gas_used") + b.ReportMetric(float64(numberOfValidators), "number_of_validators") + b.ReportMetric(float64(2*numberOfValidators/3), "number_of_verified_signatures") +} + +// generateIBCUpdateClientTransaction creates a test app then generates an IBC +// update client transaction with the specified number of validators. +// Note: the number of the verified signatures is: 2 * numberOfValidators / 3 +// the offset is just a hack for transactions to be processed by the needed +// ABCI method. +func generateIBCUpdateClientTransaction(b *testing.B, numberOfValidators int, numberOfMessages int, offsetAccountSequence int) (*app.App, [][]byte) { + account := "test" + testApp, kr := testutil.SetupTestAppWithGenesisValSetAndMaxSquareSize(app.DefaultConsensusParams(), 128, account) + addr := testfactory.GetAddress(kr, account) + enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) + acc := testutil.DirectQueryAccount(testApp, addr) + signer, err := user.NewSigner(kr, enc.TxConfig, testutil.ChainID, appconsts.LatestVersion, user.NewAccount(account, acc.GetAccountNumber(), acc.GetSequence())) + require.NoError(b, err) + + msgs := generateUpdateClientTransaction( + b, + testApp, + *signer, + acc.GetAddress().String(), + account, + numberOfValidators, + numberOfMessages, + ) + + accountSequence := testutil.DirectQueryAccount(testApp, addr).GetSequence() + err = signer.SetSequence(account, accountSequence+uint64(offsetAccountSequence)) + require.NoError(b, err) + rawTxs := make([][]byte, 0, numberOfMessages) + for i := 0; i < numberOfMessages; i++ { + rawTx, err := signer.CreateTx([]sdk.Msg{msgs[i]}, user.SetGasLimit(25497600000), user.SetFee(100000)) + require.NoError(b, err) + rawTxs = append(rawTxs, rawTx) + accountSequence++ + err = signer.SetSequence(account, accountSequence) + require.NoError(b, err) + } + + return testApp, rawTxs +} + +func generateUpdateClientTransaction(b *testing.B, app *app.App, signer user.Signer, signerAddr string, signerName string, numberOfValidators int, numberOfMsgs int) []*types3.MsgUpdateClient { + state, _, privVals := makeState(numberOfValidators, 5) + wBefore := time.Now() + time.Sleep(time.Second) + w := time.Now() + lastResultHash := crypto.CRandBytes(tmhash.Size) + lastCommitHash := crypto.CRandBytes(tmhash.Size) + lastBlockHash := crypto.CRandBytes(tmhash.Size) + lastBlockID := makeBlockID(lastBlockHash, 1000, []byte("hash")) + header := tmproto.Header{ + Version: tmprotoversion.Consensus{Block: version.BlockProtocol, App: 1}, + ChainID: state.ChainID, + Height: 5, + Time: w, + LastCommitHash: lastCommitHash, + DataHash: crypto.CRandBytes(tmhash.Size), + ValidatorsHash: state.Validators.Hash(), + NextValidatorsHash: state.Validators.Hash(), + ConsensusHash: crypto.CRandBytes(tmhash.Size), + AppHash: crypto.CRandBytes(tmhash.Size), + LastResultsHash: lastResultHash, + EvidenceHash: crypto.CRandBytes(tmhash.Size), + ProposerAddress: crypto.CRandBytes(crypto.AddressSize), + LastBlockId: lastBlockID.ToProto(), + } + t := types0.Header{ + Version: tmprotoversion.Consensus{Block: version.BlockProtocol, App: 1}, + ChainID: state.ChainID, + Height: 5, + Time: w, + LastCommitHash: header.LastCommitHash, + DataHash: header.DataHash, + ValidatorsHash: header.ValidatorsHash, + NextValidatorsHash: header.NextValidatorsHash, + ConsensusHash: header.ConsensusHash, + AppHash: header.AppHash, + LastResultsHash: header.LastResultsHash, + EvidenceHash: header.EvidenceHash, + ProposerAddress: header.ProposerAddress, + LastBlockID: lastBlockID, + } + header0Hash := t.Hash() + blockID := makeBlockID(header0Hash, 1000, []byte("partshash")) + commit, err := makeValidCommit(5, blockID, state.Validators, privVals) + require.NoError(b, err) + signatures := make([]tmproto.CommitSig, numberOfValidators) + validators := make([]*tmproto.Validator, numberOfValidators) + for i := 0; i < numberOfValidators; i++ { + signatures[i] = tmproto.CommitSig{ + BlockIdFlag: tmproto.BlockIDFlag(commit.Signatures[i].BlockIDFlag), + ValidatorAddress: commit.Signatures[i].ValidatorAddress, + Timestamp: commit.Signatures[i].Timestamp, + Signature: commit.Signatures[i].Signature, + } + validators[i] = &tmproto.Validator{ + Address: state.Validators.Validators[i].Address, + PubKey: crypto2.PublicKey{Sum: &crypto2.PublicKey_Ed25519{Ed25519: state.Validators.Validators[i].PubKey.Bytes()}}, + VotingPower: state.Validators.Validators[i].VotingPower, + ProposerPriority: state.Validators.Validators[i].ProposerPriority, + } + } + sh := tmproto.SignedHeader{ + Header: &header, + Commit: &tmproto.Commit{ + Height: commit.Height, + Round: commit.Round, + BlockID: tmproto.BlockID{ + Hash: header0Hash, + PartSetHeader: tmproto.PartSetHeader{ + Total: commit.BlockID.PartSetHeader.Total, + Hash: commit.BlockID.PartSetHeader.Hash, + }, + }, + Signatures: signatures, + }, + } + clientState := types4.ClientState{ + ChainId: chainID, + TrustLevel: types4.Fraction{Numerator: 1, Denominator: 3}, + TrustingPeriod: time.Hour * 24 * 21 * 100, // we want to always accept the upgrade + UnbondingPeriod: time.Hour * 24 * 21 * 101, + MaxClockDrift: math.MaxInt64 - 1, + FrozenHeight: types3.Height{}, + LatestHeight: types3.Height{ + RevisionNumber: 0, + RevisionHeight: 4, + }, + ProofSpecs: types2.GetSDKSpecs(), + AllowUpdateAfterExpiry: true, + AllowUpdateAfterMisbehaviour: true, + } + consensusState := types4.ConsensusState{ + Timestamp: wBefore, + Root: types2.MerkleRoot{Hash: lastBlockHash}, + NextValidatorsHash: state.Validators.Hash(), + } + + msgs := make([]*types3.MsgUpdateClient, numberOfMsgs) + for index := 0; index < numberOfMsgs; index++ { + createClientMsg, err := types3.NewMsgCreateClient(&clientState, &consensusState, signerAddr) + require.NoError(b, err) + rawTx, err := signer.CreateTx([]sdk.Msg{createClientMsg}, user.SetGasLimit(2549760000), user.SetFee(10000)) + require.NoError(b, err) + resp := app.DeliverTx(types.RequestDeliverTx{Tx: rawTx}) + var clientName string + for _, event := range resp.Events { + if event.Type == types3.EventTypeCreateClient { + for _, attribute := range event.Attributes { + if string(attribute.Key) == types3.AttributeKeyClientID { + clientName = string(attribute.Value) + } + } + } + } + require.NotEmpty(b, clientName) + + msg, err := types3.NewMsgUpdateClient( + clientName, + &types4.Header{ + SignedHeader: &sh, + ValidatorSet: &tmproto.ValidatorSet{ + Validators: validators, + Proposer: &tmproto.Validator{ + Address: state.Validators.Proposer.Address, + PubKey: crypto2.PublicKey{Sum: &crypto2.PublicKey_Ed25519{Ed25519: state.Validators.Proposer.PubKey.Bytes()}}, + VotingPower: state.Validators.Proposer.VotingPower, + ProposerPriority: state.Validators.Proposer.ProposerPriority, + }, + TotalVotingPower: state.Validators.TotalVotingPower(), + }, + TrustedHeight: types3.Height{ + RevisionNumber: 0, + RevisionHeight: 4, + }, + TrustedValidators: &tmproto.ValidatorSet{ + Validators: validators, + Proposer: &tmproto.Validator{ + Address: state.Validators.Proposer.Address, + PubKey: crypto2.PublicKey{Sum: &crypto2.PublicKey_Ed25519{Ed25519: state.Validators.Proposer.PubKey.Bytes()}}, + VotingPower: state.Validators.Proposer.VotingPower, + ProposerPriority: state.Validators.Proposer.ProposerPriority, + }, + TotalVotingPower: state.Validators.TotalVotingPower(), + }, + }, + signerAddr, + ) + require.NoError(b, err) + msgs[index] = msg + err = signer.IncrementSequence(signerName) + require.NoError(b, err) + } + + return msgs +} + +var chainID = "test" + +func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types0.PrivValidator) { + vals := make([]types0.GenesisValidator, nVals) + privVals := make(map[string]types0.PrivValidator, nVals) + for i := 0; i < nVals; i++ { + secret := []byte(fmt.Sprintf("test%d", i)) + pk := ed25519.GenPrivKeyFromSecret(secret) + valAddr := pk.PubKey().Address() + vals[i] = types0.GenesisValidator{ + Address: valAddr, + PubKey: pk.PubKey(), + Power: 1000, + Name: fmt.Sprintf("test%d", i), + } + privVals[valAddr.String()] = types0.NewMockPVWithParams(pk, false, false) + } + s, _ := sm.MakeGenesisState(&types0.GenesisDoc{ + ChainID: chainID, + Validators: vals, + AppHash: nil, + }) + + stateDB := dbm.NewMemDB() + stateStore := sm.NewStore(stateDB, sm.StoreOptions{ + DiscardABCIResponses: false, + }) + if err := stateStore.Save(s); err != nil { + panic(err) + } + + for i := 1; i < height; i++ { + s.LastBlockHeight++ + s.LastValidators = s.Validators.Copy() + if err := stateStore.Save(s); err != nil { + panic(err) + } + } + + return s, stateDB, privVals +} + +func makeValidCommit( + height int64, + blockID types0.BlockID, + vals *types0.ValidatorSet, + privVals map[string]types0.PrivValidator, +) (*types0.Commit, error) { + sigs := make([]types0.CommitSig, 0) + for i := 0; i < vals.Size(); i++ { + _, val := vals.GetByIndex(int32(i)) + vote, err := types0.MakeVote(height, blockID, vals, privVals[val.Address.String()], chainID, time.Now()) + if err != nil { + return nil, err + } + sigs = append(sigs, vote.CommitSig()) + } + return types0.NewCommit(height, 0, blockID, sigs), nil +} + +func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types0.BlockID { + var ( + h = make([]byte, tmhash.Size) + psH = make([]byte, tmhash.Size) + ) + copy(h, hash) + copy(psH, partSetHash) + return types0.BlockID{ + Hash: h, + PartSetHeader: types0.PartSetHeader{ + Total: partSetSize, + Hash: psH, + }, + } +} diff --git a/app/benchmarks/benchmark_msg_send_test.go b/app/benchmarks/benchmark_msg_send_test.go new file mode 100644 index 0000000000..7e79db9a67 --- /dev/null +++ b/app/benchmarks/benchmark_msg_send_test.go @@ -0,0 +1,333 @@ +//go:build bench_abci_methods + +package benchmarks_test + +import ( + "fmt" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + testutil "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proto/tendermint/version" +) + +func BenchmarkCheckTx_MsgSend_1(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 1) + testApp.Commit() + + checkTxRequest := types.RequestCheckTx{ + Tx: rawTxs[0], + Type: types.CheckTxType_New, + } + + b.ResetTimer() + resp := testApp.CheckTx(checkTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") +} + +func BenchmarkCheckTx_MsgSend_8MB(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 31645) + testApp.Commit() + + var totalGas int64 + b.ResetTimer() + for _, tx := range rawTxs { + checkTxRequest := types.RequestCheckTx{ + Tx: tx, + Type: types.CheckTxType_New, + } + b.StartTimer() + resp := testApp.CheckTx(checkTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + totalGas += resp.GasUsed + } + + b.StopTimer() + b.ReportMetric(float64(totalGas), "total_gas_used") +} + +func BenchmarkDeliverTx_MsgSend_1(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 1) + + deliverTxRequest := types.RequestDeliverTx{ + Tx: rawTxs[0], + } + + b.ResetTimer() + resp := testApp.DeliverTx(deliverTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") +} + +func BenchmarkDeliverTx_MsgSend_8MB(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 31645) + + var totalGas int64 + b.ResetTimer() + for _, tx := range rawTxs { + deliverTxRequest := types.RequestDeliverTx{ + Tx: tx, + } + b.StartTimer() + resp := testApp.DeliverTx(deliverTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + totalGas += resp.GasUsed + } + b.StopTimer() + b.ReportMetric(float64(totalGas), "total_gas_used") +} + +func BenchmarkPrepareProposal_MsgSend_1(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 1) + + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: &tmproto.Data{ + Txs: rawTxs, + }, + ChainId: testApp.GetChainID(), + Height: 10, + } + + b.ResetTimer() + resp := testApp.PrepareProposal(prepareProposalRequest) + b.StopTimer() + require.GreaterOrEqual(b, len(resp.BlockData.Txs), 1) + b.ReportMetric(float64(calculateTotalGasUsed(testApp, resp.BlockData.Txs)), "total_gas_used") +} + +func BenchmarkPrepareProposal_MsgSend_8MB(b *testing.B) { + // a full 8mb block equals to around 31645 msg send transactions. + // using 31645 to let prepare proposal choose the maximum + testApp, rawTxs := generateMsgSendTransactions(b, 31645) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + + b.ResetTimer() + resp := testApp.PrepareProposal(prepareProposalRequest) + b.StopTimer() + require.GreaterOrEqual(b, len(resp.BlockData.Txs), 1) + b.ReportMetric(float64(len(resp.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(calculateBlockSizeInMb(resp.BlockData.Txs), "block_size(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, resp.BlockData.Txs)), "total_gas_used") +} + +func BenchmarkProcessProposal_MsgSend_1(b *testing.B) { + testApp, rawTxs := generateMsgSendTransactions(b, 1) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 1, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: version.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + b.ResetTimer() + resp := testApp.ProcessProposal(processProposalRequest) + b.StopTimer() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + b.ReportMetric(float64(calculateTotalGasUsed(testApp, prepareProposalResponse.BlockData.Txs)), "total_gas_used") +} + +func BenchmarkProcessProposal_MsgSend_8MB(b *testing.B) { + // a full 8mb block equals to around 31645 msg send transactions. + // using 31645 to let prepare proposal choose the maximum + testApp, rawTxs := generateMsgSendTransactions(b, 31645) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + b.ReportMetric(float64(len(prepareProposalResponse.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs), "block_size_(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, prepareProposalResponse.BlockData.Txs)), "total_gas_used") + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 10, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: version.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + b.ResetTimer() + resp := testApp.ProcessProposal(processProposalRequest) + b.StopTimer() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + b.ReportMetric(float64(calculateTotalGasUsed(testApp, prepareProposalResponse.BlockData.Txs)), "total_gas_used") +} + +func BenchmarkProcessProposal_MsgSend_8MB_Find_Half_Sec(b *testing.B) { + targetTimeLowerBound := 0.499 + targetTimeUpperBound := 0.511 + numberOfTransaction := 5500 + testApp, rawTxs := generateMsgSendTransactions(b, numberOfTransaction) + start := 0 + end := numberOfTransaction + segment := end - start + for { + if segment == 1 { + break + } + + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: &tmproto.Data{ + Txs: rawTxs[start:end], + }, + ChainId: testApp.GetChainID(), + Height: 10, + } + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 10, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: version.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + startTime := time.Now() + resp := testApp.ProcessProposal(processProposalRequest) + endTime := time.Now() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + timeElapsed := float64(endTime.Sub(startTime).Nanoseconds()) / 1e9 + + switch { + case timeElapsed < targetTimeLowerBound: + newEnd := end + segment/2 + if newEnd > len(rawTxs) { + newEnd = len(rawTxs) + } + end = newEnd + segment = end - start + if segment <= 1 { + break + } + continue + case timeElapsed > targetTimeUpperBound: + newEnd := end / 2 + if newEnd <= start { + break + } + end = newEnd + segment = end - start + continue + default: + b.ReportMetric(timeElapsed, fmt.Sprintf("elapsedTime(s)_%d", end-start)) + } + break + } +} + +// generateMsgSendTransactions creates a test app then generates a number +// of valid msg send transactions. +func generateMsgSendTransactions(b *testing.B, count int) (*app.App, [][]byte) { + account := "test" + testApp, kr := testutil.SetupTestAppWithGenesisValSetAndMaxSquareSize(app.DefaultConsensusParams(), 128, account) + addr := testfactory.GetAddress(kr, account) + enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) + acc := testutil.DirectQueryAccount(testApp, addr) + signer, err := user.NewSigner(kr, enc.TxConfig, testutil.ChainID, appconsts.LatestVersion, user.NewAccount(account, acc.GetAccountNumber(), acc.GetSequence())) + require.NoError(b, err) + rawTxs := make([][]byte, 0, count) + for i := 0; i < count; i++ { + msg := banktypes.NewMsgSend( + addr, + testnode.RandomAddress().(sdk.AccAddress), + sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, 10)), + ) + rawTx, err := signer.CreateTx([]sdk.Msg{msg}, user.SetGasLimit(1000000), user.SetFee(10)) + require.NoError(b, err) + rawTxs = append(rawTxs, rawTx) + err = signer.IncrementSequence(account) + require.NoError(b, err) + } + return testApp, rawTxs +} + +// mebibyte the number of bytes in a mebibyte +const mebibyte = 1048576 + +// calculateBlockSizeInMb returns the block size in mb given a set +// of raw transactions. +func calculateBlockSizeInMb(txs [][]byte) float64 { + numberOfBytes := 0 + for _, tx := range txs { + numberOfBytes += len(tx) + } + mb := float64(numberOfBytes) / mebibyte + return mb +} + +// calculateTotalGasUsed simulates the provided transactions and returns the +// total gas used by all of them +func calculateTotalGasUsed(testApp *app.App, txs [][]byte) uint64 { + var totalGas uint64 + for _, tx := range txs { + gasInfo, _, _ := testApp.Simulate(tx) + totalGas += gasInfo.GasUsed + } + return totalGas +} diff --git a/app/benchmarks/benchmark_pfb_test.go b/app/benchmarks/benchmark_pfb_test.go new file mode 100644 index 0000000000..274dbf8353 --- /dev/null +++ b/app/benchmarks/benchmark_pfb_test.go @@ -0,0 +1,381 @@ +//go:build bench_abci_methods + +package benchmarks_test + +import ( + "fmt" + "testing" + "time" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/libs/log" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + testutil "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" + "github.com/celestiaorg/go-square/v2/share" + blobtx "github.com/celestiaorg/go-square/v2/tx" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proto/tendermint/version" +) + +func init() { + testutil.TestAppLogger = log.NewNopLogger() +} + +func BenchmarkCheckTx_PFB_Multi(b *testing.B) { + testCases := []struct { + blobSize int + }{ + {blobSize: 300}, + {blobSize: 500}, + {blobSize: 1000}, + {blobSize: 5000}, + {blobSize: 10_000}, + {blobSize: 50_000}, + {blobSize: 100_000}, + {blobSize: 200_000}, + {blobSize: 300_000}, + {blobSize: 400_000}, + {blobSize: 500_000}, + {blobSize: 1_000_000}, + {blobSize: 2_000_000}, + {blobSize: 3_000_000}, + {blobSize: 4_000_000}, + {blobSize: 5_000_000}, + {blobSize: 6_000_000}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("%d bytes", testCase.blobSize), func(b *testing.B) { + benchmarkCheckTxPFB(b, testCase.blobSize) + }) + } +} + +func benchmarkCheckTxPFB(b *testing.B, size int) { + testApp, rawTxs := generatePayForBlobTransactions(b, 1, size) + testApp.Commit() + + checkTxRequest := types.RequestCheckTx{ + Tx: rawTxs[0], + Type: types.CheckTxType_New, + } + + b.ResetTimer() + resp := testApp.CheckTx(checkTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") + b.ReportMetric(float64(len(rawTxs[0])), "transaction_size(byte)") +} + +func BenchmarkDeliverTx_PFB_Multi(b *testing.B) { + testCases := []struct { + blobSize int + }{ + {blobSize: 300}, + {blobSize: 500}, + {blobSize: 1000}, + {blobSize: 5000}, + {blobSize: 10_000}, + {blobSize: 50_000}, + {blobSize: 100_000}, + {blobSize: 200_000}, + {blobSize: 300_000}, + {blobSize: 400_000}, + {blobSize: 500_000}, + {blobSize: 1_000_000}, + {blobSize: 2_000_000}, + {blobSize: 3_000_000}, + {blobSize: 4_000_000}, + {blobSize: 5_000_000}, + {blobSize: 6_000_000}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("%d bytes", testCase.blobSize), func(b *testing.B) { + benchmarkDeliverTxPFB(b, testCase.blobSize) + }) + } +} + +func benchmarkDeliverTxPFB(b *testing.B, size int) { + testApp, rawTxs := generatePayForBlobTransactions(b, 1, size) + + blobTx, ok, err := blobtx.UnmarshalBlobTx(rawTxs[0]) + require.NoError(b, err) + require.True(b, ok) + + deliverTxRequest := types.RequestDeliverTx{ + Tx: blobTx.Tx, + } + + b.ResetTimer() + resp := testApp.DeliverTx(deliverTxRequest) + b.StopTimer() + require.Equal(b, uint32(0), resp.Code) + require.Equal(b, "", resp.Codespace) + b.ReportMetric(float64(resp.GasUsed), "gas_used") + b.ReportMetric(float64(len(rawTxs[0])), "transaction_size(byte)") +} + +func BenchmarkPrepareProposal_PFB_Multi(b *testing.B) { + testCases := []struct { + numberOfTransactions, blobSize int + }{ + {numberOfTransactions: 15_000, blobSize: 300}, + {numberOfTransactions: 10_000, blobSize: 500}, + {numberOfTransactions: 6_000, blobSize: 1000}, + {numberOfTransactions: 3_000, blobSize: 5000}, + {numberOfTransactions: 1_000, blobSize: 10_000}, + {numberOfTransactions: 500, blobSize: 50_000}, + {numberOfTransactions: 100, blobSize: 100_000}, + {numberOfTransactions: 100, blobSize: 200_000}, + {numberOfTransactions: 50, blobSize: 300_000}, + {numberOfTransactions: 50, blobSize: 400_000}, + {numberOfTransactions: 30, blobSize: 500_000}, + {numberOfTransactions: 10, blobSize: 1_000_000}, + {numberOfTransactions: 5, blobSize: 2_000_000}, + {numberOfTransactions: 3, blobSize: 3_000_000}, + {numberOfTransactions: 3, blobSize: 4_000_000}, + {numberOfTransactions: 2, blobSize: 5_000_000}, + {numberOfTransactions: 2, blobSize: 6_000_000}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("%d transactions of %d bytes", testCase.numberOfTransactions, testCase.blobSize), func(b *testing.B) { + benchmarkPrepareProposalPFB(b, testCase.numberOfTransactions, testCase.blobSize) + }) + } +} + +func benchmarkPrepareProposalPFB(b *testing.B, count, size int) { + testApp, rawTxs := generatePayForBlobTransactions(b, count, size) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + + b.ResetTimer() + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + b.StopTimer() + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + b.ReportMetric(float64(b.Elapsed().Nanoseconds()), "prepare_proposal_time(ns)") + b.ReportMetric(float64(len(prepareProposalResponse.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(float64(len(rawTxs[0])), "transactions_size(byte)") + b.ReportMetric(calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs), "block_size(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, rawTxs)), "total_gas_used") +} + +func BenchmarkProcessProposal_PFB_Multi(b *testing.B) { + testCases := []struct { + numberOfTransactions, blobSize int + }{ + {numberOfTransactions: 15_000, blobSize: 300}, + {numberOfTransactions: 10_000, blobSize: 500}, + {numberOfTransactions: 6_000, blobSize: 1000}, + {numberOfTransactions: 3_000, blobSize: 5000}, + {numberOfTransactions: 1_000, blobSize: 10_000}, + {numberOfTransactions: 500, blobSize: 50_000}, + {numberOfTransactions: 100, blobSize: 100_000}, + {numberOfTransactions: 100, blobSize: 200_000}, + {numberOfTransactions: 50, blobSize: 300_000}, + {numberOfTransactions: 50, blobSize: 400_000}, + {numberOfTransactions: 30, blobSize: 500_000}, + {numberOfTransactions: 10, blobSize: 1_000_000}, + {numberOfTransactions: 5, blobSize: 2_000_000}, + {numberOfTransactions: 3, blobSize: 3_000_000}, + {numberOfTransactions: 3, blobSize: 4_000_000}, + {numberOfTransactions: 2, blobSize: 5_000_000}, + {numberOfTransactions: 2, blobSize: 6_000_000}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("%d transactions of %d bytes", testCase.numberOfTransactions, testCase.blobSize), func(b *testing.B) { + benchmarkProcessProposalPFB(b, testCase.numberOfTransactions, testCase.blobSize) + }) + } +} + +func benchmarkProcessProposalPFB(b *testing.B, count, size int) { + testApp, rawTxs := generatePayForBlobTransactions(b, count, size) + + blockData := &tmproto.Data{ + Txs: rawTxs, + } + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: blockData, + ChainId: testApp.GetChainID(), + Height: 10, + } + + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 10, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: version.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + b.ResetTimer() + resp := testApp.ProcessProposal(processProposalRequest) + b.StopTimer() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + b.ReportMetric(float64(b.Elapsed().Nanoseconds()), "process_proposal_time(ns)") + b.ReportMetric(float64(len(prepareProposalResponse.BlockData.Txs)), "number_of_transactions") + b.ReportMetric(float64(len(rawTxs[0])), "transactions_size(byte)") + b.ReportMetric(calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs), "block_size(mb)") + b.ReportMetric(float64(calculateTotalGasUsed(testApp, rawTxs)), "total_gas_used") +} + +func BenchmarkProcessProposal_PFB_Half_Second(b *testing.B) { + testCases := []struct { + numberOfTransactions, blobSize int + }{ + {numberOfTransactions: 11_000, blobSize: 50}, + {numberOfTransactions: 11_000, blobSize: 100}, + {numberOfTransactions: 11_000, blobSize: 200}, + {numberOfTransactions: 11_000, blobSize: 300}, + {numberOfTransactions: 11_000, blobSize: 400}, + {numberOfTransactions: 7000, blobSize: 500}, + {numberOfTransactions: 7000, blobSize: 600}, + {numberOfTransactions: 5000, blobSize: 1_000}, + {numberOfTransactions: 5000, blobSize: 1200}, + {numberOfTransactions: 5000, blobSize: 1500}, + {numberOfTransactions: 5000, blobSize: 1800}, + {numberOfTransactions: 5000, blobSize: 2000}, + } + for _, testCase := range testCases { + b.Run(fmt.Sprintf("%d transactions of %d bytes", testCase.numberOfTransactions, testCase.blobSize), func(b *testing.B) { + benchmarkProcessProposalPFBHalfSecond(b, testCase.numberOfTransactions, testCase.blobSize) + }) + } +} + +func benchmarkProcessProposalPFBHalfSecond(b *testing.B, count, size int) { + testApp, rawTxs := generatePayForBlobTransactions(b, count, size) + + targetTimeLowerBound := 0.499 + targetTimeUpperBound := 0.511 + + start := 0 + end := count + segment := end - start + maxIterations := 100000 + iterations := 0 + for { + iterations++ + if iterations >= maxIterations { + b.Errorf("Maximum iterations reached without achieving target processing time") + break + } + if segment == 1 { + break + } + + prepareProposalRequest := types.RequestPrepareProposal{ + BlockData: &tmproto.Data{ + Txs: rawTxs[start:end], + }, + ChainId: testApp.GetChainID(), + Height: 10, + } + prepareProposalResponse := testApp.PrepareProposal(prepareProposalRequest) + require.GreaterOrEqual(b, len(prepareProposalResponse.BlockData.Txs), 1) + + processProposalRequest := types.RequestProcessProposal{ + BlockData: prepareProposalResponse.BlockData, + Header: tmproto.Header{ + Height: 10, + DataHash: prepareProposalResponse.BlockData.Hash, + ChainID: testutil.ChainID, + Version: version.Consensus{ + App: testApp.AppVersion(), + }, + }, + } + + startTime := time.Now() + resp := testApp.ProcessProposal(processProposalRequest) + endTime := time.Now() + require.Equal(b, types.ResponseProcessProposal_ACCEPT, resp.Result) + + timeElapsed := float64(endTime.Sub(startTime).Nanoseconds()) / 1e9 + + switch { + case timeElapsed < targetTimeLowerBound: + newEnd := end + segment/2 + if newEnd > len(rawTxs) { + newEnd = len(rawTxs) + } + end = newEnd + segment = end - start + if segment <= 1 { + break + } + continue + case timeElapsed > targetTimeUpperBound: + newEnd := end / 2 + if newEnd <= start { + break + } + end = newEnd + segment = end - start + continue + default: + b.ReportMetric( + timeElapsed, + fmt.Sprintf( + "processProposalTime(s)_%d_%d_%f", + end-start, + size, + calculateBlockSizeInMb(prepareProposalResponse.BlockData.Txs[start:end]), + ), + ) + } + break + } +} + +// generatePayForBlobTransactions creates a test app then generates a number +// of valid PFB transactions. +func generatePayForBlobTransactions(b *testing.B, count int, size int) (*app.App, [][]byte) { + account := "test" + testApp, kr := testutil.SetupTestAppWithGenesisValSetAndMaxSquareSize(app.DefaultConsensusParams(), 128, account) + addr := testfactory.GetAddress(kr, account) + enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) + acc := testutil.DirectQueryAccount(testApp, addr) + accountSequence := acc.GetSequence() + signer, err := user.NewSigner(kr, enc.TxConfig, testutil.ChainID, appconsts.LatestVersion, user.NewAccount(account, acc.GetAccountNumber(), acc.GetSequence())) + require.NoError(b, err) + + rawTxs := make([][]byte, 0, count) + randomBytes := crypto.CRandBytes(size) + blob, err := share.NewBlob(share.RandomNamespace(), randomBytes, 1, acc.GetAddress().Bytes()) + require.NoError(b, err) + for i := 0; i < count; i++ { + tx, _, err := signer.CreatePayForBlobs(account, []*share.Blob{blob}, user.SetGasLimit(2549760000), user.SetFee(10000)) + require.NoError(b, err) + rawTxs = append(rawTxs, tx) + accountSequence++ + err = signer.SetSequence(account, accountSequence) + require.NoError(b, err) + } + return testApp, rawTxs +} diff --git a/app/benchmarks/results.md b/app/benchmarks/results.md new file mode 100644 index 0000000000..9562a6a340 --- /dev/null +++ b/app/benchmarks/results.md @@ -0,0 +1,839 @@ + +# Benchmark results + +This document contains the results of the benchmarks defined under `app/benchmarks`. + +The benchmarks were run on a Macbook Pro M3 MAX with 16 cores 48GB RAM. + +The benchmarks will be run using an in memory DB, then a local db, goleveldb. + +## In memory DB benchmarks + +### `sendMsg` benchmarks + +#### CheckTx + +A single `checkTx` of a `sendMsg` message takes 0.0003585 **ns** to execute. And it uses 74374 gas. + +The transactions in an `8mb` block containing 31645 `sendMsg` messages take 6,29 s (6293858682 ns) to run `checkTx` on all of them. The total gas used is 1884371034 gas. + +#### DeliverTx + +A single `deliverTx` of a `sendMsg` message takes 0.0002890 **ns** to execute. And it uses 103251 gas. + +The transactions in an `8mb` block containing 31645 `sendMsg` messages take 7,56 s (7564111078 ns) to run `deliverTx` on all of them. The total gas used is 2801272121 gas. + +#### PrepareProposal + +A single `prepareProposal` of a `sendMsg` message takes 0.0002801 **ns** to execute. And it uses 101110 gas. + +An `8mb` block containing 31645 `sendMsg` messages takes 5,04 s (5049140917 ns) to execute. The total gas used 1843040790 gas. + +#### ProcessProposal + +A single `processProposal` of a `sendMsg` message takes 0.0002313 **ns** to execute. And it uses 101110 gas. + +An `8mb` block containing 31645 `sendMsg` messages takes 5,17 s (5179850250 ns) to execute. The total gas used 1,843,040,790 gas. + +For the processing time of a block full of `sendMsg`, we benchmarked how much time they take depending on the number of transactions, and we have the following results: + +| Number of Transactions | ElapsedTime(s) | Number of Transactions | ElapsedTime(s) | +|------------------------|----------------|------------------------|----------------| +| 1650 | 0.2494 | 1670 | 0.2594 | +| 1690 | 0.2628 | 1739 | 0.2723 | +| 1761 | 0.2732 | 1782 | 0.2770 | +| 1856 | 0.2878 | 1878 | 0.2976 | +| 1901 | 0.2990 | 1956 | 0.3023 | +| 1980 | 0.3076 | 2004 | 0.3232 | +| 2062 | 0.3252 | 2088 | 0.3257 | +| 2112 | 0.3326 | 2138 | 0.3417 | +| 2200 | 0.3398 | 2227 | 0.3495 | +| 2254 | 0.3545 | 2319 | 0.3688 | +| 2349 | 0.3684 | 2376 | 0.3771 | +| 2475 | 0.3972 | 2505 | 0.3928 | +| 2535 | 0.4080 | 2608 | 0.4098 | +| 2641 | 0.4123 | 2673 | 0.4135 | +| 2750 | 0.4614 | 2784 | 0.4333 | +| 2817 | 0.4537 | 2851 | 0.4530 | +| 2934 | 0.4633 | 2970 | 0.4623 | +| 3006 | 0.4863 | 3093 | 0.4821 | +| 3132 | 0.4888 | 3168 | 0.4962 | +| 3207 | 0.5058 | 3300 | 0.5119 | +| 3340 | 0.5275 | 3381 | 0.5280 | +| 3478 | 0.5441 | 3523 | 0.5473 | +| 3564 | 0.5546 | 3712 | 0.5743 | +| 3757 | 0.6081 | 3802 | 0.5970 | +| 3912 | 0.6093 | 3961 | 0.6125 | +| 4009 | 0.6329 | 4125 | 0.6663 | +| 4176 | 0.6395 | 4225 | 0.6615 | +| 4276 | 0.6844 | 4401 | 0.7190 | +| 4455 | 0.6943 | 4509 | 0.7006 | +| 4639 | 0.7219 | 4698 | 0.7365 | +| 4752 | 0.7340 | 5500 | 0.8489 | + +### `PFB` benchmarks + +#### CheckTx: `BenchmarkCheckTx_PFB_Multi` + +Benchmarks of `CheckTx` for a single PFB with different sizes: + +| Benchmark Name | Time (ns/op) | Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|---------------------------------------------|--------------|----------|--------------------------|-----------------------| +| BenchmarkCheckTx_PFB_Multi/300_bytes-16 | 0.0003121 ns | 74,664 | 703 | 0.000703 MB | +| BenchmarkCheckTx_PFB_Multi/500_bytes-16 | 0.0003392 ns | 74,664 | 903 | 0.000903 MB | +| BenchmarkCheckTx_PFB_Multi/1000_bytes-16 | 0.0002797 ns | 74,664 | 1,403 | 0.001403 MB | +| BenchmarkCheckTx_PFB_Multi/5000_bytes-16 | 0.0002818 ns | 74,664 | 5,403 | 0.005403 MB | +| BenchmarkCheckTx_PFB_Multi/10000_bytes-16 | 0.0003094 ns | 74,664 | 10,403 | 0.010403 MB | +| BenchmarkCheckTx_PFB_Multi/50000_bytes-16 | 0.0004127 ns | 74,674 | 50,406 | 0.050406 MB | +| BenchmarkCheckTx_PFB_Multi/100000_bytes-16 | 0.0004789 ns | 74,674 | 100,406 | 0.100406 MB | +| BenchmarkCheckTx_PFB_Multi/200000_bytes-16 | 0.0006958 ns | 74,674 | 200,406 | 0.200406 MB | +| BenchmarkCheckTx_PFB_Multi/300000_bytes-16 | 0.0008678 ns | 74,674 | 300,406 | 0.300406 MB | +| BenchmarkCheckTx_PFB_Multi/400000_bytes-16 | 0.001076 ns | 74,674 | 400,406 | 0.400406 MB | +| BenchmarkCheckTx_PFB_Multi/500000_bytes-16 | 0.001307 ns | 74,674 | 500,406 | 0.500406 MB | +| BenchmarkCheckTx_PFB_Multi/1000000_bytes-16 | 0.002291 ns | 74,674 | 1,000,406 | 1.000406 MB | +| BenchmarkCheckTx_PFB_Multi/2000000_bytes-16 | 0.005049 ns | 74,674 | 2,000,406 | 2.000406 MB | +| BenchmarkCheckTx_PFB_Multi/3000000_bytes-16 | 0.006911 ns | 74,684 | 3,000,409 | 3.000409 MB | +| BenchmarkCheckTx_PFB_Multi/4000000_bytes-16 | 0.008246 ns | 74,684 | 4,000,409 | 4.000409 MB | +| BenchmarkCheckTx_PFB_Multi/5000000_bytes-16 | 0.01127 ns | 74,684 | 5,000,409 | 5.000409 MB | +| BenchmarkCheckTx_PFB_Multi/6000000_bytes-16 | 0.01316 ns | 74,684 | 6,000,409 | 6.000409 MB | + +#### DeliverTx: `BenchmarkDeliverTx_PFB_Multi` + +Benchmarks of `DeliverTx` for a single PFB with different sizes: + +| Benchmark Name | Time (ns/op) | Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-----------------------------------------------|--------------|------------|--------------------------|-----------------------| +| BenchmarkDeliverTx_PFB_Multi/300_bytes-16 | 0.0002718 ns | 77,682 | 703 | 0.000703 MB | +| BenchmarkDeliverTx_PFB_Multi/500_bytes-16 | 0.0002574 ns | 81,778 | 903 | 0.000903 MB | +| BenchmarkDeliverTx_PFB_Multi/1000_bytes-16 | 0.0002509 ns | 85,874 | 1,403 | 0.001403 MB | +| BenchmarkDeliverTx_PFB_Multi/5000_bytes-16 | 0.0002755 ns | 118,642 | 5,403 | 0.005403 MB | +| BenchmarkDeliverTx_PFB_Multi/10000_bytes-16 | 0.0002726 ns | 159,602 | 10,403 | 0.010403 MB | +| BenchmarkDeliverTx_PFB_Multi/50000_bytes-16 | 0.0002795 ns | 499,580 | 50,406 | 0.050406 MB | +| BenchmarkDeliverTx_PFB_Multi/100000_bytes-16 | 0.0002488 ns | 925,564 | 100,406 | 0.100406 MB | +| BenchmarkDeliverTx_PFB_Multi/200000_bytes-16 | 0.0002487 ns | 1,773,436 | 200,406 | 0.200406 MB | +| BenchmarkDeliverTx_PFB_Multi/300000_bytes-16 | 0.0002887 ns | 2,625,404 | 300,406 | 0.300406 MB | +| BenchmarkDeliverTx_PFB_Multi/400000_bytes-16 | 0.0002810 ns | 3,473,276 | 400,406 | 0.400406 MB | +| BenchmarkDeliverTx_PFB_Multi/500000_bytes-16 | 0.0002616 ns | 4,325,244 | 500,406 | 0.500406 MB | +| BenchmarkDeliverTx_PFB_Multi/1000000_bytes-16 | 0.0003983 ns | 8,572,796 | 1,000,406 | 1.000406 MB | +| BenchmarkDeliverTx_PFB_Multi/2000000_bytes-16 | 0.0003368 ns | 17,071,996 | 2,000,406 | 2.000406 MB | +| BenchmarkDeliverTx_PFB_Multi/3000000_bytes-16 | 0.0005770 ns | 25,571,206 | 3,000,409 | 3.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/4000000_bytes-16 | 0.0003752 ns | 34,066,310 | 4,000,409 | 4.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/5000000_bytes-16 | 0.0003788 ns | 42,565,510 | 5,000,409 | 5.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/6000000_bytes-16 | 0.0003975 ns | 51,064,710 | 6,000,409 | 6.000409 MB | + +#### PrepareProposal: `BenchmarkPrepareProposal_PFB_Multi` + +The benchmarks for `PrepareProposal` for 8mb blocks containing PFBs of different sizes: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Prepare Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|------------------------------------------------------------------------|-----------------|------------------------|---------------------------|-----------------|--------------------------|-----------------------| +| BenchmarkPrepareProposal_PFB_Multi/15000_transactions_of_300_bytes-16 | 6.239 | 10,318 | 2.411 s | 988,490,895,000 | 703 | 0.000703 MB | +| BenchmarkPrepareProposal_PFB_Multi/10000_transactions_of_500_bytes-16 | 5.035 | 6,331 | 1.710 s | 439,343,930,000 | 903 | 0.000903 MB | +| BenchmarkPrepareProposal_PFB_Multi/6000_transactions_of_1000_bytes-16 | 5.809 | 4,566 | 1.033 s | 158,174,358,000 | 1,403 | 0.001403 MB | +| BenchmarkPrepareProposal_PFB_Multi/3000_transactions_of_5000_bytes-16 | 7.188 | 1,413 | 0.547 s | 39,550,179,000 | 5,403 | 0.005403 MB | +| BenchmarkPrepareProposal_PFB_Multi/1000_transactions_of_10000_bytes-16 | 7.470 | 758 | 0.210 s | 4,397,393,000 | 10,403 | 0.010403 MB | +| BenchmarkPrepareProposal_PFB_Multi/500_transactions_of_50000_bytes-16 | 7.441 | 155 | 0.127 s | 1,100,446,500 | 50,406 | 0.050406 MB | +| BenchmarkPrepareProposal_PFB_Multi/100_transactions_of_100000_bytes-16 | 7.368 | 77 | 0.045 s | 44,369,300 | 100,406 | 0.100406 MB | +| BenchmarkPrepareProposal_PFB_Multi/100_transactions_of_200000_bytes-16 | 7.260 | 38 | 0.059 s | 44,369,300 | 200,406 | 0.200406 MB | +| BenchmarkPrepareProposal_PFB_Multi/50_transactions_of_300000_bytes-16 | 7.161 | 25 | 0.056 s | 11,202,150 | 300,406 | 0.300406 MB | +| BenchmarkPrepareProposal_PFB_Multi/50_transactions_of_400000_bytes-16 | 7.254 | 19 | 0.054 s | 11,202,150 | 400,406 | 0.400406 MB | +| BenchmarkPrepareProposal_PFB_Multi/30_transactions_of_500000_bytes-16 | 7.157 | 15 | 0.041 s | 4,085,490 | 500,406 | 0.500406 MB | +| BenchmarkPrepareProposal_PFB_Multi/10_transactions_of_1000000_bytes-16 | 6.678 | 7 | 0.031 s | 483,230 | 1,000,406 | 1.000406 MB | +| BenchmarkPrepareProposal_PFB_Multi/5_transactions_of_2000000_bytes-16 | 5.723 | 3 | 0.032 s | 131,790 | 2,000,406 | 2.000406 MB | +| BenchmarkPrepareProposal_PFB_Multi/3_transactions_of_3000000_bytes-16 | 5.723 | 2 | 0.042 s | 52,716 | 3,000,409 | 3.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/3_transactions_of_4000000_bytes-16 | 3.815 | 1 | 0.040 s | 52,716 | 4,000,409 | 4.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/2_transactions_of_5000000_bytes-16 | 4.769 | 1 | 0.039 s | 26,358 | 5,000,409 | 5.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/2_transactions_of_6000000_bytes-16 | 5.722 | 1 | 0.032 s | 26,358 | 6,000,409 | 6.000409 MB | + +#### ProcessProposal: `BenchmarkProcessProposal_PFB_Multi` + +The benchmarks for `ProcessProposal` for 8mb blocks containing PFBs of different sizes: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Process Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|------------------------------------------------------------------------|-----------------|------------------------|---------------------------|-----------------|--------------------------|-----------------------| +| BenchmarkProcessProposal_PFB_Multi/15000_transactions_of_300_bytes-16 | 6.239 | 10,318 | 1.767 s | 988,490,895,000 | 703 | 0.000703 MB | +| BenchmarkProcessProposal_PFB_Multi/10000_transactions_of_500_bytes-16 | 5.035 | 6,331 | 1.101 s | 439,343,930,000 | 903 | 0.000903 MB | +| BenchmarkProcessProposal_PFB_Multi/6000_transactions_of_1000_bytes-16 | 5.809 | 4,566 | 0.820 s | 158,174,358,000 | 1,403 | 0.001403 MB | +| BenchmarkProcessProposal_PFB_Multi/3000_transactions_of_5000_bytes-16 | 7.188 | 1,413 | 0.300 s | 39,550,179,000 | 5,403 | 0.005403 MB | +| BenchmarkProcessProposal_PFB_Multi/1000_transactions_of_10000_bytes-16 | 7.470 | 758 | 0.185 s | 4,397,393,000 | 10,403 | 0.010403 MB | +| BenchmarkProcessProposal_PFB_Multi/500_transactions_of_50000_bytes-16 | 7.441 | 155 | 0.092 s | 1,100,446,500 | 50,406 | 0.050406 MB | +| BenchmarkProcessProposal_PFB_Multi/100_transactions_of_100000_bytes-16 | 7.368 | 77 | 0.089 s | 44,369,300 | 100,406 | 0.100406 MB | +| BenchmarkProcessProposal_PFB_Multi/100_transactions_of_200000_bytes-16 | 7.260 | 38 | 0.060 s | 44,369,300 | 200,406 | 0.200406 MB | +| BenchmarkProcessProposal_PFB_Multi/50_transactions_of_300000_bytes-16 | 7.161 | 25 | 0.048 s | 11,202,150 | 300,406 | 0.300406 MB | +| BenchmarkProcessProposal_PFB_Multi/50_transactions_of_400000_bytes-16 | 7.254 | 19 | 0.051 s | 11,202,150 | 400,406 | 0.400406 MB | +| BenchmarkProcessProposal_PFB_Multi/30_transactions_of_500000_bytes-16 | 7.157 | 15 | 0.062 s | 4,085,490 | 500,406 | 0.500406 MB | +| BenchmarkProcessProposal_PFB_Multi/10_transactions_of_1000000_bytes-16 | 6.678 | 7 | 0.047 s | 483,230 | 1,000,406 | 1.000406 MB | +| BenchmarkProcessProposal_PFB_Multi/5_transactions_of_2000000_bytes-16 | 5.723 | 3 | 0.043 s | 131,790 | 2,000,406 | 2.000406 MB | +| BenchmarkProcessProposal_PFB_Multi/3_transactions_of_3000000_bytes-16 | 5.723 | 2 | 0.053 s | 52,716 | 3,000,409 | 3.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/3_transactions_of_4000000_bytes-16 | 3.815 | 1 | 0.047 s | 52,716 | 4,000,409 | 4.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/2_transactions_of_5000000_bytes-16 | 4.769 | 1 | 0.068 s | 26,358 | 5,000,409 | 5.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/2_transactions_of_6000000_bytes-16 | 5.722 | 1 | 0.047 s | 26,358 | 6,000,409 | 6.000409 MB | + +### IBC `UpdateClient` benchmarks + +#### CheckTx: `BenchmarkIBC_CheckTx_Update_Client_Multi` + +The benchmarks of executing `checkTx` on a single transaction containing an IBC `updateClient` with different numbers of required signatures: + +| Benchmark Name | Time (ns/op) | Gas Used | Number of Validators | Number of Verified Signatures | Transaction Size (Bytes) | Transaction Size (MB) | +|-----------------------------------------------------------------------|--------------|-----------|----------------------|-------------------------------|--------------------------|-----------------------| +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_2-16 | 0.0007940 ns | 108,598 | 2.0 | 1.0 | 1,396 | 0.001396 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_10-16 | 0.002127 ns | 127,710 | 10.0 | 6.0 | 3,303 | 0.003303 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_25-16 | 0.003694 ns | 163,430 | 25.0 | 16.0 | 6,875 | 0.006875 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_50-16 | 0.004701 ns | 222,930 | 50.0 | 33.0 | 12,825 | 0.012825 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_75-16 | 0.004095 ns | 282,480 | 75.0 | 50.0 | 18,780 | 0.018780 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_100-16 | 0.004112 ns | 340,928 | 100.0 | 66.0 | 24,629 | 0.024629 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_125-16 | 0.007009 ns | 400,178 | 125.0 | 83.0 | 30,554 | 0.030554 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_150-16 | 0.004906 ns | 460,980 | 150.0 | 100.0 | 36,630 | 0.036630 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_175-16 | 0.01056 ns | 520,500 | 175.0 | 116.0 | 42,582 | 0.042582 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_200-16 | 0.01181 ns | 580,000 | 200.0 | 133.0 | 48,532 | 0.048532 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_225-16 | 0.01339 ns | 637,198 | 225.0 | 150.0 | 54,256 | 0.054256 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_250-16 | 0.01411 ns | 699,020 | 250.0 | 166.0 | 60,434 | 0.060434 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_300-16 | 0.01931 ns | 818,020 | 300.0 | 200.0 | 72,334 | 0.072334 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_400-16 | 0.02312 ns | 1,056,020 | 400.0 | 266.0 | 96,134 | 0.096134 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_500-16 | 0.01675 ns | 1,288,968 | 500.0 | 333.0 | 119,433 | 0.119433 MB | + +#### DeliverTx: `BenchmarkIBC_DeliverTx_Update_Client_Multi` + +The benchmarks of executing `deliverTx` on a single transaction containing an IBC `updateClient` with different numbers of required signatures: + +| Benchmark Name | Time (ns/op) | Gas Used | Number of Validators | Number of Verified Signatures | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------|--------------|-----------|----------------------|-------------------------------|--------------------------|-----------------------| +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_2-16 | 0.0006931 ns | 107,520 | 2.0 | 1.0 | 1,396 | 0.001396 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_10-16 | 0.004647 ns | 126,480 | 10.0 | 6.0 | 3,292 | 0.003292 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_25-16 | 0.005861 ns | 162,352 | 25.0 | 16.0 | 6,875 | 0.006875 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_50-16 | 0.009248 ns | 221,852 | 50.0 | 33.0 | 12,825 | 0.012825 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_75-16 | 0.01252 ns | 281,402 | 75.0 | 50.0 | 18,780 | 0.018780 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_100-16 | 0.01239 ns | 339,850 | 100.0 | 66.0 | 24,629 | 0.024629 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_125-16 | 0.01300 ns | 400,402 | 125.0 | 83.0 | 30,680 | 0.030680 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_150-16 | 0.01691 ns | 459,902 | 150.0 | 100.0 | 36,630 | 0.036630 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_175-16 | 0.01560 ns | 517,620 | 175.0 | 116.0 | 42,406 | 0.042406 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_200-16 | 0.01894 ns | 578,922 | 200.0 | 133.0 | 48,532 | 0.048532 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_225-16 | 0.01714 ns | 638,422 | 225.0 | 150.0 | 54,482 | 0.054482 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_250-16 | 0.01736 ns | 697,942 | 250.0 | 166.0 | 60,434 | 0.060434 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_300-16 | 0.02008 ns | 816,942 | 300.0 | 200.0 | 72,334 | 0.072334 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_400-16 | 0.02320 ns | 1,054,942 | 400.0 | 266.0 | 96,134 | 0.096134 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_500-16 | 0.02724 ns | 1,288,522 | 500.0 | 333.0 | 119,492 | 0.119492 MB | + +#### PrepareProposal: `BenchmarkIBC_PrepareProposal_Update_Client_Multi` + +Benchmarks of an `8mb` containing the maximum number of IBC `UpdateClient` with different number of signatures: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Number of Validators | Number of Verified Signatures | Prepare Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------------|------------------|-------------------------|----------------------|-------------------------------|-----------------------------|------------------|----------------------------|------------------------| +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_10-16 | 7.464 | 2,367 | 10.0 | 6.0 | 0.571 s | 266,926,655 | 3,373 | 0.003373 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_25-16 | 7.465 | 1,138 | 25.0 | 16.0 | 0.436 s | 249,391,655 | 6,945 | 0.006945 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_50-16 | 7.462 | 610.0 | 50.0 | 33.0 | 0.271 s | 184,196,655 | 12,895 | 0.012895 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_75-16 | 7.452 | 416.0 | 75.0 | 50.0 | 0.181 s | 121,879,155 | 18,850 | 0.018850 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_100-16 | 7.453 | 316.0 | 100.0 | 66.0 | 0.180 s | 151,629,155 | 24,800 | 0.024800 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_125-16 | 7.462 | 255.0 | 125.0 | 83.0 | 0.197 s | 181,379,155 | 30,750 | 0.030750 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_150-16 | 7.441 | 213.0 | 150.0 | 100.0 | 0.207 s | 211,129,155 | 36,700 | 0.036700 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_175-16 | 7.432 | 183.0 | 175.0 | 116.0 | 0.215 s | 240,889,155 | 42,652 | 0.042652 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_200-16 | 7.467 | 162.0 | 200.0 | 133.0 | 0.227 s | 269,634,155 | 48,401 | 0.048401 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_225-16 | 7.451 | 144.0 | 225.0 | 150.0 | 0.235 s | 299,259,155 | 54,326 | 0.054326 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_250-16 | 7.462 | 130.0 | 250.0 | 166.0 | 0.242 s | 328,894,155 | 60,253 | 0.060253 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_300-16 | 7.450 | 108.0 | 300.0 | 200.0 | 0.270 s | 389,649,155 | 72,404 | 0.072404 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_400-16 | 7.426 | 81.0 | 400.0 | 266.0 | 0.304 s | 508,649,155 | 96,204 | 0.096204 MB | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_500-16 | 7.404 | 65.0 | 500.0 | 333.0 | 0.361 s | 625,144,155 | 119,503 | 0.119503 MB | + +#### ProcessProposal: `BenchmarkIBC_ProcessProposal_Update_Client_Multi` + +Benchmarks of an `8mb` containing the maximum number of IBC `UpdateClient` with different number of signatures: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Number of Validators | Number of Verified Signatures | Process Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------------|-----------------|------------------------|----------------------|-------------------------------|---------------------------|----------------|--------------------------|-----------------------| +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_2-16 | 7.457 | 5,574 | 2.0 | 1.0 | 1.022 s | 419,611,655 | 1,469 | 0.001469 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_10-16 | 7.464 | 2,367 | 10.0 | 6.0 | 0.455 s | 266,926,655 | 3,373 | 0.003373 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_25-16 | 7.465 | 1,138 | 25.0 | 16.0 | 0.270 s | 249,391,655 | 6,945 | 0.006945 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_50-16 | 7.462 | 610.0 | 50.0 | 33.0 | 0.181 s | 184,196,655 | 12,895 | 0.012895 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_75-16 | 7.452 | 416.0 | 75.0 | 50.0 | 0.150 s | 121,879,155 | 18,850 | 0.018850 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_100-16 | 7.453 | 316.0 | 100.0 | 66.0 | 0.132 s | 151,629,155 | 24,800 | 0.024800 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_125-16 | 7.462 | 255.0 | 125.0 | 83.0 | 0.122 s | 181,379,155 | 30,750 | 0.030750 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_150-16 | 7.441 | 213.0 | 150.0 | 100.0 | 0.107 s | 211,129,155 | 36,700 | 0.036700 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_175-16 | 7.442 | 184.0 | 175.0 | 116.0 | 0.092 s | 240,009,155 | 42,476 | 0.042476 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_200-16 | 7.452 | 161.0 | 200.0 | 133.0 | 0.098 s | 270,639,155 | 48,602 | 0.048602 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_225-16 | 7.430 | 143.0 | 225.0 | 150.0 | 0.089 s | 300,389,155 | 54,552 | 0.054552 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_250-16 | 7.435 | 129.0 | 250.0 | 166.0 | 0.081 s | 330,149,155 | 60,504 | 0.060504 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_300-16 | 7.450 | 108.0 | 300.0 | 200.0 | 0.078 s | 389,649,155 | 72,404 | 0.072404 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_400-16 | 7.426 | 81.0 | 400.0 | 266.0 | 0.077 s | 508,649,155 | 96,204 | 0.096204 MB | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_500-16 | 7.435 | 65.0 | 500.0 | 333.0 | 0.092 s | 627,649,155 | 120,004 | 0.120004 MB | + +#### Process proposal time with different number of transactions per block + +**50 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1467 | 0.532979 | 0.2508 | +| 1546 | 0.561684 | 0.2766 | +| 1566 | 0.568951 | 0.2511 | +| 1650 | 0.599472 | 0.2711 | +| 1739 | 0.631810 | 0.3007 | +| 1761 | 0.639804 | 0.2832 | +| 1856 | 0.674322 | 0.3017 | +| 1956 | 0.710657 | 0.3203 | +| 1980 | 0.719378 | 0.3291 | +| 2062 | 0.749172 | 0.3670 | +| 2088 | 0.758619 | 0.3426 | +| 2200 | 0.799314 | 0.3610 | +| 2319 | 0.842553 | 0.3980 | +| 2349 | 0.853454 | 0.3794 | +| 2475 | 0.899236 | 0.4086 | +| 2608 | 0.947561 | 0.4555 | +| 2641 | 0.959552 | 0.4561 | +| 2750 | 0.999157 | 0.4920 | +| 2784 | 1.011511 | 0.4782 | +| 2934 | 1.066013 | 0.5209 | +| 2970 | 1.079094 | 0.5069 | +| 3093 | 1.123786 | 0.5816 | +| 3132 | 1.137957 | 0.5360 | +| 3300 | 1.198999 | 0.5766 | +| 3478 | 1.263676 | 0.6072 | +| 3523 | 1.280026 | 0.6028 | +| 3712 | 1.348700 | 0.6394 | +| 3912 | 1.421370 | 0.6928 | +| 3961 | 1.439174 | 0.6559 | +| 4125 | 1.498763 | 0.7463 | +| 4176 | 1.517294 | 0.6967 | +| 5500 | 1.998369 | 0.9183 | +| 11000 | 3.753713 | 1.732 | + +**100 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1546 | 0.636877 | 0.2726 | +| 1739 | 0.716391 | 0.2762 | +| 1956 | 0.805792 | 0.3207 | +| 2062 | 0.849463 | 0.3361 | +| 2319 | 0.955343 | 0.3774 | +| 2608 | 1.074408 | 0.4387 | +| 2750 | 1.132910 | 0.4873 | +| 2934 | 1.208715 | 0.5015 | +| 3093 | 1.274221 | 0.5202 | +| 3478 | 1.432837 | 0.5797 | +| 3912 | 1.611639 | 0.6520 | +| 4125 | 1.699392 | 0.6758 | +| 5500 | 2.265875 | 0.9318 | +| 11000 | 4.256186 | 1.685 | + +**200 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1546 | 0.787264 | 0.2472 | +| 1739 | 0.885551 | 0.3009 | +| 1956 | 0.996061 | 0.3188 | +| 2062 | 1.050043 | 0.3400 | +| 2319 | 1.180923 | 0.3781 | +| 2608 | 1.328100 | 0.4439 | +| 2750 | 1.400415 | 0.4720 | +| 2934 | 1.494120 | 0.5049 | +| 3093 | 1.575092 | 0.5384 | +| 3478 | 1.771158 | 0.5913 | +| 3912 | 1.992178 | 0.6459 | +| 4125 | 2.100651 | 0.6927 | +| 5500 | 2.800886 | 0.8970 | +| 11000 | 5.254511 | 1.691 | + +**300 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1546 | 0.934702 | 0.2506 | +| 1739 | 1.051395 | 0.2910 | +| 1956 | 1.182600 | 0.3316 | +| 2062 | 1.246691 | 0.3439 | +| 2319 | 1.402081 | 0.3830 | +| 2608 | 1.576818 | 0.4674 | +| 2750 | 1.662676 | 0.4803 | +| 2934 | 1.773928 | 0.5110 | +| 3093 | 1.870064 | 0.5431 | +| 3478 | 2.102846 | 0.6002 | +| 3912 | 2.365255 | 0.6659 | +| 4125 | 2.494041 | 0.7052 | +| 5500 | 3.325407 | 0.9117 | +| 11000 | 6.238512 | 1.688 | + +**400 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1375 | 0.962440 | 0.2425 | +| 1467 | 1.026840 | 0.2564 | +| 1546 | 1.082140 | 0.2583 | +| 1650 | 1.154940 | 0.2713 | +| 1739 | 1.217239 | 0.2854 | +| 1856 | 1.299139 | 0.3204 | +| 1956 | 1.369139 | 0.3205 | +| 2062 | 1.443338 | 0.3535 | +| 2200 | 1.539938 | 0.3674 | +| 2319 | 1.623238 | 0.3873 | +| 2475 | 1.732437 | 0.4184 | +| 2608 | 1.825537 | 0.4635 | +| 2750 | 1.924936 | 0.5227 | +| 2784 | 1.948736 | 0.5029 | +| 2934 | 2.053736 | 0.5193 | +| 3093 | 2.165035 | 0.5505 | +| 3300 | 2.309935 | 0.6121 | +| 3478 | 2.434534 | 0.6077 | +| 3712 | 2.598333 | 0.6534 | +| 3912 | 2.738333 | 0.6625 | +| 5500 | 3.849928 | 0.9410 | +| 11000 | 7.222513 | 1.782 | + +**500 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1476 | 1.173903 | 0.2640 | +| 1660 | 1.320250 | 0.3192 | +| 1750 | 1.391832 | 0.3249 | +| 1867 | 1.484890 | 0.3494 | +| 1968 | 1.565222 | 0.3664 | +| 2214 | 1.760881 | 0.4322 | +| 2490 | 1.980402 | 0.4667 | +| 2625 | 2.087776 | 0.4795 | +| 2800 | 2.226965 | 0.5033 | +| 2952 | 2.347860 | 0.5529 | +| 3321 | 2.641350 | 0.6263 | +| 3500 | 2.783720 | 0.6101 | +| 3735 | 2.970631 | 0.6629 | +| 3937 | 3.131294 | 0.7341 | +| 7000 | 5.035397 | 1.127 | + +**600 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1400 | 1.246969 | 0.2492 | +| 1417 | 1.262112 | 0.2554 | +| 1432 | 1.275473 | 0.2465 | +| 1476 | 1.314665 | 0.2575 | +| 1494 | 1.330698 | 0.2716 | +| 1510 | 1.344950 | 0.2729 | +| 1575 | 1.402847 | 0.2777 | +| 1593 | 1.418880 | 0.3210 | +| 1611 | 1.434914 | 0.3269 | +| 1660 | 1.478559 | 0.3331 | +| 1680 | 1.496374 | 0.3202 | +| 1698 | 1.512407 | 0.3387 | +| 1750 | 1.558725 | 0.3430 | +| 1771 | 1.577431 | 0.3476 | +| 1791 | 1.595245 | 0.3550 | +| 1812 | 1.613951 | 0.3526 | +| 1867 | 1.662941 | 0.3702 | +| 1890 | 1.683428 | 0.3592 | +| 1910 | 1.701242 | 0.3728 | +| 1968 | 1.752905 | 0.3790 | +| 1992 | 1.774282 | 0.3636 | +| 2014 | 1.793879 | 0.3740 | +| 2100 | 1.870481 | 0.4125 | +| 2125 | 1.892750 | 0.3915 | +| 2148 | 1.913237 | 0.4158 | +| 2214 | 1.972025 | 0.4057 | +| 2241 | 1.996075 | 0.4231 | +| 2265 | 2.017452 | 0.4210 | +| 2362 | 2.103853 | 0.4392 | +| 2389 | 2.127903 | 0.4406 | +| 2416 | 2.151953 | 0.4700 | +| 2490 | 2.217867 | 0.4615 | +| 2520 | 2.244589 | 0.4727 | +| 2547 | 2.268639 | 0.4743 | +| 2625 | 2.338116 | 0.4812 | +| 2656 | 2.365728 | 0.4923 | +| 2686 | 2.392450 | 0.4905 | +| 2718 | 2.420954 | 0.5042 | +| 2800 | 2.493994 | 0.5309 | +| 2835 | 2.525169 | 0.5166 | +| 2865 | 2.551891 | 0.5340 | +| 2952 | 2.629385 | 0.5378 | +| 2988 | 2.661451 | 0.5504 | +| 3021 | 2.690845 | 0.5532 | +| 3150 | 2.805750 | 0.5948 | +| 3187 | 2.838707 | 0.5747 | +| 3222 | 2.869883 | 0.5986 | +| 3321 | 2.958065 | 0.6170 | +| 3361 | 2.993694 | 0.6092 | +| 3397 | 3.025761 | 0.6193 | +| 3500 | 3.117506 | 0.6357 | +| 3543 | 3.155807 | 0.6425 | +| 3583 | 3.191437 | 0.6764 | +| 3624 | 3.227957 | 0.6628 | +| 3735 | 3.326828 | 0.6819 | +| 3780 | 3.366911 | 0.6935 | +| 3820 | 3.402540 | 0.7127 | +| 3937 | 3.506756 | 0.7093 | +| 3984 | 3.548620 | 0.7404 | +| 4029 | 3.588703 | 0.7535 | +| 7000 | 5.639168 | 1.133 | + +**1000 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1333 | 1.695789 | 0.2682 | +| 1348 | 1.714872 | 0.2605 | +| 1406 | 1.788660 | 0.2858 | +| 1422 | 1.809015 | 0.2827 | +| 1437 | 1.828098 | 0.2881 | +| 1499 | 1.906975 | 0.2945 | +| 1516 | 1.928602 | 0.2985 | +| 1581 | 2.011295 | 0.3039 | +| 1599 | 2.034195 | 0.3111 | +| 1616 | 2.055822 | 0.3185 | +| 1686 | 2.144876 | 0.3450 | +| 1705 | 2.169048 | 0.3501 | +| 1778 | 2.261919 | 0.3496 | +| 1798 | 2.287363 | 0.3554 | +| 1818 | 2.312807 | 0.3507 | +| 1875 | 2.385323 | 0.3849 | +| 1896 | 2.412039 | 0.3877 | +| 1917 | 2.438755 | 0.3746 | +| 1999 | 2.543076 | 0.3815 | +| 2022 | 2.572336 | 0.4042 | +| 2109 | 2.683018 | 0.4223 | +| 2133 | 2.713551 | 0.4126 | +| 2155 | 2.741539 | 0.4115 | +| 2248 | 2.859854 | 0.4183 | +| 2274 | 2.892931 | 0.4343 | +| 2371 | 3.016335 | 0.4642 | +| 2398 | 3.050684 | 0.4631 | +| 2424 | 3.083761 | 0.4575 | +| 2500 | 3.180449 | 0.4825 | +| 2529 | 3.217342 | 0.4757 | +| 2557 | 3.252964 | 0.4812 | +| 2667 | 3.392906 | 0.5144 | +| 2697 | 3.431072 | 0.5141 | +| 2727 | 3.469238 | 0.5071 | +| 2812 | 3.577375 | 0.5250 | +| 2844 | 3.618086 | 0.5359 | +| 2875 | 3.657524 | 0.5506 | +| 2998 | 3.814005 | 0.5659 | +| 3033 | 3.858532 | 0.5797 | +| 3163 | 4.023918 | 0.5964 | +| 3199 | 4.069717 | 0.6023 | +| 3232 | 4.111700 | 0.6142 | +| 3372 | 4.289808 | 0.6249 | +| 3411 | 4.339424 | 0.6465 | +| 3556 | 4.523893 | 0.6488 | +| 3597 | 4.576054 | 0.6829 | +| 3636 | 4.625669 | 0.6699 | +| 3750 | 4.770700 | 0.6820 | +| 3793 | 4.825405 | 0.6983 | +| 3835 | 4.878838 | 0.6991 | +| 5000 | 5.808817 | 0.8490 | + +**1200 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1406 | 2.056833 | 0.2758 | +| 1500 | 2.194349 | 0.3071 | +| 1581 | 2.312847 | 0.3054 | +| 1687 | 2.467918 | 0.3332 | +| 1778 | 2.601046 | 0.3569 | +| 1875 | 2.742950 | 0.3688 | +| 2000 | 2.925817 | 0.3793 | +| 2109 | 3.085278 | 0.4087 | +| 2250 | 3.291552 | 0.4359 | +| 2371 | 3.468567 | 0.4462 | +| 2500 | 3.657286 | 0.4789 | +| 2530 | 3.701174 | 0.4999 | +| 2667 | 3.901596 | 0.4836 | +| 2812 | 4.113722 | 0.5371 | +| 3000 | 4.388754 | 0.5768 | +| 3163 | 4.627213 | 0.5897 | +| 3375 | 4.937355 | 0.6156 | +| 3556 | 5.202147 | 0.6549 | +| 3750 | 5.485956 | 0.6933 | +| 4000 | 5.851690 | 0.7415 | +| 5000 | 6.679712 | 0.8498 | + +**1500 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1406 | 2.459093 | 0.2941 | +| 1581 | 2.765175 | 0.3109 | +| 1778 | 3.109735 | 0.3373 | +| 1875 | 3.279392 | 0.3706 | +| 2109 | 3.688667 | 0.4100 | +| 2371 | 4.146915 | 0.4601 | +| 2500 | 4.372541 | 0.4735 | +| 2667 | 4.664631 | 0.5013 | +| 2812 | 4.918242 | 0.5260 | +| 3163 | 5.532154 | 0.5946 | +| 3556 | 6.219526 | 0.6634 | +| 3750 | 6.245762 | 0.6879 | +| 5000 | 6.245762 | 0.6781 | + +**1800 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1333 | 2.712788 | 0.2643 | +| 1406 | 2.861353 | 0.2840 | +| 1422 | 2.893915 | 0.2843 | +| 1499 | 3.050621 | 0.2956 | +| 1581 | 3.217503 | 0.3094 | +| 1599 | 3.254135 | 0.3302 | +| 1686 | 3.431192 | 0.3396 | +| 1778 | 3.618425 | 0.3407 | +| 1798 | 3.659128 | 0.3397 | +| 1875 | 3.815834 | 0.3777 | +| 1896 | 3.858572 | 0.3813 | +| 1999 | 4.068192 | 0.3647 | +| 2109 | 4.292057 | 0.4191 | +| 2133 | 4.340900 | 0.4057 | +| 2248 | 4.574942 | 0.4349 | +| 2371 | 4.825264 | 0.4446 | +| 2398 | 4.880213 | 0.4481 | +| 2500 | 5.087797 | 0.4676 | +| 2529 | 5.146816 | 0.4740 | +| 2667 | 5.427666 | 0.5127 | +| 2697 | 5.488720 | 0.5039 | +| 2812 | 5.722761 | 0.5547 | +| 2844 | 5.787886 | 0.5411 | +| 2998 | 6.101297 | 0.5710 | +| 3163 | 6.437096 | 0.5896 | +| 3199 | 6.510361 | 0.5965 | +| 3372 | 6.862440 | 0.6149 | +| 3556 | 7.236906 | 0.6572 | +| 3597 | 7.267433 | 0.6716 | +| 5000 | 7.267433 | 0.6742 | + +**2000 bytes blobs**: + +| Number of Transactions | Block Size (bytes) | Elapsed Time (s) | +|------------------------|--------------------|------------------| +| 1406 | 3.129526 | 0.2732 | +| 1581 | 3.519054 | 0.3078 | +| 1778 | 3.957552 | 0.3477 | +| 1875 | 4.173462 | 0.3764 | +| 2109 | 4.694317 | 0.4059 | +| 2371 | 5.277496 | 0.4412 | +| 2500 | 5.564634 | 0.4664 | +| 2667 | 5.936356 | 0.5006 | +| 2812 | 6.259108 | 0.5262 | +| 3163 | 6.526213 | 0.5574 | +| 3556 | 6.526213 | 0.5667 | +| 3750 | 6.526213 | 0.5509 | +| 5000 | 6.526213 | 0.5556 | + +## GoLevelDB benchmarks + +### `sendMsg` benchmarks + +#### CheckTx + +A single `checkTx` of a `sendMsg` message takes 0.0003071 **ns** to execute. And it uses 74374 gas. + +The transactions in an `8mb` block containing 31645 `sendMsg` messages take 6,45 s (6455816060 ns) to run `checkTx` on all of them. The total gas used is 1884371034 gas. + +#### DeliverTx + +A single `deliverTx` of a `sendMsg` message takes 0.0003948 **ns** to execute. And it uses 103251 gas. + +The transactions in an `8mb` block containing 31645 `sendMsg` messages take 7,50 s (7506830940 ns) to run `deliverTx` on all of them. The total gas used is 2801272121 gas. + +#### PrepareProposal + +A single `prepareProposal` of a `sendMsg` message takes 0.0003943 **ns** to execute. And it uses 101110 gas. + +An `8mb` block containing 31645 `sendMsg` messages takes 5,2 s (5242159792 ns) to execute. The total gas used 1843040790 gas. + +#### ProcessProposal + +A single `processProposal` of a `sendMsg` message takes 0.0003010 **ns** to execute. And it uses 101110 gas. + +An `8mb` block containing 31645 `sendMsg` messages takes 5,21 s (5214205041 ns) to execute. The total gas used 1843040790 gas. + +### `PFB` benchmarks + +#### CheckTx: `BenchmarkCheckTx_PFB_Multi` + +Benchmarks of `CheckTx` for a single PFB with different sizes: + +| Benchmark Name | Time (ns/op) | Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|---------------------------------------------|--------------|----------|--------------------------|-----------------------| +| BenchmarkCheckTx_PFB_Multi/300_bytes-16 | 0.0005847 ns | 74,664 | 703 | 0.000703 MB | +| BenchmarkCheckTx_PFB_Multi/500_bytes-16 | 0.0005136 ns | 74,664 | 903 | 0.000903 MB | +| BenchmarkCheckTx_PFB_Multi/1000_bytes-16 | 0.0005754 ns | 74,664 | 1,403 | 0.001403 MB | +| BenchmarkCheckTx_PFB_Multi/5000_bytes-16 | 0.0005706 ns | 74,664 | 5,403 | 0.005403 MB | +| BenchmarkCheckTx_PFB_Multi/10000_bytes-16 | 0.0006885 ns | 74,664 | 10,403 | 0.010403 MB | +| BenchmarkCheckTx_PFB_Multi/50000_bytes-16 | 0.0006683 ns | 74,674 | 50,406 | 0.050406 MB | +| BenchmarkCheckTx_PFB_Multi/100000_bytes-16 | 0.0008378 ns | 74,674 | 100,406 | 0.100406 MB | +| BenchmarkCheckTx_PFB_Multi/200000_bytes-16 | 0.001130 ns | 74,674 | 200,406 | 0.200406 MB | +| BenchmarkCheckTx_PFB_Multi/300000_bytes-16 | 0.001164 ns | 74,674 | 300,406 | 0.300406 MB | +| BenchmarkCheckTx_PFB_Multi/400000_bytes-16 | 0.001550 ns | 74,674 | 400,406 | 0.400406 MB | +| BenchmarkCheckTx_PFB_Multi/500000_bytes-16 | 0.001829 ns | 74,674 | 500,406 | 0.500406 MB | +| BenchmarkCheckTx_PFB_Multi/1000000_bytes-16 | 0.002452 ns | 74,674 | 1,000,406 | 1.000406 MB | +| BenchmarkCheckTx_PFB_Multi/2000000_bytes-16 | 0.004647 ns | 74,674 | 2,000,406 | 2.000406 MB | +| BenchmarkCheckTx_PFB_Multi/3000000_bytes-16 | 0.006415 ns | 74,684 | 3,000,409 | 3.000409 MB | +| BenchmarkCheckTx_PFB_Multi/4000000_bytes-16 | 0.007709 ns | 74,684 | 4,000,409 | 4.000409 MB | +| BenchmarkCheckTx_PFB_Multi/5000000_bytes-16 | 0.01014 ns | 74,684 | 5,000,409 | 5.000409 MB | +| BenchmarkCheckTx_PFB_Multi/6000000_bytes-16 | 0.01153 ns | 74,684 | 6,000,409 | 6.000409 MB | + +#### DeliverTx: `BenchmarkDeliverTx_PFB_Multi` + +Benchmarks of `DeliverTx` for a single PFB with different sizes: + +| Benchmark Name | Time (ns/op) | Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-----------------------------------------------|--------------|------------|--------------------------|-----------------------| +| BenchmarkDeliverTx_PFB_Multi/300_bytes-16 | 0.0005010 ns | 77,682 | 703 | 0.000703 MB | +| BenchmarkDeliverTx_PFB_Multi/500_bytes-16 | 0.0004297 ns | 81,778 | 903 | 0.000903 MB | +| BenchmarkDeliverTx_PFB_Multi/1000_bytes-16 | 0.0005227 ns | 85,874 | 1,403 | 0.001403 MB | +| BenchmarkDeliverTx_PFB_Multi/5000_bytes-16 | 0.0005552 ns | 118,642 | 5,403 | 0.005403 MB | +| BenchmarkDeliverTx_PFB_Multi/10000_bytes-16 | 0.0004537 ns | 159,602 | 10,403 | 0.010403 MB | +| BenchmarkDeliverTx_PFB_Multi/50000_bytes-16 | 0.0004896 ns | 499,580 | 50,406 | 0.050406 MB | +| BenchmarkDeliverTx_PFB_Multi/100000_bytes-16 | 0.0005505 ns | 925,564 | 100,406 | 0.100406 MB | +| BenchmarkDeliverTx_PFB_Multi/200000_bytes-16 | 0.0003661 ns | 1,773,436 | 200,406 | 0.200406 MB | +| BenchmarkDeliverTx_PFB_Multi/300000_bytes-16 | 0.0004681 ns | 2,625,404 | 300,406 | 0.300406 MB | +| BenchmarkDeliverTx_PFB_Multi/400000_bytes-16 | 0.0003012 ns | 3,473,276 | 400,406 | 0.400406 MB | +| BenchmarkDeliverTx_PFB_Multi/500000_bytes-16 | 0.0003164 ns | 4,325,244 | 500,406 | 0.500406 MB | +| BenchmarkDeliverTx_PFB_Multi/1000000_bytes-16 | 0.0004873 ns | 8,572,796 | 1,000,406 | 1.000406 MB | +| BenchmarkDeliverTx_PFB_Multi/2000000_bytes-16 | 0.0004004 ns | 17,071,996 | 2,000,406 | 2.000406 MB | +| BenchmarkDeliverTx_PFB_Multi/3000000_bytes-16 | 0.0003486 ns | 25,571,206 | 3,000,409 | 3.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/4000000_bytes-16 | 0.0004354 ns | 34,066,310 | 4,000,409 | 4.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/5000000_bytes-16 | 0.0003734 ns | 42,565,510 | 5,000,409 | 5.000409 MB | +| BenchmarkDeliverTx_PFB_Multi/6000000_bytes-16 | 0.0003595 ns | 51,064,710 | 6,000,409 | 6.000409 MB | + +#### PrepareProposal: `BenchmarkPrepareProposal_PFB_Multi` + +The benchmarks for `PrepareProposal` for 8mb blocks containing PFBs of different sizes: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Prepare Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|------------------------------------------------------------------------|-----------------|------------------------|---------------------------|-----------------|--------------------------|-----------------------| +| BenchmarkPrepareProposal_PFB_Multi/15000_transactions_of_300_bytes-16 | 6.239 | 10,318 | 2.452 s | 988,490,895,000 | 703 | 0.000703 MB | +| BenchmarkPrepareProposal_PFB_Multi/10000_transactions_of_500_bytes-16 | 5.035 | 6,331 | 1.721 s | 439,343,930,000 | 903 | 0.000903 MB | +| BenchmarkPrepareProposal_PFB_Multi/6000_transactions_of_1000_bytes-16 | 5.809 | 4,566 | 1.063 s | 158,174,358,000 | 1,403 | 0.001403 MB | +| BenchmarkPrepareProposal_PFB_Multi/3000_transactions_of_5000_bytes-16 | 7.188 | 1,413 | 0.527 s | 39,550,179,000 | 5,403 | 0.005403 MB | +| BenchmarkPrepareProposal_PFB_Multi/1000_transactions_of_10000_bytes-16 | 7.470 | 758 | 0.210 s | 4,397,393,000 | 10,403 | 0.010403 MB | +| BenchmarkPrepareProposal_PFB_Multi/500_transactions_of_50000_bytes-16 | 7.441 | 155 | 0.125 s | 1,100,446,500 | 50,406 | 0.050406 MB | +| BenchmarkPrepareProposal_PFB_Multi/100_transactions_of_100000_bytes-16 | 7.368 | 77 | 0.061 s | 44,369,300 | 100,406 | 0.100406 MB | +| BenchmarkPrepareProposal_PFB_Multi/100_transactions_of_200000_bytes-16 | 7.260 | 38 | 0.058 s | 44,369,300 | 200,406 | 0.200406 MB | +| BenchmarkPrepareProposal_PFB_Multi/50_transactions_of_300000_bytes-16 | 7.161 | 25 | 0.042 s | 11,202,150 | 300,406 | 0.300406 MB | +| BenchmarkPrepareProposal_PFB_Multi/50_transactions_of_400000_bytes-16 | 7.254 | 19 | 0.038 s | 11,202,150 | 400,406 | 0.400406 MB | +| BenchmarkPrepareProposal_PFB_Multi/30_transactions_of_500000_bytes-16 | 7.157 | 15 | 0.031 s | 4,085,490 | 500,406 | 0.500406 MB | +| BenchmarkPrepareProposal_PFB_Multi/10_transactions_of_1000000_bytes-16 | 6.678 | 7 | 0.026 s | 483,230 | 1,000,406 | 1.000406 MB | +| BenchmarkPrepareProposal_PFB_Multi/5_transactions_of_2000000_bytes-16 | 5.723 | 3 | 0.027 s | 131,790 | 2,000,406 | 2.000406 MB | +| BenchmarkPrepareProposal_PFB_Multi/3_transactions_of_3000000_bytes-16 | 5.723 | 2 | 0.030 s | 52,716 | 3,000,409 | 3.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/3_transactions_of_4000000_bytes-16 | 3.815 | 1 | 0.026 s | 52,716 | 4,000,409 | 4.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/2_transactions_of_5000000_bytes-16 | 4.769 | 1 | 0.031 s | 26,358 | 5,000,409 | 5.000409 MB | +| BenchmarkPrepareProposal_PFB_Multi/2_transactions_of_6000000_bytes-16 | 5.722 | 1 | 0.028 s | 26,358 | 6,000,409 | 6.000409 MB | + +#### ProcessProposal: `BenchmarkProcessProposal_PFB_Multi` + +The benchmarks for `ProcessProposal` for 8mb blocks containing PFBs of different sizes: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Process Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|------------------------------------------------------------------------|-----------------|------------------------|---------------------------|-----------------|--------------------------|-----------------------| +| BenchmarkProcessProposal_PFB_Multi/15000_transactions_of_300_bytes-16 | 6.239 | 10,318 | 1.813 s | 988,490,895,000 | 703 | 0.000703 MB | +| BenchmarkProcessProposal_PFB_Multi/10000_transactions_of_500_bytes-16 | 5.035 | 6,331 | 1.120 s | 439,343,930,000 | 903 | 0.000903 MB | +| BenchmarkProcessProposal_PFB_Multi/6000_transactions_of_1000_bytes-16 | 5.809 | 4,566 | 0.829 s | 158,174,358,000 | 1,403 | 0.001403 MB | +| BenchmarkProcessProposal_PFB_Multi/3000_transactions_of_5000_bytes-16 | 7.188 | 1,413 | 0.290 s | 39,550,179,000 | 5,403 | 0.005403 MB | +| BenchmarkProcessProposal_PFB_Multi/1000_transactions_of_10000_bytes-16 | 7.470 | 758 | 0.188 s | 4,397,393,000 | 10,403 | 0.010403 MB | +| BenchmarkProcessProposal_PFB_Multi/500_transactions_of_50000_bytes-16 | 7.441 | 155 | 0.076 s | 1,100,446,500 | 50,406 | 0.050406 MB | +| BenchmarkProcessProposal_PFB_Multi/100_transactions_of_100000_bytes-16 | 7.368 | 77 | 0.056 s | 44,369,300 | 100,406 | 0.100406 MB | +| BenchmarkProcessProposal_PFB_Multi/100_transactions_of_200000_bytes-16 | 7.260 | 38 | 0.050 s | 44,369,300 | 200,406 | 0.200406 MB | +| BenchmarkProcessProposal_PFB_Multi/50_transactions_of_300000_bytes-16 | 7.161 | 25 | 0.048 s | 11,202,150 | 300,406 | 0.300406 MB | +| BenchmarkProcessProposal_PFB_Multi/50_transactions_of_400000_bytes-16 | 7.254 | 19 | 0.048 s | 11,202,150 | 400,406 | 0.400406 MB | +| BenchmarkProcessProposal_PFB_Multi/30_transactions_of_500000_bytes-16 | 7.157 | 15 | 0.043 s | 4,085,490 | 500,406 | 0.500406 MB | +| BenchmarkProcessProposal_PFB_Multi/10_transactions_of_1000000_bytes-16 | 6.678 | 7 | 0.041 s | 483,230 | 1,000,406 | 1.000406 MB | +| BenchmarkProcessProposal_PFB_Multi/5_transactions_of_2000000_bytes-16 | 5.723 | 3 | 0.053 s | 131,790 | 2,000,406 | 2.000406 MB | +| BenchmarkProcessProposal_PFB_Multi/3_transactions_of_3000000_bytes-16 | 5.723 | 2 | 0.037 s | 52,716 | 3,000,409 | 3.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/3_transactions_of_4000000_bytes-16 | 3.815 | 1 | 0.071 s | 52,716 | 4,000,409 | 4.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/2_transactions_of_5000000_bytes-16 | 4.769 | 1 | 0.034 s | 26,358 | 5,000,409 | 5.000409 MB | +| BenchmarkProcessProposal_PFB_Multi/2_transactions_of_6000000_bytes-16 | 5.722 | 1 | 0.062 s | 26,358 | 6,000,409 | 6.000409 MB | + +### IBC `UpdateClient` benchmarks + +#### CheckTx: `BenchmarkIBC_CheckTx_Update_Client_Multi` + +The benchmarks of executing `checkTx` on a single transaction containing an IBC `updateClient` with different numbers of required signatures: + +| Benchmark Name | Time (ns/op) | Total Gas Used | Number of Validators | Number of Verified Signatures | Transaction Size (Bytes) | Transaction Size (MB) | +|-----------------------------------------------------------------------|--------------|----------------|----------------------|-------------------------------|--------------------------|-----------------------| +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_2-16 | 1,370 | 108,670 | 2 | 1 | 1,399 | 0.001399 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_10-16 | 3,577 | 127,710 | 10 | 6 | 3,303 | 0.003303 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_25-16 | 7,432 | 163,430 | 25 | 16 | 6,875 | 0.006875 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_50-16 | 9,879 | 222,930 | 50 | 33 | 12,825 | 0.012825 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_75-16 | 12,060 | 282,480 | 75 | 50 | 18,780 | 0.018780 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_100-16 | 13,080 | 341,980 | 100 | 66 | 24,730 | 0.024730 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_125-16 | 14,390 | 401,480 | 125 | 83 | 30,680 | 0.030680 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_150-16 | 16,440 | 459,428 | 150 | 100 | 36,479 | 0.036479 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_175-16 | 17,370 | 520,500 | 175 | 116 | 42,582 | 0.042582 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_200-16 | 18,840 | 580,000 | 200 | 133 | 48,532 | 0.048532 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_225-16 | 21,760 | 637,198 | 225 | 150 | 54,256 | 0.054256 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_250-16 | 19,680 | 699,020 | 250 | 166 | 60,434 | 0.060434 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_300-16 | 22,580 | 818,020 | 300 | 200 | 72,334 | 0.072334 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_400-16 | 25,990 | 1,056,020 | 400 | 266 | 96,134 | 0.096134 MB | +| BenchmarkIBC_CheckTx_Update_Client_Multi/number_of_validators:_500-16 | 27,100 | 1,288,968 | 500 | 333 | 119,433 | 0.119433 MB | + +#### DeliverTx: `BenchmarkIBC_DeliverTx_Update_Client_Multi` + +The benchmarks of executing `deliverTx` on a single transaction containing an IBC `updateClient` with different numbers of required signatures: + +| Benchmark Name | Time (ns/op) | Gas Used | Number of Validators | Number of Verified Signatures | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------|--------------|-----------|----------------------|-------------------------------|--------------------------|-----------------------| +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_2-16 | 1,575 | 107,592 | 2 | 1 | 1,399 | 0.001399 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_10-16 | 1,240 | 126,632 | 10 | 6 | 3,303 | 0.003303 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_25-16 | 1,142 | 162,352 | 25 | 16 | 6,875 | 0.006875 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_50-16 | 16,260 | 221,852 | 50 | 33 | 12,825 | 0.012825 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_75-16 | 13,120 | 281,402 | 75 | 50 | 18,780 | 0.018780 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_100-16 | 7,336 | 340,902 | 100 | 66 | 24,730 | 0.024730 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_125-16 | 7,668 | 399,100 | 125 | 83 | 30,554 | 0.030554 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_150-16 | 5,603 | 459,902 | 150 | 100 | 36,630 | 0.036630 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_175-16 | 11,050 | 519,422 | 175 | 116 | 42,582 | 0.042582 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_200-16 | 9,553 | 578,922 | 200 | 133 | 48,532 | 0.048532 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_225-16 | 13,170 | 638,422 | 225 | 150 | 54,482 | 0.054482 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_250-16 | 8,286 | 695,390 | 250 | 166 | 60,183 | 0.060183 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_300-16 | 15,820 | 816,942 | 300 | 200 | 72,334 | 0.072334 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_400-16 | 19,650 | 1,050,890 | 400 | 266 | 95,733 | 0.095733 MB | +| BenchmarkIBC_DeliverTx_Update_Client_Multi/number_of_validators:_500-16 | 22,900 | 1,292,942 | 500 | 333 | 119,934 | 0.119934 MB | + +#### PrepareProposal: `BenchmarkIBC_PrepareProposal_Update_Client_Multi` + +Benchmarks of an `8mb` containing the maximum number of IBC `UpdateClient` with different number of signatures: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Number of Validators | Number of Verified Signatures | Prepare Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------------|-----------------|------------------------|----------------------|-------------------------------|---------------------------|----------------|--------------------------|-----------------------| +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_2-16 | 7.457 | 5,574 | 2 | 1 | 1.0729 | 389,819,345 | 1,469 | 0.001469 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_10-16 | 7.464 | 2,367 | 10 | 6 | 0.5564 | 210,605,480 | 3,373 | 0.003373 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_25-16 | 7.462 | 1,142 | 25 | 16 | 0.4047 | 142,106,425 | 6,919 | 0.006919 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_50-16 | 7.462 | 610 | 50 | 33 | 0.2432 | 112,364,505 | 12,895 | 0.012895 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_75-16 | 7.452 | 416 | 75 | 50 | 0.1357 | 101,405,415 | 18,850 | 0.018850 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_100-16 | 7.453 | 316 | 100 | 66 | 0.1573 | 95,833,915 | 24,800 | 0.024800 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_125-16 | 7.460 | 256 | 125 | 83 | 0.1653 | 92,549,255 | 30,624 | 0.030624 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_150-16 | 7.445 | 214 | 150 | 100 | 0.1804 | 90,046,805 | 36,549 | 0.036549 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_175-16 | 7.432 | 183 | 175 | 116 | 0.1916 | 88,172,820 | 42,652 | 0.042652 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_200-16 | 7.452 | 161 | 200 | 133 | 0.2167 | 87,153,710 | 48,602 | 0.048602 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_225-16 | 7.430 | 143 | 225 | 150 | 0.2065 | 85,919,620 | 54,552 | 0.054552 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_250-16 | 7.435 | 129 | 250 | 166 | 0.2292 | 85,187,130 | 60,504 | 0.060504 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_300-16 | 7.450 | 108 | 300 | 200 | 0.2440 | 84,173,555 | 72,404 | 0.072404 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_400-16 | 7.426 | 81 | 400 | 266 | 0.2959 | 82,411,590 | 96,204 | 0.096204 | +| BenchmarkIBC_PrepareProposal_Update_Client_Multi/number_of_validators:_500-16 | 7.435 | 65 | 500 | 333 | 0.3309 | 81,605,510 | 120,004 | 0.120004 | + +#### ProcessProposal: `BenchmarkIBC_ProcessProposal_Update_Client_Multi` + +Benchmarks of an `8mb` containing the maximum number of IBC `UpdateClient` with different number of signatures: + +| Benchmark Name | Block Size (MB) | Number of Transactions | Number of Validators | Number of Verified Signatures | Process Proposal Time (s) | Total Gas Used | Transaction Size (Bytes) | Transaction Size (MB) | +|-------------------------------------------------------------------------------|-----------------|------------------------|----------------------|-------------------------------|---------------------------|----------------|--------------------------|-----------------------| +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_2-16 | 7.457 | 5,586 | 2 | 1 | 1.0388 | 390,490,985 | 1,466 | 0.001466 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_10-16 | 7.464 | 2,367 | 10 | 6 | 0.4714 | 210,605,480 | 3,373 | 0.003373 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_25-16 | 7.465 | 1,138 | 25 | 16 | 0.2771 | 141,904,565 | 6,945 | 0.006945 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_50-16 | 7.462 | 610 | 50 | 33 | 0.1598 | 112,364,505 | 12,895 | 0.012895 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_75-16 | 7.452 | 416 | 75 | 50 | 0.1227 | 101,405,415 | 18,850 | 0.018850 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_100-16 | 7.453 | 316 | 100 | 66 | 0.1112 | 95,833,915 | 24,800 | 0.024800 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_125-16 | 7.462 | 255 | 125 | 83 | 0.1012 | 92,509,080 | 30,750 | 0.030750 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_150-16 | 7.441 | 213 | 150 | 100 | 0.1035 | 89,947,710 | 36,700 | 0.036700 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_175-16 | 7.432 | 183 | 175 | 116 | 0.0878 | 88,172,820 | 42,652 | 0.042652 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_200-16 | 7.467 | 162 | 200 | 133 | 0.0974 | 87,369,345 | 48,401 | 0.048401 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_225-16 | 7.451 | 144 | 225 | 150 | 0.0789 | 86,194,935 | 54,326 | 0.054326 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_250-16 | 7.428 | 129 | 250 | 166 | 0.0775 | 85,109,730 | 60,444 | 0.060444 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_300-16 | 7.450 | 108 | 300 | 200 | 0.0879 | 84,173,555 | 72,404 | 0.072404 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_400-16 | 7.426 | 81 | 400 | 266 | 0.0616 | 82,411,590 | 96,204 | 0.096204 | +| BenchmarkIBC_ProcessProposal_Update_Client_Multi/number_of_validators:_500-16 | 7.435 | 65 | 500 | 333 | 0.0596 | 81,605,510 | 120,004 | 0.120004 | + diff --git a/app/check_tx.go b/app/check_tx.go index 0867cd2436..f76b37880f 100644 --- a/app/check_tx.go +++ b/app/check_tx.go @@ -41,9 +41,8 @@ func (app *App) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { switch req.Type { // new transactions must be checked in their entirety case abci.CheckTxType_New: - // FIXME: we have a hardcoded subtree root threshold here. This is because we can't access - // the app version because the context is not initialized - err := blobtypes.ValidateBlobTx(app.txConfig, btx, appconsts.DefaultSubtreeRootThreshold) + appVersion := app.AppVersion() + err := blobtypes.ValidateBlobTx(app.txConfig, btx, appconsts.SubtreeRootThreshold(appVersion), appVersion) if err != nil { return sdkerrors.ResponseCheckTxWithEvents(err, 0, 0, []abci.Event{}, false) } diff --git a/app/default_overrides.go b/app/default_overrides.go index 0ceedaeee1..9e0b5dd382 100644 --- a/app/default_overrides.go +++ b/app/default_overrides.go @@ -8,7 +8,6 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/mint" minttypes "github.com/celestiaorg/celestia-app/v3/x/mint/types" - "github.com/celestiaorg/go-square/v2/share" "github.com/cosmos/cosmos-sdk/codec" serverconfig "github.com/cosmos/cosmos-sdk/server/config" sdk "github.com/cosmos/cosmos-sdk/types" @@ -259,23 +258,17 @@ func DefaultEvidenceParams() tmproto.EvidenceParams { func DefaultConsensusConfig() *tmcfg.Config { cfg := tmcfg.DefaultConfig() // Set broadcast timeout to be 50 seconds in order to avoid timeouts for long block times - // TODO: make TimeoutBroadcastTx configurable per https://github.com/celestiaorg/celestia-app/issues/1034 cfg.RPC.TimeoutBroadcastTxCommit = 50 * time.Second cfg.RPC.MaxBodyBytes = int64(8388608) // 8 MiB - cfg.Mempool.TTLNumBlocks = 5 - cfg.Mempool.TTLDuration = time.Duration(cfg.Mempool.TTLNumBlocks) * appconsts.GoalBlockTime - // Given that there is a stateful transaction size check in CheckTx, - // We set a loose upper bound on what we expect the transaction to - // be based on the upper bound size of the entire block for the given - // version. This acts as a first line of DoS protection - upperBoundBytes := appconsts.DefaultSquareSizeUpperBound * appconsts.DefaultSquareSizeUpperBound * share.ContinuationSparseShareContentSize - cfg.Mempool.MaxTxBytes = upperBoundBytes - cfg.Mempool.MaxTxsBytes = int64(upperBoundBytes) * cfg.Mempool.TTLNumBlocks + cfg.Mempool.TTLNumBlocks = 12 + cfg.Mempool.TTLDuration = 75 * time.Second + cfg.Mempool.MaxTxBytes = 7_897_088 + cfg.Mempool.MaxTxsBytes = 39_485_440 cfg.Mempool.Version = "v1" // prioritized mempool - cfg.Consensus.TimeoutPropose = appconsts.TimeoutPropose - cfg.Consensus.TimeoutCommit = appconsts.TimeoutCommit + cfg.Consensus.TimeoutPropose = appconsts.GetTimeoutPropose(appconsts.LatestVersion) + cfg.Consensus.TimeoutCommit = appconsts.GetTimeoutCommit(appconsts.LatestVersion) cfg.Consensus.SkipTimeoutCommit = false cfg.TxIndex.Indexer = "null" diff --git a/app/default_overrides_test.go b/app/default_overrides_test.go index 674cd13d9f..c78195717a 100644 --- a/app/default_overrides_test.go +++ b/app/default_overrides_test.go @@ -80,11 +80,11 @@ func TestDefaultConsensusConfig(t *testing.T) { Size: tmcfg.DefaultMempoolConfig().Size, WalPath: tmcfg.DefaultMempoolConfig().WalPath, - // overrides + // Overrides MaxTxBytes: 7_897_088, MaxTxsBytes: 39_485_440, TTLDuration: 75 * time.Second, - TTLNumBlocks: 5, + TTLNumBlocks: 12, Version: "v1", } assert.Equal(t, want, *got.Mempool) diff --git a/app/grpc/tx/server.go b/app/grpc/tx/server.go index 93b3c9da36..417b7c088b 100644 --- a/app/grpc/tx/server.go +++ b/app/grpc/tx/server.go @@ -76,6 +76,7 @@ func (s *txServer) TxStatus(ctx context.Context, req *TxStatusRequest) (*TxStatu Height: resTx.Height, Index: resTx.Index, ExecutionCode: resTx.ExecutionCode, + Error: resTx.Error, Status: resTx.Status, }, nil } diff --git a/app/grpc/tx/tx.pb.go b/app/grpc/tx/tx.pb.go index c962ec2dd5..de589600d2 100644 --- a/app/grpc/tx/tx.pb.go +++ b/app/grpc/tx/tx.pb.go @@ -82,8 +82,10 @@ type TxStatusResponse struct { // and returns whether it was successful or errored. A non zero // execution code indicated an error. ExecutionCode uint32 `protobuf:"varint,3,opt,name=execution_code,json=executionCode,proto3" json:"execution_code,omitempty"` + // error log for failed transactions. + Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` // status is the status of the transaction. - Status string `protobuf:"bytes,4,opt,name=status,proto3" json:"status,omitempty"` + Status string `protobuf:"bytes,5,opt,name=status,proto3" json:"status,omitempty"` } func (m *TxStatusResponse) Reset() { *m = TxStatusResponse{} } @@ -140,6 +142,13 @@ func (m *TxStatusResponse) GetExecutionCode() uint32 { return 0 } +func (m *TxStatusResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + func (m *TxStatusResponse) GetStatus() string { if m != nil { return m.Status @@ -155,28 +164,29 @@ func init() { func init() { proto.RegisterFile("celestia/core/v1/tx/tx.proto", fileDescriptor_7d8b070565b0dcb6) } var fileDescriptor_7d8b070565b0dcb6 = []byte{ - // 322 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x51, 0xcd, 0x4a, 0x03, 0x31, - 0x18, 0x6c, 0xfa, 0x87, 0x06, 0xaa, 0x92, 0x8a, 0x2c, 0xa5, 0x84, 0x52, 0x5a, 0xe9, 0xc5, 0x84, - 0xea, 0x1b, 0xe8, 0xa9, 0xd7, 0xb5, 0x27, 0x2f, 0x65, 0xbb, 0x1b, 0xb6, 0x81, 0xba, 0x89, 0x9b, - 0x6f, 0x4b, 0x40, 0x8a, 0xa0, 0x2f, 0x20, 0xf8, 0x52, 0x1e, 0x0b, 0x5e, 0x3c, 0x4a, 0xeb, 0x83, - 0x48, 0xd3, 0x76, 0x05, 0x29, 0x78, 0x08, 0x64, 0x32, 0x93, 0x6f, 0x32, 0x13, 0xdc, 0x0c, 0xc5, - 0x54, 0x18, 0x90, 0x01, 0x0f, 0x55, 0x2a, 0xf8, 0xac, 0xcf, 0xc1, 0x72, 0xb0, 0x4c, 0xa7, 0x0a, - 0x14, 0xa9, 0xef, 0x58, 0xb6, 0x66, 0xd9, 0xac, 0xcf, 0xc0, 0x36, 0x9a, 0xb1, 0x52, 0xf1, 0x54, - 0xf0, 0x40, 0x4b, 0x1e, 0x24, 0x89, 0x82, 0x00, 0xa4, 0x4a, 0xcc, 0xe6, 0x4a, 0xfb, 0x1c, 0x1f, - 0x0f, 0xed, 0x2d, 0x04, 0x90, 0x19, 0x5f, 0x3c, 0x64, 0xc2, 0x00, 0xa9, 0xe3, 0x0a, 0xd8, 0x91, - 0x8c, 0x3c, 0xd4, 0x42, 0xbd, 0x43, 0xbf, 0x0c, 0x76, 0x10, 0xb5, 0x9f, 0xf0, 0xc9, 0xaf, 0xce, - 0x68, 0x95, 0x18, 0x41, 0xce, 0x70, 0x75, 0x22, 0x64, 0x3c, 0x01, 0xa7, 0x2c, 0xf9, 0x5b, 0x44, - 0x4e, 0x71, 0x45, 0x26, 0x91, 0xb0, 0x5e, 0xb1, 0x85, 0x7a, 0x35, 0x7f, 0x03, 0x48, 0x17, 0x1f, - 0x09, 0x2b, 0xc2, 0x6c, 0xed, 0x3e, 0x0a, 0x55, 0x24, 0xbc, 0x92, 0xa3, 0x6b, 0xf9, 0xe9, 0x8d, - 0x8a, 0xdc, 0x50, 0xe3, 0x6c, 0xbc, 0xb2, 0xb3, 0xdf, 0xa2, 0xcb, 0x17, 0x84, 0x8b, 0x43, 0x4b, - 0xe6, 0xf8, 0x60, 0xf7, 0x0e, 0xd2, 0x61, 0x7b, 0xf2, 0xb2, 0x3f, 0x71, 0x1a, 0xdd, 0x7f, 0x54, - 0x9b, 0x30, 0xed, 0xce, 0xf3, 0xc7, 0xf7, 0x5b, 0x91, 0x92, 0x26, 0xdf, 0x57, 0xf1, 0xa3, 0x6b, - 0x64, 0x7e, 0x3d, 0x78, 0x5f, 0x52, 0xb4, 0x58, 0x52, 0xf4, 0xb5, 0xa4, 0xe8, 0x75, 0x45, 0x0b, - 0x8b, 0x15, 0x2d, 0x7c, 0xae, 0x68, 0xe1, 0x8e, 0xc7, 0x12, 0x26, 0xd9, 0x98, 0x85, 0xea, 0x3e, - 0x9f, 0xa0, 0xd2, 0x38, 0xdf, 0x5f, 0x04, 0x5a, 0xf3, 0xf5, 0x8a, 0x53, 0x1d, 0x72, 0xb0, 0xe3, - 0xaa, 0xfb, 0x80, 0xab, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdb, 0x2a, 0x51, 0xff, 0xd3, 0x01, - 0x00, 0x00, + // 337 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x51, 0xcd, 0x4a, 0x33, 0x31, + 0x14, 0x6d, 0xfa, 0xc7, 0xf7, 0x05, 0xfa, 0x7d, 0x92, 0x8a, 0x0c, 0xa5, 0x0c, 0xa5, 0xb4, 0xd2, + 0x8d, 0x13, 0xaa, 0x6f, 0xa0, 0xab, 0x6e, 0xc7, 0xae, 0xdc, 0x94, 0xe9, 0xcc, 0x65, 0x1a, 0xa8, + 0x93, 0x31, 0xb9, 0x53, 0x02, 0xd2, 0x8d, 0xbe, 0x80, 0x20, 0xbe, 0x93, 0xcb, 0x82, 0x1b, 0x97, + 0xd2, 0xfa, 0x20, 0x32, 0x99, 0xb6, 0x82, 0x14, 0x5c, 0x04, 0x72, 0xee, 0x39, 0x37, 0x27, 0xf7, + 0x5c, 0xda, 0x0e, 0x61, 0x0e, 0x1a, 0x45, 0xc0, 0x43, 0xa9, 0x80, 0x2f, 0x86, 0x1c, 0x0d, 0x47, + 0xe3, 0xa5, 0x4a, 0xa2, 0x64, 0xcd, 0x1d, 0xeb, 0xe5, 0xac, 0xb7, 0x18, 0x7a, 0x68, 0x5a, 0xed, + 0x58, 0xca, 0x78, 0x0e, 0x3c, 0x48, 0x05, 0x0f, 0x92, 0x44, 0x62, 0x80, 0x42, 0x26, 0xba, 0x68, + 0xe9, 0x9e, 0xd2, 0xff, 0x63, 0x73, 0x8d, 0x01, 0x66, 0xda, 0x87, 0xbb, 0x0c, 0x34, 0xb2, 0x26, + 0xad, 0xa1, 0x99, 0x88, 0xc8, 0x21, 0x1d, 0x32, 0xf8, 0xeb, 0x57, 0xd1, 0x8c, 0xa2, 0xee, 0x0b, + 0xa1, 0x47, 0xdf, 0x42, 0x9d, 0xca, 0x44, 0x03, 0x3b, 0xa1, 0xf5, 0x19, 0x88, 0x78, 0x86, 0x56, + 0x5a, 0xf1, 0xb7, 0x88, 0x1d, 0xd3, 0x9a, 0x48, 0x22, 0x30, 0x4e, 0xb9, 0x43, 0x06, 0x0d, 0xbf, + 0x00, 0xac, 0x4f, 0xff, 0x81, 0x81, 0x30, 0xcb, 0xed, 0x27, 0xa1, 0x8c, 0xc0, 0xa9, 0x58, 0xba, + 0xb1, 0xaf, 0x5e, 0xc9, 0x08, 0xf2, 0x66, 0x50, 0x4a, 0x2a, 0xa7, 0x6a, 0xed, 0x0b, 0x90, 0x5b, + 0x69, 0x6b, 0xee, 0xd4, 0x6c, 0x79, 0x8b, 0xce, 0x1f, 0x09, 0x2d, 0x8f, 0x0d, 0x5b, 0xd2, 0x3f, + 0xbb, 0xdf, 0xb1, 0x9e, 0x77, 0x20, 0x06, 0xef, 0xc7, 0x94, 0xad, 0xfe, 0x2f, 0xaa, 0x62, 0xc4, + 0x6e, 0xef, 0xe1, 0xed, 0xf3, 0xb9, 0xec, 0xb2, 0x36, 0x3f, 0x94, 0xfc, 0xbd, 0x0d, 0x6a, 0x79, + 0x39, 0x7a, 0x5d, 0xbb, 0x64, 0xb5, 0x76, 0xc9, 0xc7, 0xda, 0x25, 0x4f, 0x1b, 0xb7, 0xb4, 0xda, + 0xb8, 0xa5, 0xf7, 0x8d, 0x5b, 0xba, 0xe1, 0xb1, 0xc0, 0x59, 0x36, 0xf5, 0x42, 0x79, 0xbb, 0x7f, + 0x41, 0xaa, 0x78, 0x7f, 0x3f, 0x0b, 0xd2, 0x94, 0xe7, 0x27, 0x56, 0x69, 0xc8, 0xd1, 0x4c, 0xeb, + 0x76, 0x2f, 0x17, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x2f, 0x1b, 0xd1, 0xea, 0x01, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -324,6 +334,13 @@ func (m *TxStatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Status) i = encodeVarintTx(dAtA, i, uint64(len(m.Status))) i-- + dAtA[i] = 0x2a + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintTx(dAtA, i, uint64(len(m.Error))) + i-- dAtA[i] = 0x22 } if m.ExecutionCode != 0 { @@ -383,6 +400,10 @@ func (m *TxStatusResponse) Size() (n int) { if m.ExecutionCode != 0 { n += 1 + sovTx(uint64(m.ExecutionCode)) } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } l = len(m.Status) if l > 0 { n += 1 + l + sovTx(uint64(l)) @@ -565,6 +586,38 @@ func (m *TxStatusResponse) Unmarshal(dAtA []byte) error { } } case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) } diff --git a/app/module/configurator_test.go b/app/module/configurator_test.go index b81516dfee..a93713938a 100644 --- a/app/module/configurator_test.go +++ b/app/module/configurator_test.go @@ -6,8 +6,8 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/app/module" - "github.com/celestiaorg/celestia-app/x/signal" - signaltypes "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/cosmos/cosmos-sdk/store" storetypes "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/tests/mocks" diff --git a/app/module/versioned_ibc_module_test.go b/app/module/versioned_ibc_module_test.go index 8d2fb23d0e..57f94ec9f9 100644 --- a/app/module/versioned_ibc_module_test.go +++ b/app/module/versioned_ibc_module_test.go @@ -23,7 +23,7 @@ func TestVersionedIBCModule(t *testing.T) { mockWrappedModule := mocks.NewMockIBCModule(ctrl) mockNextModule := mocks.NewMockIBCModule(ctrl) - versionedModule := module.NewVersionedIBCModule(mockWrappedModule, mockNextModule, 2, 2) + versionedModule := module.NewVersionedIBCModule(mockWrappedModule, mockNextModule, 2, 3) testCases := []struct { name string diff --git a/app/modules.go b/app/modules.go index 8890054d89..d629a99073 100644 --- a/app/modules.go +++ b/app/modules.go @@ -12,8 +12,8 @@ import ( "github.com/celestiaorg/celestia-app/v3/x/minfee" "github.com/celestiaorg/celestia-app/v3/x/mint" minttypes "github.com/celestiaorg/celestia-app/v3/x/mint/types" - "github.com/celestiaorg/celestia-app/x/signal" - signaltypes "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" sdkmodule "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/auth" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -91,9 +91,6 @@ var ( ModuleEncodingRegisters = extractRegisters(ModuleBasics) ) -// TODO: remove this constant. The v2 state machin shouldn't need to support app version 3. -const v3 = uint64(3) - func (app *App) setupModuleManager(skipGenesisInvariants bool) error { var err error app.manager, err = module.NewManager([]module.VersionedModule{ @@ -306,7 +303,7 @@ func allStoreKeys() []string { // versionedStoreKeys returns the store keys for each app version. func versionedStoreKeys() map[uint64][]string { return map[uint64][]string{ - 1: { + v1: { authtypes.StoreKey, authzkeeper.StoreKey, banktypes.StoreKey, @@ -324,7 +321,7 @@ func versionedStoreKeys() map[uint64][]string { stakingtypes.StoreKey, upgradetypes.StoreKey, }, - 2: { + v2: { authtypes.StoreKey, authzkeeper.StoreKey, banktypes.StoreKey, @@ -344,7 +341,7 @@ func versionedStoreKeys() map[uint64][]string { stakingtypes.StoreKey, upgradetypes.StoreKey, }, - 3: { + v3: { // same as v2 authtypes.StoreKey, authzkeeper.StoreKey, banktypes.StoreKey, diff --git a/app/prepare_proposal.go b/app/prepare_proposal.go index 78049a1ad4..a34c64bd7d 100644 --- a/app/prepare_proposal.go +++ b/app/prepare_proposal.go @@ -1,13 +1,16 @@ package app import ( + "fmt" "time" "github.com/celestiaorg/celestia-app/v3/app/ante" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/pkg/da" - square "github.com/celestiaorg/go-square/v2" - "github.com/celestiaorg/go-square/v2/share" + shares "github.com/celestiaorg/go-square/shares" + square "github.com/celestiaorg/go-square/square" + squarev2 "github.com/celestiaorg/go-square/v2" + sharev2 "github.com/celestiaorg/go-square/v2/share" "github.com/cosmos/cosmos-sdk/telemetry" abci "github.com/tendermint/tendermint/abci/types" core "github.com/tendermint/tendermint/proto/tendermint/types" @@ -27,7 +30,7 @@ func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePr Height: req.Height, Time: req.Time, Version: version.Consensus{ - App: app.BaseApp.AppVersion(), + App: app.AppVersion(), }, }) handler := ante.NewAnteHandler( @@ -47,10 +50,31 @@ func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePr // Build the square from the set of valid and prioritised transactions. // The txs returned are the ones used in the square and block. - dataSquare, txs, err := square.Build(txs, - app.MaxEffectiveSquareSize(sdkCtx), - appconsts.SubtreeRootThreshold(app.GetBaseApp().AppVersion()), + var ( + dataSquareBytes [][]byte + err error + size uint64 ) + switch app.AppVersion() { + case v3: + var dataSquare squarev2.Square + dataSquare, txs, err = squarev2.Build(txs, + app.MaxEffectiveSquareSize(sdkCtx), + appconsts.SubtreeRootThreshold(app.GetBaseApp().AppVersion()), + ) + dataSquareBytes = sharev2.ToBytes(dataSquare) + size = uint64(dataSquare.Size()) + case v2, v1: + var dataSquare square.Square + dataSquare, txs, err = square.Build(txs, + app.MaxEffectiveSquareSize(sdkCtx), + appconsts.SubtreeRootThreshold(app.GetBaseApp().AppVersion()), + ) + dataSquareBytes = shares.ToBytes(dataSquare) + size = uint64(dataSquare.Size()) + default: + err = fmt.Errorf("unsupported app version: %d", app.AppVersion()) + } if err != nil { panic(err) } @@ -58,7 +82,7 @@ func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePr // Erasure encode the data square to create the extended data square (eds). // Note: uses the nmt wrapper to construct the tree. See // pkg/wrapper/nmt_wrapper.go for more information. - eds, err := da.ExtendShares(share.ToBytes(dataSquare)) + eds, err := da.ExtendShares(dataSquareBytes) if err != nil { app.Logger().Error( "failure to erasure the data square while creating a proposal block", @@ -84,7 +108,7 @@ func (app *App) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePr return abci.ResponsePrepareProposal{ BlockData: &core.Data{ Txs: txs, - SquareSize: uint64(dataSquare.Size()), + SquareSize: size, Hash: dah.Hash(), // also known as the data root }, } diff --git a/app/process_proposal.go b/app/process_proposal.go index d1b367179c..68e574f67d 100644 --- a/app/process_proposal.go +++ b/app/process_proposal.go @@ -9,8 +9,10 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/pkg/da" blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" - "github.com/celestiaorg/go-square/v2" - "github.com/celestiaorg/go-square/v2/share" + shares "github.com/celestiaorg/go-square/shares" + square "github.com/celestiaorg/go-square/square" + squarev2 "github.com/celestiaorg/go-square/v2" + sharev2 "github.com/celestiaorg/go-square/v2/share" blobtx "github.com/celestiaorg/go-square/v2/tx" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" @@ -65,7 +67,15 @@ func (app *App) ProcessProposal(req abci.RequestProcessProposal) (resp abci.Resp tx = blobTx.Tx } + // todo: uncomment once we're sure this isn't consensus breaking + // sdkCtx = sdkCtx.WithTxBytes(tx) + sdkTx, err := app.txConfig.TxDecoder()(tx) + // Set the tx bytes in the context for app version v3 and greater + if sdkCtx.BlockHeader().Version.App >= 3 { + sdkCtx = sdkCtx.WithTxBytes(tx) + } + if err != nil { if req.Header.Version.App == v1 { // For appVersion 1, there was no block validity rule that all @@ -108,7 +118,7 @@ func (app *App) ProcessProposal(req abci.RequestProcessProposal) (resp abci.Resp // - that the sizes match // - that the namespaces match between blob and PFB // - that the share commitment is correct - if err := blobtypes.ValidateBlobTx(app.txConfig, blobTx, subtreeRootThreshold); err != nil { + if err := blobtypes.ValidateBlobTx(app.txConfig, blobTx, subtreeRootThreshold, app.AppVersion()); err != nil { logInvalidPropBlockError(app.Logger(), req.Header, fmt.Sprintf("invalid blob tx %d", idx), err) return reject() } @@ -122,24 +132,40 @@ func (app *App) ProcessProposal(req abci.RequestProcessProposal) (resp abci.Resp } - // Construct the data square from the block's transactions - dataSquare, err := square.Construct( - req.BlockData.Txs, - app.MaxEffectiveSquareSize(sdkCtx), - subtreeRootThreshold, + var ( + dataSquareBytes [][]byte + err error ) - if err != nil { - logInvalidPropBlockError(app.Logger(), req.Header, "failure to compute data square from transactions:", err) + + switch app.AppVersion() { + case v3: + var dataSquare squarev2.Square + dataSquare, err = squarev2.Construct(req.BlockData.Txs, app.MaxEffectiveSquareSize(sdkCtx), subtreeRootThreshold) + dataSquareBytes = sharev2.ToBytes(dataSquare) + // Assert that the square size stated by the proposer is correct + if uint64(dataSquare.Size()) != req.BlockData.SquareSize { + logInvalidPropBlock(app.Logger(), req.Header, "proposed square size differs from calculated square size") + return reject() + } + case v2, v1: + var dataSquare square.Square + dataSquare, err = square.Construct(req.BlockData.Txs, app.MaxEffectiveSquareSize(sdkCtx), subtreeRootThreshold) + dataSquareBytes = shares.ToBytes(dataSquare) + // Assert that the square size stated by the proposer is correct + if uint64(dataSquare.Size()) != req.BlockData.SquareSize { + logInvalidPropBlock(app.Logger(), req.Header, "proposed square size differs from calculated square size") + return reject() + } + default: + logInvalidPropBlock(app.Logger(), req.Header, "unsupported app version") return reject() } - - // Assert that the square size stated by the proposer is correct - if uint64(dataSquare.Size()) != req.BlockData.SquareSize { - logInvalidPropBlock(app.Logger(), req.Header, "proposed square size differs from calculated square size") + if err != nil { + logInvalidPropBlockError(app.Logger(), req.Header, "failure to compute data square from transactions:", err) return reject() } - eds, err := da.ExtendShares(share.ToBytes(dataSquare)) + eds, err := da.ExtendShares(dataSquareBytes) if err != nil { logInvalidPropBlockError(app.Logger(), req.Header, "failure to erasure the data square", err) return reject() diff --git a/app/test/big_blob_test.go b/app/test/big_blob_test.go index 41934c6379..cede1ae65d 100644 --- a/app/test/big_blob_test.go +++ b/app/test/big_blob_test.go @@ -82,8 +82,9 @@ func (s *BigBlobSuite) TestErrBlobsTooLarge() { defer cancel() res, err := txClient.SubmitPayForBlob(subCtx, []*share.Blob{tc.blob}, user.SetGasLimitAndGasPrice(1e9, appconsts.DefaultMinGasPrice)) require.Error(t, err) - require.NotNil(t, res) - require.Equal(t, tc.want, res.Code, res.Logs) + require.Nil(t, res) + code := err.(*user.BroadcastTxError).Code + require.Equal(t, tc.want, code, err.Error()) }) } } diff --git a/app/test/circuit_breaker_test.go b/app/test/circuit_breaker_test.go index 5cb01b554b..078f53bc08 100644 --- a/app/test/circuit_breaker_test.go +++ b/app/test/circuit_breaker_test.go @@ -11,7 +11,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/test/util" "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" - signaltypes "github.com/celestiaorg/celestia-app/x/signal/types" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/authz" "github.com/stretchr/testify/assert" diff --git a/app/test/consistent_apphash_test.go b/app/test/consistent_apphash_test.go index 972f42da58..9a108e4dd1 100644 --- a/app/test/consistent_apphash_test.go +++ b/app/test/consistent_apphash_test.go @@ -8,19 +8,25 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" "github.com/celestiaorg/celestia-app/v3/pkg/user" testutil "github.com/celestiaorg/celestia-app/v3/test/util" "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" + blobstreamtypes "github.com/celestiaorg/celestia-app/v3/x/blobstream/types" + signal "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/celestiaorg/go-square/v2/share" "github.com/celestiaorg/go-square/v2/tx" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" "github.com/cosmos/cosmos-sdk/x/authz" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" crisisTypes "github.com/cosmos/cosmos-sdk/x/crisis/types" @@ -29,72 +35,125 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types/v1" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + gethcommon "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/proto/tendermint/version" ) -type BlobTx struct { +type blobTx struct { author string blobs []*share.Blob txOptions []user.TxOption } -// TestConsistentAppHash executes all state machine messages, generates an app hash, +type ( + encodedSdkMessages func(*testing.T, []sdk.AccAddress, []stakingtypes.Validator, *app.App, *user.Signer, *user.Signer) ([][]byte, [][]byte, [][]byte) + encodedBlobTxs func(*testing.T, *user.Signer, []sdk.AccAddress) []byte +) + +type appHashTest struct { + name string + version uint64 + encodedSdkMessages encodedSdkMessages + encodedBlobTxs encodedBlobTxs + expectedDataRoot []byte + expectedAppHash []byte +} + +// TestConsistentAppHash executes all state machine messages on all app versions, generates an app hash, // and compares it against a previously generated hash from the same set of transactions. // App hashes across different commits should be consistent. func TestConsistentAppHash(t *testing.T) { - // Expected app hash produced by v1.x - https://github.com/celestiaorg/celestia-app/blob/v1.x/app/consistent_apphash_test.go - expectedAppHash := []byte{84, 216, 210, 48, 113, 204, 234, 21, 150, 236, 97, 87, 242, 184, 45, 248, 116, 127, 49, 88, 134, 197, 202, 125, 44, 210, 67, 144, 107, 51, 145, 65} - expectedDataRoot := []byte{100, 59, 112, 241, 238, 49, 50, 64, 105, 90, 209, 211, 49, 254, 211, 83, 133, 88, 5, 89, 221, 116, 141, 72, 33, 110, 16, 78, 5, 48, 118, 72} - - // Initialize testApp - testApp := testutil.NewTestApp() - enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) - - // Create deterministic keys - kr, pubKeys := deterministicKeyRing(enc.Codec) - - // Apply genesis state to the app. - valKeyRing, _, err := testutil.SetupDeterministicGenesisState(testApp, pubKeys, 20_000_000_000, app.DefaultInitialConsensusParams()) - require.NoError(t, err) + tc := []appHashTest{ + { + name: "execute sdk messages and blob tx on v1", + version: v1.Version, + encodedSdkMessages: encodedSdkMessagesV1, + encodedBlobTxs: createEncodedBlobTx, + expectedDataRoot: []byte{30, 142, 46, 120, 191, 30, 242, 150, 164, 242, 166, 245, 89, 183, 181, 41, 88, 197, 11, 19, 243, 46, 69, 97, 3, 51, 27, 133, 68, 95, 95, 121}, + // Expected app hash produced by v1.x - https://github.com/celestiaorg/celestia-app/blob/v1.x/app/consistent_apphash_test.go + expectedAppHash: []byte{57, 128, 107, 57, 6, 131, 221, 188, 181, 181, 135, 58, 37, 240, 135, 66, 199, 107, 80, 154, 240, 176, 57, 36, 238, 69, 25, 188, 86, 203, 145, 145}, + }, + { + name: "execute sdk messages and blob tx on v2", + version: v2.Version, + encodedSdkMessages: func(t *testing.T, accountAddresses []sdk.AccAddress, genValidators []stakingtypes.Validator, testApp *app.App, signer *user.Signer, valSigner *user.Signer) ([][]byte, [][]byte, [][]byte) { + firstBlockEncodedTxs, secondBlockEncodedTxs, thirdBlockEncodedTxs := encodedSdkMessagesV1(t, accountAddresses, genValidators, testApp, signer, valSigner) + encodedMessagesV2 := encodedSdkMessagesV2(t, genValidators, valSigner) + thirdBlockEncodedTxs = append(thirdBlockEncodedTxs, encodedMessagesV2...) + + return firstBlockEncodedTxs, secondBlockEncodedTxs, thirdBlockEncodedTxs + }, + encodedBlobTxs: createEncodedBlobTx, + expectedDataRoot: []byte{200, 61, 245, 166, 119, 211, 170, 2, 73, 239, 253, 97, 243, 112, 116, 196, 70, 41, 201, 172, 123, 28, 15, 182, 52, 222, 122, 243, 95, 97, 66, 233}, + // Expected app hash produced on v2.x - https://github.com/celestiaorg/celestia-app/blob/v2.x/app/test/consistent_apphash_test.go + expectedAppHash: []byte{14, 115, 34, 28, 33, 70, 118, 3, 111, 250, 161, 185, 187, 151, 54, 78, 86, 37, 44, 252, 8, 26, 164, 251, 36, 20, 151, 170, 181, 84, 32, 136}, + }, + } - // ------------ Genesis User Accounts ------------ + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + testApp := testutil.NewTestApp() + enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) + // Create deterministic keys + kr, pubKeys := deterministicKeyRing(enc.Codec) + consensusParams := app.DefaultConsensusParams() + consensusParams.Version.AppVersion = tt.version + // Apply genesis state to the app. + valKeyRing, _, err := testutil.SetupDeterministicGenesisState(testApp, pubKeys, 20_000_000_000, consensusParams) + require.NoError(t, err) + + // Get account names and addresses from the keyring and create signer + signer, accountAddresses := getAccountsAndCreateSigner(t, kr, enc.TxConfig, testutil.ChainID, tt.version, testApp) + // Validators from genesis state + genValidators := testApp.StakingKeeper.GetAllValidators(testApp.NewContext(false, tmproto.Header{})) + valSigner, _ := getAccountsAndCreateSigner(t, valKeyRing, enc.TxConfig, testutil.ChainID, tt.version, testApp) + + // Convert validators to ABCI validators + abciValidators, err := convertToABCIValidators(genValidators) + require.NoError(t, err) + + firstBlockTxs, secondBlockTxs, thirdBlockTxs := tt.encodedSdkMessages(t, accountAddresses, genValidators, testApp, signer, valSigner) + encodedBlobTx := tt.encodedBlobTxs(t, signer, accountAddresses) + + // Execute the first block + _, firstBlockAppHash, err := executeTxs(testApp, []byte{}, firstBlockTxs, abciValidators, testApp.LastCommitID().Hash) + require.NoError(t, err) + // Execute the second block + _, secondBlockAppHash, err := executeTxs(testApp, encodedBlobTx, secondBlockTxs, abciValidators, firstBlockAppHash) + require.NoError(t, err) + // Execute the final block and get the data root alongside the final app hash + finalDataRoot, finalAppHash, err := executeTxs(testApp, []byte{}, thirdBlockTxs, abciValidators, secondBlockAppHash) + require.NoError(t, err) + + // Require that the app hash is equal to the app hash produced on a different commit + require.Equal(t, tt.expectedAppHash, finalAppHash) + // Require that the data root is equal to the data root produced on a different commit + require.Equal(t, tt.expectedDataRoot, finalDataRoot) + }) + } +} +// getAccountsAndCreateSigner returns a signer with accounts +func getAccountsAndCreateSigner(t *testing.T, kr keyring.Keyring, enc client.TxConfig, chainID string, appVersion uint64, testApp *app.App) (*user.Signer, []sdk.AccAddress) { // Get account names and addresses from the keyring accountNames := testfactory.GetAccountNames(kr) accountAddresses := testfactory.GetAddresses(kr) - // Query keyring account infos accountInfos := queryAccountInfo(testApp, accountNames, kr) - // Create accounts for the signer accounts := createAccounts(accountInfos, accountNames) - // Create a signer with accounts - signer, err := user.NewSigner(kr, enc.TxConfig, testutil.ChainID, app.DefaultInitialVersion, accounts...) - require.NoError(t, err) - - // ------------ Genesis Validator Accounts ------------ - - // Validators from genesis state - genValidators := testApp.StakingKeeper.GetAllValidators(testApp.NewContext(false, tmproto.Header{})) - - // Get validator account names from the validator keyring - valAccountNames := testfactory.GetAccountNames(valKeyRing) - - // Query validator account infos - valAccountInfos := queryAccountInfo(testApp, valAccountNames, valKeyRing) - - // Create accounts for the validators' signer - valAccounts := createAccounts(valAccountInfos, valAccountNames) - - // Create a signer with validator accounts - valSigner, err := user.NewSigner(valKeyRing, enc.TxConfig, testutil.ChainID, app.DefaultInitialVersion, valAccounts...) + signer, err := user.NewSigner(kr, enc, chainID, appVersion, accounts...) require.NoError(t, err) + return signer, accountAddresses +} - // ----------- Create SDK Messages ------------ +// encodedSdkMessagesV1 returns encoded SDK messages for v1 +func encodedSdkMessagesV1(t *testing.T, accountAddresses []sdk.AccAddress, genValidators []stakingtypes.Validator, testApp *app.App, signer *user.Signer, valSigner *user.Signer) ([][]byte, [][]byte, [][]byte) { + // ----------- Create v1 SDK Messages ------------ amount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewIntFromUint64(1_000))) // Minimum deposit required for a gov proposal to become active @@ -242,6 +301,27 @@ func TestConsistentAppHash(t *testing.T) { msgWithdrawDelegatorReward := distribution.NewMsgWithdrawDelegatorReward(accountAddresses[0], genValidators[0].GetOperator()) secondBlockSdkMsgs = append(secondBlockSdkMsgs, msgWithdrawDelegatorReward) + // NewMsgCreatePeriodicVestingAccount - creates a periodic vesting account + newAddress := sdk.AccAddress(ed25519.GenPrivKeyFromSecret([]byte("anotherAddress")).PubKey().Address()) + vestingPeriod := []vestingtypes.Period{ + { + Length: 3600, + Amount: amount, + }, + } + msgCreatePeriodicVestingAccount := vestingtypes.NewMsgCreatePeriodicVestingAccount(accountAddresses[3], newAddress, 2, vestingPeriod) + secondBlockSdkMsgs = append(secondBlockSdkMsgs, msgCreatePeriodicVestingAccount) + + // NewMsgCreatePermanentLockedAccount - creates a permanent locked account + newAddress = sdk.AccAddress(ed25519.GenPrivKeyFromSecret([]byte("anotherAddress2")).PubKey().Address()) + msgCreatePermamentLockedAccount := vestingtypes.NewMsgCreatePermanentLockedAccount(accountAddresses[3], newAddress, amount) + secondBlockSdkMsgs = append(secondBlockSdkMsgs, msgCreatePermamentLockedAccount) + + // NewMsgCreateVestingAccount - creates a vesting account + newAddress = sdk.AccAddress(ed25519.GenPrivKeyFromSecret([]byte("anotherAddress3")).PubKey().Address()) + msgCreateVestingAccount := vestingtypes.NewMsgCreateVestingAccount(accountAddresses[3], newAddress, amount, 1, 2, false) + secondBlockSdkMsgs = append(secondBlockSdkMsgs, msgCreateVestingAccount) + // ------------ Third Block ------------ // Txs within the third block are signed by the validator's signer @@ -255,51 +335,53 @@ func TestConsistentAppHash(t *testing.T) { msgUnjail := slashingtypes.NewMsgUnjail(genValidators[3].GetOperator()) thirdBlockSdkMsgs = append(thirdBlockSdkMsgs, msgUnjail) - // ------------ Construct Txs ------------ + // NewMsgRegisterEVMAddress - registers an EVM address + // This message was removed in v2 + if testApp.AppVersion() == v1.Version { + msgRegisterEVMAddress := blobstreamtypes.NewMsgRegisterEVMAddress(genValidators[1].GetOperator(), gethcommon.HexToAddress("hi")) + thirdBlockSdkMsgs = append(thirdBlockSdkMsgs, msgRegisterEVMAddress) + } - // Create SDK transactions from the list of messages - // and separate them into 3 different blocks - firstBlockEncodedTxs, err := processSdkMessages(signer, firstBlockSdkMsgs) + firstBlockTxs, err := processSdkMessages(signer, firstBlockSdkMsgs) require.NoError(t, err) - - secondBlockEncodedTxs, err := processSdkMessages(signer, secondBlockSdkMsgs) + secondBlockTxs, err := processSdkMessages(signer, secondBlockSdkMsgs) + require.NoError(t, err) + thirdBlockTxs, err := processSdkMessages(valSigner, thirdBlockSdkMsgs) require.NoError(t, err) - thirdBlockEncodedTxs, err := processSdkMessages(valSigner, thirdBlockSdkMsgs) + return firstBlockTxs, secondBlockTxs, thirdBlockTxs +} + +// encodedSdkMessagesV2 returns encoded SDK messages introduced in v2 +func encodedSdkMessagesV2(t *testing.T, genValidators []stakingtypes.Validator, valSigner *user.Signer) [][]byte { + var v2Messages []sdk.Msg + msgTryUpgrade := signal.NewMsgTryUpgrade(sdk.AccAddress(genValidators[0].GetOperator())) + v2Messages = append(v2Messages, msgTryUpgrade) + + msgSignalVersion := signal.NewMsgSignalVersion(genValidators[0].GetOperator(), 2) + v2Messages = append(v2Messages, msgSignalVersion) + + encodedTxs, err := processSdkMessages(valSigner, v2Messages) require.NoError(t, err) + return encodedTxs +} + +// createEncodedBlobTx creates, signs and returns an encoded blob transaction +func createEncodedBlobTx(t *testing.T, signer *user.Signer, accountAddresses []sdk.AccAddress) []byte { + senderAcc := signer.AccountByAddress(accountAddresses[1]) blob, err := share.NewBlob(fixedNamespace(), []byte{1}, appconsts.DefaultShareVersion, nil) require.NoError(t, err) // Create a Blob Tx - blobTx := BlobTx{ - author: accountNames[1], + blobTx := blobTx{ + author: senderAcc.Name(), blobs: []*share.Blob{blob}, txOptions: blobfactory.DefaultTxOpts(), } encodedBlobTx, _, err := signer.CreatePayForBlobs(blobTx.author, blobTx.blobs, blobTx.txOptions...) require.NoError(t, err) - - // Convert validators to ABCI validators - abciValidators, err := convertToABCIValidators(genValidators) - require.NoError(t, err) - - // Execute the first block - _, firstBlockAppHash, err := executeTxs(testApp, []byte{}, firstBlockEncodedTxs, abciValidators, testApp.LastCommitID().Hash) - require.NoError(t, err) - - // Execute the second block - _, secondBlockAppHash, err := executeTxs(testApp, encodedBlobTx, secondBlockEncodedTxs, abciValidators, firstBlockAppHash) - require.NoError(t, err) - - // Execute the final block and get the data root alongside the final app hash - finalDataRoot, finalAppHash, err := executeTxs(testApp, []byte{}, thirdBlockEncodedTxs, abciValidators, secondBlockAppHash) - require.NoError(t, err) - - // Require that the app hash is equal to the app hash produced on a different commit - require.Equal(t, expectedAppHash, finalAppHash) - // Require that the data root is equal to the data root produced on a different commit - require.Equal(t, expectedDataRoot, finalDataRoot) + return encodedBlobTx } // fixedNamespace returns a hardcoded namespace @@ -388,7 +470,7 @@ func executeTxs(testApp *app.App, encodedBlobTx []byte, encodedSdkTxs [][]byte, dataHash := resPrepareProposal.BlockData.Hash header := tmproto.Header{ - Version: version.Consensus{App: 1}, + Version: version.Consensus{App: testApp.AppVersion()}, DataHash: resPrepareProposal.BlockData.Hash, ChainID: chainID, Time: genesisTime.Add(time.Duration(height) * time.Minute), diff --git a/app/test/prepare_proposal_context_test.go b/app/test/prepare_proposal_context_test.go index dbec6798b3..d01fad5a9d 100644 --- a/app/test/prepare_proposal_context_test.go +++ b/app/test/prepare_proposal_context_test.go @@ -12,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/assert" @@ -80,8 +81,11 @@ func TestTimeInPrepareProposalContext(t *testing.T) { msgs, _ := tt.msgFunc() res, err := txClient.SubmitTx(cctx.GoContext(), msgs, user.SetGasLimit(1000000), user.SetFee(2000)) require.NoError(t, err) + serviceClient := sdktx.NewServiceClient(cctx.GRPCClient) + getTxResp, err := serviceClient.GetTx(cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash}) + require.NoError(t, err) require.NotNil(t, res) - assert.Equal(t, abci.CodeTypeOK, res.Code, res.RawLog) + assert.Equal(t, abci.CodeTypeOK, res.Code, getTxResp.TxResponse.RawLog) }) } } diff --git a/app/test/prepare_proposal_test.go b/app/test/prepare_proposal_test.go index 8bfcc281f8..f274d9da6a 100644 --- a/app/test/prepare_proposal_test.go +++ b/app/test/prepare_proposal_test.go @@ -1,9 +1,21 @@ package app_test import ( + "crypto/rand" + "strings" "testing" "time" + blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" + blobtx "github.com/celestiaorg/go-square/v2/tx" + + "github.com/celestiaorg/celestia-app/v3/pkg/user" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/assert" + tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/cosmos/cosmos-sdk/crypto/hd" @@ -39,6 +51,7 @@ func TestPrepareProposalPutsPFBsAtEnd(t *testing.T) { accnts[:numBlobTxs], infos[:numBlobTxs], testfactory.Repeat([]*share.Blob{protoBlob}, numBlobTxs), + blobfactory.DefaultTxOpts()..., ) normalTxs := testutil.SendTxsWithAccounts( @@ -96,6 +109,7 @@ func TestPrepareProposalFiltering(t *testing.T) { testfactory.RandomBlobNamespaces(tmrand.NewRand(), 3), [][]int{{100}, {1000}, {420}}, ), + blobfactory.DefaultTxOpts()..., ) // create 3 MsgSend transactions that are signed with valid account numbers @@ -137,6 +151,44 @@ func TestPrepareProposalFiltering(t *testing.T) { require.NoError(t, err) noAccountTx := []byte(testutil.SendTxWithManualSequence(t, encConf.TxConfig, kr, nilAccount, accounts[0], 1000, "", 0, 6)) + // create a tx that can't be included in a 64 x 64 when accounting for the + // pfb along with the shares + tooManyShareBtx := blobfactory.ManyMultiBlobTx( + t, + encConf.TxConfig, + kr, + testutil.ChainID, + accounts[3:4], + infos[3:4], + blobfactory.NestedBlobs( + t, + testfactory.RandomBlobNamespaces(tmrand.NewRand(), 4000), + [][]int{repeat(4000, 1)}, + ), + )[0] + + // memo is 2 MiB resulting in the transaction being over limit + largeString := strings.Repeat("a", 2*1024*1024) + + // 3 transactions over MaxTxSize limit + largeTxs := coretypes.Txs(testutil.SendTxsWithAccounts(t, testApp, encConf.TxConfig, kr, 1000, accounts[0], accounts[:3], testutil.ChainID, user.SetMemo(largeString))).ToSliceOfBytes() + + // 3 blobTxs over MaxTxSize limit + largeBlobTxs := blobfactory.ManyMultiBlobTx( + t, + encConf.TxConfig, + kr, + testutil.ChainID, + accounts[:3], + infos[:3], + blobfactory.NestedBlobs( + t, + testfactory.RandomBlobNamespaces(tmrand.NewRand(), 3), + [][]int{{100}, {1000}, {420}}, + ), + user.SetMemo(largeString), + ) + type test struct { name string txs func() [][]byte @@ -181,6 +233,20 @@ func TestPrepareProposalFiltering(t *testing.T) { }, prunedTxs: [][]byte{noAccountTx}, }, + { + name: "blob tx with too many shares", + txs: func() [][]byte { + return [][]byte{tooManyShareBtx} + }, + prunedTxs: [][]byte{tooManyShareBtx}, + }, + { + name: "blobTxs and sendTxs that exceed MaxTxSize limit", + txs: func() [][]byte { + return append(largeTxs, largeBlobTxs...) // All txs are over MaxTxSize limit + }, + prunedTxs: append(largeTxs, largeBlobTxs...), + }, } for _, tt := range tests { @@ -204,6 +270,148 @@ func TestPrepareProposalFiltering(t *testing.T) { } } +func TestPrepareProposalCappingNumberOfMessages(t *testing.T) { + if testing.Short() { + t.Skip("skipping prepare proposal capping number of transactions test in short mode.") + } + // creating a big number of accounts so that every account + // only creates a single transaction. This is for transactions + // to be skipped without worrying about the sequence number being + // sequential. + numberOfAccounts := 8000 + accounts := testnode.GenerateAccounts(numberOfAccounts) + consensusParams := app.DefaultConsensusParams() + testApp, kr := testutil.SetupTestAppWithGenesisValSetAndMaxSquareSize(consensusParams, 128, accounts...) + enc := encoding.MakeConfig(app.ModuleEncodingRegisters...) + + addrs := make([]sdk.AccAddress, 0, numberOfAccounts) + accs := make([]types.AccountI, 0, numberOfAccounts) + signers := make([]*user.Signer, 0, numberOfAccounts) + for index, account := range accounts { + addr := testfactory.GetAddress(kr, account) + addrs = append(addrs, addr) + acc := testutil.DirectQueryAccount(testApp, addrs[index]) + accs = append(accs, acc) + signer, err := user.NewSigner(kr, enc.TxConfig, testutil.ChainID, appconsts.LatestVersion, user.NewAccount(account, acc.GetAccountNumber(), acc.GetSequence())) + require.NoError(t, err) + signers = append(signers, signer) + } + + numberOfPFBs := appconsts.MaxPFBMessages + 500 + pfbTxs := make([][]byte, 0, numberOfPFBs) + randomBytes := make([]byte, 2000) + _, err := rand.Read(randomBytes) + require.NoError(t, err) + accountIndex := 0 + for i := 0; i < numberOfPFBs; i++ { + blob, err := share.NewBlob(share.RandomNamespace(), randomBytes, 1, accs[accountIndex].GetAddress().Bytes()) + require.NoError(t, err) + tx, _, err := signers[accountIndex].CreatePayForBlobs(accounts[accountIndex], []*share.Blob{blob}, user.SetGasLimit(2549760000), user.SetFee(10000)) + require.NoError(t, err) + pfbTxs = append(pfbTxs, tx) + accountIndex++ + } + + multiPFBsPerTxs := make([][]byte, 0, numberOfPFBs) + numberOfMsgsPerTx := 10 + for i := 0; i < numberOfPFBs; i++ { + msgs := make([]sdk.Msg, 0) + blobs := make([]*share.Blob, 0) + for j := 0; j < numberOfMsgsPerTx; j++ { + blob, err := share.NewBlob(share.RandomNamespace(), randomBytes, 1, accs[accountIndex].GetAddress().Bytes()) + require.NoError(t, err) + msg, err := blobtypes.NewMsgPayForBlobs(addrs[accountIndex].String(), appconsts.LatestVersion, blob) + require.NoError(t, err) + msgs = append(msgs, msg) + blobs = append(blobs, blob) + } + txBytes, err := signers[accountIndex].CreateTx(msgs, user.SetGasLimit(2549760000), user.SetFee(10000)) + require.NoError(t, err) + blobTx, err := blobtx.MarshalBlobTx(txBytes, blobs...) + require.NoError(t, err) + multiPFBsPerTxs = append(multiPFBsPerTxs, blobTx) + accountIndex++ + } + + numberOfMsgSends := appconsts.MaxNonPFBMessages + 500 + msgSendTxs := make([][]byte, 0, numberOfMsgSends) + for i := 0; i < numberOfMsgSends; i++ { + msg := banktypes.NewMsgSend( + addrs[accountIndex], + testnode.RandomAddress().(sdk.AccAddress), + sdk.NewCoins(sdk.NewInt64Coin(appconsts.BondDenom, 10)), + ) + rawTx, err := signers[accountIndex].CreateTx([]sdk.Msg{msg}, user.SetGasLimit(1000000), user.SetFee(10)) + require.NoError(t, err) + msgSendTxs = append(msgSendTxs, rawTx) + accountIndex++ + } + + testCases := []struct { + name string + inputTransactions [][]byte + expectedTransactions [][]byte + }{ + { + name: "capping only PFB transactions", + inputTransactions: pfbTxs[:appconsts.MaxPFBMessages+50], + expectedTransactions: pfbTxs[:appconsts.MaxPFBMessages], + }, + { + name: "capping only PFB transactions with multiple messages", + inputTransactions: multiPFBsPerTxs[:appconsts.MaxPFBMessages], + expectedTransactions: multiPFBsPerTxs[:appconsts.MaxPFBMessages/numberOfMsgsPerTx], + }, + { + name: "capping only msg send transactions", + inputTransactions: msgSendTxs[:appconsts.MaxNonPFBMessages+50], + expectedTransactions: msgSendTxs[:appconsts.MaxNonPFBMessages], + }, + { + name: "capping msg send after pfb transactions", + inputTransactions: func() [][]byte { + input := make([][]byte, 0, len(msgSendTxs)+100) + input = append(input, pfbTxs[:100]...) + input = append(input, msgSendTxs...) + return input + }(), + expectedTransactions: func() [][]byte { + expected := make([][]byte, 0, appconsts.MaxNonPFBMessages+100) + expected = append(expected, msgSendTxs[:appconsts.MaxNonPFBMessages]...) + expected = append(expected, pfbTxs[:100]...) + return expected + }(), + }, + { + name: "capping pfb after msg send transactions", + inputTransactions: func() [][]byte { + input := make([][]byte, 0, len(pfbTxs)+100) + input = append(input, msgSendTxs[:100]...) + input = append(input, pfbTxs...) + return input + }(), + expectedTransactions: func() [][]byte { + expected := make([][]byte, 0, appconsts.MaxPFBMessages+100) + expected = append(expected, msgSendTxs[:100]...) + expected = append(expected, pfbTxs[:appconsts.MaxPFBMessages]...) + return expected + }(), + }, + } + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + resp := testApp.PrepareProposal(abci.RequestPrepareProposal{ + BlockData: &tmproto.Data{ + Txs: testCase.inputTransactions, + }, + ChainId: testApp.GetChainID(), + Height: 10, + }) + assert.Equal(t, testCase.expectedTransactions, resp.BlockData.Txs) + }) + } +} + func queryAccountInfo(capp *app.App, accs []string, kr keyring.Keyring) []blobfactory.AccountInfo { infos := make([]blobfactory.AccountInfo, len(accs)) for i, acc := range accs { @@ -216,3 +424,12 @@ func queryAccountInfo(capp *app.App, accs []string, kr keyring.Keyring) []blobfa } return infos } + +// repeat returns a slice of length n with each element set to val. +func repeat[T any](n int, val T) []T { + result := make([]T, n) + for i := range result { + result[i] = val + } + return result +} diff --git a/app/test/priority_test.go b/app/test/priority_test.go index 72586e5718..da7936dd0d 100644 --- a/app/test/priority_test.go +++ b/app/test/priority_test.go @@ -80,7 +80,6 @@ func (s *PriorityTestSuite) TestPriorityByGasPrice() { wg := &sync.WaitGroup{} for _, accName := range s.accountNames { wg.Add(1) - accName := accName // new variable per iteration go func() { defer wg.Done() // ensure that it is greater than the min gas price diff --git a/app/test/process_proposal_test.go b/app/test/process_proposal_test.go index df390dcdfa..69f18b8bd4 100644 --- a/app/test/process_proposal_test.go +++ b/app/test/process_proposal_test.go @@ -3,6 +3,7 @@ package app_test import ( "bytes" "fmt" + "strings" "testing" "time" @@ -20,6 +21,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" "github.com/celestiaorg/celestia-app/v3/pkg/da" "github.com/celestiaorg/celestia-app/v3/pkg/user" testutil "github.com/celestiaorg/celestia-app/v3/test/util" @@ -49,6 +51,26 @@ func TestProcessProposal(t *testing.T) { testfactory.RandomBlobNamespaces(tmrand.NewRand(), 4), [][]int{{100}, {1000}, {420}, {300}}, ), + blobfactory.DefaultTxOpts()..., + ) + + largeMemo := strings.Repeat("a", appconsts.MaxTxSize(appconsts.LatestVersion)) + + // create 2 single blobTxs that include a large memo making the transaction + // larger than the configured max tx size + largeBlobTxs := blobfactory.ManyMultiBlobTx( + t, enc, kr, testutil.ChainID, accounts[3:], infos[3:], + blobfactory.NestedBlobs( + t, + testfactory.RandomBlobNamespaces(tmrand.NewRand(), 4), + [][]int{{100}, {1000}, {420}, {300}}, + ), + user.SetMemo(largeMemo)) + + // create 1 large sendTx that includes a large memo making the + // transaction over the configured max tx size limit + largeSendTx := testutil.SendTxsWithAccounts( + t, testApp, enc, kr, 1000, accounts[0], accounts[1:2], testutil.ChainID, user.SetMemo(largeMemo), ) // create 3 MsgSend transactions that are signed with valid account numbers @@ -80,6 +102,20 @@ func TestProcessProposal(t *testing.T) { ns1 := share.MustNewV0Namespace(bytes.Repeat([]byte{1}, share.NamespaceVersionZeroIDSize)) data := bytes.Repeat([]byte{1}, 13) + tooManyShareBtx := blobfactory.ManyMultiBlobTx( + t, + enc, + kr, + testutil.ChainID, + accounts[3:4], + infos[3:4], + blobfactory.NestedBlobs( + t, + testfactory.RandomBlobNamespaces(tmrand.NewRand(), 4000), + [][]int{repeat(4000, 1)}, + ), + )[0] + type test struct { name string input *tmproto.Data @@ -299,6 +335,39 @@ func TestProcessProposal(t *testing.T) { appVersion: appconsts.LatestVersion, expectedResult: abci.ResponseProcessProposal_REJECT, }, + { + name: "blob tx that takes up too many shares", + input: &tmproto.Data{ + Txs: [][]byte{}, + }, + mutator: func(d *tmproto.Data) { + // this tx will get filtered out by prepare proposal before this + // so we add it here + d.Txs = append(d.Txs, tooManyShareBtx) + }, + appVersion: v3.Version, + expectedResult: abci.ResponseProcessProposal_REJECT, + }, + { + name: "blob txs larger than configured max tx size", + input: validData(), + mutator: func(d *tmproto.Data) { + d.Txs = append(d.Txs, largeBlobTxs...) + d.Hash = calculateNewDataHash(t, d.Txs) + }, + appVersion: appconsts.LatestVersion, + expectedResult: abci.ResponseProcessProposal_REJECT, + }, + { + name: "send tx larger than configured max tx size", + input: validData(), + mutator: func(d *tmproto.Data) { + d.Txs = append(coretypes.Txs(largeSendTx).ToSliceOfBytes(), d.Txs...) + d.Hash = calculateNewDataHash(t, d.Txs) + }, + appVersion: appconsts.LatestVersion, + expectedResult: abci.ResponseProcessProposal_REJECT, + }, } for _, tt := range tests { diff --git a/app/test/square_size_test.go b/app/test/square_size_test.go index e8082b17f5..d030b89093 100644 --- a/app/test/square_size_test.go +++ b/app/test/square_size_test.go @@ -17,6 +17,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/test/util/testnode" blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1" oldgov "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" @@ -173,7 +174,10 @@ func (s *SquareSizeIntegrationTest) setBlockSizeParams(t *testing.T, squareSize, res, err := txClient.SubmitTx(s.cctx.GoContext(), []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) require.NoError(t, err) - require.Equal(t, res.Code, abci.CodeTypeOK, res.RawLog) + serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient) + getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash}) + require.NoError(t, err) + require.Equal(t, res.Code, abci.CodeTypeOK, getTxResp.TxResponse.RawLog) require.NoError(t, s.cctx.WaitForNextBlock()) diff --git a/app/test/std_sdk_test.go b/app/test/std_sdk_test.go index 810da6001a..dc54a030d0 100644 --- a/app/test/std_sdk_test.go +++ b/app/test/std_sdk_test.go @@ -8,19 +8,20 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/app/grpc/tx" - v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/pkg/user" "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" "github.com/celestiaorg/celestia-app/v3/x/minfee" - signal "github.com/celestiaorg/celestia-app/x/signal/types" + signal "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/celestiaorg/go-square/v2/share" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/testutil/mock" sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" @@ -306,7 +307,7 @@ func (s *StandardSDKIntegrationTestSuite) TestStandardSDK() { name: "signal a version change", msgFunc: func() (msgs []sdk.Msg, signer string) { valAccount := s.getValidatorAccount() - msg := signal.NewMsgSignalVersion(valAccount, 2) + msg := signal.NewMsgSignalVersion(valAccount, appconsts.LatestVersion+1) return []sdk.Msg{msg}, s.getValidatorName() }, expectedCode: abci.CodeTypeOK, @@ -316,17 +317,26 @@ func (s *StandardSDKIntegrationTestSuite) TestStandardSDK() { // sign and submit the transactions for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient) msgs, signer := tt.msgFunc() txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg, user.WithDefaultAccount(signer)) require.NoError(t, err) res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...) if tt.expectedCode != abci.CodeTypeOK { require.Error(t, err) + require.Nil(t, res) + txHash := err.(*user.ExecutionError).TxHash + code := err.(*user.ExecutionError).Code + getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash}) + require.NoError(t, err) + assert.Equal(t, tt.expectedCode, code, getTxResp.TxResponse.RawLog) } else { require.NoError(t, err) + require.NotNil(t, res) + getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash}) + require.NoError(t, err) + assert.Equal(t, tt.expectedCode, res.Code, getTxResp.TxResponse.RawLog) } - require.NotNil(t, res) - assert.Equal(t, tt.expectedCode, res.Code, res.RawLog) }) } } @@ -339,7 +349,7 @@ func (s *StandardSDKIntegrationTestSuite) TestGRPCQueries() { require.NoError(t, err) got, err := resp.NetworkMinGasPrice.Float64() require.NoError(t, err) - assert.Equal(t, v2.NetworkMinGasPrice, got) + assert.Equal(t, appconsts.DefaultNetworkMinGasPrice, got) }) t.Run("testnode can query local min gas price", func(t *testing.T) { serviceClient := nodeservice.NewServiceClient(s.cctx.GRPCClient) diff --git a/app/test/upgrade_test.go b/app/test/upgrade_test.go index ec0d655922..b188a6cb47 100644 --- a/app/test/upgrade_test.go +++ b/app/test/upgrade_test.go @@ -1,21 +1,27 @@ package app_test import ( - "encoding/json" "fmt" "strings" "testing" - "time" app "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" + "github.com/celestiaorg/celestia-app/v3/pkg/user" "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/genesis" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" blobstreamtypes "github.com/celestiaorg/celestia-app/v3/x/blobstream/types" "github.com/celestiaorg/celestia-app/v3/x/minfee" - "github.com/cosmos/cosmos-sdk/crypto/keyring" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" + "github.com/celestiaorg/go-square/v2/share" + "github.com/celestiaorg/go-square/v2/tx" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6/packetforward/types" icahosttypes "github.com/cosmos/ibc-go/v6/modules/apps/27-interchain-accounts/host/types" @@ -27,10 +33,134 @@ import ( dbm "github.com/tendermint/tm-db" ) -// TestAppUpgrades verifies that the all module's params are overridden during an +func TestAppUpgradeV3(t *testing.T) { + if testing.Short() { + t.Skip("skipping TestAppUpgradeV3 in short mode") + } + + appconsts.OverrideUpgradeHeightDelayStr = "1" + defer func() { appconsts.OverrideUpgradeHeightDelayStr = "" }() + + testApp, genesis := SetupTestAppWithUpgradeHeight(t, 3) + upgradeFromV1ToV2(t, testApp) + + ctx := testApp.NewContext(true, tmproto.Header{}) + validators := testApp.StakingKeeper.GetAllValidators(ctx) + valAddr, err := sdk.ValAddressFromBech32(validators[0].OperatorAddress) + require.NoError(t, err) + record, err := genesis.Keyring().Key(testnode.DefaultValidatorAccountName) + require.NoError(t, err) + accAddr, err := record.GetAddress() + require.NoError(t, err) + encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) + resp, err := testApp.AccountKeeper.Account(ctx, &authtypes.QueryAccountRequest{ + Address: accAddr.String(), + }) + require.NoError(t, err) + var account authtypes.AccountI + err = encCfg.InterfaceRegistry.UnpackAny(resp.Account, &account) + require.NoError(t, err) + + signer, err := user.NewSigner( + genesis.Keyring(), encCfg.TxConfig, testApp.GetChainID(), v3.Version, + user.NewAccount(testnode.DefaultValidatorAccountName, account.GetAccountNumber(), account.GetSequence()), + ) + require.NoError(t, err) + + upgradeTx, err := signer.CreateTx( + []sdk.Msg{ + signaltypes.NewMsgSignalVersion(valAddr, 3), + signaltypes.NewMsgTryUpgrade(accAddr), + }, + user.SetGasLimitAndGasPrice(100_000, appconsts.DefaultMinGasPrice), + ) + require.NoError(t, err) + testApp.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + ChainID: genesis.ChainID, + Height: 3, + Version: tmversion.Consensus{App: 2}, + }, + }) + + deliverTxResp := testApp.DeliverTx(abci.RequestDeliverTx{ + Tx: upgradeTx, + }) + require.Equal(t, abci.CodeTypeOK, deliverTxResp.Code, deliverTxResp.Log) + + endBlockResp := testApp.EndBlock(abci.RequestEndBlock{ + Height: 3, + }) + require.Equal(t, v2.Version, endBlockResp.ConsensusParamUpdates.Version.AppVersion) + require.Equal(t, appconsts.GetTimeoutCommit(v2.Version), + endBlockResp.Timeouts.TimeoutCommit) + require.Equal(t, appconsts.GetTimeoutPropose(v2.Version), + endBlockResp.Timeouts.TimeoutPropose) + testApp.Commit() + require.NoError(t, signer.IncrementSequence(testnode.DefaultValidatorAccountName)) + + ctx = testApp.NewContext(true, tmproto.Header{}) + getUpgradeResp, err := testApp.SignalKeeper.GetUpgrade(ctx, &signaltypes.QueryGetUpgradeRequest{}) + require.NoError(t, err) + require.Equal(t, v3.Version, getUpgradeResp.Upgrade.AppVersion) + + // brace yourselfs, this part may take a while + initialHeight := int64(4) + for height := initialHeight; height < initialHeight+appconsts.UpgradeHeightDelay(v2.Version); height++ { + appVersion := v2.Version + _ = testApp.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + Height: height, + Version: tmversion.Consensus{App: appVersion}, + }, + }) + + endBlockResp = testApp.EndBlock(abci.RequestEndBlock{ + Height: 3 + appconsts.UpgradeHeightDelay(v2.Version), + }) + + require.Equal(t, appconsts.GetTimeoutCommit(appVersion), endBlockResp.Timeouts.TimeoutCommit) + require.Equal(t, appconsts.GetTimeoutPropose(appVersion), endBlockResp.Timeouts.TimeoutPropose) + + _ = testApp.Commit() + } + require.Equal(t, v3.Version, endBlockResp.ConsensusParamUpdates.Version.AppVersion) + + // confirm that an authored blob tx works + blob, err := share.NewV1Blob(share.RandomBlobNamespace(), []byte("hello world"), accAddr.Bytes()) + require.NoError(t, err) + blobTxBytes, _, err := signer.CreatePayForBlobs( + testnode.DefaultValidatorAccountName, + []*share.Blob{blob}, + user.SetGasLimitAndGasPrice(200_000, appconsts.DefaultMinGasPrice), + ) + require.NoError(t, err) + blobTx, _, err := tx.UnmarshalBlobTx(blobTxBytes) + require.NoError(t, err) + + _ = testApp.BeginBlock(abci.RequestBeginBlock{ + Header: tmproto.Header{ + ChainID: genesis.ChainID, + Height: initialHeight + appconsts.UpgradeHeightDelay(v3.Version), + Version: tmversion.Consensus{App: 3}, + }, + }) + + deliverTxResp = testApp.DeliverTx(abci.RequestDeliverTx{ + Tx: blobTx.Tx, + }) + require.Equal(t, abci.CodeTypeOK, deliverTxResp.Code, deliverTxResp.Log) + + respEndBlock := testApp.EndBlock(abci. + RequestEndBlock{Height: initialHeight + appconsts.UpgradeHeightDelay(v3.Version)}) + require.Equal(t, appconsts.GetTimeoutCommit(v3.Version), respEndBlock.Timeouts.TimeoutCommit) + require.Equal(t, appconsts.GetTimeoutPropose(v3.Version), respEndBlock.Timeouts.TimeoutPropose) +} + +// TestAppUpgradeV2 verifies that the all module's params are overridden during an // upgrade from v1 -> v2 and the app version changes correctly. -func TestAppUpgrades(t *testing.T) { - NetworkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", v2.NetworkMinGasPrice)) +func TestAppUpgradeV2(t *testing.T) { + NetworkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", appconsts.DefaultNetworkMinGasPrice)) require.NoError(t, err) tests := []struct { @@ -122,18 +252,17 @@ func TestBlobstreamRemovedInV2(t *testing.T) { require.Error(t, err) } -func SetupTestAppWithUpgradeHeight(t *testing.T, upgradeHeight int64) (*app.App, keyring.Keyring) { +func SetupTestAppWithUpgradeHeight(t *testing.T, upgradeHeight int64) (*app.App, *genesis.Genesis) { t.Helper() db := dbm.NewMemDB() - chainID := "test_chain" encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) testApp := app.New(log.NewNopLogger(), db, nil, 0, encCfg, upgradeHeight, util.EmptyAppOptions{}) - genesisState, _, kr := util.GenesisStateWithSingleValidator(testApp, "account") - stateBytes, err := json.MarshalIndent(genesisState, "", " ") + genesis := genesis.NewDefaultGenesis(). + WithValidators(genesis.NewDefaultValidator(testnode.DefaultValidatorAccountName)). + WithConsensusParams(app.DefaultInitialConsensusParams()) + genDoc, err := genesis.Export() require.NoError(t, err) - infoResp := testApp.Info(abci.RequestInfo{}) - require.EqualValues(t, 0, infoResp.AppVersion) - cp := app.DefaultInitialConsensusParams() + cp := genDoc.ConsensusParams abciParams := &abci.ConsensusParams{ Block: &abci.BlockParams{ MaxBytes: cp.Block.MaxBytes, @@ -146,23 +275,26 @@ func SetupTestAppWithUpgradeHeight(t *testing.T, upgradeHeight int64) (*app.App, _ = testApp.InitChain( abci.RequestInitChain{ - Time: time.Now(), + Time: genDoc.GenesisTime, Validators: []abci.ValidatorUpdate{}, ConsensusParams: abciParams, - AppStateBytes: stateBytes, - ChainId: chainID, + AppStateBytes: genDoc.AppState, + ChainId: genDoc.ChainID, }, ) // assert that the chain starts with version provided in genesis - infoResp = testApp.Info(abci.RequestInfo{}) - require.EqualValues(t, app.DefaultInitialConsensusParams().Version.AppVersion, infoResp.AppVersion) + infoResp := testApp.Info(abci.RequestInfo{}) + appVersion := app.DefaultInitialConsensusParams().Version.AppVersion + require.EqualValues(t, appVersion, infoResp.AppVersion) + require.EqualValues(t, appconsts.GetTimeoutCommit(appVersion), infoResp.Timeouts.TimeoutCommit) + require.EqualValues(t, appconsts.GetTimeoutPropose(appVersion), infoResp.Timeouts.TimeoutPropose) - supportedVersions := []uint64{v1.Version, v2.Version} + supportedVersions := []uint64{v1.Version, v2.Version, v3.Version} require.Equal(t, supportedVersions, testApp.SupportedVersions()) _ = testApp.Commit() - return testApp, kr + return testApp, genesis } func upgradeFromV1ToV2(t *testing.T, testApp *app.App) { @@ -171,7 +303,11 @@ func upgradeFromV1ToV2(t *testing.T, testApp *app.App) { Height: 2, Version: tmversion.Consensus{App: 1}, }}) - testApp.EndBlock(abci.RequestEndBlock{Height: 2}) + endBlockResp := testApp.EndBlock(abci.RequestEndBlock{Height: 2}) + require.Equal(t, appconsts.GetTimeoutCommit(v1.Version), + endBlockResp.Timeouts.TimeoutCommit) + require.Equal(t, appconsts.GetTimeoutPropose(v1.Version), + endBlockResp.Timeouts.TimeoutPropose) testApp.Commit() require.EqualValues(t, 2, testApp.AppVersion()) } diff --git a/app/validate_txs.go b/app/validate_txs.go index 3538e221a0..ee3edfbb6f 100644 --- a/app/validate_txs.go +++ b/app/validate_txs.go @@ -1,6 +1,7 @@ package app import ( + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/go-square/v2/tx" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/telemetry" @@ -44,12 +45,24 @@ func FilterTxs(logger log.Logger, ctx sdk.Context, handler sdk.AnteHandler, txCo // function used to apply the ante handler. func filterStdTxs(logger log.Logger, dec sdk.TxDecoder, ctx sdk.Context, handler sdk.AnteHandler, txs [][]byte) ([][]byte, sdk.Context) { n := 0 + nonPFBMessageCount := 0 for _, tx := range txs { sdkTx, err := dec(tx) if err != nil { logger.Error("decoding already checked transaction", "tx", tmbytes.HexBytes(coretypes.Tx(tx).Hash()), "error", err) continue } + + // Set the tx size on the context before calling the AnteHandler + ctx = ctx.WithTxBytes(tx) + + msgTypes := msgTypes(sdkTx) + if nonPFBMessageCount+len(sdkTx.GetMsgs()) > appconsts.MaxNonPFBMessages { + logger.Debug("skipping tx because the max non PFB message count was reached", "tx", tmbytes.HexBytes(coretypes.Tx(tx).Hash())) + continue + } + nonPFBMessageCount += len(sdkTx.GetMsgs()) + ctx, err = handler(ctx, sdkTx, false) // either the transaction is invalid (ie incorrect nonce) and we // simply want to remove this tx, or we're catching a panic from one @@ -59,7 +72,7 @@ func filterStdTxs(logger log.Logger, dec sdk.TxDecoder, ctx sdk.Context, handler "filtering already checked transaction", "tx", tmbytes.HexBytes(coretypes.Tx(tx).Hash()), "error", err, - "msgs", msgTypes(sdkTx), + "msgs", msgTypes, ) telemetry.IncrCounter(1, "prepare_proposal", "invalid_std_txs") continue @@ -77,12 +90,23 @@ func filterStdTxs(logger log.Logger, dec sdk.TxDecoder, ctx sdk.Context, handler // function used to apply the ante handler. func filterBlobTxs(logger log.Logger, dec sdk.TxDecoder, ctx sdk.Context, handler sdk.AnteHandler, txs []*tx.BlobTx) ([]*tx.BlobTx, sdk.Context) { n := 0 + pfbMessageCount := 0 for _, tx := range txs { sdkTx, err := dec(tx.Tx) if err != nil { logger.Error("decoding already checked blob transaction", "tx", tmbytes.HexBytes(coretypes.Tx(tx.Tx).Hash()), "error", err) continue } + + // Set the tx size on the context before calling the AnteHandler + ctx = ctx.WithTxBytes(tx.Tx) + + if pfbMessageCount+len(sdkTx.GetMsgs()) > appconsts.MaxPFBMessages { + logger.Debug("skipping tx because the max pfb message count was reached", "tx", tmbytes.HexBytes(coretypes.Tx(tx.Tx).Hash())) + continue + } + pfbMessageCount += len(sdkTx.GetMsgs()) + ctx, err = handler(ctx, sdkTx, false) // either the transaction is invalid (ie incorrect nonce) and we // simply want to remove this tx, or we're catching a panic from one diff --git a/cmd/celestia-appd/cmd/root.go b/cmd/celestia-appd/cmd/root.go index bfb052fc8a..f8d57040fb 100644 --- a/cmd/celestia-appd/cmd/root.go +++ b/cmd/celestia-appd/cmd/root.go @@ -16,7 +16,6 @@ import ( "github.com/cosmos/cosmos-sdk/server" serverconfig "github.com/cosmos/cosmos-sdk/server/config" simdcmd "github.com/cosmos/cosmos-sdk/simapp/simd/cmd" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/crisis" @@ -100,9 +99,6 @@ func NewRootCmd() *cobra.Command { // initRootCommand performs a bunch of side-effects on the root command. func initRootCommand(rootCommand *cobra.Command, encodingConfig encoding.Config) { - config := sdk.GetConfig() - config.Seal() - rootCommand.AddCommand( genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome), genutilcli.CollectGenTxsCmd(banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), @@ -126,7 +122,7 @@ func initRootCommand(rootCommand *cobra.Command, encodingConfig encoding.Config) ) // Add the following commands to the rootCommand: start, tendermint, export, version, and rollback. - server.AddCommands(rootCommand, app.DefaultNodeHome, NewAppServer, appExporter, addModuleInitFlags) + addCommands(rootCommand, app.DefaultNodeHome, NewAppServer, appExporter, addModuleInitFlags) } // setDefaultConsensusParams sets the default consensus parameters for the diff --git a/cmd/celestia-appd/cmd/start.go b/cmd/celestia-appd/cmd/start.go new file mode 100644 index 0000000000..763f1b6cd5 --- /dev/null +++ b/cmd/celestia-appd/cmd/start.go @@ -0,0 +1,626 @@ +package cmd + +// NOTE: This file was copy paste forked from the sdk in order to modify the +// start command flag. + +import ( + "fmt" + "io" + "net" + "net/http" + "os" + "os/exec" + "path/filepath" + "runtime/pprof" + "strings" + "time" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/codec" + pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/server/api" + serverconfig "github.com/cosmos/cosmos-sdk/server/config" + servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" + "github.com/cosmos/cosmos-sdk/server/rosetta" + crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server" + srvrtypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/telemetry" + sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/version" + "github.com/spf13/cobra" + tmserver "github.com/tendermint/tendermint/abci/server" + cmtcmd "github.com/tendermint/tendermint/cmd/cometbft/commands" + tmos "github.com/tendermint/tendermint/libs/os" + "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/proxy" + "github.com/tendermint/tendermint/rpc/client/local" + dbm "github.com/tendermint/tm-db" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + // Tendermint full-node start flags + flagWithTendermint = "with-tendermint" + flagAddress = "address" + flagTransport = "transport" + flagTraceStore = "trace-store" + flagCPUProfile = "cpu-profile" + + FlagForceNoBBR = "force-no-bbr" + + // gRPC-related flags + flagGRPCOnly = "grpc-only" + flagGRPCEnable = "grpc.enable" + flagGRPCAddress = "grpc.address" + flagGRPCWebEnable = "grpc-web.enable" + flagGRPCWebAddress = "grpc-web.address" +) + +// startCmd runs the service passed in, either stand-alone or in-process with +// Tendermint. +func startCmd(appCreator srvrtypes.AppCreator, defaultNodeHome string) *cobra.Command { + cmd := &cobra.Command{ + Use: "start", + Short: "Run the full node", + Long: `Run the full node application with Tendermint in or out of process. By +default, the application will run with Tendermint in process. + +Pruning options can be provided via the '--pruning' flag or alternatively with '--pruning-keep-recent', and +'pruning-interval' together. + +For '--pruning' the options are as follows: + +default: the last 362880 states are kept, pruning at 10 block intervals +nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) +everything: 2 latest states will be kept; pruning at 10 block intervals. +custom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval' + +Node halting configurations exist in the form of two flags: '--halt-height' and '--halt-time'. During +the ABCI Commit phase, the node will check if the current block height is greater than or equal to +the halt-height or if the current block time is greater than or equal to the halt-time. If so, the +node will attempt to gracefully shutdown and the block will not be committed. In addition, the node +will not be able to commit subsequent blocks. + +For profiling and benchmarking purposes, CPU profiling can be enabled via the '--cpu-profile' flag +which accepts a path for the resulting pprof file. + +The node may be started in a 'query only' mode where only the gRPC and JSON HTTP +API services are enabled via the 'grpc-only' flag. In this mode, Tendermint is +bypassed and can be used when legacy queries are needed after an on-chain upgrade +is performed. Note, when enabled, gRPC will also be automatically enabled. +`, + PreRunE: func(cmd *cobra.Command, _ []string) error { + serverCtx := server.GetServerContextFromCmd(cmd) + + // Bind flags to the Context's Viper so the app construction can set + // options accordingly. + if err := serverCtx.Viper.BindPFlags(cmd.Flags()); err != nil { + return err + } + + _, err := server.GetPruningOptionsFromFlags(serverCtx.Viper) + return err + }, + RunE: func(cmd *cobra.Command, _ []string) error { + err := checkBBR(cmd) + if err != nil { + return err + } + + serverCtx := server.GetServerContextFromCmd(cmd) + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + withTM, _ := cmd.Flags().GetBool(flagWithTendermint) + if !withTM { + serverCtx.Logger.Info("starting ABCI without Tendermint") + return wrapCPUProfile(serverCtx, func() error { + return startStandAlone(serverCtx, appCreator) + }) + } + + // amino is needed here for backwards compatibility of REST routes + err = wrapCPUProfile(serverCtx, func() error { + return startInProcess(serverCtx, clientCtx, appCreator) + }) + errCode, ok := err.(server.ErrorCode) + if !ok { + return err + } + + serverCtx.Logger.Debug(fmt.Sprintf("received quit signal: %d", errCode.Code)) + return nil + }, + } + + cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory") + cmd.Flags().Bool(flagWithTendermint, true, "Run abci app embedded in-process with tendermint") + cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address") + cmd.Flags().String(flagTransport, "socket", "Transport protocol: socket, grpc") + cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file") + cmd.Flags().String(server.FlagMinGasPrices, "", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)") + cmd.Flags().IntSlice(server.FlagUnsafeSkipUpgrades, []int{}, "Skip a set of upgrade heights to continue the old binary") + cmd.Flags().Uint64(server.FlagHaltHeight, 0, "Block height at which to gracefully halt the chain and shutdown the node") + cmd.Flags().Uint64(server.FlagHaltTime, 0, "Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node") + cmd.Flags().Bool(server.FlagInterBlockCache, true, "Enable inter-block caching") + cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file") + cmd.Flags().Bool(server.FlagTrace, false, "Provide full stack traces for errors in ABCI Log") + cmd.Flags().String(server.FlagPruning, pruningtypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)") + cmd.Flags().Uint64(server.FlagPruningKeepRecent, 0, "Number of recent heights to keep on disk (ignored if pruning is not 'custom')") + cmd.Flags().Uint64(server.FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')") + cmd.Flags().Uint(server.FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks") + cmd.Flags().Uint64(server.FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks") + cmd.Flags().Bool(FlagForceNoBBR, false, "bypass the requirement to use bbr locally") + + cmd.Flags().Bool(server.FlagAPIEnable, false, "Define if the API server should be enabled") + cmd.Flags().Bool(server.FlagAPISwagger, false, "Define if swagger documentation should automatically be registered (Note: the API must also be enabled)") + cmd.Flags().String(server.FlagAPIAddress, serverconfig.DefaultAPIAddress, "the API server address to listen on") + cmd.Flags().Uint(server.FlagAPIMaxOpenConnections, 1000, "Define the number of maximum open connections") + cmd.Flags().Uint(server.FlagRPCReadTimeout, 10, "Define the Tendermint RPC read timeout (in seconds)") + cmd.Flags().Uint(server.FlagRPCWriteTimeout, 0, "Define the Tendermint RPC write timeout (in seconds)") + cmd.Flags().Uint(server.FlagRPCMaxBodyBytes, 1000000, "Define the Tendermint maximum response body (in bytes)") + cmd.Flags().Bool(server.FlagAPIEnableUnsafeCORS, false, "Define if CORS should be enabled (unsafe - use it at your own risk)") + + cmd.Flags().Bool(flagGRPCOnly, false, "Start the node in gRPC query only mode (no Tendermint process is started)") + cmd.Flags().Bool(flagGRPCEnable, true, "Define if the gRPC server should be enabled") + cmd.Flags().String(flagGRPCAddress, serverconfig.DefaultGRPCAddress, "the gRPC server address to listen on") + + cmd.Flags().Bool(flagGRPCWebEnable, true, "Define if the gRPC-Web server should be enabled. (Note: gRPC must also be enabled)") + cmd.Flags().String(flagGRPCWebAddress, serverconfig.DefaultGRPCWebAddress, "The gRPC-Web server address to listen on") + + cmd.Flags().Uint64(server.FlagStateSyncSnapshotInterval, 0, "State sync snapshot interval") + cmd.Flags().Uint32(server.FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep") + + cmd.Flags().Bool(server.FlagDisableIAVLFastNode, false, "Disable fast node for IAVL tree") + + // add support for all Tendermint-specific command line options + cmtcmd.AddNodeFlags(cmd) + return cmd +} + +func startStandAlone(ctx *server.Context, appCreator srvrtypes.AppCreator) error { + addr := ctx.Viper.GetString(flagAddress) + transport := ctx.Viper.GetString(flagTransport) + home := ctx.Viper.GetString(flags.FlagHome) + + db, err := openDB(home, server.GetAppDBBackend(ctx.Viper)) + if err != nil { + return err + } + + traceWriterFile := ctx.Viper.GetString(flagTraceStore) + traceWriter, err := openTraceWriter(traceWriterFile) + if err != nil { + return err + } + + app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper) + + config, err := serverconfig.GetConfig(ctx.Viper) + if err != nil { + return err + } + + _, err = startTelemetry(config) + if err != nil { + return err + } + + svr, err := tmserver.NewServer(addr, transport, app) + if err != nil { + return fmt.Errorf("error creating listener: %v", err) + } + + svr.SetLogger(ctx.Logger.With("module", "abci-server")) + + err = svr.Start() + if err != nil { + tmos.Exit(err.Error()) + } + + defer func() { + if err = svr.Stop(); err != nil { + tmos.Exit(err.Error()) + } + + if err = app.Close(); err != nil { + tmos.Exit(err.Error()) + } + }() + + // Wait for SIGINT or SIGTERM signal + return server.WaitForQuitSignals() +} + +func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator srvrtypes.AppCreator) error { + cfg := ctx.Config + home := cfg.RootDir + + db, err := openDB(home, server.GetAppDBBackend(ctx.Viper)) + if err != nil { + return err + } + + traceWriterFile := ctx.Viper.GetString(flagTraceStore) + traceWriter, err := openTraceWriter(traceWriterFile) + if err != nil { + return err + } + + config, err := serverconfig.GetConfig(ctx.Viper) + if err != nil { + return err + } + + if err := config.ValidateBasic(); err != nil { + return err + } + + app := appCreator(ctx.Logger, db, traceWriter, ctx.Viper) + + nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) + if err != nil { + return err + } + + genDocProvider := node.DefaultGenesisDocProviderFunc(cfg) + + var ( + tmNode *node.Node + gRPCOnly = ctx.Viper.GetBool(flagGRPCOnly) + ) + + if gRPCOnly { + ctx.Logger.Info("starting node in gRPC only mode; Tendermint is disabled") + config.GRPC.Enable = true + } else { + ctx.Logger.Info("starting node with ABCI Tendermint in-process") + + tmNode, err = node.NewNode( + cfg, + privval.LoadOrGenFilePV(cfg.PrivValidatorKeyFile(), cfg.PrivValidatorStateFile()), + nodeKey, + proxy.NewLocalClientCreator(app), + genDocProvider, + node.DefaultDBProvider, + node.DefaultMetricsProvider(cfg.Instrumentation), + ctx.Logger, + ) + if err != nil { + return err + } + if err := tmNode.Start(); err != nil { + return err + } + } + + // Add the tx service to the gRPC router. We only need to register this + // service if API or gRPC is enabled, and avoid doing so in the general + // case, because it spawns a new local tendermint RPC client. + if (config.API.Enable || config.GRPC.Enable) && tmNode != nil { + // re-assign for making the client available below + // do not use := to avoid shadowing clientCtx + clientCtx = clientCtx.WithClient(local.New(tmNode)) + + app.RegisterTxService(clientCtx) + app.RegisterTendermintService(clientCtx) + + if a, ok := app.(srvrtypes.ApplicationQueryService); ok { + a.RegisterNodeService(clientCtx) + } + } + + metrics, err := startTelemetry(config) + if err != nil { + return err + } + + var apiSrv *api.Server + if config.API.Enable { + genDoc, err := genDocProvider() + if err != nil { + return err + } + + clientCtx := clientCtx.WithHomeDir(home).WithChainID(genDoc.ChainID) + + if config.GRPC.Enable { + _, _, err := net.SplitHostPort(config.GRPC.Address) + if err != nil { + return err + } + + maxSendMsgSize := config.GRPC.MaxSendMsgSize + if maxSendMsgSize == 0 { + maxSendMsgSize = serverconfig.DefaultGRPCMaxSendMsgSize + } + + maxRecvMsgSize := config.GRPC.MaxRecvMsgSize + if maxRecvMsgSize == 0 { + maxRecvMsgSize = serverconfig.DefaultGRPCMaxRecvMsgSize + } + + // If grpc is enabled, configure grpc client for grpc gateway. + grpcClient, err := grpc.NewClient( + config.GRPC.Address, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithDefaultCallOptions( + grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()), + grpc.MaxCallRecvMsgSize(maxRecvMsgSize), + grpc.MaxCallSendMsgSize(maxSendMsgSize), + ), + ) + if err != nil { + return err + } + + clientCtx = clientCtx.WithGRPCClient(grpcClient) + ctx.Logger.Debug("grpc client assigned to client context", "target", config.GRPC.Address) + } + + apiSrv = api.New(clientCtx, ctx.Logger.With("module", "api-server")) + app.RegisterAPIRoutes(apiSrv, config.API) + if config.Telemetry.Enabled { + apiSrv.SetTelemetry(metrics) + } + errCh := make(chan error) + + go func() { + if err := apiSrv.Start(config); err != nil { + errCh <- err + } + }() + + select { + case err := <-errCh: + return err + + case <-time.After(srvrtypes.ServerStartTime): // assume server started successfully + } + } + + var ( + grpcSrv *grpc.Server + grpcWebSrv *http.Server + ) + + if config.GRPC.Enable { + grpcSrv, err = servergrpc.StartGRPCServer(clientCtx, app, config.GRPC) + if err != nil { + return err + } + defer grpcSrv.Stop() + if config.GRPCWeb.Enable { + grpcWebSrv, err = servergrpc.StartGRPCWeb(grpcSrv, config) + if err != nil { + ctx.Logger.Error("failed to start grpc-web http server: ", err) + return err + } + defer func() { + if err := grpcWebSrv.Close(); err != nil { + ctx.Logger.Error("failed to close grpc-web http server: ", err) + } + }() + } + } + + // At this point it is safe to block the process if we're in gRPC only mode as + // we do not need to start Rosetta or handle any Tendermint related processes. + if gRPCOnly { + // wait for signal capture and gracefully return + return server.WaitForQuitSignals() + } + + var rosettaSrv crgserver.Server + if config.Rosetta.Enable { + offlineMode := config.Rosetta.Offline + + // If GRPC is not enabled rosetta cannot work in online mode, so it works in + // offline mode. + if !config.GRPC.Enable { + offlineMode = true + } + + minGasPrices, err := sdktypes.ParseDecCoins(config.MinGasPrices) + if err != nil { + ctx.Logger.Error("failed to parse minimum-gas-prices: ", err) + return err + } + + conf := &rosetta.Config{ + Blockchain: config.Rosetta.Blockchain, + Network: config.Rosetta.Network, + TendermintRPC: ctx.Config.RPC.ListenAddress, + GRPCEndpoint: config.GRPC.Address, + Addr: config.Rosetta.Address, + Retries: config.Rosetta.Retries, + Offline: offlineMode, + GasToSuggest: config.Rosetta.GasToSuggest, + EnableFeeSuggestion: config.Rosetta.EnableFeeSuggestion, + GasPrices: minGasPrices.Sort(), + Codec: clientCtx.Codec.(*codec.ProtoCodec), + InterfaceRegistry: clientCtx.InterfaceRegistry, + } + + rosettaSrv, err = rosetta.ServerFromConfig(conf) + if err != nil { + return err + } + + errCh := make(chan error) + go func() { + if err := rosettaSrv.Start(); err != nil { + errCh <- err + } + }() + + select { + case err := <-errCh: + return err + + case <-time.After(srvrtypes.ServerStartTime): // assume server started successfully + } + } + + defer func() { + if tmNode != nil && tmNode.IsRunning() { + _ = tmNode.Stop() + _ = app.Close() + } + + if apiSrv != nil { + _ = apiSrv.Close() + } + + ctx.Logger.Info("exiting...") + }() + + // wait for signal capture and gracefully return + return server.WaitForQuitSignals() +} + +func startTelemetry(cfg serverconfig.Config) (*telemetry.Metrics, error) { + if !cfg.Telemetry.Enabled { + return nil, nil + } + return telemetry.New(cfg.Telemetry) +} + +// wrapCPUProfile runs callback in a goroutine, then wait for quit signals. +func wrapCPUProfile(ctx *server.Context, callback func() error) error { + if cpuProfile := ctx.Viper.GetString(flagCPUProfile); cpuProfile != "" { + f, err := os.Create(cpuProfile) + if err != nil { + return err + } + + ctx.Logger.Info("starting CPU profiler", "profile", cpuProfile) + if err := pprof.StartCPUProfile(f); err != nil { + return err + } + + defer func() { + ctx.Logger.Info("stopping CPU profiler", "profile", cpuProfile) + pprof.StopCPUProfile() + if err := f.Close(); err != nil { + ctx.Logger.Info("failed to close cpu-profile file", "profile", cpuProfile, "err", err.Error()) + } + }() + } + + errCh := make(chan error) + go func() { + errCh <- callback() + }() + + select { + case err := <-errCh: + return err + + case <-time.After(srvrtypes.ServerStartTime): + } + + return server.WaitForQuitSignals() +} + +func addCommands( + rootCmd *cobra.Command, + defaultNodeHome string, + appCreator srvrtypes.AppCreator, + appExport srvrtypes.AppExporter, + addStartFlags srvrtypes.ModuleInitFlags, +) { + tendermintCmd := &cobra.Command{ + Use: "tendermint", + Aliases: []string{"comet", "cometbft"}, + Short: "Tendermint subcommands", + } + + tendermintCmd.AddCommand( + server.ShowNodeIDCmd(), + server.ShowValidatorCmd(), + server.ShowAddressCmd(), + server.VersionCmd(), + cmtcmd.ResetAllCmd, + cmtcmd.ResetStateCmd, + server.BootstrapStateCmd(appCreator), + ) + + startCmd := startCmd(appCreator, defaultNodeHome) + addStartFlags(startCmd) + + rootCmd.AddCommand( + startCmd, + tendermintCmd, + server.ExportCmd(appExport, defaultNodeHome), + version.NewVersionCommand(), + server.NewRollbackCmd(appCreator, defaultNodeHome), + ) +} + +// checkBBR checks if BBR is enabled. +func checkBBR(command *cobra.Command) error { + const ( + warning = ` +The BBR (Bottleneck Bandwidth and Round-trip propagation time) congestion control algorithm is not enabled in this system's kernel. +BBR is important for the performance of the p2p stack. + +To enable BBR: +sudo modprobe tcp_bbr +net.core.default_qdisc=fq +net.ipv4.tcp_congestion_control=bbr +sudo sysctl -p + +Then verify BBR is enabled: +sysctl net.ipv4.tcp_congestion_control + +This node will get worse p2p performance using a different congestion control algorithm. +If you need to bypass this check use the --force-no-bbr flag. +` + ) + + forceNoBBR, err := command.Flags().GetBool(FlagForceNoBBR) + if err != nil { + return err + } + if forceNoBBR { + return nil + } + + cmd := exec.Command("sysctl", "net.ipv4.tcp_congestion_control") + output, err := cmd.Output() + if err != nil { + fmt.Print(warning) + return fmt.Errorf("failed to execute 'sysctl net.ipv4.tcp_congestion_control' %w", err) + } + + if !strings.Contains(string(output), "bbr") { + fmt.Print(warning) + return fmt.Errorf("BBR not enabled because output %v does not contain 'bbr'", string(output)) + } + + return nil +} + +func openDB(rootDir string, backendType dbm.BackendType) (dbm.DB, error) { + dataDir := filepath.Join(rootDir, "data") + return dbm.NewDB("application", backendType, dataDir) +} + +func openTraceWriter(traceWriterFile string) (w io.Writer, err error) { + if traceWriterFile == "" { + return nil, nil + } + return os.OpenFile( + traceWriterFile, + os.O_WRONLY|os.O_APPEND|os.O_CREATE, + 0o666, + ) +} diff --git a/Dockerfile b/docker/Dockerfile similarity index 82% rename from Dockerfile rename to docker/Dockerfile index 050d45a306..0e3c4bf51d 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -4,10 +4,16 @@ # # Separating the builder and runtime image allows the runtime image to be # considerably smaller because it doesn't need to have Golang installed. -ARG BUILDER_IMAGE=docker.io/golang:1.22.6-alpine3.19 +ARG BUILDER_IMAGE=docker.io/golang:1.23.1-alpine3.20 ARG RUNTIME_IMAGE=docker.io/alpine:3.19 ARG TARGETOS ARG TARGETARCH +# Use build args to override the maxuimum square size of the docker image i.e. +# docker build --build-arg MAX_SQUARE_SIZE=64 -t celestia-app:latest . +ARG MAX_SQUARE_SIZE +# Use build args to override the upgrade height delay of the docker image i.e. +# docker build --build-arg UPGRADE_HEIGHT_DELAY=1000 -t celestia-app:latest . +ARG UPGRADE_HEIGHT_DELAY # Stage 1: Build the celestia-appd binary inside a builder image that will be discarded later. # Ignore hadolint rule because hadolint can't parse the variable. @@ -28,6 +34,8 @@ COPY . /celestia-app WORKDIR /celestia-app RUN uname -a &&\ CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ + OVERRIDE_MAX_SQUARE_SIZE=${MAX_SQUARE_SIZE} \ + OVERRIDE_UPGRADE_HEIGHT_DELAY=${UPGRADE_HEIGHT_DELAY} \ make build # Stage 2: Create a minimal image to run the celestia-appd binary diff --git a/docker/txsim.sh b/docker/txsim.sh deleted file mode 100644 index c27cedb3ea..0000000000 --- a/docker/txsim.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash - -CREATE_KEY=0 -KEY_PATH="/home/celestia" -GRPC_ENDPOINT="" -POLL_TIME="" -BLOB=0 -BLOB_AMOUNTS="1" -BLOB_SIZES="100-1000" -KEY_MNEMONIC="" -SEED=0 -SEND=0 -SEND_AMOUNT=1000 -SEND_ITERATIONS=1000 -STAKE=0 -STAKE_VALUE=1000 - -while getopts "k:p:r:g:t:b:a:s:m:d:e:i:v:u:w:" opt; do - case ${opt} in - k ) - CREATE_KEY=$OPTARG - ;; - p ) - KEY_PATH=$OPTARG - ;; - g ) - GRPC_ENDPOINT=$OPTARG - ;; - t ) - POLL_TIME=$OPTARG - ;; - b ) - BLOB=$OPTARG - ;; - a ) - BLOB_AMOUNTS=$OPTARG - ;; - s ) - BLOB_SIZES=$OPTARG - ;; - m ) - KEY_MNEMONIC=$OPTARG - ;; - d ) - SEED=$OPTARG - ;; - e ) - SEND=$OPTARG - ;; - i ) - SEND_AMOUNT=$OPTARG - ;; - v ) - SEND_ITERATIONS=$OPTARG - ;; - u ) - STAKE=$OPTARG - ;; - w ) - STAKE_VALUE=$OPTARG - ;; - \? ) - echo "Invalid option: $OPTARG" 1>&2 - exit 1 - ;; - : ) - echo "Invalid option: $OPTARG requires an argument" 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND -1)) - -if [ "$CREATE_KEY" -eq 1 ]; then - echo "Creating a new keyring-test for the txsim" - /bin/celestia-appd keys add sim --keyring-backend test --home $KEY_PATH - sleep 5 -fi - -# Running a tx simulator -txsim --key-path $KEY_PATH \ - --grpc-endpoint $GRPC_ENDPOINT \ - --poll-time $POLL_TIME \ - --blob $BLOB \ - --blob-amounts $BLOB_AMOUNTS \ - --blob-sizes $BLOB_SIZES \ - --key-mnemonic "$KEY_MNEMONIC" \ - --seed $SEED \ - --send $SEND \ - --send-amount $SEND_AMOUNT \ - --send-iterations $SEND_ITERATIONS \ - --stake $STAKE \ - --stake-value $STAKE_VALUE diff --git a/docker/Dockerfile_txsim b/docker/txsim/Dockerfile similarity index 70% rename from docker/Dockerfile_txsim rename to docker/txsim/Dockerfile index 471db9c76a..563a06ab09 100644 --- a/docker/Dockerfile_txsim +++ b/docker/txsim/Dockerfile @@ -1,5 +1,5 @@ -# Stage 1: generate celestia-appd binary -FROM --platform=$BUILDPLATFORM docker.io/golang:1.22.6-alpine3.19 as builder +# Stage 1: generate txsim binary +FROM --platform=$BUILDPLATFORM docker.io/golang:1.23.1-alpine3.20 as builder ARG TARGETOS ARG TARGETARCH @@ -16,11 +16,10 @@ RUN apk update && apk add --no-cache \ musl-dev COPY . /celestia-app WORKDIR /celestia-app -# we need the celestia-appd build as we might want to create an account -# internally for txsimulation + RUN uname -a &&\ CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - make build && make txsim-build + make txsim-build # Stage 2: create a minimal image with the binary FROM docker.io/alpine:3.20 @@ -45,18 +44,14 @@ RUN apk update && apk add --no-cache \ -s /sbin/nologin \ -u ${UID} -# Copy in the celestia-appd binary -COPY --from=builder /celestia-app/build/celestia-appd /bin/celestia-appd +# Copy in the txsim binary COPY --from=builder /celestia-app/build/txsim /bin/txsim -COPY --chown=${USER_NAME}:${USER_NAME} docker/txsim.sh /opt/entrypoint.sh +COPY --chown=${USER_NAME}:${USER_NAME} docker/txsim/entrypoint.sh /opt/entrypoint.sh USER ${USER_NAME} # Set the working directory to the home directory. WORKDIR ${CELESTIA_HOME} -# grpc, rpc, api ports -EXPOSE 26657 1317 9090 - ENTRYPOINT [ "/bin/bash", "/opt/entrypoint.sh" ] diff --git a/docker/README.md b/docker/txsim/README.md similarity index 100% rename from docker/README.md rename to docker/txsim/README.md diff --git a/docker/txsim/entrypoint.sh b/docker/txsim/entrypoint.sh new file mode 100644 index 0000000000..f919a4d33d --- /dev/null +++ b/docker/txsim/entrypoint.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +echo "Starting txsim with command:" +echo "/bin/txsim $@" +echo "" + +exec /bin/txsim $@ diff --git a/docs/audit/informal-systems-authored-blobs.pdf b/docs/audit/informal-systems-authored-blobs.pdf new file mode 100644 index 0000000000..b2ac02776a Binary files /dev/null and b/docs/audit/informal-systems-authored-blobs.pdf differ diff --git a/docs/maintainers/docker.md b/docs/maintainers/docker.md new file mode 100644 index 0000000000..37dfff2d9e --- /dev/null +++ b/docs/maintainers/docker.md @@ -0,0 +1,29 @@ +# Docker + +## Context + +Github Actions should automatically build and publish a Docker image for each release. If Github Actions failed, you can manually build and publish a Docker image using this guide. + +## Prerequisites + +1. Navigate to and generate a new token with the `write:packages` scope. + +## Steps + +1. Verify that a Docker image with the correct tag doesn't already exist for the release you're trying to create publish on [GHCR](https://github.com/celestiaorg/celestia-app/pkgs/container/celestia-app/versions) + +1. In a new terminal + + ```shell + # Set the CR_PAT environment variable to your token + export CR_PAT=YOUR_TOKEN + # Login to the GitHub Container Registry + echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin + + # Tell docker to use buildx for the multiple platform support + docker buildx create --use + # Build the image, in this example the v2.2.0-mocha image + docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/celestiaorg/celestia-app:v2.2.0-mocha --push . + ``` + +1. Verify that a Docker image with the correct tag was published on [GHCR](https://github.com/celestiaorg/celestia-app/pkgs/container/celestia-app/versions). diff --git a/docs/maintainers/modify-param.md b/docs/maintainers/modify-param.md new file mode 100644 index 0000000000..47fff0d757 --- /dev/null +++ b/docs/maintainers/modify-param.md @@ -0,0 +1,48 @@ +# Modify Param + +This doc will guide you through the process of modifying a parameter via governance. + +## Prerequisites + +```shell +# Verify the current parameter value +$ celestia-appd query params subspace icahost AllowMessages +key: AllowMessages +subspace: icahost +value: '["*"]' +``` + +## Steps + +```shell +# Create a proposal.json file +echo '{"title": "Modify ICA host allow messages", "description": "Modify ICA host allow messages", "changes": [{"subspace": "icahost", "key": "AllowMessages", "value": ["/ibc.applications.transfer.v1.MsgTransfer","/cosmos.bank.v1beta1.MsgSend","/cosmos.staking.v1beta1.MsgDelegate","/cosmos.staking.v1beta1.MsgBeginRedelegate","/cosmos.staking.v1beta1.MsgUndelegate","/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation","/cosmos.distribution.v1beta1.MsgSetWithdrawAddress","/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward","/cosmos.distribution.v1beta1.MsgFundCommunityPool","/cosmos.gov.v1.MsgVote","/cosmos.feegrant.v1beta1.MsgGrantAllowance","/cosmos.feegrant.v1beta1.MsgRevokeAllowance"]}], "deposit": "10000000000utia"}' > proposal.json + +# Export a variable for the key that will be used to submit the proposal +export FROM="validator" +export FEES="210000utia" +export GAS="auto" +export GAS_ADJUSTMENT="1.5" + +# Submit the proposal +celestia-appd tx gov submit-legacy-proposal param-change proposal.json --from $FROM --fees $FEES --gas $GAS --gas-adjustment $GAS_ADJUSTMENT --yes + +# Query the proposals +celestia-appd query gov proposals --output json | jq . + +# Export a variable for the relevant proposal ID based on the output from the previous command +export PROPOSAL_ID=1 + +# Vote yes on the proposal +celestia-appd tx gov vote $PROPOSAL_ID yes --from $FROM --fees $FEES --gas $GAS --gas-adjustment $GAS_ADJUSTMENT --yes +``` + +## After the proposal passes + +```shell +# Verify the parameter value changed +$ celestia-appd query params subspace icahost AllowMessages +key: AllowMessages +subspace: icahost +value: '["/ibc.applications.transfer.v1.MsgTransfer","/cosmos.bank.v1beta1.MsgSend","/cosmos.staking.v1beta1.MsgDelegate","/cosmos.staking.v1beta1.MsgBeginRedelegate","/cosmos.staking.v1beta1.MsgUndelegate","/cosmos.staking.v1beta1.MsgCancelUnbondingDelegation","/cosmos.distribution.v1beta1.MsgSetWithdrawAddress","/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward","/cosmos.distribution.v1beta1.MsgFundCommunityPool","/cosmos.gov.v1.MsgVote","/cosmos.feegrant.v1beta1.MsgGrantAllowance","/cosmos.feegrant.v1beta1.MsgRevokeAllowance"]' +``` diff --git a/docs/maintainers/prebuilt-binaries.md b/docs/maintainers/prebuilt-binaries.md new file mode 100644 index 0000000000..9be52d76bc --- /dev/null +++ b/docs/maintainers/prebuilt-binaries.md @@ -0,0 +1,49 @@ +# Prebuilt binaries + +Prebuilt binaries are attached to each release via [GoReleaser](https://goreleaser.com/) which runs in Github Actions. If GoReleaser failed to attach prebuilt binaries, you may want to attach them manually by following the steps below. + +## Prerequisites + +1. Create a Github token (classic) that has `repo:public_repo` scope via: + + ```shell + export GORELEASER_ACCESS_TOKEN= + echo "GITHUB_TOKEN=${GORELEASER_ACCESS_TOKEN}" >> .release-env + ``` + +## Steps + +1. [Optional] If you need to make any code changes to fix the issue that occured when CI tried to generate and attach the prebuilt binaries, then you likely need to skip validation when running GoReleaser locally. To skip validation, modify the Makefile command like so: + + ```diff + ## prebuilt-binary: Create prebuilt binaries and attach them to GitHub release. Requires Docker. + prebuilt-binary: + @if [ ! -f ".release-env" ]; then \ + echo "A .release-env file was not found but is required to create prebuilt binaries. This command is expected to be run in CI where a .release-env file exists. If you need to run this command locally to attach binaries to a release, you need to create a .release-env file with a Github token (classic) that has repo:public_repo scope."; \ + exit 1;\ + fi + docker run \ + --rm \ + -e CGO_ENABLED=1 \ + --env-file .release-env \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v `pwd`:/go/src/$(PACKAGE_NAME) \ + -w /go/src/$(PACKAGE_NAME) \ + ghcr.io/goreleaser/goreleaser-cross:${GOLANG_CROSS_VERSION} \ + - release --clean + + release --clean --skip=validate + .PHONY: prebuilt-binary + ``` + +1. Before proceeding, test your change by running `make prebuilt-binary` and verifying that prebuilt binaries are attached to a release on your Github fork. +1. Modify `.goreleaser.yaml` so that you can upload assets to the main repository: + + ```diff + release: + + github: + + owner: celestiaorg + + name: celestia-app + ``` + +1. Run `make prebuilt-binary` to generate and attach the prebuilt binaries. +1. Verify the assets were attached to the release on the main repository. diff --git a/docs/maintainers/release-guide.md b/docs/maintainers/release-guide.md new file mode 100644 index 0000000000..698799235e --- /dev/null +++ b/docs/maintainers/release-guide.md @@ -0,0 +1,40 @@ +# Release Guide + +The target audience for this guide is maintainers of this repo. In general, the release process is as follows: + +1. Create a release candidate +1. Test the release candidate + 1. If the release candidate is not satisfactory, go back to step 1 + 1. If the release candidate is satisfactory, create an official release + +## Release Candidate + +### Creating a release candidate + +1. Navigate to . +1. Choose a version tag based on [Semantic Versioning](https://semver.org/). Include the `-rc` suffix followed by the next integer. RCs start at 0. +1. Change the target branch to `v1.x` or `v2.x` based on the version you're releasing. +1. Click **Generate release notes**. +1. Toggle on the **Set as a pre-relase** checkbox. +1. **Publish release**. + +### After creating the release candidate + +1. Wait until CI passes on the release and verify that prebuilt binaries were attached to the release. +1. Create a PR to bump the celestia-app dependency in [celestia-node](https://github.com/celestiaorg/celestia-node). +1. [Optional] Start a testnet via auto-devops that uses the release candidate. Confirm it works. +1. [Optional] Use the release candidate to sync from genesis. Confirm it works. + +## Official Release + +Follow the [creating a release candidate](#creating-a-release-candidate) section with the following considerations: + +- The version tag should not include the `-rc` suffix. +- If the release targets a testnet, suffix the release with `-arabica` or `-mocha`. +- The release notes should contain an **Upgrade Notice** section with notable changes for node operators or library consumers. +- The release notes section should contain a link to https://github.com/celestiaorg/celestia-app/blob/main/docs/release-notes/release-notes.md where we capture breaking changes + +After creating the release: + +1. Wait until CI passes on the release and verify that prebuilt binaries were attached to the release. +1. Create a PR to bump the celestia-app dependency in [celestia-node](https://github.com/celestiaorg/celestia-node). diff --git a/docs/release-notes/pending-release.md b/docs/release-notes/pending-release.md new file mode 100644 index 0000000000..80c7c228eb --- /dev/null +++ b/docs/release-notes/pending-release.md @@ -0,0 +1,11 @@ +# Pending Nelease + +## v3.0.0 [Unreleased] + +### Node Operators + +- Consensus node operators should enable the BBR (Bottleneck Bandwidth and Round-trip propagation time) congestion control algorithm. See [#3774](https://github.com/celestiaorg/celestia-app/pull/3774). + +### Library Consumers + +- Namespace and share constants in the `appconsts` package were moved to [celestiaorg/go-square](https://github.com/celestiaorg/go-square). See [#3765](https://github.com/celestiaorg/celestia-app/pull/3765). diff --git a/docs/release-notes/release-notes.md b/docs/release-notes/release-notes.md new file mode 100644 index 0000000000..c5031566e5 --- /dev/null +++ b/docs/release-notes/release-notes.md @@ -0,0 +1,22 @@ +# Release Notes + +This guide provides notes for major version releases. These notes may be helpful for users when upgrading from previous major versions. + +## [v2.0.0](https://github.com/celestiaorg/celestia-app/releases/tag/v2.0.0) + +### Node Operators + +If you are a consensus node operator, please follow the communication channels listed under [network upgrades](https://docs.celestia.org/nodes/participate#network-upgrades) to learn when this release is recommended for each network (e.g. Mocha, Mainnet Beta). + +Consensus node operators are expected to upgrade to this release _prior_ to the Lemongrass hardfork if they intend to continue participating in the network. The command used to start the [consensus node](https://docs.celestia.org/nodes/consensus-node#start-the-consensus-node) or [validator node](https://docs.celestia.org/nodes/validator-node#run-the-validator-node) will accept an additional `--v2-upgrade-height` flag. See [this table](https://docs.celestia.org/nodes/network-upgrade-process#lemongrass-network-upgrade) for upgrade heights for each network. + +Consensus node operators should enable the BBR (Bottleneck Bandwidth and Round-trip propagation time) congestion control algorithm. See [#3812](https://github.com/celestiaorg/celestia-app/pull/3812). + +### Library Consumers + +If you are a library consumer, a number of the Go APIs have changed since celestia-app v1.x.x. Some of the notable changes are: + +- Code pertaining to the original data square was extracted to [celestiaorg/go-square](https://github.com/celestiaorg/go-square). + - celestia-app v1.x had a shares package. celestia-app v2.x uses [go-square/shares](https://github.com/celestiaorg/go-square/tree/c8242f96a844956f8d1c60e5511104deed8bc361/shares) + - celestia-app v1.x had a blob.types package with `CreateCommitment` function. celestia-app v2.x uses `CreateCommitment` function from the [go-square/inclusion](https://github.com/celestiaorg/go-square/tree/c8242f96a844956f8d1c60e5511104deed8bc361/inclusion). +- celestia-app v1.x had a lot of functionality included in the signer. celestia-app v2.x splits a txClient from the signer. See [#3433](https://github.com/celestiaorg/celestia-app/pull/3433). diff --git a/go.mod b/go.mod index 6ad1be6deb..7ad4054fc1 100644 --- a/go.mod +++ b/go.mod @@ -1,22 +1,23 @@ module github.com/celestiaorg/celestia-app/v3 -go 1.22.6 +go 1.23.1 require ( cosmossdk.io/errors v1.0.1 cosmossdk.io/math v1.3.0 github.com/celestiaorg/blobstream-contracts/v3 v3.1.0 - github.com/celestiaorg/celestia-app/x/signal v1.0.0 - github.com/celestiaorg/go-square/v2 v2.0.0-rc2 - github.com/celestiaorg/knuu v0.14.0 - github.com/celestiaorg/nmt v0.22.1 + github.com/celestiaorg/go-square v1.1.1 + github.com/celestiaorg/go-square/v2 v2.0.0 + github.com/celestiaorg/knuu v0.16.1 + github.com/celestiaorg/nmt v0.22.2 github.com/celestiaorg/rsmt2d v0.14.0 + github.com/cometbft/cometbft-db v1.0.1 github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/cosmos-sdk v0.46.16 - github.com/cosmos/gogoproto v1.5.0 + github.com/cosmos/gogoproto v1.7.0 github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 - github.com/cosmos/ibc-go/v6 v6.3.1 - github.com/ethereum/go-ethereum v1.14.7 + github.com/cosmos/ibc-go/v6 v6.2.2 + github.com/ethereum/go-ethereum v1.14.11 github.com/gogo/protobuf v1.3.3 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 @@ -30,22 +31,24 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tendermint/tendermint v0.34.29 github.com/tendermint/tm-db v0.6.7 - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a + golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.65.0 - google.golang.org/protobuf v1.34.2 + google.golang.org/grpc v1.67.1 + google.golang.org/protobuf v1.35.1 gopkg.in/yaml.v2 v2.4.0 + k8s.io/apimachinery v0.31.1 ) require ( cloud.google.com/go v0.112.1 // indirect - cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.38.0 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.2 // indirect github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect + github.com/DataDog/zstd v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/Workiva/go-datastructures v1.0.53 // indirect @@ -54,26 +57,34 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/bufbuild/protocompile v0.14.1 // indirect github.com/celestiaorg/bittwister v0.0.0-20231213180407-65cdbaf5b8c7 // indirect github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cilium/ebpf v0.12.3 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect github.com/confio/ics23/go v0.9.1 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/containerd/continuity v0.4.2 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gorocksdb v1.2.0 // indirect github.com/cosmos/iavl v0.19.6 // indirect github.com/cosmos/ledger-cosmos-go v0.13.2 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect github.com/creachadair/taskgroup v0.3.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -82,35 +93,35 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgraph-io/badger/v4 v4.3.0 // indirect + github.com/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v26.1.5+incompatible // indirect - github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-kit/kit v0.12.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-playground/validator/v10 v10.11.2 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/go-openapi/swag v0.22.4 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/gateway v1.1.0 // indirect - github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/btree v1.1.2 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/flatbuffers v1.12.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -120,10 +131,10 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.2 // indirect github.com/gorilla/handlers v1.5.2 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grafana/otel-profiling-go v0.5.1 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect + github.com/grafana/pyroscope-go v1.1.2 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.8 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/gtank/merlin v0.1.1 // indirect @@ -132,60 +143,60 @@ require ( github.com/hashicorp/go-getter v1.7.4 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/holiman/uint256 v1.3.0 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.6 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/klauspost/reedsolomon v1.12.1 // indirect - github.com/lib/pq v1.10.7 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/linxGnu/grocksdb v1.9.3 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect - github.com/minio/highwayhash v1.0.2 // indirect + github.com/minio/highwayhash v1.0.3 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/minio/minio-go/v7 v7.0.70 // indirect + github.com/minio/minio-go/v7 v7.0.74 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/spdystream v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/onsi/ginkgo v1.16.5 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.20.3 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/regen-network/cosmos-proto v0.3.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/xid v1.5.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -195,51 +206,47 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.15.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.5.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/ugorji/go/codec v1.2.9 // indirect github.com/ulikunitz/xz v0.5.10 // indirect + github.com/x448/float16 v0.8.4 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.3.6 // indirect + go.etcd.io/bbolt v1.3.11 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect + go.opentelemetry.io/otel v1.30.0 // indirect go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/sdk v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect - go.opentelemetry.io/proto/otlp v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.30.0 // indirect + go.opentelemetry.io/otel/sdk v1.30.0 // indirect + go.opentelemetry.io/otel/trace v1.30.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/oauth2 v0.22.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect google.golang.org/api v0.169.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.28.2 // indirect - k8s.io/apimachinery v0.28.2 // indirect - k8s.io/client-go v0.28.2 // indirect - k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/api v0.30.2 // indirect + k8s.io/client-go v0.30.2 // indirect + k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect - nhooyr.io/websocket v1.8.6 // indirect + k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect + nhooyr.io/websocket v1.8.17 // indirect rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect @@ -247,13 +254,11 @@ require ( ) replace ( - github.com/celestiaorg/celestia-app/x/signal => ./x/signal - // replace cosmos-sdk with a local copy that exposes config.IsSealed(). - github.com/cosmos/cosmos-sdk => ../cosmos-sdk + github.com/cosmos/cosmos-sdk => github.com/celestiaorg/cosmos-sdk v1.25.0-sdk-v0.46.16 // Pin to ledger-cosmos-go v0.12.4 to avoid a breaking change introduced in v0.13.0 // The following replace statement can be removed when we upgrade to cosmos-sdk >= v0.50.0 github.com/cosmos/ledger-cosmos-go => github.com/cosmos/ledger-cosmos-go v0.12.4 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29 + github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.43.0-tm-v0.34.35 ) diff --git a/go.sum b/go.sum index 78e333ef19..22fd80bf43 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz 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/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= @@ -213,7 +213,6 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= @@ -280,8 +279,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= @@ -290,8 +289,8 @@ github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv 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/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= @@ -309,8 +308,8 @@ 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/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg= -github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= @@ -318,23 +317,27 @@ github.com/celestiaorg/bittwister v0.0.0-20231213180407-65cdbaf5b8c7 h1:nxplQi8w github.com/celestiaorg/bittwister v0.0.0-20231213180407-65cdbaf5b8c7/go.mod h1:1EF5MfOxVf0WC51Gb7pJ6bcZxnXKNAf9pqWtjgPBAYc= github.com/celestiaorg/blobstream-contracts/v3 v3.1.0 h1:h1Y4V3EMQ2mFmNtWt2sIhZIuyASInj1a9ExI8xOsTOw= github.com/celestiaorg/blobstream-contracts/v3 v3.1.0/go.mod h1:x4DKyfKOSv1ZJM9NwV+Pw01kH2CD7N5zTFclXIVJ6GQ= -github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29 h1:9Co/2peu4+9S6KMVNPFS0NTI/RYIRirNpM4N7dmi9ak= -github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29/go.mod h1:5jJ5magtH7gQOwSYfS/m5fliIS7irKunLV7kLNaD8o0= -github.com/celestiaorg/go-square/v2 v2.0.0-rc2 h1:4D+ASgZGYVCsffc2uhPagACrvNiLZu9/CqNYvnlHCgg= -github.com/celestiaorg/go-square/v2 v2.0.0-rc2/go.mod h1:eeaU8f8jBpk3ZS/gaDZIlTesJR2F51QAmveNzWH6aEU= -github.com/celestiaorg/knuu v0.14.0 h1:96uaDHTzlTfhDLrAiygq9Ewow7UzOzGAbUvMwws1S4A= -github.com/celestiaorg/knuu v0.14.0/go.mod h1:5x/+tlLebBSfLmmSBm2ps6aLjnKLn5bOaZpUfI5FpsA= +github.com/celestiaorg/celestia-core v1.43.0-tm-v0.34.35 h1:L4GTm+JUXhB0a/nGPMq6jEqqe6THuYSQ8m2kUCtZYqw= +github.com/celestiaorg/celestia-core v1.43.0-tm-v0.34.35/go.mod h1:bFr0lAGwaJ0mOHSBmib5/ca5pbBf1yKWGPs93Td0HPw= +github.com/celestiaorg/cosmos-sdk v1.25.0-sdk-v0.46.16 h1:f+fTe7GGk0/qgdzyqB8kk8EcDf9d6MC22khBTQiDXsU= +github.com/celestiaorg/cosmos-sdk v1.25.0-sdk-v0.46.16/go.mod h1:07Z8HJqS8Rw4XlZ+ok3D3NM/X/in8mvcGLvl0Zb5wrA= +github.com/celestiaorg/go-square v1.1.1 h1:Cy3p8WVspVcyOqHM8BWFuuYPwMitO1pYGe+ImILFZRA= +github.com/celestiaorg/go-square v1.1.1/go.mod h1:1EXMErhDrWJM8B8V9hN7dqJ2kUTClfwdqMOmF9yQUa0= +github.com/celestiaorg/go-square/v2 v2.0.0 h1:U5QV8/de5lc7glosfgyHhcxbFwNuwU4+6aYZ2RgjM04= +github.com/celestiaorg/go-square/v2 v2.0.0/go.mod h1:y0BolG0tRM7UN1sAQyDDUkT+aMJPwFIjviVvnCB62C0= +github.com/celestiaorg/knuu v0.16.1 h1:EOR/c9kvc0jZet/mma2qwAdlvEbl94bW9cC8FItkyBE= +github.com/celestiaorg/knuu v0.16.1/go.mod h1:y20nUmVWVgbzxBKHqmbwp3C0ZJ9J9ovCg1ylHo85hdQ= github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 h1:CJdIpo8n5MFP2MwK0gSRcOVlDlFdQJO1p+FqdxYzmvc= github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4/go.mod h1:fzuHnhzj1pUygGz+1ZkB3uQbEUL4htqCGJ4Qs2LwMZA= -github.com/celestiaorg/nmt v0.22.1 h1:t7fqoP5MJ8mBns5DB2XjfcPxQpS3CKMkY+v+BEkDxYc= -github.com/celestiaorg/nmt v0.22.1/go.mod h1:ia/EpCk0enD5yO5frcxoNoFToz2Ghtk2i+blmCRjIY8= +github.com/celestiaorg/nmt v0.22.2 h1:JmOMtZL9zWAed1hiwb9DDs+ELcKp/ZQZ3rPverge/V8= +github.com/celestiaorg/nmt v0.22.2/go.mod h1:/7huDiSRL/d2EGhoiKctgSzmLOJoWG8yEfbFtY1+Mow= github.com/celestiaorg/rsmt2d v0.14.0 h1:L7XJ3tRJDY8sQcvCjzHq0L7JmsmaSD+VItymIYFLqYc= github.com/celestiaorg/rsmt2d v0.14.0/go.mod h1:4kxqiTdFev49sGiKXTDjohbWYOG5GlcIfftTgaBJnpc= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.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/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -372,14 +375,16 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= -github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= @@ -388,8 +393,8 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= +github.com/cometbft/cometbft-db v1.0.1 h1:SylKuLseMLQKw3+i8y8KozZyJcQSL98qEe2CGMCGTYE= +github.com/cometbft/cometbft-db v1.0.1/go.mod h1:EBrFs1GDRiTqrWXYi4v90Awf/gcdD5ExzdPbg4X8+mk= github.com/confio/ics23/go v0.9.1 h1:3MV46eeWwO3xCauKyAtuAdJYMyPnnchW4iLr2bTw6/U= github.com/confio/ics23/go v0.9.1/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= @@ -400,10 +405,8 @@ github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1 github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -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/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= +github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 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= @@ -417,16 +420,16 @@ github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRAp github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o= -github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I= +github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= +github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cosmos/iavl v0.19.6 h1:XY78yEeNPrEYyNCKlqr9chrwoeSDJ0bV2VjocTk//OU= github.com/cosmos/iavl v0.19.6/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 h1:Hz4nkpStoXIHrC77CIEyu2mRiN2qysGEZPFRf0fpv7w= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2/go.mod h1:Jo934o/sW7fNxuOa/TjCalSalz+1Fd649eLyANaJx8g= -github.com/cosmos/ibc-go/v6 v6.3.1 h1:/5ur3AsmNW8WuOevfODHlaY5Ze236PBNE3vVo9o3fQA= -github.com/cosmos/ibc-go/v6 v6.3.1/go.mod h1:Dm14j9s094bGyCEE8W4fD+2t8IneHv+cz+80Mvwjr1w= +github.com/cosmos/ibc-go/v6 v6.2.2 h1:xVnlfV+IFPMkAEuWdZpRbky1jfGcob9i+T+xQ2LRf48= +github.com/cosmos/ibc-go/v6 v6.2.2/go.mod h1:XLsARy4Y7+GtAqzMcxNdlQf6lx+ti1e8KcMGv5NIK7A= github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= @@ -466,24 +469,22 @@ github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/badger/v4 v4.3.0 h1:lcsCE1/1qrRhqP+zYx6xDZb8n7U+QlwNicpc676Ub40= +github.com/dgraph-io/badger/v4 v4.3.0/go.mod h1:Sc0T595g8zqAQRDf44n+z3wG4BOqLwceaFntt8KPxUM= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91 h1:Pux6+xANi0I7RRo5E1gflI4EZ2yx3BGZ75JkAIvGEOA= +github.com/dgraph-io/ristretto v0.1.2-0.20240116140435-c67e07994f91/go.mod h1:swkazRqnUf1N62d0Nutz7KIj2UKqsm/H8tD0nBJAXqM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v26.1.5+incompatible h1:NEAxTwEjxV6VbBMBoGG3zPqbiJosIApZjxlbrG9q3/g= -github.com/docker/docker v26.1.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -517,10 +518,10 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMNhAT29g= -github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= @@ -534,8 +535,6 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -547,6 +546,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= @@ -554,17 +555,18 @@ github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= -github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= +github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -579,8 +581,8 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi 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.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= @@ -593,33 +595,26 @@ github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaL github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= -github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= 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-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -635,8 +630,6 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= 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= @@ -681,9 +674,11 @@ github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= +github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -731,8 +726,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe 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-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af h1:kmjWCqn2qkEml422C2Rrd27c3VGxi6a/6HNq8QmHRKM= +github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -773,14 +768,14 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS 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.4.2/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/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= +github.com/grafana/pyroscope-go v1.1.2 h1:7vCfdORYQMCxIzI3NlYAs3FcBP760+gWuYWOyiVyYx8= +github.com/grafana/pyroscope-go v1.1.2/go.mod h1:HSSmHo2KRn6FasBA4vK7BMiQqyQq8KSuBKvrhkXxYPU= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8 h1:iwOtYXeeVSAeYefJNaxDytgjKtUuKQbJqgAIjlnicKg= +github.com/grafana/pyroscope-go/godeltaprof v0.1.8/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 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= @@ -791,8 +786,6 @@ github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= @@ -823,9 +816,8 @@ github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoD github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.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= @@ -847,8 +839,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8 github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= @@ -892,8 +884,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw 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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= -github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -923,13 +913,12 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/reedsolomon v1.12.1 h1:NhWgum1efX1x58daOBGCFWcxtEhOhXKKl1HAPQUp03Q= @@ -952,15 +941,15 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/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.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linxGnu/grocksdb v1.9.3 h1:s1cbPcOd0cU2SKXRG1nEqCOWYAELQjdqg3RVI2MH9ik= +github.com/linxGnu/grocksdb v1.9.3/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -994,8 +983,8 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.3/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -1003,12 +992,12 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -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/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q= +github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g= -github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo= +github.com/minio/minio-go/v7 v7.0.74 h1:fTo/XlPBTSpo3BAMshlwKL5RspXRv9us5UeHEGYCFe0= +github.com/minio/minio-go/v7 v7.0.74/go.mod h1:qydcVzV8Hqtj1VtEocfxbmVFa2siu6HGa+LDEPogjD8= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -1029,12 +1018,8 @@ github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8oh github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -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/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= +github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1043,8 +1028,6 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 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/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= @@ -1054,6 +1037,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= @@ -1080,19 +1065,19 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= 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.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= 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.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= +github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1113,8 +1098,8 @@ github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144T github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= @@ -1125,6 +1110,9 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG 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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +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= @@ -1141,16 +1129,16 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= 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.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.3 h1:oPksm4K8B+Vt35tUhw6GbSNSgVlVSBH0qELP/7u83l4= +github.com/prometheus/client_golang v1.20.3/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1159,16 +1147,16 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 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.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 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= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= @@ -1180,15 +1168,15 @@ github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNw github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= 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.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1215,7 +1203,6 @@ github.com/shirou/gopsutil v3.21.6+incompatible h1:mmZtAlWSd8U2HeRTjswbnDLPxqsEo github.com/shirou/gopsutil v3.21.6+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -1275,12 +1262,10 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= @@ -1289,8 +1274,8 @@ github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= -github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= @@ -1315,8 +1300,6 @@ github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3C github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -1331,6 +1314,8 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+ github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -1353,8 +1338,8 @@ gitlab.com/NebulousLabs/errors v0.0.0-20200929122200-06c536cf6975/go.mod h1:ZkMZ gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs= gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -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/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0= +go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -1372,26 +1357,20 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0 h1:1wp/gyxsuYtuE/JFxsQRtcCDtMrO2qMvlfXALU5wkzI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.26.0/go.mod h1:gbTHmghkGgqxMomVQQMur1Nba4M0MQ8AYThXDUjsJ38= +go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts= +go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0 h1:hSWWvDjXHVLq9DkmB+77fl8v7+t+yYiS+eNkiplDK54= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0/go.mod h1:zG7KQql1WjZCaUJd+L/ReSYx4bjbYJxg5ws9ws+mYes= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= +go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w= +go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= -go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= +go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE= +go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= +go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc= +go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI= -go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY= 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= @@ -1431,8 +1410,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/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.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1447,8 +1426,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-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-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1540,8 +1519,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1567,8 +1546,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -1583,8 +1562,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ 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.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1594,7 +1573,6 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1640,7 +1618,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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= @@ -1689,7 +1666,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc 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-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1697,14 +1673,15 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1715,8 +1692,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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= @@ -1789,8 +1766,8 @@ 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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1978,8 +1955,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2022,8 +1999,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2040,8 +2017,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ 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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2081,10 +2058,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 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= @@ -2094,20 +2068,21 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt 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.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.28.2 h1:9mpl5mOb6vXZvqbQmankOfPIGiudghwCoLl1EYfUZbw= -k8s.io/api v0.28.2/go.mod h1:RVnJBsjU8tcMq7C3iaRSGMeaKt2TWEUXcpIt/90fjEg= -k8s.io/apimachinery v0.28.2 h1:KCOJLrc6gu+wV1BYgwik4AF4vXOlVJPdiqn0yAWWwXQ= -k8s.io/apimachinery v0.28.2/go.mod h1:RdzF87y/ngqk9H4z3EL2Rppv5jj95vGS/HaFXrLDApU= -k8s.io/client-go v0.28.2 h1:DNoYI1vGq0slMBN/SWKMZMw0Rq+0EQW6/AK4v9+3VeY= -k8s.io/client-go v0.28.2/go.mod h1:sMkApowspLuc7omj1FOSUxSoqjr+d5Q0Yc0LOFnYFJY= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= +k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= +k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U= +k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= +k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= +k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= -k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= +k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= +nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/go.work.example b/go.work.example index 85b25f4976..64b0c2f5d2 100644 --- a/go.work.example +++ b/go.work.example @@ -1,4 +1,4 @@ -go 1.22.6 +go 1.23.1 use ( . diff --git a/local_devnet/docker-compose.yml b/local_devnet/docker-compose.yml index 15c0a38704..1cf768d53d 100644 --- a/local_devnet/docker-compose.yml +++ b/local_devnet/docker-compose.yml @@ -6,6 +6,7 @@ services: container_name: core0 build: context: .. + dockerfile: ./docker/Dockerfile expose: - "26660" # for prometheus ports: @@ -31,6 +32,7 @@ services: container_name: core1 build: context: .. + dockerfile: ./docker/Dockerfile expose: - "26660" # for prometheus depends_on: @@ -59,6 +61,7 @@ services: container_name: core2 build: context: .. + dockerfile: ./docker/Dockerfile expose: - "26660" # for prometheus depends_on: @@ -87,6 +90,7 @@ services: container_name: core3 build: context: .. + dockerfile: ./docker/Dockerfile expose: - "26660" # for prometheus depends_on: diff --git a/local_devnet/scripts/start_core0.sh b/local_devnet/scripts/start_core0.sh index 1218ee1386..ee01080ac2 100644 --- a/local_devnet/scripts/start_core0.sh +++ b/local_devnet/scripts/start_core0.sh @@ -17,4 +17,5 @@ fi /bin/celestia-appd start \ --moniker core0 \ --rpc.laddr tcp://0.0.0.0:26657 \ - --home /opt + --home /opt \ + --force-no-bbr diff --git a/local_devnet/scripts/start_node_and_create_validator.sh b/local_devnet/scripts/start_node_and_create_validator.sh index c9ac25f3bb..2b29953666 100644 --- a/local_devnet/scripts/start_node_and_create_validator.sh +++ b/local_devnet/scripts/start_node_and_create_validator.sh @@ -66,7 +66,8 @@ fi # start node celestia-appd start \ ---home="${CELESTIA_HOME}" \ ---moniker="${MONIKER}" \ ---p2p.persistent_peers=e3c592c0c2ad4b05cef3791456b0d6dd4da72ed2@core0:26656 \ ---rpc.laddr=tcp://0.0.0.0:26657 + --home="${CELESTIA_HOME}" \ + --moniker="${MONIKER}" \ + --p2p.persistent_peers=e3c592c0c2ad4b05cef3791456b0d6dd4da72ed2@core0:26656 \ + --rpc.laddr=tcp://0.0.0.0:26657 \ + --force-no-bbr diff --git a/node/go.mod b/node/go.mod index 2205117e95..f52a80ab15 100644 --- a/node/go.mod +++ b/node/go.mod @@ -35,7 +35,7 @@ require ( github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/celestiaorg/blobstream-contracts/v3 v3.1.0 // indirect - github.com/celestiaorg/celestia-app/x/signal v1.0.0 // indirect + github.com/celestiaorg/celestia-app/v3/x/signal v1.0.0 // indirect github.com/celestiaorg/go-square v1.1.0 // indirect github.com/celestiaorg/go-square/merkle v0.0.0-20240117232118-fd78256df076 // indirect github.com/celestiaorg/go-square/v2 v2.0.0-rc2 // indirect @@ -212,7 +212,7 @@ replace ( github.com/celestiaorg/celestia-app/v2 => ../../celestia-app-v2 // replace celestia-app v3 with a local copy so that we can modify it's modules.go github.com/celestiaorg/celestia-app/v3 => ../ - github.com/celestiaorg/celestia-app/x/signal => ../x/signal + github.com/celestiaorg/celestia-app/v3/x/signal => ../x/signal // replace cosmos-sdk with a local copy that exposes config.IsSealed(). github.com/cosmos/cosmos-sdk => ../../cosmos-sdk // Pin to ledger-cosmos-go v0.12.4 to avoid a breaking change introduced in v0.13.0 diff --git a/pkg/appconsts/consensus_consts.go b/pkg/appconsts/consensus_consts.go index c26e4078eb..43aa335f93 100644 --- a/pkg/appconsts/consensus_consts.go +++ b/pkg/appconsts/consensus_consts.go @@ -3,8 +3,6 @@ package appconsts import "time" const ( - TimeoutPropose = time.Second * 10 - TimeoutCommit = time.Second * 11 // GoalBlockTime is the target time interval between blocks. Since the block // interval isn't enforced at consensus, the real block interval isn't // guaranteed to exactly match GoalBlockTime. GoalBlockTime is currently targeted diff --git a/pkg/appconsts/global_consts.go b/pkg/appconsts/global_consts.go index 340f651840..1bcdb7ac6c 100644 --- a/pkg/appconsts/global_consts.go +++ b/pkg/appconsts/global_consts.go @@ -9,7 +9,7 @@ import ( // These constants were originally sourced from: // https://github.com/celestiaorg/celestia-specs/blob/master/src/specs/consensus.md#constants // -// They can not change throughout the lifetime of a network. +// They cannot change throughout the lifetime of a network. const ( // DefaultShareVersion is the defacto share version. Use this if you are // unsure of which version to use. @@ -18,7 +18,7 @@ const ( // MinSquareSize is the smallest original square width. MinSquareSize = 1 - // MinshareCount is the minimum number of shares allowed in the original + // MinShareCount is the minimum number of shares allowed in the original // data square. MinShareCount = MinSquareSize * MinSquareSize diff --git a/pkg/appconsts/initial_consts.go b/pkg/appconsts/initial_consts.go index 1f97adf951..18cafc969d 100644 --- a/pkg/appconsts/initial_consts.go +++ b/pkg/appconsts/initial_consts.go @@ -17,10 +17,6 @@ const ( // maximum number of bytes allowed in a valid block. DefaultMaxBytes = DefaultGovMaxSquareSize * DefaultGovMaxSquareSize * share.ContinuationSparseShareContentSize - // DefaultGasPerBlobByte is the default gas cost deducted per byte of blob - // included in a PayForBlobs txn - DefaultGasPerBlobByte = 8 - // DefaultMinGasPrice is the default min gas price that gets set in the app.toml file. // The min gas price acts as a filter. Transactions below that limit will not pass // a nodes `CheckTx` and thus not be proposed by that node. @@ -30,6 +26,11 @@ const ( // to unbond in a proof of stake system. Any validator within this // time can be subject to slashing under conditions of misbehavior. DefaultUnbondingTime = 3 * 7 * 24 * time.Hour + + // DefaultNetworkMinGasPrice is used by x/minfee to prevent transactions from being + // included in a block if they specify a gas price lower than this. + // Only applies to app version >= 2 + DefaultNetworkMinGasPrice = 0.000001 // utia ) var DefaultUpperBoundMaxBytes = DefaultSquareSizeUpperBound * DefaultSquareSizeUpperBound * share.ContinuationSparseShareContentSize diff --git a/pkg/appconsts/overrides.go b/pkg/appconsts/overrides.go new file mode 100644 index 0000000000..39c5f4c6d0 --- /dev/null +++ b/pkg/appconsts/overrides.go @@ -0,0 +1,10 @@ +package appconsts + +// Set of values that can be overridden at compile time to modify the behavior of the app. +// WARNING: This should only be modified for testing purposes. All nodes in a network +// must have the same values for these constants. +// Look at the Makefile to see how these are set. +var ( + OverrideSquareSizeUpperBoundStr string + OverrideUpgradeHeightDelayStr string +) diff --git a/pkg/appconsts/prepare_proposal_consts.go b/pkg/appconsts/prepare_proposal_consts.go new file mode 100644 index 0000000000..c933aabd68 --- /dev/null +++ b/pkg/appconsts/prepare_proposal_consts.go @@ -0,0 +1,15 @@ +//go:build !bench_abci_methods + +package appconsts + +// The following consts are not consensus breaking and will be applied straight +// after this binary is started. +// These numbers softly constrain the processing time of blocks to 0.25sec. +// The benchmarks used to find these limits can be found in `app/benchmarks`. +const ( + // MaxPFBMessages is the maximum number of SDK messages, aside from PFBs, that a block can contain. + MaxPFBMessages = 200 + + // MaxNonPFBMessages is the maximum number of PFB messages a block can contain. + MaxNonPFBMessages = 600 +) diff --git a/pkg/appconsts/prepare_proposal_consts_bench.go b/pkg/appconsts/prepare_proposal_consts_bench.go new file mode 100644 index 0000000000..cc8141f791 --- /dev/null +++ b/pkg/appconsts/prepare_proposal_consts_bench.go @@ -0,0 +1,14 @@ +//go:build bench_abci_methods + +package appconsts + +// Note: these constants are set to these values only when running `bench_abci_methods` benchmarks. +// For the production values, check prepare_proposal_consts.go file. + +const ( + // MaxPFBMessages arbitrary high numbers for running benchmarks. + MaxPFBMessages = 999999999999 + + // MaxNonPFBMessages arbitrary high numbers for running benchmarks. + MaxNonPFBMessages = 999999999999 +) diff --git a/pkg/appconsts/v1/app_consts.go b/pkg/appconsts/v1/app_consts.go index 72b040f819..873d3ec18a 100644 --- a/pkg/appconsts/v1/app_consts.go +++ b/pkg/appconsts/v1/app_consts.go @@ -1,7 +1,15 @@ package v1 +import "time" + const ( Version uint64 = 1 SquareSizeUpperBound int = 128 SubtreeRootThreshold int = 64 + TimeoutPropose = time.Second * 10 + TimeoutCommit = time.Second * 11 + // UpgradeHeightDelay is the number of blocks after a quorum has been + // reached that the chain should upgrade to the new version. Assuming a block + // interval of 12 seconds, this is 7 days. + UpgradeHeightDelay = int64(7 * 24 * 60 * 60 / 12) // 7 days * 24 hours * 60 minutes * 60 seconds / 12 seconds per block = 50,400 blocks. ) diff --git a/pkg/appconsts/v2/app_consts.go b/pkg/appconsts/v2/app_consts.go index 2ef7a4075c..d02a97079b 100644 --- a/pkg/appconsts/v2/app_consts.go +++ b/pkg/appconsts/v2/app_consts.go @@ -1,10 +1,15 @@ package v2 +import "time" + const ( Version uint64 = 2 SquareSizeUpperBound int = 128 SubtreeRootThreshold int = 64 - // NetworkMinGasPrice is used by x/minfee to prevent transactions from being - // included in a block if they specify a gas price lower than this. - NetworkMinGasPrice float64 = 0.000001 // utia + TimeoutPropose = time.Second * 10 + TimeoutCommit = time.Second * 11 + // UpgradeHeightDelay is the number of blocks after a quorum has been + // reached that the chain should upgrade to the new version. Assuming a block + // interval of 12 seconds, this is 7 days. + UpgradeHeightDelay = int64(7 * 24 * 60 * 60 / 12) // 7 days * 24 hours * 60 minutes * 60 seconds / 12 seconds per block = 50,400 blocks. ) diff --git a/pkg/appconsts/v3/app_consts.go b/pkg/appconsts/v3/app_consts.go new file mode 100644 index 0000000000..3f9279518d --- /dev/null +++ b/pkg/appconsts/v3/app_consts.go @@ -0,0 +1,18 @@ +package v3 + +import "time" + +const ( + Version uint64 = 3 + SquareSizeUpperBound int = 128 + SubtreeRootThreshold int = 64 + TxSizeCostPerByte uint64 = 10 + GasPerBlobByte uint32 = 8 + MaxTxSize int = 2097152 // 2 MiB in bytes + TimeoutPropose = time.Millisecond * 3500 + TimeoutCommit = time.Millisecond * 4200 + // UpgradeHeightDelay is the number of blocks after a quorum has been + // reached that the chain should upgrade to the new version. Assuming a block + // interval of 12 seconds, this is 7 days. + UpgradeHeightDelay = int64(7 * 24 * 60 * 60 / 6) // 7 days * 24 hours * 60 minutes * 60 seconds / 6 seconds per block = 100,800 blocks. +) diff --git a/pkg/appconsts/versioned_consts.go b/pkg/appconsts/versioned_consts.go index 67c3c8a8f2..2455e87791 100644 --- a/pkg/appconsts/versioned_consts.go +++ b/pkg/appconsts/versioned_consts.go @@ -1,12 +1,16 @@ package appconsts import ( + "strconv" + "time" + v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" ) const ( - LatestVersion = v2.Version + LatestVersion = v3.Version ) // SubtreeRootThreshold works as a target upper bound for the number of subtree @@ -18,15 +22,78 @@ const ( // // The rationale for this value is described in more detail in ADR-013. func SubtreeRootThreshold(_ uint64) int { - return v1.SubtreeRootThreshold + return v3.SubtreeRootThreshold } // SquareSizeUpperBound imposes an upper bound on the max effective square size. func SquareSizeUpperBound(_ uint64) int { - return v1.SquareSizeUpperBound + if OverrideSquareSizeUpperBoundStr != "" { + parsedValue, err := strconv.Atoi(OverrideSquareSizeUpperBoundStr) + if err != nil { + panic("Invalid OverrideSquareSizeUpperBoundStr value") + } + return parsedValue + } + return v3.SquareSizeUpperBound +} + +func TxSizeCostPerByte(_ uint64) uint64 { + return v3.TxSizeCostPerByte +} + +func GasPerBlobByte(_ uint64) uint32 { + return v3.GasPerBlobByte +} + +func MaxTxSize(_ uint64) int { + return v3.MaxTxSize } var ( DefaultSubtreeRootThreshold = SubtreeRootThreshold(LatestVersion) DefaultSquareSizeUpperBound = SquareSizeUpperBound(LatestVersion) + DefaultTxSizeCostPerByte = TxSizeCostPerByte(LatestVersion) + DefaultGasPerBlobByte = GasPerBlobByte(LatestVersion) ) + +func GetTimeoutPropose(v uint64) time.Duration { + switch v { + case v1.Version: + return v1.TimeoutPropose + case v2.Version: + return v2.TimeoutPropose + default: + return v3.TimeoutPropose + } +} + +func GetTimeoutCommit(v uint64) time.Duration { + switch v { + case v1.Version: + return v1.TimeoutCommit + case v2.Version: + return v2.TimeoutCommit + default: + return v3.TimeoutCommit + } +} + +// UpgradeHeightDelay returns the delay in blocks after a quorum has been reached that the chain should upgrade to the new version. +func UpgradeHeightDelay(v uint64) int64 { + if OverrideUpgradeHeightDelayStr != "" { + parsedValue, err := strconv.ParseInt(OverrideUpgradeHeightDelayStr, 10, 64) + if err != nil { + panic("Invalid OverrideUpgradeHeightDelayStr value") + } + return parsedValue + } + switch v { + case v1.Version: + return v1.UpgradeHeightDelay + case v2.Version: + return v2.UpgradeHeightDelay + default: + return v3.UpgradeHeightDelay + + } +} diff --git a/pkg/appconsts/versioned_consts_test.go b/pkg/appconsts/versioned_consts_test.go index 6fb5cfc48d..f621c0199e 100644 --- a/pkg/appconsts/versioned_consts_test.go +++ b/pkg/appconsts/versioned_consts_test.go @@ -1,7 +1,6 @@ package appconsts_test import ( - "fmt" "testing" "github.com/stretchr/testify/require" @@ -9,52 +8,75 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" ) -func TestSubtreeRootThreshold(t *testing.T) { +func TestVersionedConsts(t *testing.T) { testCases := []struct { - version uint64 - expected int + name string + version uint64 + expectedConstant interface{} + got interface{} }{ { - version: v1.Version, - expected: v1.SubtreeRootThreshold, + name: "SubtreeRootThreshold v1", + version: v1.Version, + expectedConstant: v1.SubtreeRootThreshold, + got: appconsts.SubtreeRootThreshold(v1.Version), }, { - version: v2.Version, - expected: v2.SubtreeRootThreshold, + name: "SubtreeRootThreshold v2", + version: v2.Version, + expectedConstant: v2.SubtreeRootThreshold, + got: appconsts.SubtreeRootThreshold(v2.Version), + }, + { + name: "SubtreeRootThreshold v3", + version: v3.Version, + expectedConstant: v3.SubtreeRootThreshold, + got: appconsts.SubtreeRootThreshold(v3.Version), + }, + { + name: "SquareSizeUpperBound v1", + version: v1.Version, + expectedConstant: v1.SquareSizeUpperBound, + got: appconsts.SquareSizeUpperBound(v1.Version), + }, + { + name: "SquareSizeUpperBound v2", + version: v2.Version, + expectedConstant: v2.SquareSizeUpperBound, + got: appconsts.SquareSizeUpperBound(v2.Version), + }, + { + name: "SquareSizeUpperBound v3", + version: v3.Version, + expectedConstant: v3.SquareSizeUpperBound, + got: appconsts.SquareSizeUpperBound(v3.Version), + }, + { + name: "TxSizeCostPerByte v3", + version: v3.Version, + expectedConstant: v3.TxSizeCostPerByte, + got: appconsts.TxSizeCostPerByte(v3.Version), }, - } - - for _, tc := range testCases { - name := fmt.Sprintf("version %v", tc.version) - t.Run(name, func(t *testing.T) { - got := appconsts.SubtreeRootThreshold(tc.version) - require.Equal(t, tc.expected, got) - }) - } -} - -func TestSquareSizeUpperBound(t *testing.T) { - testCases := []struct { - version uint64 - expected int - }{ { - version: v1.Version, - expected: v1.SquareSizeUpperBound, + name: "GasPerBlobByte v3", + version: v3.Version, + expectedConstant: v3.GasPerBlobByte, + got: appconsts.GasPerBlobByte(v3.Version), }, { - version: v2.Version, - expected: v2.SquareSizeUpperBound, + name: "MaxTxSize v3", + version: v3.Version, + expectedConstant: v3.MaxTxSize, + got: appconsts.MaxTxSize(v3.Version), }, } for _, tc := range testCases { - name := fmt.Sprintf("version %v", tc.version) - t.Run(name, func(t *testing.T) { - got := appconsts.SquareSizeUpperBound(tc.version) - require.Equal(t, tc.expected, got) + t.Run(tc.name, func(t *testing.T) { + require.Equal(t, tc.expectedConstant, tc.got) }) } } diff --git a/pkg/da/data_availability_header_test.go b/pkg/da/data_availability_header_test.go index fa73aeaa5e..7649750d09 100644 --- a/pkg/da/data_availability_header_test.go +++ b/pkg/da/data_availability_header_test.go @@ -88,7 +88,6 @@ func TestExtendShares(t *testing.T) { } for _, tt := range tests { - tt := tt _, err := ExtendShares(tt.shares) if tt.expectedErr { require.NotNil(t, err) @@ -122,7 +121,6 @@ func TestDataAvailabilityHeaderProtoConversion(t *testing.T) { } for _, tt := range tests { - tt := tt pdah, err := tt.dah.ToProto() require.NoError(t, err) resDah, err := DataAvailabilityHeaderFromProto(pdah) @@ -203,7 +201,6 @@ func Test_DAHValidateBasic(t *testing.T) { } for _, tt := range tests { - tt := tt err := tt.dah.ValidateBasic() if tt.expectErr { require.True(t, strings.Contains(err.Error(), tt.errStr), tt.name) diff --git a/pkg/user/account.go b/pkg/user/account.go index 8ab1d031f4..9d66dc0540 100644 --- a/pkg/user/account.go +++ b/pkg/user/account.go @@ -40,6 +40,10 @@ func (a Account) PubKey() cryptotypes.PubKey { return a.pubKey } +func (a Account) AccountNumber() uint64 { + return a.accountNumber +} + // Sequence returns the sequence number of the account. // This is locally tracked func (a Account) Sequence() uint64 { diff --git a/pkg/user/pruning_test.go b/pkg/user/pruning_test.go new file mode 100644 index 0000000000..6019325b19 --- /dev/null +++ b/pkg/user/pruning_test.go @@ -0,0 +1,50 @@ +package user + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestPruningInTxTracker(t *testing.T) { + txClient := &TxClient{ + txTracker: make(map[string]txInfo), + } + numTransactions := 10 + + // Add 10 transactions to the tracker that are 10 and 5 minutes old + var txsToBePruned int + var txsNotReadyToBePruned int + for i := 0; i < numTransactions; i++ { + // 5 transactions will be pruned + if i%2 == 0 { + txClient.txTracker["tx"+fmt.Sprint(i)] = txInfo{ + signer: "signer" + fmt.Sprint(i), + sequence: uint64(i), + timestamp: time.Now(). + Add(-10 * time.Minute), + } + txsToBePruned++ + } else { + txClient.txTracker["tx"+fmt.Sprint(i)] = txInfo{ + signer: "signer" + fmt.Sprint(i), + sequence: uint64(i), + timestamp: time.Now(). + Add(-5 * time.Minute), + } + txsNotReadyToBePruned++ + } + } + + txTrackerBeforePruning := len(txClient.txTracker) + + // All transactions were indexed + require.Equal(t, numTransactions, len(txClient.txTracker)) + txClient.pruneTxTracker() + // Prunes the transactions that are 10 minutes old + // 5 transactions will be pruned + require.Equal(t, txsToBePruned, txTrackerBeforePruning-txsToBePruned) + require.Equal(t, len(txClient.txTracker), txsNotReadyToBePruned) +} diff --git a/pkg/user/tx_client.go b/pkg/user/tx_client.go index 0d14128421..ce2f7b8933 100644 --- a/pkg/user/tx_client.go +++ b/pkg/user/tx_client.go @@ -12,7 +12,6 @@ import ( "time" "github.com/celestiaorg/go-square/v2/share" - blobtx "github.com/celestiaorg/go-square/v2/tx" "github.com/cosmos/cosmos-sdk/client" nodeservice "github.com/cosmos/cosmos-sdk/client/grpc/node" "github.com/cosmos/cosmos-sdk/client/grpc/tmservice" @@ -22,23 +21,66 @@ import ( sdktx "github.com/cosmos/cosmos-sdk/types/tx" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal" abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/rpc/core" "google.golang.org/grpc" "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" - apperrors "github.com/celestiaorg/celestia-app/v3/app/errors" + "github.com/celestiaorg/celestia-app/v3/app/grpc/tx" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/celestiaorg/celestia-app/v3/x/minfee" ) const ( - DefaultPollTime = 3 * time.Second - DefaultGasMultiplier float64 = 1.1 + DefaultPollTime = 3 * time.Second + DefaultGasMultiplier float64 = 1.1 + txTrackerPruningInterval = 10 * time.Minute ) type Option func(client *TxClient) +// txInfo is a struct that holds the sequence and the signer of a transaction +// in the local tx pool. +type txInfo struct { + sequence uint64 + signer string + timestamp time.Time +} + +// TxResponse is a response from the chain after +// a transaction has been submitted. +type TxResponse struct { + // Height is the block height at which the transaction was included on-chain. + Height int64 + TxHash string + Code uint32 +} + +// BroadcastTxError is an error that occurs when broadcasting a transaction. +type BroadcastTxError struct { + TxHash string + Code uint32 + // ErrorLog is the error output of the app's logger + ErrorLog string +} + +func (e *BroadcastTxError) Error() string { + return fmt.Sprintf("broadcast tx error: %s", e.ErrorLog) +} + +// ExecutionError is an error that occurs when a transaction gets executed. +type ExecutionError struct { + TxHash string + Code uint32 + // ErrorLog is the error output of the app's logger + ErrorLog string +} + +func (e *ExecutionError) Error() string { + return fmt.Sprintf("tx execution failed with code %d: %s", e.Code, e.ErrorLog) +} + // WithGasMultiplier is a functional option allows to configure the gas multiplier. func WithGasMultiplier(multiplier float64) Option { return func(c *TxClient) { @@ -102,6 +144,9 @@ type TxClient struct { defaultGasPrice float64 defaultAccount string defaultAddress sdktypes.AccAddress + // txTracker maps the tx hash to the Sequence and signer of the transaction + // that was submitted to the chain + txTracker map[string]txInfo } // NewTxClient returns a new signer using the provided keyring @@ -134,6 +179,7 @@ func NewTxClient( defaultGasPrice: appconsts.DefaultMinGasPrice, defaultAccount: records[0].Name, defaultAddress: addr, + txTracker: make(map[string]txInfo), } for _, opt := range options { @@ -200,19 +246,21 @@ func SetupTxClient( // SubmitPayForBlob forms a transaction from the provided blobs, signs it, and submits it to the chain. // TxOptions may be provided to set the fee and gas limit. -func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blob, opts ...TxOption) (*sdktypes.TxResponse, error) { +func (client *TxClient) SubmitPayForBlob(ctx context.Context, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) { resp, err := client.BroadcastPayForBlob(ctx, blobs, opts...) if err != nil { - return resp, err + return nil, err } return client.ConfirmTx(ctx, resp.TxHash) } -func (client *TxClient) SubmitPayForBlobWithAccount(ctx context.Context, account string, blobs []*share.Blob, opts ...TxOption) (*sdktypes.TxResponse, error) { +// SubmitPayForBlobWithAccount forms a transaction from the provided blobs, signs it with the provided account, and submits it to the chain. +// TxOptions may be provided to set the fee and gas limit. +func (client *TxClient) SubmitPayForBlobWithAccount(ctx context.Context, account string, blobs []*share.Blob, opts ...TxOption) (*TxResponse, error) { resp, err := client.BroadcastPayForBlobWithAccount(ctx, account, blobs, opts...) if err != nil { - return resp, err + return nil, err } return client.ConfirmTx(ctx, resp.TxHash) @@ -253,10 +301,10 @@ func (client *TxClient) BroadcastPayForBlobWithAccount(ctx context.Context, acco // SubmitTx forms a transaction from the provided messages, signs it, and submits it to the chain. TxOptions // may be provided to set the fee and gas limit. -func (client *TxClient) SubmitTx(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (*sdktypes.TxResponse, error) { +func (client *TxClient) SubmitTx(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (*TxResponse, error) { resp, err := client.BroadcastTx(ctx, msgs, opts...) if err != nil { - return resp, err + return nil, err } return client.ConfirmTx(ctx, resp.TxHash) @@ -265,6 +313,12 @@ func (client *TxClient) SubmitTx(ctx context.Context, msgs []sdktypes.Msg, opts func (client *TxClient) BroadcastTx(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (*sdktypes.TxResponse, error) { client.mtx.Lock() defer client.mtx.Unlock() + + // prune transactions that are older than 10 minutes + // pruning has to be done in broadcast, since users + // might not always call ConfirmTx(). + client.pruneTxTracker() + account, err := client.getAccountNameFromMsgs(msgs) if err != nil { return nil, err @@ -331,18 +385,20 @@ func (client *TxClient) broadcastTx(ctx context.Context, txBytes []byte, signer return nil, err } if resp.TxResponse.Code != abci.CodeTypeOK { - if apperrors.IsNonceMismatchCode(resp.TxResponse.Code) { - // query the account to update the sequence number on-chain for the account - _, seqNum, err := QueryAccount(ctx, client.grpc, client.registry, client.signer.accounts[signer].address) - if err != nil { - return nil, fmt.Errorf("querying account for new sequence number: %w\noriginal tx response: %s", err, resp.TxResponse.RawLog) - } - if err := client.signer.SetSequence(signer, seqNum); err != nil { - return nil, fmt.Errorf("setting sequence: %w", err) - } - return client.retryBroadcastingTx(ctx, txBytes) + broadcastTxErr := &BroadcastTxError{ + TxHash: resp.TxResponse.TxHash, + Code: resp.TxResponse.Code, + ErrorLog: resp.TxResponse.RawLog, } - return resp.TxResponse, fmt.Errorf("tx failed with code %d: %s", resp.TxResponse.Code, resp.TxResponse.RawLog) + return nil, broadcastTxErr + } + + // save the sequence and signer of the transaction in the local txTracker + // before the sequence is incremented + client.txTracker[resp.TxResponse.TxHash] = txInfo{ + sequence: client.signer.accounts[signer].Sequence(), + signer: signer, + timestamp: time.Now(), } // after the transaction has been submitted, we can increment the @@ -353,97 +409,92 @@ func (client *TxClient) broadcastTx(ctx context.Context, txBytes []byte, signer return resp.TxResponse, nil } -// retryBroadcastingTx creates a new transaction by copying over an existing transaction but creates a new signature with the -// new sequence number. It then calls `broadcastTx` and attempts to submit the transaction -func (client *TxClient) retryBroadcastingTx(ctx context.Context, txBytes []byte) (*sdktypes.TxResponse, error) { - blobTx, isBlobTx, err := blobtx.UnmarshalBlobTx(txBytes) - if isBlobTx { - // only check the error if the bytes are supposed to be of type blob tx - if err != nil { - return nil, err - } - txBytes = blobTx.Tx - } - tx, err := client.signer.DecodeTx(txBytes) - if err != nil { - return nil, err - } - - opts := make([]TxOption, 0) - if granter := tx.FeeGranter(); granter != nil { - opts = append(opts, SetFeeGranter(granter)) - } - if payer := tx.FeePayer(); payer != nil { - opts = append(opts, SetFeePayer(payer)) - } - if memo := tx.GetMemo(); memo != "" { - opts = append(opts, SetMemo(memo)) - } - if fee := tx.GetFee(); fee != nil { - opts = append(opts, SetFee(fee.AmountOf(appconsts.BondDenom).Uint64())) - } - if gas := tx.GetGas(); gas > 0 { - opts = append(opts, SetGasLimit(gas)) - } - - txBuilder, err := client.signer.txBuilder(tx.GetMsgs(), opts...) - if err != nil { - return nil, err - } - signer, _, err := client.signer.signTransaction(txBuilder) - if err != nil { - return nil, fmt.Errorf("resigning transaction: %w", err) - } - - newTxBytes, err := client.signer.EncodeTx(txBuilder.GetTx()) - if err != nil { - return nil, err - } - - // rewrap the blob tx if it was originally a blob tx - if isBlobTx { - newTxBytes, err = blobtx.MarshalBlobTx(newTxBytes, blobTx.Blobs...) - if err != nil { - return nil, err +// pruneTxTracker removes transactions from the local tx tracker that are older than 10 minutes +func (client *TxClient) pruneTxTracker() { + for hash, txInfo := range client.txTracker { + if time.Since(txInfo.timestamp) >= txTrackerPruningInterval { + delete(client.txTracker, hash) } } - - return client.broadcastTx(ctx, newTxBytes, signer) } // ConfirmTx periodically pings the provided node for the commitment of a transaction by its // hash. It will continually loop until the context is cancelled, the tx is found or an error // is encountered. -func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*sdktypes.TxResponse, error) { - txClient := sdktx.NewServiceClient(client.grpc) +func (client *TxClient) ConfirmTx(ctx context.Context, txHash string) (*TxResponse, error) { + txClient := tx.NewTxClient(client.grpc) pollTicker := time.NewTicker(client.pollTime) defer pollTicker.Stop() for { - resp, err := txClient.GetTx(ctx, &sdktx.GetTxRequest{Hash: txHash}) - if err == nil { - if resp.TxResponse.Code != 0 { - return resp.TxResponse, fmt.Errorf("tx was included but failed with code %d: %s", resp.TxResponse.Code, resp.TxResponse.RawLog) - } - return resp.TxResponse, nil - } - // FIXME: this is a relatively brittle of working out whether to retry or not. The tx might be not found for other - // reasons. It may have been removed from the mempool at a later point. We should build an endpoint that gives the - // signer more information on the status of their transaction and then update the logic here - if !strings.Contains(err.Error(), "not found") { - return &sdktypes.TxResponse{}, err + resp, err := txClient.TxStatus(ctx, &tx.TxStatusRequest{TxId: txHash}) + if err != nil { + return nil, err } - // Wait for the next round. - select { - case <-ctx.Done(): - return &sdktypes.TxResponse{}, ctx.Err() - case <-pollTicker.C: + switch resp.Status { + case core.TxStatusPending: + // Continue polling if the transaction is still pending + select { + case <-ctx.Done(): + return nil, ctx.Err() + case <-pollTicker.C: + continue + } + case core.TxStatusCommitted: + txResponse := &TxResponse{ + Height: resp.Height, + TxHash: txHash, + Code: resp.ExecutionCode, + } + if resp.ExecutionCode != abci.CodeTypeOK { + executionErr := &ExecutionError{ + TxHash: txHash, + Code: resp.ExecutionCode, + ErrorLog: resp.Error, + } + client.deleteFromTxTracker(txHash) + return nil, executionErr + } + client.deleteFromTxTracker(txHash) + return txResponse, nil + case core.TxStatusEvicted: + return nil, client.handleEvictions(txHash) + default: + client.deleteFromTxTracker(txHash) + return nil, fmt.Errorf("transaction with hash %s not found; it was likely rejected", txHash) } } } +// handleEvictions handles the scenario where a transaction is evicted from the mempool. +// It removes the evicted transaction from the local tx tracker without incrementing +// the signer's sequence. +func (client *TxClient) handleEvictions(txHash string) error { + client.mtx.Lock() + defer client.mtx.Unlock() + // Get transaction from the local tx tracker + txInfo, exists := client.txTracker[txHash] + if !exists { + return fmt.Errorf("tx: %s not found in tx client txTracker; likely failed during broadcast", txHash) + } + // The sequence should be rolled back to the sequence of the transaction that was evicted to be + // ready for resubmission. All transactions with a later nonce will be kicked by the nodes tx pool. + if err := client.signer.SetSequence(txInfo.signer, txInfo.sequence); err != nil { + return fmt.Errorf("setting sequence: %w", err) + } + delete(client.txTracker, txHash) + return fmt.Errorf("tx was evicted from the mempool") +} + +// deleteFromTxTracker safely deletes a transaction from the local tx tracker. +func (client *TxClient) deleteFromTxTracker(txHash string) { + client.mtx.Lock() + defer client.mtx.Unlock() + delete(client.txTracker, txHash) +} + // EstimateGas simulates the transaction, calculating the amount of gas that was consumed during execution. The final // result will be multiplied by gasMultiplier(that is set in TxClient) func (client *TxClient) EstimateGas(ctx context.Context, msgs []sdktypes.Msg, opts ...TxOption) (uint64, error) { @@ -518,6 +569,7 @@ func (client *TxClient) checkAccountLoaded(ctx context.Context, account string) if err != nil { return fmt.Errorf("retrieving address from keyring: %w", err) } + // FIXME: have a less trusting way of getting the account number and sequence accNum, sequence, err := QueryAccount(ctx, client.grpc, client.registry, addr) if err != nil { return fmt.Errorf("querying account %s: %w", account, err) @@ -546,6 +598,14 @@ func (client *TxClient) getAccountNameFromMsgs(msgs []sdktypes.Msg) (string, err return record.Name, nil } +// GetTxFromTxTracker gets transaction info from the tx client's local tx tracker by its hash +func (client *TxClient) GetTxFromTxTracker(hash string) (sequence uint64, signer string, exists bool) { + client.mtx.Lock() + defer client.mtx.Unlock() + txInfo, exists := client.txTracker[hash] + return txInfo.sequence, txInfo.signer, exists +} + // Signer exposes the tx clients underlying signer func (client *TxClient) Signer() *Signer { return client.signer diff --git a/pkg/user/tx_client_test.go b/pkg/user/tx_client_test.go index 0c4821b2c4..6ae0c2efa2 100644 --- a/pkg/user/tx_client_test.go +++ b/pkg/user/tx_client_test.go @@ -5,19 +5,21 @@ import ( "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" - bank "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/suite" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/rand" - "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/pkg/user" "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" + + "github.com/cosmos/cosmos-sdk/x/authz" + bank "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/rand" ) func TestTxClientTestSuite(t *testing.T) { @@ -30,21 +32,15 @@ func TestTxClientTestSuite(t *testing.T) { type TxClientTestSuite struct { suite.Suite - ctx testnode.Context - encCfg encoding.Config - txClient *user.TxClient + ctx testnode.Context + encCfg encoding.Config + txClient *user.TxClient + serviceClient sdktx.ServiceClient } func (suite *TxClientTestSuite) SetupSuite() { - suite.encCfg = encoding.MakeConfig(app.ModuleEncodingRegisters...) - config := testnode.DefaultConfig(). - WithFundedAccounts("a", "b", "c"). - WithAppCreator(testnode.CustomAppCreator("0utia")) - suite.ctx, _, _ = testnode.NewNetwork(suite.T(), config) - _, err := suite.ctx.WaitForHeight(1) - suite.Require().NoError(err) - suite.txClient, err = user.SetupTxClient(suite.ctx.GoContext(), suite.ctx.Keyring, suite.ctx.GRPCClient, suite.encCfg, user.WithGasMultiplier(1.2)) - suite.Require().NoError(err) + suite.encCfg, suite.txClient, suite.ctx = setupTxClient(suite.T(), testnode.DefaultTendermintConfig().Mempool.TTLDuration) + suite.serviceClient = sdktx.NewServiceClient(suite.ctx.GRPCClient) } func (suite *TxClientTestSuite) TestSubmitPayForBlob() { @@ -57,8 +53,10 @@ func (suite *TxClientTestSuite) TestSubmitPayForBlob() { t.Run("submit blob without provided fee and gas limit", func(t *testing.T) { resp, err := suite.txClient.SubmitPayForBlob(subCtx, blobs) require.NoError(t, err) + getTxResp, err := suite.serviceClient.GetTx(subCtx, &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) require.EqualValues(t, 0, resp.Code) - require.Greater(t, resp.GasWanted, int64(0)) + require.Greater(t, getTxResp.TxResponse.GasWanted, int64(0)) }) t.Run("submit blob with provided fee and gas limit", func(t *testing.T) { @@ -66,15 +64,19 @@ func (suite *TxClientTestSuite) TestSubmitPayForBlob() { gas := user.SetGasLimit(1e6) resp, err := suite.txClient.SubmitPayForBlob(subCtx, blobs, fee, gas) require.NoError(t, err) + getTxResp, err := suite.serviceClient.GetTx(subCtx, &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) require.EqualValues(t, 0, resp.Code) - require.EqualValues(t, resp.GasWanted, 1e6) + require.EqualValues(t, getTxResp.TxResponse.GasWanted, 1e6) }) t.Run("submit blob with different account", func(t *testing.T) { resp, err := suite.txClient.SubmitPayForBlobWithAccount(subCtx, "c", blobs, user.SetFee(1e6), user.SetGasLimit(1e6)) require.NoError(t, err) + getTxResp, err := suite.serviceClient.GetTx(subCtx, &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) require.EqualValues(t, 0, resp.Code) - require.EqualValues(t, resp.GasWanted, 1e6) + require.EqualValues(t, getTxResp.TxResponse.GasWanted, 1e6) }) t.Run("try submit a blob with an account that doesn't exist", func(t *testing.T) { @@ -96,14 +98,18 @@ func (suite *TxClientTestSuite) TestSubmitTx() { resp, err := suite.txClient.SubmitTx(suite.ctx.GoContext(), []sdk.Msg{msg}) require.NoError(t, err) require.Equal(t, abci.CodeTypeOK, resp.Code) - require.Greater(t, resp.GasWanted, int64(0)) + getTxResp, err := suite.serviceClient.GetTx(suite.ctx.GoContext(), &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) + require.Greater(t, getTxResp.TxResponse.GasWanted, int64(0)) }) t.Run("submit tx with provided gas limit", func(t *testing.T) { resp, err := suite.txClient.SubmitTx(suite.ctx.GoContext(), []sdk.Msg{msg}, gasLimitOption) require.NoError(t, err) require.Equal(t, abci.CodeTypeOK, resp.Code) - require.EqualValues(t, gasLimit, resp.GasWanted) + getTxResp, err := suite.serviceClient.GetTx(suite.ctx.GoContext(), &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) + require.EqualValues(t, int64(gasLimit), getTxResp.TxResponse.GasWanted) }) t.Run("submit tx with provided fee", func(t *testing.T) { @@ -116,7 +122,9 @@ func (suite *TxClientTestSuite) TestSubmitTx() { resp, err := suite.txClient.SubmitTx(suite.ctx.GoContext(), []sdk.Msg{msg}, feeOption, gasLimitOption) require.NoError(t, err) require.Equal(t, abci.CodeTypeOK, resp.Code) - require.EqualValues(t, gasLimit, resp.GasWanted) + getTxResp, err := suite.serviceClient.GetTx(suite.ctx.GoContext(), &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) + require.EqualValues(t, int64(gasLimit), getTxResp.TxResponse.GasWanted) }) t.Run("submit tx with a different account", func(t *testing.T) { @@ -145,7 +153,14 @@ func (suite *TxClientTestSuite) TestConfirmTx() { t.Run("deadline exceeded when the context times out", func(t *testing.T) { ctx, cancel := context.WithTimeout(suite.ctx.GoContext(), time.Second) defer cancel() - _, err := suite.txClient.ConfirmTx(ctx, "E32BD15CAF57AF15D17B0D63CF4E63A9835DD1CEBB059C335C79586BC3013728") + + seqBeforeBroadcast := suite.txClient.Signer().Account(suite.txClient.DefaultAccountName()).Sequence() + msg := bank.NewMsgSend(suite.txClient.DefaultAddress(), testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10))) + resp, err := suite.txClient.BroadcastTx(ctx, []sdk.Msg{msg}) + require.NoError(t, err) + assertTxInTxTracker(t, suite.txClient, resp.TxHash, suite.txClient.DefaultAccountName(), seqBeforeBroadcast) + + _, err = suite.txClient.ConfirmTx(ctx, resp.TxHash) require.Error(t, err) require.Contains(t, err.Error(), context.DeadlineExceeded.Error()) }) @@ -153,37 +168,90 @@ func (suite *TxClientTestSuite) TestConfirmTx() { t.Run("should error when tx is not found", func(t *testing.T) { ctx, cancel := context.WithTimeout(suite.ctx.GoContext(), 5*time.Second) defer cancel() - _, err := suite.txClient.ConfirmTx(ctx, "not found tx") + resp, err := suite.txClient.ConfirmTx(ctx, "E32BD15CAF57AF15D17B0D63CF4E63A9835DD1CEBB059C335C79586BC3013728") + require.Contains(t, err.Error(), "transaction with hash E32BD15CAF57AF15D17B0D63CF4E63A9835DD1CEBB059C335C79586BC3013728 not found; it was likely rejected") + require.Nil(t, resp) + }) + + t.Run("should return error log when execution fails", func(t *testing.T) { + seqBeforeBroadcast := suite.txClient.Signer().Account(suite.txClient.DefaultAccountName()).Sequence() + innerMsg := bank.NewMsgSend(testnode.RandomAddress().(sdk.AccAddress), testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10))) + msg := authz.NewMsgExec(suite.txClient.DefaultAddress(), []sdk.Msg{innerMsg}) + resp, err := suite.txClient.BroadcastTx(suite.ctx.GoContext(), []sdk.Msg{&msg}, fee, gas) + require.NoError(t, err) + assertTxInTxTracker(t, suite.txClient, resp.TxHash, suite.txClient.DefaultAccountName(), seqBeforeBroadcast) + + confirmTxResp, err := suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash) require.Error(t, err) + require.Contains(t, err.Error(), "authorization not found") + require.Nil(t, confirmTxResp) + require.True(t, wasRemovedFromTxTracker(resp.TxHash, suite.txClient)) }) t.Run("should success when tx is found immediately", func(t *testing.T) { addr := suite.txClient.DefaultAddress() + seqBeforeBroadcast := suite.txClient.Signer().Account(suite.txClient.DefaultAccountName()).Sequence() msg := bank.NewMsgSend(addr, testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10))) resp, err := suite.txClient.BroadcastTx(suite.ctx.GoContext(), []sdk.Msg{msg}, fee, gas) require.NoError(t, err) - require.NotNil(t, resp) + require.Equal(t, resp.Code, abci.CodeTypeOK) + assertTxInTxTracker(t, suite.txClient, resp.TxHash, suite.txClient.DefaultAccountName(), seqBeforeBroadcast) + ctx, cancel := context.WithTimeout(suite.ctx.GoContext(), 30*time.Second) defer cancel() - resp, err = suite.txClient.ConfirmTx(ctx, resp.TxHash) + confirmTxResp, err := suite.txClient.ConfirmTx(ctx, resp.TxHash) require.NoError(t, err) - require.Equal(t, abci.CodeTypeOK, resp.Code) + require.Equal(t, abci.CodeTypeOK, confirmTxResp.Code) + require.True(t, wasRemovedFromTxTracker(resp.TxHash, suite.txClient)) }) t.Run("should error when tx is found with a non-zero error code", func(t *testing.T) { balance := suite.queryCurrentBalance(t) addr := suite.txClient.DefaultAddress() + seqBeforeBroadcast := suite.txClient.Signer().Account(suite.txClient.DefaultAccountName()).Sequence() // Create a msg send with out of balance, ensure this tx fails msg := bank.NewMsgSend(addr, testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 1+balance))) resp, err := suite.txClient.BroadcastTx(suite.ctx.GoContext(), []sdk.Msg{msg}, fee, gas) require.NoError(t, err) - require.NotNil(t, resp) - resp, err = suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash) + require.Equal(t, resp.Code, abci.CodeTypeOK) + assertTxInTxTracker(t, suite.txClient, resp.TxHash, suite.txClient.DefaultAccountName(), seqBeforeBroadcast) + + confirmTxResp, err := suite.txClient.ConfirmTx(suite.ctx.GoContext(), resp.TxHash) require.Error(t, err) - require.NotEqual(t, abci.CodeTypeOK, resp.Code) + require.Nil(t, confirmTxResp) + code := err.(*user.ExecutionError).Code + require.NotEqual(t, abci.CodeTypeOK, code) + require.True(t, wasRemovedFromTxTracker(resp.TxHash, suite.txClient)) }) } +func TestEvictions(t *testing.T) { + _, txClient, ctx := setupTxClient(t, 1*time.Nanosecond) + + fee := user.SetFee(1e6) + gas := user.SetGasLimit(1e6) + + // Keep submitting the transaction until we get the eviction error + sender := txClient.Signer().Account(txClient.DefaultAccountName()) + msg := bank.NewMsgSend(sender.Address(), testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10))) + var seqBeforeEviction uint64 + // Loop five times until the tx is evicted + for i := 0; i < 5; i++ { + seqBeforeEviction = sender.Sequence() + resp, err := txClient.BroadcastTx(ctx.GoContext(), []sdk.Msg{msg}, fee, gas) + require.NoError(t, err) + _, err = txClient.ConfirmTx(ctx.GoContext(), resp.TxHash) + if err != nil { + if err.Error() == "tx was evicted from the mempool" { + break + } + } + } + + seqAfterEviction := sender.Sequence() + require.Equal(t, seqBeforeEviction, seqAfterEviction) +} + func (suite *TxClientTestSuite) TestGasEstimation() { addr := suite.txClient.DefaultAddress() msg := bank.NewMsgSend(addr, testnode.RandomAddress().(sdk.AccAddress), sdk.NewCoins(sdk.NewInt64Coin(app.BondDenom, 10))) @@ -221,8 +289,11 @@ func (suite *TxClientTestSuite) TestGasConsumption() { amountDeducted := balanceBefore - balanceAfter - utiaToSend require.Equal(t, int64(fee), amountDeducted) + res, err := suite.serviceClient.GetTx(suite.ctx.GoContext(), &sdktx.GetTxRequest{Hash: resp.TxHash}) + require.NoError(t, err) + // verify that the amount deducted does not depend on the actual gas used. - gasUsedBasedDeduction := resp.GasUsed * gasPrice + gasUsedBasedDeduction := res.TxResponse.GasUsed * gasPrice require.NotEqual(t, gasUsedBasedDeduction, amountDeducted) // The gas used based deduction should be less than the fee because the fee is 1 TIA. require.Less(t, gasUsedBasedDeduction, int64(fee)) @@ -246,3 +317,36 @@ func (suite *TxClientTestSuite) queryCurrentBalance(t *testing.T) int64 { require.NoError(t, err) return balanceResp.Balances.AmountOf(app.BondDenom).Int64() } + +func wasRemovedFromTxTracker(txHash string, txClient *user.TxClient) bool { + seq, signer, exists := txClient.GetTxFromTxTracker(txHash) + return !exists && seq == 0 && signer == "" +} + +// asserts that a tx was indexed in the tx tracker and that the sequence does not increase +func assertTxInTxTracker(t *testing.T, txClient *user.TxClient, txHash string, expectedSigner string, seqBeforeBroadcast uint64) { + seqFromTxTracker, signer, exists := txClient.GetTxFromTxTracker(txHash) + require.True(t, exists) + require.Equal(t, expectedSigner, signer) + seqAfterBroadcast := txClient.Signer().Account(expectedSigner).Sequence() + // TxInfo is indexed before the nonce is increased + require.Equal(t, seqBeforeBroadcast, seqFromTxTracker) + // Successfully broadcast transaction increases the sequence + require.Equal(t, seqAfterBroadcast, seqBeforeBroadcast+1) +} + +func setupTxClient(t *testing.T, ttlDuration time.Duration) (encoding.Config, *user.TxClient, testnode.Context) { + encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) + defaultTmConfig := testnode.DefaultTendermintConfig() + defaultTmConfig.Mempool.TTLDuration = ttlDuration + testnodeConfig := testnode.DefaultConfig(). + WithTendermintConfig(defaultTmConfig). + WithFundedAccounts("a", "b", "c"). + WithAppCreator(testnode.CustomAppCreator("0utia")) + ctx, _, _ := testnode.NewNetwork(t, testnodeConfig) + _, err := ctx.WaitForHeight(1) + require.NoError(t, err) + txClient, err := user.SetupTxClient(ctx.GoContext(), ctx.Keyring, ctx.GRPCClient, encCfg, user.WithGasMultiplier(1.2)) + require.NoError(t, err) + return encCfg, txClient, ctx +} diff --git a/pkg/wrapper/README.md b/pkg/wrapper/README.md index e58188bd7a..cacbd55dda 100644 --- a/pkg/wrapper/README.md +++ b/pkg/wrapper/README.md @@ -76,9 +76,9 @@ One namespace ID is located in the first `NamespaceIDSize` bytes, while the othe ## References - Namespaced Merkle tree specifications: -- Celestia original data square specification: -- Celestia constants: -- Celestia reserved namespace IDs: +- Celestia original data square specification: +- Celestia constants: +- Celestia reserved namespace IDs: [nmtlink]: https://github.com/celestiaorg/nmt/blob/master/docs/spec/nmt.md [nmtwrapper-link]: https://github.com/celestiaorg/celestia-app/blob/main/pkg/wrapper/nmt_wrapper.go diff --git a/proto/celestia/core/v1/tx/tx.proto b/proto/celestia/core/v1/tx/tx.proto index f4a8301606..0da698ad84 100644 --- a/proto/celestia/core/v1/tx/tx.proto +++ b/proto/celestia/core/v1/tx/tx.proto @@ -33,6 +33,8 @@ message TxStatusResponse { // and returns whether it was successful or errored. A non zero // execution code indicated an error. uint32 execution_code = 3; + // error log for failed transactions. + string error = 4; // status is the status of the transaction. - string status = 4; + string status = 5; } \ No newline at end of file diff --git a/scripts/arabica-block-sync.sh b/scripts/arabica-block-sync.sh new file mode 100755 index 0000000000..1b911ccdfb --- /dev/null +++ b/scripts/arabica-block-sync.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# This script starts a consensus node on Arabica and block syncs from genesis to +# the tip of the chain. + +# Stop script execution if an error is encountered +set -o errexit +# Stop script execution if an undefined variable is used +set -o nounset + +CHAIN_ID="arabica-11" +NODE_NAME="node-name" +SEEDS="827583022cc6ce65cf762115642258f937c954cd@validator-1.celestia-arabica-11.com:26656,74e42b39f512f844492ff09e30af23d54579b7bc@validator-2.celestia-arabica-11.com:26656,00d577159b2eb1f524ef9c37cb389c020a2c38d2@validator-3.celestia-arabica-11.com:26656,b2871b6dc2e18916d07264af0e87c456c2bba04f@validator-4.celestia-arabica-11.com:26656" + +CELESTIA_APP_HOME="${HOME}/.celestia-app" +CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) + +echo "celestia-app home: ${CELESTIA_APP_HOME}" +echo "celestia-app version: ${CELESTIA_APP_VERSION}" +echo "" + +# Ask the user for confirmation before deleting the existing celestia-app home +# directory. +read -p "Are you sure you want to delete: $CELESTIA_APP_HOME? [y/n] " response + +# Check the user's response +if [ "$response" != "y" ]; then + # Exit if the user did not respond with "y" + echo "You must delete $CELESTIA_APP_HOME to continue." + exit 1 +fi + +echo "Deleting $CELESTIA_APP_HOME..." +rm -r "$CELESTIA_APP_HOME" + +echo "Initializing config files..." +celestia-appd init ${NODE_NAME} --chain-id ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Settings seeds in config.toml..." +sed -i.bak -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $CELESTIA_APP_HOME/config/config.toml + +echo "Downloading genesis file..." +celestia-appd download-genesis ${CHAIN_ID} + +echo "Starting celestia-appd..." +celestia-appd start --v2-upgrade-height 1751707 --force-no-bbr diff --git a/scripts/arabica.sh b/scripts/arabica.sh new file mode 100755 index 0000000000..d09b9d8441 --- /dev/null +++ b/scripts/arabica.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# This script starts a consensus node on Arabica and state syncs to the tip of +# the chain. + +# Stop script execution if an error is encountered +set -o errexit +# Stop script execution if an undefined variable is used +set -o nounset + +CHAIN_ID="arabica-11" +NODE_NAME="node-name" +SEEDS="827583022cc6ce65cf762115642258f937c954cd@validator-1.celestia-arabica-11.com:26656,74e42b39f512f844492ff09e30af23d54579b7bc@validator-2.celestia-arabica-11.com:26656,00d577159b2eb1f524ef9c37cb389c020a2c38d2@validator-3.celestia-arabica-11.com:26656,b2871b6dc2e18916d07264af0e87c456c2bba04f@validator-4.celestia-arabica-11.com:26656" +RPC="https://rpc.celestia-arabica-11.com:443" + +CELESTIA_APP_HOME="${HOME}/.celestia-app" +CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) + +echo "celestia-app home: ${CELESTIA_APP_HOME}" +echo "celestia-app version: ${CELESTIA_APP_VERSION}" +echo "" + +# Ask the user for confirmation before deleting the existing celestia-app home +# directory. +read -p "Are you sure you want to delete: $CELESTIA_APP_HOME? [y/n] " response + +# Check the user's response +if [ "$response" != "y" ]; then + # Exit if the user did not respond with "y" + echo "You must delete $CELESTIA_APP_HOME to continue." + exit 1 +fi + +echo "Deleting $CELESTIA_APP_HOME..." +rm -r "$CELESTIA_APP_HOME" + +echo "Initializing config files..." +celestia-appd init ${NODE_NAME} --chain-id ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Settings seeds in config.toml..." +sed -i.bak -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $CELESTIA_APP_HOME/config/config.toml + +LATEST_HEIGHT=$(curl -s $RPC/block | jq -r .result.block.header.height); +BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \ +TRUST_HASH=$(curl -s "$RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) + +echo "Latest height: $LATEST_HEIGHT" +echo "Block height: $BLOCK_HEIGHT" +echo "Trust hash: $TRUST_HASH" +echo "Enabling state sync in config.toml..." +sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \ +s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$RPC,$RPC\"| ; \ +s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \ +s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.celestia-app/config/config.toml + +echo "Downloading genesis file..." +celestia-appd download-genesis ${CHAIN_ID} + +echo "Starting celestia-appd..." +celestia-appd start --v2-upgrade-height 1751707 --force-no-bbr diff --git a/scripts/mainnet.sh b/scripts/mainnet.sh index 317fe5dbdc..aa92e13326 100755 --- a/scripts/mainnet.sh +++ b/scripts/mainnet.sh @@ -1,5 +1,8 @@ #!/bin/sh +# This script starts a consensus node on Mainnet Beta and state syncs to the tip +# of the chain. + # Stop script execution if an error is encountered set -o errexit # Stop script execution if an undefined variable is used @@ -10,6 +13,7 @@ NODE_NAME="node-name" SEEDS="e6116822e1a5e283d8a85d3ec38f4d232274eaf3@consensus-full-seed-1.celestia-bootstrap.net:26656,cf7ac8b19ff56a9d47c75551bd4864883d1e24b5@consensus-full-seed-2.celestia-bootstrap.net:26656" CELESTIA_APP_HOME="${HOME}/.celestia-app" CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) +RPC="https://celestia-rpc.polkachu.com:443" echo "celestia-app home: ${CELESTIA_APP_HOME}" echo "celestia-app version: ${CELESTIA_APP_VERSION}" @@ -35,10 +39,20 @@ celestia-appd init ${NODE_NAME} --chain-id ${CHAIN_ID} > /dev/null 2>&1 # Hide o echo "Settings seeds in config.toml..." sed -i.bak -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $CELESTIA_APP_HOME/config/config.toml +LATEST_HEIGHT=$(curl -s $RPC/block | jq -r .result.block.header.height); +BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \ +TRUST_HASH=$(curl -s "$RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) + +echo "Block height: $BLOCK_HEIGHT" +echo "Trust hash: $TRUST_HASH" +echo "Enabling state sync in config.toml..." +sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \ +s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$RPC,$RPC\"| ; \ +s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \ +s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.celestia-app/config/config.toml + echo "Downloading genesis file..." celestia-appd download-genesis ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise -echo "Starting celestia-appd in the background and piping logs to mainnet.log" -nohup celestia-appd start > "${HOME}/mainnet.log" 2>&1 & - -echo "You can check the node's status via: celestia-appd status" +echo "Starting celestia-appd..." +celestia-appd start --v2-upgrade-height 2371495 diff --git a/scripts/mocha-block-sync.sh b/scripts/mocha-block-sync.sh new file mode 100755 index 0000000000..3f8795dd6e --- /dev/null +++ b/scripts/mocha-block-sync.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# This script starts a consensus node on Mocha and block syncs from genesis to +# the tip of the chain. This is expected to take a few weeks. + +# Stop script execution if an error is encountered +set -o errexit +# Stop script execution if an undefined variable is used +set -o nounset + +CHAIN_ID="mocha-4" +NODE_NAME="node-name" +SEEDS="ee9f90974f85c59d3861fc7f7edb10894f6ac3c8@seed-mocha.pops.one:26656,258f523c96efde50d5fe0a9faeea8a3e83be22ca@seed.mocha-4.celestia.aviaone.com:20279,5d0bf034d6e6a8b5ee31a2f42f753f1107b3a00e@celestia-testnet-seed.itrocket.net:11656,7da0fb48d6ef0823bc9770c0c8068dd7c89ed4ee@celest-test-seed.theamsolutions.info:443" + +CELESTIA_APP_HOME="${HOME}/.celestia-app" +CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) + +echo "celestia-app home: ${CELESTIA_APP_HOME}" +echo "celestia-app version: ${CELESTIA_APP_VERSION}" +echo "" + +# Ask the user for confirmation before deleting the existing celestia-app home +# directory. +read -p "Are you sure you want to delete: $CELESTIA_APP_HOME? [y/n] " response + +# Check the user's response +if [ "$response" != "y" ]; then + # Exit if the user did not respond with "y" + echo "You must delete $CELESTIA_APP_HOME to continue." + exit 1 +fi + +echo "Deleting $CELESTIA_APP_HOME..." +rm -r "$CELESTIA_APP_HOME" + +echo "Initializing config files..." +celestia-appd init ${NODE_NAME} --chain-id ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Settings seeds in config.toml..." +sed -i.bak -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $CELESTIA_APP_HOME/config/config.toml + +echo "Downloading genesis file..." +celestia-appd download-genesis ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Starting celestia-appd..." +celestia-appd start --v2-upgrade-height 2585031 --force-no-bbr diff --git a/scripts/mocha.sh b/scripts/mocha.sh new file mode 100755 index 0000000000..56c0e89480 --- /dev/null +++ b/scripts/mocha.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# This script starts a consensus node on Mocha and state syncs to the tip of the +# chain. + +# Stop script execution if an error is encountered +set -o errexit +# Stop script execution if an undefined variable is used +set -o nounset + +CHAIN_ID="mocha-4" +NODE_NAME="node-name" +SEEDS="ee9f90974f85c59d3861fc7f7edb10894f6ac3c8@seed-mocha.pops.one:26656,258f523c96efde50d5fe0a9faeea8a3e83be22ca@seed.mocha-4.celestia.aviaone.com:20279,5d0bf034d6e6a8b5ee31a2f42f753f1107b3a00e@celestia-testnet-seed.itrocket.net:11656,7da0fb48d6ef0823bc9770c0c8068dd7c89ed4ee@celest-test-seed.theamsolutions.info:443" +RPC="https://celestia-testnet-rpc.itrocket.net:443" + +CELESTIA_APP_HOME="${HOME}/.celestia-app" +CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) + +echo "celestia-app home: ${CELESTIA_APP_HOME}" +echo "celestia-app version: ${CELESTIA_APP_VERSION}" +echo "" + +# Ask the user for confirmation before deleting the existing celestia-app home +# directory. +read -p "Are you sure you want to delete: $CELESTIA_APP_HOME? [y/n] " response + +# Check the user's response +if [ "$response" != "y" ]; then + # Exit if the user did not respond with "y" + echo "You must delete $CELESTIA_APP_HOME to continue." + exit 1 +fi + +echo "Deleting $CELESTIA_APP_HOME..." +rm -r "$CELESTIA_APP_HOME" + +echo "Initializing config files..." +celestia-appd init ${NODE_NAME} --chain-id ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Settings seeds in config.toml..." +sed -i.bak -e "s/^seeds *=.*/seeds = \"$SEEDS\"/" $CELESTIA_APP_HOME/config/config.toml + +LATEST_HEIGHT=$(curl -s $RPC/block | jq -r .result.block.header.height); +BLOCK_HEIGHT=$((LATEST_HEIGHT - 2000)); \ +TRUST_HASH=$(curl -s "$RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) + +echo "Latest height: $LATEST_HEIGHT" +echo "Block height: $BLOCK_HEIGHT" +echo "Trust hash: $TRUST_HASH" +echo "Enabling state sync in config.toml..." +sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \ +s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$RPC,$RPC\"| ; \ +s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \ +s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $HOME/.celestia-app/config/config.toml + +echo "Downloading genesis file..." +celestia-appd download-genesis ${CHAIN_ID} > /dev/null 2>&1 # Hide output to reduce terminal noise + +echo "Starting celestia-appd..." +celestia-appd start --v2-upgrade-height 2585031 --force-no-bbr diff --git a/scripts/single-node.sh b/scripts/single-node.sh index 982f3430f1..b6a6e6486a 100755 --- a/scripts/single-node.sh +++ b/scripts/single-node.sh @@ -1,5 +1,7 @@ #!/bin/sh +# This script starts a single node testnet. + # Stop script execution if an error is encountered set -o errexit # Stop script execution if an undefined variable is used @@ -60,7 +62,7 @@ createGenesis() { # If you encounter: `sed: -I or -i may not be used with stdin` on MacOS you can mitigate by installing gnu-sed # https://gist.github.com/andre3k1/e3a1a7133fded5de5a9ee99c87c6fa0d?permalink_comment_id=3082272#gistcomment-3082272 - # Override the default RPC servier listening address + # Override the default RPC server listening address sed -i'.bak' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' "${CELESTIA_APP_HOME}"/config/config.toml # Enable transaction indexing @@ -102,7 +104,8 @@ startCelestiaApp() { --api.enable \ --grpc.enable \ --grpc-web.enable \ - --v2-upgrade-height 3 + --v2-upgrade-height 3 \ + --force-no-bbr // no need to require BBR usage on a local node } if [ -f $GENESIS_FILE ]; then diff --git a/scripts/state-sync.sh b/scripts/state-sync.sh new file mode 100755 index 0000000000..9d7a8417b0 --- /dev/null +++ b/scripts/state-sync.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +# This script starts a single node and attempts to state sync with a node +# started via ./single-node.sh + +# Stop script execution if an error is encountered +set -o errexit +# Stop script execution if an undefined variable is used +set -o nounset + +if ! [ -x "$(command -v celestia-appd)" ] +then + echo "celestia-appd could not be found. Please install the celestia-appd binary using 'make install' and make sure the PATH contains the directory where the binary exists. By default, go will install the binary under '~/go/bin'" + exit 1 +fi + +CHAIN_ID="test" +KEY_NAME="validator" +KEYRING_BACKEND="test" +COINS="1000000000000000utia" +DELEGATION_AMOUNT="5000000000utia" +SINGLE_NODE_HOME="${HOME}/.celestia-app" +CELESTIA_APP_HOME="${HOME}/.celestia-app-state-sync" +CELESTIA_APP_VERSION=$(celestia-appd version 2>&1) +GENESIS_FILE="${CELESTIA_APP_HOME}/config/genesis.json" +FEES="500utia" +RPC="0.0.0.0:26657" + +echo "celestia-app home: ${CELESTIA_APP_HOME}" +echo "celestia-app version: ${CELESTIA_APP_VERSION}" +echo "" + +BLOCK_HEIGHT=$(curl -s $RPC/block | jq -r .result.block.header.height); +TRUST_HASH=$(curl -s "$RPC/block?height=$BLOCK_HEIGHT" | jq -r .result.block_id.hash) + +echo "Block height: $BLOCK_HEIGHT" +echo "Trust hash: $TRUST_HASH" +echo "Enabling state sync in config.toml..." +sed -i.bak -E "s|^(enable[[:space:]]+=[[:space:]]+).*$|\1true| ; \ +s|^(rpc_servers[[:space:]]+=[[:space:]]+).*$|\1\"$RPC,$RPC\"| ; \ +s|^(trust_height[[:space:]]+=[[:space:]]+).*$|\1$BLOCK_HEIGHT| ; \ +s|^(trust_hash[[:space:]]+=[[:space:]]+).*$|\1\"$TRUST_HASH\"|" $CELESTIA_APP_HOME/config/config.toml + +PEER=$(curl -s http://${RPC}/status | jq -r '.result.node_info.id + "@127.0.0.1:26656"') +echo "Setting persistent peer to ${PEER}" + +createGenesis() { + echo "Initializing validator and node config files..." + celestia-appd init ${CHAIN_ID} \ + --chain-id ${CHAIN_ID} \ + --home "${CELESTIA_APP_HOME}" \ + > /dev/null 2>&1 # Hide output to reduce terminal noise + + echo "Adding a new key to the keyring..." + celestia-appd keys add ${KEY_NAME} \ + --keyring-backend=${KEYRING_BACKEND} \ + --home "${CELESTIA_APP_HOME}" \ + > /dev/null 2>&1 # Hide output to reduce terminal noise + + echo "Copying genesis.json from the node started via ./single-node.sh..." + cp ${SINGLE_NODE_HOME}/config/genesis.json ${CELESTIA_APP_HOME}/config/genesis.json + + # If you encounter: `sed: -I or -i may not be used with stdin` on MacOS you can mitigate by installing gnu-sed + # https://gist.github.com/andre3k1/e3a1a7133fded5de5a9ee99c87c6fa0d?permalink_comment_id=3082272#gistcomment-3082272 + + # Override the default RPC server listening address to not conflict with the node started via ./single-node.sh + sed -i'.bak' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26000"#g' "${CELESTIA_APP_HOME}"/config/config.toml + + # Override the p2p address to not conflict with the node started via ./single-node.sh + sed -i'.bak' 's#laddr = "tcp://0.0.0.0:26656"#laddr = "tcp://0.0.0.0:36656"#g' "${CELESTIA_APP_HOME}"/config/config.toml + + # Enable transaction indexing + sed -i'.bak' 's#"null"#"kv"#g' "${CELESTIA_APP_HOME}"/config/config.toml + + # Persist ABCI responses + sed -i'.bak' 's#discard_abci_responses = true#discard_abci_responses = false#g' "${CELESTIA_APP_HOME}"/config/config.toml + + # Override the log level to debug + # sed -i'.bak' 's#log_level = "info"#log_level = "debug"#g' "${CELESTIA_APP_HOME}"/config/config.toml +} + +deleteCelestiaAppHome() { + echo "Deleting $CELESTIA_APP_HOME..." + rm -r "$CELESTIA_APP_HOME" +} + +startCelestiaApp() { + echo "Starting celestia-app..." + celestia-appd start \ + --home "${CELESTIA_APP_HOME}" \ + --grpc.enable \ + --grpc.address="0.0.0.0:9999" \ + --p2p.persistent_peers=${PEER} \ + --fast_sync false \ + --v2-upgrade-height 3 +} + +if [ -f $GENESIS_FILE ]; then + echo "Do you want to delete existing ${CELESTIA_APP_HOME}? [y/n]" + read -r response + if [ "$response" = "y" ]; then + deleteCelestiaAppHome + createGenesis + fi +else + createGenesis +fi +startCelestiaApp diff --git a/specs/src/SUMMARY.md b/specs/src/SUMMARY.md index 9f27074a92..e6c4633574 100644 --- a/specs/src/SUMMARY.md +++ b/specs/src/SUMMARY.md @@ -2,26 +2,27 @@ Celestia App Specifications -- [Specification](./specs/index.md) - - [Data Structures](./specs/data_structures.md) - - [Namespace](./specs/namespace.md) - - [Shares](./specs/shares.md) - - [Consensus](./specs/consensus.md) - - [CAT Pool](./specs/cat_pool.md) - - [Block Proposer](./specs/block_proposer.md) - - [Block Validity Rules](./specs/block_validity_rules.md) - - [AnteHandler](./specs/ante_handler.md) - - [AnteHandler v1](./specs/ante_handler_v1.md) - - [AnteHandler v2](./specs/ante_handler_v2.md) - - [Fraud Proofs](./specs/fraud_proofs.md) - - [Networking](./specs/networking.md) - - [Public-Key Cryptography](./specs/public_key_cryptography.md) - - [Data Square Layout](./specs/data_square_layout.md) - - [Resource Pricing](./specs/resource_pricing.md) - - [Multisig](./specs/multisig.md) -- [State Machine Modules](./specs/state_machine_modules.md) - - [State Machine Modules v1](./specs/state_machine_modules_v1.md) - - [State Machine Modules v2](./specs/state_machine_modules_v2.md) -- [Parameters](./specs/parameters.md) - - [Parameters v1](./specs/parameters_v1.md) - - [Parameters v2](./specs/parameters_v2.md) +- [Data Structures](./data_structures.md) +- [Namespace](./namespace.md) +- [Shares](./shares.md) +- [Consensus](./consensus.md) + - [CAT Pool](./cat_pool.md) +- [Block Proposer](./block_proposer.md) +- [Block Validity Rules](./block_validity_rules.md) +- [AnteHandler](./ante_handler.md) + - [AnteHandler v1](./ante_handler_v1.md) + - [AnteHandler v2](./ante_handler_v2.md) + - [AnteHandler v3](./ante_handler_v3.md) +- [Fraud Proofs](./fraud_proofs.md) +- [Networking](./networking.md) +- [Public-Key Cryptography](./public_key_cryptography.md) +- [Data Square Layout](./data_square_layout.md) +- [Resource Pricing](./resource_pricing.md) +- [Multisig](./multisig.md) +- [State Machine Modules](./state_machine_modules.md) + - [State Machine Modules v1](./state_machine_modules_v1.md) + - [State Machine Modules v2](./state_machine_modules_v2.md) +- [Parameters](./parameters.md) + - [Parameters v1](./parameters_v1.md) + - [Parameters v2](./parameters_v2.md) + - [Parameters v3](./parameters_v3.md) diff --git a/specs/src/specs/ante_handler.md b/specs/src/ante_handler.md similarity index 95% rename from specs/src/specs/ante_handler.md rename to specs/src/ante_handler.md index 2ebe759a79..d002c1e7eb 100644 --- a/specs/src/specs/ante_handler.md +++ b/specs/src/ante_handler.md @@ -11,3 +11,4 @@ The AnteHandler is defined in `app/ante/ante.go`. The app version impacts AnteHa - [AnteHandler v1](./ante_handler_v1.md) - [AnteHandler v2](./ante_handler_v2.md) +- [AnteHandler v3](./ante_handler_v3.md) diff --git a/specs/src/specs/ante_handler_v1.md b/specs/src/ante_handler_v1.md similarity index 100% rename from specs/src/specs/ante_handler_v1.md rename to specs/src/ante_handler_v1.md diff --git a/specs/src/specs/ante_handler_v2.md b/specs/src/ante_handler_v2.md similarity index 100% rename from specs/src/specs/ante_handler_v2.md rename to specs/src/ante_handler_v2.md diff --git a/specs/src/ante_handler_v3.md b/specs/src/ante_handler_v3.md new file mode 100644 index 0000000000..cff67cd117 --- /dev/null +++ b/specs/src/ante_handler_v3.md @@ -0,0 +1,26 @@ +# AnteHandler v3 + +The AnteHandler chains together several decorators to ensure the following criteria are met for app version 3: + +- The tx does not contain any messages that are unsupported by the current app version. See `MsgVersioningGateKeeper`. +- The tx size is not larger than the application's configured versioned constant [MaxTxSize](https://github.com/celestiaorg/celestia-app/blob/8ba82c1b872b7f5686d9bb91b93a0442223d7bb2/pkg/appconsts/v3/app_consts.go#L9). +- The tx does not contain any [extension options](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L119-L122). +- The tx passes `ValidateBasic()`. +- The tx's [timeout_height](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L115-L117) has not been reached if one is specified. +- The tx's [memo](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L110-L113) is <= the max memo characters where [`MaxMemoCharacters = 256`](). +- The tx's [gas_limit](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L211-L213) is > the gas consumed based on the tx's size where [`TxSizeCostPerByte = 10`](https://github.com/celestiaorg/celestia-app/blob/32fc6903478ea08eba728ac9cd4ffedf9ef72d98/pkg/appconsts/v3/app_consts.go#L8). +- The tx's feepayer has enough funds to pay fees for the tx. The tx's feepayer is the feegranter (if specified) or the tx's first signer. Note the [feegrant](https://github.com/cosmos/cosmos-sdk/blob/v0.46.15/x/feegrant/README.md) module is enabled. +- The tx's gas price is >= the network minimum gas price where [`NetworkMinGasPrice = 0.000001` utia](https://github.com/celestiaorg/celestia-app/blob/32fc6903478ea08eba728ac9cd4ffedf9ef72d98/pkg/appconsts/initial_consts.go#L33). +- The tx's count of signatures <= the max number of signatures. The max number of signatures is [`TxSigLimit = 7`](https://github.com/cosmos/cosmos-sdk/blob/a429238fc267da88a8548bfebe0ba7fb28b82a13/x/auth/README.md?plain=1#L231). +- The tx's [gas_limit](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L211-L213) is > the gas consumed based on the tx's signatures. +- The tx's [signatures](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/types/tx/signing/signature.go#L10-L26) are valid. For each signature, ensure that the signature's sequence number (a.k.a nonce) matches the account sequence number of the signer. +- The tx's [gas_limit](https://github.com/cosmos/cosmos-sdk/blob/22c28366466e64ebf0df1ce5bec8b1130523552c/proto/cosmos/tx/v1beta1/tx.proto#L211-L213) is > the gas consumed based on the blob size(s). Since blobs are charged based on the number of shares they occupy, the gas consumed is calculated as follows: `gasToConsume = sharesNeeded(blob) * bytesPerShare * gasPerBlobByte`. Where `bytesPerShare` is a global constant (an alias for [`ShareSize = 512`](https://github.com/celestiaorg/celestia-app/blob/c90e61d5a2d0c0bd0e123df4ab416f6f0d141b7f/pkg/appconsts/global_consts.go#L27-L28)) and `gasPerBlobByte` is a versioned constant that can be modified through hard forks (the [`DefaultGasPerBlobByte = 8`](https://github.com/celestiaorg/celestia-app/blob/32fc6903478ea08eba728ac9cd4ffedf9ef72d98/pkg/appconsts/v3/app_consts.go#L8)). +- The tx's total blob share count is <= the max blob share count. The max blob share count is derived from the maximum valid square size. The max valid square size is the minimum of: `GovMaxSquareSize` and `SquareSizeUpperBound`. +- The tx does not contain a message of type [MsgSubmitProposal](https://github.com/cosmos/cosmos-sdk/blob/d6d929843bbd331b885467475bcb3050788e30ca/proto/cosmos/gov/v1/tx.proto#L33-L43) with zero proposal messages. +- The tx is not an IBC packet or update message that has already been processed. + +In addition to the above criteria, the AnteHandler also has a number of side-effects: + +- Tx fees are deducted from the tx's feepayer and added to the fee collector module account. +- Tx priority is calculated based on the smallest denomination of gas price in the tx and set in context. +- The nonce of all tx signers is incremented by 1. diff --git a/specs/src/specs/block_proposer.md b/specs/src/block_proposer.md similarity index 79% rename from specs/src/specs/block_proposer.md rename to specs/src/block_proposer.md index e53acec673..213449bbd9 100644 --- a/specs/src/specs/block_proposer.md +++ b/specs/src/block_proposer.md @@ -18,7 +18,7 @@ With these restrictions in mind, the block proposer performs the following actio 1. Collect as many transactions and blobs from the mempool as possible, such that the total number of shares is at most [`AVAILABLE_DATA_ORIGINAL_SQUARE_MAX`](./consensus.md#constants). 1. Compute the smallest square size that is a power of 2 that can fit the number of shares. 1. Attempt to lay out the collected transactions and blobs in the current square. - 1. If the square is too small to fit all transactions and blobs (which may happen [due to needing to insert padding between blobs](../specs/data_square_layout.md)) and the square size is smaller than [`AVAILABLE_DATA_ORIGINAL_SQUARE_MAX`](./consensus.md#constants), double the size of the square and repeat the above step. - 1. If the square is too small to fit all transactions and blobs (which may happen [due to needing to insert padding between blobs](../specs/data_square_layout.md)) and the square size is at [`AVAILABLE_DATA_ORIGINAL_SQUARE_MAX`](./consensus.md#constants), drop the transactions and blobs until the data fits within the square. + 1. If the square is too small to fit all transactions and blobs (which may happen [due to needing to insert padding between blobs](./data_square_layout.md)) and the square size is smaller than [`AVAILABLE_DATA_ORIGINAL_SQUARE_MAX`](./consensus.md#constants), double the size of the square and repeat the above step. + 1. If the square is too small to fit all transactions and blobs (which may happen [due to needing to insert padding between blobs](./data_square_layout.md)) and the square size is at [`AVAILABLE_DATA_ORIGINAL_SQUARE_MAX`](./consensus.md#constants), drop the transactions and blobs until the data fits within the square. Note: the maximum padding shares between blobs should be at most twice the number of blob shares. Doubling the square size (i.e. quadrupling the number of shares in the square) should thus only have to happen at most once. diff --git a/specs/src/specs/block_validity_rules.md b/specs/src/block_validity_rules.md similarity index 93% rename from specs/src/specs/block_validity_rules.md rename to specs/src/block_validity_rules.md index 858d4a8708..b7ae2f2df4 100644 --- a/specs/src/specs/block_validity_rules.md +++ b/specs/src/block_validity_rules.md @@ -49,18 +49,18 @@ There is no validity rule that transactions must be decodable so the following r 1. Decodable transactions must pass all [AnteHandler](./ante_handler.md) checks. 1. Decodable non-`BlobTx` transactions must not contain a `MsgPayForBlobs` message. -1. Decodable `BlobTx` transactions must be valid according to the [BlobTx validity rules](../../../x/blob/README.md#validity-rules). +1. Decodable `BlobTx` transactions must be valid according to the [BlobTx validity rules](../../x/blob/README.md#validity-rules). #### App Version 2 1. All transactions must be decodable. 1. All transactions must pass all [AnteHandler](./ante_handler.md) checks. 1. Non-`BlobTx` transactions must not contain a `MsgPayForBlobs` message. -1. `BlobTx` transactions must be valid according to the [BlobTx validity rules](../../../x/blob/README.md#validity-rules). +1. `BlobTx` transactions must be valid according to the [BlobTx validity rules](../../x/blob/README.md#validity-rules). ### Data Root Construction -The data root must be calculated from a correctly constructed data square per the [data square layout rules](./data_square_layout.md) +The data root must be calculated from a correctly constructed data square per the [data square layout](./data_square_layout.md) rules. Figure 1: Erasure Encoding Figure 2: rsmt2d Figure 3: Data Root diff --git a/specs/src/specs/cat_pool.md b/specs/src/cat_pool.md similarity index 100% rename from specs/src/specs/cat_pool.md rename to specs/src/cat_pool.md diff --git a/specs/src/specs/consensus.md b/specs/src/consensus.md similarity index 99% rename from specs/src/specs/consensus.md rename to specs/src/consensus.md index 69dc17f136..fa708ce95d 100644 --- a/specs/src/specs/consensus.md +++ b/specs/src/consensus.md @@ -32,6 +32,7 @@ | `SHARE_INFO_BYTES` | `uint64` | `1` | `byte` | The number of bytes used for [share](data_structures.md#share) information | | `SHARE_RESERVED_BYTES` | `uint64` | `4` | `byte` | The number of bytes used to store the index of the first transaction in a transaction share. Must be able to represent any integer up to and including `SHARE_SIZE - 1`. | | `SHARE_SIZE` | `uint64` | `512` | `byte` | Size of transaction and blob [shares](data_structures.md#share), in bytes. | +| `SignerSize` | `int` | `20` | `byte` | The number of bytes used to store the signer in a [share](data_structures.md#share). | | `STATE_SUBTREE_RESERVED_BYTES` | `uint64` | `1` | `byte` | Number of bytes reserved to identify state subtrees. | | `UNBONDING_DURATION` | `uint32` | | `block` | Duration, in blocks, for unbonding a validator or delegation. | | `v1.Version` | `uint64` | `1` | | First version of the application. Breaking changes (hard forks) must update this parameter. | diff --git a/specs/src/specs/data_square_layout.md b/specs/src/data_square_layout.md similarity index 88% rename from specs/src/specs/data_square_layout.md rename to specs/src/data_square_layout.md index 7960e6e88c..70e476250f 100644 --- a/specs/src/specs/data_square_layout.md +++ b/specs/src/data_square_layout.md @@ -11,10 +11,10 @@ Celestia uses [a data availability scheme](https://arxiv.org/abs/1809.09044) tha Block data consists of: 1. Standard cosmos-SDK transactions: (which are often represented internally as the [`sdk.Tx` interface](https://github.com/celestiaorg/cosmos-sdk/blob/v1.14.0-sdk-v0.46.11/types/tx_msg.go#L42-L50)) as described in [cosmos-sdk ADR020](https://github.com/celestiaorg/cosmos-sdk/blob/v1.14.0-sdk-v0.46.11/docs/architecture/adr-020-protobuf-transaction-encoding.md) - 1. These transactions contain protobuf encoded [`sdk.Msg`](https://github.com/celestiaorg/cosmos-sdk/blob/v1.14.0-sdk-v0.46.11/types/tx_msg.go#L14-L26)s, which get executed atomically (if one fails they all fail) to update the Celestia state. The complete list of modules, which define the `sdk.Msg`s that the state machine is capable of handling, can be found in the [state machine modules spec](../specs/state_machine_modules.md). Examples include standard cosmos-sdk module messages such as [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/f71df80e93bffbf7ce5fbd519c6154a2ee9f991b/proto/cosmos/bank/v1beta1/tx.proto#L21-L32)), and celestia specific module messages such as [`MsgPayForBlobs`](https://github.com/celestiaorg/celestia-app/blob/v1.0.0-rc2/proto/celestia/blob/v1/tx.proto#L16-L31) + 1. These transactions contain protobuf encoded [`sdk.Msg`](https://github.com/celestiaorg/cosmos-sdk/blob/v1.14.0-sdk-v0.46.11/types/tx_msg.go#L14-L26)s, which get executed atomically (if one fails they all fail) to update the Celestia state. The complete list of modules, which define the `sdk.Msg`s that the state machine is capable of handling, can be found in the [state machine modules spec](./state_machine_modules.md). Examples include standard cosmos-sdk module messages such as [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/f71df80e93bffbf7ce5fbd519c6154a2ee9f991b/proto/cosmos/bank/v1beta1/tx.proto#L21-L32)), and celestia specific module messages such as [`MsgPayForBlobs`](https://github.com/celestiaorg/celestia-app/blob/v1.0.0-rc2/proto/celestia/blob/v1/tx.proto#L16-L31) 1. Blobs: binary large objects which do not modify the Celestia state, but which are intended for a Celestia application identified with a provided namespace. -We want to arrange this data into a `k * k` matrix of fixed-sized [shares](../specs/shares.md), which will later be committed to in [Namespace Merkle Trees (NMTs)](https://github.com/celestiaorg/nmt/blob/v0.16.0/docs/spec/nmt.md) so that individual shares in this matrix can be proven to belong to a single data root. `k` must always be a power of 2 (e.g. 1, 2, 4, 8, 16, 32, etc.) as this is optimal for the erasure coding algorithm. +We want to arrange this data into a `k * k` matrix of fixed-sized [shares](./shares.md), which will later be committed to in [Namespace Merkle Trees (NMTs)](https://github.com/celestiaorg/nmt/blob/v0.16.0/docs/spec/nmt.md) so that individual shares in this matrix can be proven to belong to a single data root. `k` must always be a power of 2 (e.g. 1, 2, 4, 8, 16, 32, etc.) as this is optimal for the erasure coding algorithm. The simplest way we can imagine arranging block data is to simply serialize it all in no particular order, split it into fixed-sized shares, then arrange those shares into the `k * k` matrix in row-major order. However, this naive scheme can be improved in a number of ways, described below. @@ -54,7 +54,7 @@ The `SubtreeWidth` is calculated as the length of the blob in shares, divided by ![subtree root width](./figures/subtree_width.svg) -The `SubtreeRootThreshold` is an arbitrary versioned protocol constant that aims to put a soft limit on the number of subtree roots included in a blob inclusion proof, as described in [ADR013](../../../docs/architecture/adr-013-non-interactive-default-rules-for-zero-padding.md). A higher `SubtreeRootThreshold` means less padding and more tightly packed squares but also means greater blob inclusion proof sizes. +The `SubtreeRootThreshold` is an arbitrary versioned protocol constant that aims to put a soft limit on the number of subtree roots included in a blob inclusion proof, as described in [ADR013](../../docs/architecture/adr-013-non-interactive-default-rules-for-zero-padding.md). A higher `SubtreeRootThreshold` means less padding and more tightly packed squares but also means greater blob inclusion proof sizes. With the above constraint, we can compute subtree roots deterministically. For example, a blob of 172 shares and `SubtreeRootThreshold` (SRT) = 64, must start on a share index that is a multiple of 4 because 172/64 = 3. 3 rounded up to the nearest power of 2 is 4. In this case, there will be a maximum of 3 shares of padding between blobs (more on padding below). The maximum subtree width in shares for the first mountain in the Merkle range will be 4 (The actual mountain range would be 43 subtree roots of 4 shares each). The `ShareCommitment` is then the Merkle tree over the peaks of the mountain range. ## Padding diff --git a/specs/src/specs/data_structures.md b/specs/src/data_structures.md similarity index 99% rename from specs/src/specs/data_structures.md rename to specs/src/data_structures.md index 745e06f8cb..a7a8bba805 100644 --- a/specs/src/specs/data_structures.md +++ b/specs/src/data_structures.md @@ -354,7 +354,7 @@ For each blob, it is placed in the available data matrix, with row-major order, 1. Place the first share of the blob at the next unused location in the matrix, then place the remaining shares in the following locations. -Transactions [must commit to a Merkle root of a list of hashes](#transaction) that are each guaranteed (assuming the block is valid) to be subtree roots in one or more of the row NMTs. For additional info, see [the rationale document](../specs/data_square_layout.md) for this section. +Transactions [must commit to a Merkle root of a list of hashes](#transaction) that are each guaranteed (assuming the block is valid) to be subtree roots in one or more of the row NMTs. For additional info, see [the rationale document](./data_square_layout.md) for this section. However, with only the rule above, interaction between the block producer and transaction sender may be required to compute a commitment to the blob the transaction sender can sign over. To remove interaction, blobs can optionally be laid out using a non-interactive default: @@ -365,7 +365,7 @@ In the example below, two blobs (of lengths 2 and 1, respectively) are placed us ![fig: original data blob](./figures/rs2d_originaldata_blob.svg) -The blob share commitment rules may introduce empty shares that do not belong to any blob (in the example above, the top-right share is empty). These are zeroes with namespace ID equal to the either [`TAIL_TRANSACTION_PADDING_NAMESPACE_ID`](./consensus.md#constants) if between a request with a reserved namespace ID and a blob, or the namespace ID of the previous blob if succeeded by a blob. See the [rationale doc](../specs/data_square_layout.md) for more info. +The blob share commitment rules may introduce empty shares that do not belong to any blob (in the example above, the top-right share is empty). These are zeroes with namespace ID equal to the either [`TAIL_TRANSACTION_PADDING_NAMESPACE_ID`](./consensus.md#constants) if between a request with a reserved namespace ID and a blob, or the namespace ID of the previous blob if succeeded by a blob. See the [data square layout](./data_square_layout.md) for more info. ## Available Data diff --git a/specs/src/specs/figures/blob_share_commitment.svg b/specs/src/figures/blob_share_commitment.svg similarity index 100% rename from specs/src/specs/figures/blob_share_commitment.svg rename to specs/src/figures/blob_share_commitment.svg diff --git a/specs/src/specs/figures/block_data_structures.dot b/specs/src/figures/block_data_structures.dot similarity index 100% rename from specs/src/specs/figures/block_data_structures.dot rename to specs/src/figures/block_data_structures.dot diff --git a/specs/src/specs/figures/block_data_structures.svg b/specs/src/figures/block_data_structures.svg similarity index 100% rename from specs/src/specs/figures/block_data_structures.svg rename to specs/src/figures/block_data_structures.svg diff --git a/specs/src/specs/figures/data_root.svg b/specs/src/figures/data_root.svg similarity index 100% rename from specs/src/specs/figures/data_root.svg rename to specs/src/figures/data_root.svg diff --git a/specs/src/figures/first_share_with_signer.dot b/specs/src/figures/first_share_with_signer.dot new file mode 100644 index 0000000000..d22e7eff1e --- /dev/null +++ b/specs/src/figures/first_share_with_signer.dot @@ -0,0 +1,25 @@ +digraph G { + node [shape = record, penwidth = 0]; + + share [label=< + + + + + + + + + + + + + + + + + + +
0129303454512
namespace versionnamespace idinfo bytesequence lengthsignerblob1
+ >]; +} diff --git a/specs/src/figures/first_share_with_signer.svg b/specs/src/figures/first_share_with_signer.svg new file mode 100644 index 0000000000..71dfe3d8e3 --- /dev/null +++ b/specs/src/figures/first_share_with_signer.svg @@ -0,0 +1,31 @@ + + + +G + + + +share + +0 +1 +29 +30 +34 +54 +512 + +namespace version + +namespace id + +info byte + +sequence length + +signer + +blob1 + + + \ No newline at end of file diff --git a/specs/src/specs/figures/gas_consumption/100kib_pfb_trace.png b/specs/src/figures/gas_consumption/100kib_pfb_trace.png similarity index 100% rename from specs/src/specs/figures/gas_consumption/100kib_pfb_trace.png rename to specs/src/figures/gas_consumption/100kib_pfb_trace.png diff --git a/specs/src/specs/figures/gas_consumption/msg_create_validator_trace.png b/specs/src/figures/gas_consumption/msg_create_validator_trace.png similarity index 100% rename from specs/src/specs/figures/gas_consumption/msg_create_validator_trace.png rename to specs/src/figures/gas_consumption/msg_create_validator_trace.png diff --git a/specs/src/specs/figures/gas_consumption/msg_send_trace.png b/specs/src/figures/gas_consumption/msg_send_trace.png similarity index 100% rename from specs/src/specs/figures/gas_consumption/msg_send_trace.png rename to specs/src/figures/gas_consumption/msg_send_trace.png diff --git a/specs/src/specs/figures/gas_consumption/pfb_with_two_single_share_blobs_trace.png b/specs/src/figures/gas_consumption/pfb_with_two_single_share_blobs_trace.png similarity index 100% rename from specs/src/specs/figures/gas_consumption/pfb_with_two_single_share_blobs_trace.png rename to specs/src/figures/gas_consumption/pfb_with_two_single_share_blobs_trace.png diff --git a/specs/src/specs/figures/gas_consumption/single_share_pfb_trace.png b/specs/src/figures/gas_consumption/single_share_pfb_trace.png similarity index 100% rename from specs/src/specs/figures/gas_consumption/single_share_pfb_trace.png rename to specs/src/figures/gas_consumption/single_share_pfb_trace.png diff --git a/specs/src/specs/figures/namespace.dot b/specs/src/figures/namespace.dot similarity index 100% rename from specs/src/specs/figures/namespace.dot rename to specs/src/figures/namespace.dot diff --git a/specs/src/specs/figures/namespace.svg b/specs/src/figures/namespace.svg similarity index 100% rename from specs/src/specs/figures/namespace.svg rename to specs/src/figures/namespace.svg diff --git a/specs/src/specs/figures/rs2d.svg b/specs/src/figures/rs2d.svg similarity index 100% rename from specs/src/specs/figures/rs2d.svg rename to specs/src/figures/rs2d.svg diff --git a/specs/src/specs/figures/rs2d_extend.svg b/specs/src/figures/rs2d_extend.svg similarity index 100% rename from specs/src/specs/figures/rs2d_extend.svg rename to specs/src/figures/rs2d_extend.svg diff --git a/specs/src/specs/figures/rs2d_extending.svg b/specs/src/figures/rs2d_extending.svg similarity index 100% rename from specs/src/specs/figures/rs2d_extending.svg rename to specs/src/figures/rs2d_extending.svg diff --git a/specs/src/specs/figures/rs2d_originaldata_blob.svg b/specs/src/figures/rs2d_originaldata_blob.svg similarity index 100% rename from specs/src/specs/figures/rs2d_originaldata_blob.svg rename to specs/src/figures/rs2d_originaldata_blob.svg diff --git a/specs/src/specs/figures/rs2d_originaldata_reserved.svg b/specs/src/figures/rs2d_originaldata_reserved.svg similarity index 100% rename from specs/src/specs/figures/rs2d_originaldata_reserved.svg rename to specs/src/figures/rs2d_originaldata_reserved.svg diff --git a/specs/src/specs/figures/rs2d_quadrants.svg b/specs/src/figures/rs2d_quadrants.svg similarity index 100% rename from specs/src/specs/figures/rs2d_quadrants.svg rename to specs/src/figures/rs2d_quadrants.svg diff --git a/specs/src/specs/figures/rs2d_row.svg b/specs/src/figures/rs2d_row.svg similarity index 100% rename from specs/src/specs/figures/rs2d_row.svg rename to specs/src/figures/rs2d_row.svg diff --git a/specs/src/specs/figures/share_continuation.dot b/specs/src/figures/share_continuation.dot similarity index 100% rename from specs/src/specs/figures/share_continuation.dot rename to specs/src/figures/share_continuation.dot diff --git a/specs/src/specs/figures/share_continuation.svg b/specs/src/figures/share_continuation.svg similarity index 100% rename from specs/src/specs/figures/share_continuation.svg rename to specs/src/figures/share_continuation.svg diff --git a/specs/src/specs/figures/share_start.dot b/specs/src/figures/share_start.dot similarity index 100% rename from specs/src/specs/figures/share_start.dot rename to specs/src/figures/share_start.dot diff --git a/specs/src/specs/figures/share_start.svg b/specs/src/figures/share_start.svg similarity index 100% rename from specs/src/specs/figures/share_start.svg rename to specs/src/figures/share_start.svg diff --git a/specs/src/specs/figures/square_layout.svg b/specs/src/figures/square_layout.svg similarity index 100% rename from specs/src/specs/figures/square_layout.svg rename to specs/src/figures/square_layout.svg diff --git a/specs/src/specs/figures/subtree_width.svg b/specs/src/figures/subtree_width.svg similarity index 100% rename from specs/src/specs/figures/subtree_width.svg rename to specs/src/figures/subtree_width.svg diff --git a/specs/src/specs/figures/transaction_share_continuation.dot b/specs/src/figures/transaction_share_continuation.dot similarity index 100% rename from specs/src/specs/figures/transaction_share_continuation.dot rename to specs/src/figures/transaction_share_continuation.dot diff --git a/specs/src/specs/figures/transaction_share_continuation.svg b/specs/src/figures/transaction_share_continuation.svg similarity index 100% rename from specs/src/specs/figures/transaction_share_continuation.svg rename to specs/src/figures/transaction_share_continuation.svg diff --git a/specs/src/specs/figures/transaction_share_start.dot b/specs/src/figures/transaction_share_start.dot similarity index 100% rename from specs/src/specs/figures/transaction_share_start.dot rename to specs/src/figures/transaction_share_start.dot diff --git a/specs/src/specs/figures/transaction_share_start.svg b/specs/src/figures/transaction_share_start.svg similarity index 100% rename from specs/src/specs/figures/transaction_share_start.svg rename to specs/src/figures/transaction_share_start.svg diff --git a/specs/src/specs/fraud_proofs.md b/specs/src/fraud_proofs.md similarity index 100% rename from specs/src/specs/fraud_proofs.md rename to specs/src/fraud_proofs.md diff --git a/specs/src/specs/multisig.md b/specs/src/multisig.md similarity index 100% rename from specs/src/specs/multisig.md rename to specs/src/multisig.md diff --git a/specs/src/specs/namespace.md b/specs/src/namespace.md similarity index 98% rename from specs/src/specs/namespace.md rename to specs/src/namespace.md index 2042595452..7f0098cdc4 100644 --- a/specs/src/specs/namespace.md +++ b/specs/src/namespace.md @@ -108,8 +108,8 @@ type Namespace struct { ## References -1. [ADR-014](../../../docs/architecture/adr-014-versioned-namespaces.md) -1. [ADR-015](../../../docs/architecture/adr-015-namespace-id-size.md) +1. [ADR-014](../../docs/architecture/adr-014-versioned-namespaces.md) +1. [ADR-015](../../docs/architecture/adr-015-namespace-id-size.md) 1. [Namespaced Merkle Tree](https://github.com/celestiaorg/nmt) 1. [LazyLedger whitepaper](https://arxiv.org/pdf/1905.09274.pdf) 1. [Data Square Layout](./data_square_layout.md) diff --git a/specs/src/specs/networking.md b/specs/src/networking.md similarity index 96% rename from specs/src/specs/networking.md rename to specs/src/networking.md index 454b56c197..8f58da5be1 100644 --- a/specs/src/specs/networking.md +++ b/specs/src/networking.md @@ -59,9 +59,9 @@ Defined as `MsgWirePayForData`: Accepting a `MsgWirePayForData` into the mempool requires different logic than other transactions in Celestia, since it leverages the paradigm of block proposers being able to malleate transaction data. Unlike [SignedTransactionDataMsgPayForData](./data_structures.md#signedtransactiondatamsgpayfordata) (the canonical data type that is included in blocks and committed to with a data root in the block header), each `MsgWirePayForData` (the over-the-wire representation of the same) has potentially multiple signatures. -Transaction senders who want to pay for a blob will create a [SignedTransactionDataMsgPayForData](./data_structures.md#signedtransactiondatamsgpayfordata) object, `stx`, filling in the `stx.blobShareCommitment` field [based on the blob share commitmentrules](../specs/data_square_layout.md#blob-share-commitment-rules), then signing it to get a [transaction](./data_structures.md#transaction) `tx`. +Transaction senders who want to pay for a blob will create a [SignedTransactionDataMsgPayForData](./data_structures.md#signedtransactiondatamsgpayfordata) object, `stx`, filling in the `stx.blobShareCommitment` field based on the [blob share commitment rules](./data_square_layout.md#blob-share-commitment-rules), then signing it to get a [transaction](./data_structures.md#transaction) `tx`. -Receiving a `MsgWirePayForData` object from the network follows the reverse process: verify using the [blob share commitmentrules](../specs/data_square_layout.md#blob-share-commitment-rules) that the signature is valid. +Receiving a `MsgWirePayForData` object from the network follows the reverse process: verify using the [blob share commitment rules](./data_square_layout.md#blob-share-commitment-rules) that the signature is valid. ## Invalid Erasure Coding diff --git a/specs/src/specs/parameters.md b/specs/src/parameters.md similarity index 80% rename from specs/src/specs/parameters.md rename to specs/src/parameters.md index 4dcecce93d..2e32514c9d 100644 --- a/specs/src/specs/parameters.md +++ b/specs/src/parameters.md @@ -4,3 +4,4 @@ The parameters in the application depend on the app version: - [Parameters v1](./parameters_v1.md) - [Parameters v2](./parameters_v2.md) +- [Parameters v3](./parameters_v3.md) diff --git a/specs/src/specs/parameters_v1.md b/specs/src/parameters_v1.md similarity index 100% rename from specs/src/specs/parameters_v1.md rename to specs/src/parameters_v1.md diff --git a/specs/src/specs/parameters_v2.md b/specs/src/parameters_v2.md similarity index 98% rename from specs/src/specs/parameters_v2.md rename to specs/src/parameters_v2.md index 7555dd8761..9bd3e63f25 100644 --- a/specs/src/specs/parameters_v2.md +++ b/specs/src/parameters_v2.md @@ -54,6 +54,7 @@ hardcoded in the application or they are blocked by the `x/paramfilter` module. | mint.DisinflationRate | 0.10 (10%) | The rate at which the inflation rate decreases each year. | False | | mint.InitialInflationRate | 0.08 (8%) | The inflation rate the network starts at. | False | | mint.TargetInflationRate | 0.015 (1.5%) | The inflation rate that the network aims to stabilize at. | False | +| packetfowardmiddleware.FeePercentage | 0 | % of the forwarded packet amount which will be subtracted and distributed to the community pool. | True | | slashing.DowntimeJailDuration | 1 min | Duration of time a validator must stay jailed. | True | | slashing.MinSignedPerWindow | 0.75 (75%) | The percentage of SignedBlocksWindow that must be signed not to get jailed. | True | | slashing.SignedBlocksWindow | 5000 | The range of blocks used to count for downtime. | True | diff --git a/specs/src/parameters_v3.md b/specs/src/parameters_v3.md new file mode 100644 index 0000000000..860cdb286f --- /dev/null +++ b/specs/src/parameters_v3.md @@ -0,0 +1,72 @@ +# Parameters v3 + +The parameters below represent the parameters for app version 3. + +Note that not all of these parameters are changeable via governance. This list +also includes parameter that require a hardfork to change due to being manually +hardcoded in the application or they are blocked by the `x/paramfilter` module. + +## Global parameters + +| Parameter | Default | Summary | Changeable via Governance | +|-------------------|---------|------------------------------------------------------------------------------------------------------------------------|---------------------------| +| MaxBlockSizeBytes | 100MiB | Hardcoded value in CometBFT for the protobuf encoded block. | False | +| MaxSquareSize | 128 | Hardcoded maximum square size determined per shares per row or column for the original data square (not yet extended). | False | + +## Module parameters + +| Module.Parameter | Default | Summary | Changeable via Governance | +|-----------------------------------------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|---------------------------| +| auth.MaxMemoCharacters | 256 | Largest allowed size for a memo in bytes. | True | +| auth.SigVerifyCostED25519 | 590 | Gas used to verify Ed25519 signature. | True | +| auth.SigVerifyCostSecp256k1 | 1000 | Gas used to verify secp256k1 signature. | True | +| auth.TxSigLimit | 7 | Max number of signatures allowed in a multisig transaction. | True | +| auth.TxSizeCostPerByte | 10 | Gas used per transaction byte. | False | +| bank.SendEnabled | true | Allow transfers. | False | +| blob.GasPerBlobByte | 8 | Gas used per blob byte. | False | +| blob.GovMaxSquareSize | 64 | Governance parameter for the maximum square size of the original data square. | True | +| consensus.block.MaxBytes | 1974272 bytes (~1.88 MiB) | Governance parameter for the maximum size of the protobuf encoded block. | True | +| consensus.block.MaxGas | -1 | Maximum gas allowed per block (-1 is infinite). | True | +| consensus.block.TimeIotaMs | 1000 | Minimum time added to the time in the header each block. | False | +| consensus.evidence.MaxAgeDuration | 1814400000000000 (21 days) | The maximum age of evidence before it is considered invalid in nanoseconds. This value should be identical to the unbonding period. | True | +| consensus.evidence.MaxAgeNumBlocks | 120960 | The maximum number of blocks before evidence is considered invalid. This value will stop CometBFT from pruning block data. | True | +| consensus.evidence.MaxBytes | 1MiB | Maximum size in bytes used by evidence in a given block. | True | +| consensus.validator.PubKeyTypes | Ed25519 | The type of public key used by validators. | False | +| consensus.Version.AppVersion | 3 | Determines protocol rules used for a given height. Incremented by the application upon an upgrade. | True | +| distribution.BaseProposerReward | 0 | Reward in the mint denomination for proposing a block. | True | +| distribution.BonusProposerReward | 0 | Extra reward in the mint denomination for proposers based on the voting power included in the commit. | True | +| distribution.CommunityTax | 0.02 (2%) | Percentage of the inflation sent to the community pool. | True | +| distribution.WithdrawAddrEnabled | true | Enables delegators to withdraw funds to a different address. | True | +| gov.DepositParams.MaxDepositPeriod | 604800000000000 (1 week) | Maximum period for token holders to deposit on a proposal in nanoseconds. | True | +| gov.DepositParams.MinDeposit | 10_000_000_000 utia (10,000 TIA) | Minimum deposit for a proposal to enter voting period. | True | +| gov.TallyParams.Quorum | 0.334 (33.4%) | Minimum percentage of total stake needed to vote for a result to be considered valid. | True | +| gov.TallyParams.Threshold | 0.50 (50%) | Minimum proportion of Yes votes for proposal to pass. | True | +| gov.TallyParams.VetoThreshold | 0.334 (33.4%) | Minimum value of Veto votes to Total votes ratio for proposal to be vetoed. | True | +| gov.VotingParams.VotingPeriod | 604800000000000 (1 week) | Duration of the voting period in nanoseconds. | True | +| ibc.ClientGenesis.AllowedClients | []string{"06-solomachine", "07-tendermint"} | List of allowed IBC light clients. | True | +| ibc.ConnectionGenesis.MaxExpectedTimePerBlock | 7500000000000 (75 seconds) | Maximum expected time per block in nanoseconds under normal operation. | True | +| ibc.Transfer.ReceiveEnabled | true | Enable receiving tokens via IBC. | True | +| ibc.Transfer.SendEnabled | true | Enable sending tokens via IBC. | True | +| icahost.HostEnabled | True | Enables or disables the Inter-Chain Accounts host module. | True | +| icahost.AllowMessages | [icaAllowMessages] | Defines a list of sdk message typeURLs allowed to be executed on a host chain. | True | +| minfee.NetworkMinGasPrice | 0.000001 utia | All transactions must have a gas price greater than or equal to this value. | True | +| mint.BondDenom | utia | Denomination that is inflated and sent to the distribution module account. | False | +| mint.DisinflationRate | 0.10 (10%) | The rate at which the inflation rate decreases each year. | False | +| mint.InitialInflationRate | 0.08 (8%) | The inflation rate the network starts at. | False | +| mint.TargetInflationRate | 0.015 (1.5%) | The inflation rate that the network aims to stabilize at. | False | +| packetfowardmiddleware.FeePercentage | 0 | % of the forwarded packet amount which will be subtracted and distributed to the community pool. | True | +| slashing.DowntimeJailDuration | 1 min | Duration of time a validator must stay jailed. | True | +| slashing.MinSignedPerWindow | 0.75 (75%) | The percentage of SignedBlocksWindow that must be signed not to get jailed. | True | +| slashing.SignedBlocksWindow | 5000 | The range of blocks used to count for downtime. | True | +| slashing.SlashFractionDoubleSign | 0.02 (2%) | Percentage slashed after a validator is jailed for double signing. | True | +| slashing.SlashFractionDowntime | 0.00 (0%) | Percentage slashed after a validator is jailed for downtime. | True | +| staking.BondDenom | utia | Bondable coin denomination. | False | +| staking.HistoricalEntries | 10000 | Number of historical entries to persist in store. | True | +| staking.MaxEntries | 7 | Maximum number of entries in the redelegation queue. | True | +| staking.MaxValidators | 100 | Maximum number of validators. | True | +| staking.MinCommissionRate | 0.05 (5%) | Minimum commission rate used by all validators. | True | +| staking.UnbondingTime | 1814400 (21 days) | Duration of time for unbonding in seconds. | False | + +Note: none of the mint module parameters are governance modifiable because they have been converted into hardcoded constants. See the x/mint README.md for more details. + +[icaAllowMessages]: https://github.com/rootulp/celestia-app/blob/8caa5807df8d15477554eba953bd056ae72d4503/app/ica_host.go#L3-L18 diff --git a/specs/src/specs/proto/consensus.proto b/specs/src/proto/consensus.proto similarity index 100% rename from specs/src/specs/proto/consensus.proto rename to specs/src/proto/consensus.proto diff --git a/specs/src/specs/proto/types.proto b/specs/src/proto/types.proto similarity index 100% rename from specs/src/specs/proto/types.proto rename to specs/src/proto/types.proto diff --git a/specs/src/specs/proto/wire.proto b/specs/src/proto/wire.proto similarity index 100% rename from specs/src/specs/proto/wire.proto rename to specs/src/proto/wire.proto diff --git a/specs/src/specs/public_key_cryptography.md b/specs/src/public_key_cryptography.md similarity index 100% rename from specs/src/specs/public_key_cryptography.md rename to specs/src/public_key_cryptography.md diff --git a/specs/src/specs/resource_pricing.md b/specs/src/resource_pricing.md similarity index 100% rename from specs/src/specs/resource_pricing.md rename to specs/src/resource_pricing.md diff --git a/specs/src/specs/shares.md b/specs/src/shares.md similarity index 87% rename from specs/src/specs/shares.md rename to specs/src/shares.md index ee469f25f7..59ed91c9f3 100644 --- a/specs/src/specs/shares.md +++ b/specs/src/shares.md @@ -10,7 +10,7 @@ All available data in a Celestia [block](./data_structures.md#block) is split in - **Blob**: User specified data (e.g. a roll-up block) that is associated with exactly one namespace. Blob data are opaque bytes of data that are included in the block but do not impact Celestia's state. - **Share**: A fixed-size data chunk that is associated with exactly one namespace. -- **Share sequence**: A share sequence is a contiguous set of shares that contain semantically relevant data. A share sequence MUST contain one or more shares. When a [blob](../../../x/blob/README.md) is split into shares, it is written to one share sequence. As a result, all shares in a share sequence are typically parsed together because the original blob data may have been split across share boundaries. All transactions in the [`TRANSACTION_NAMESPACE`](./namespace.md#reserved-namespaces) are contained in one share sequence. All transactions in the [`PAY_FOR_BLOB_NAMESPACE`](./namespace.md#reserved-namespaces) are contained in one share sequence. +- **Share sequence**: A share sequence is a contiguous set of shares that contain semantically relevant data. A share sequence MUST contain one or more shares. When a [blob](../../x/blob/README.md) is split into shares, it is written to one share sequence. As a result, all shares in a share sequence are typically parsed together because the original blob data may have been split across share boundaries. All transactions in the [`TRANSACTION_NAMESPACE`](./namespace.md#reserved-namespaces) are contained in one share sequence. All transactions in the [`PAY_FOR_BLOB_NAMESPACE`](./namespace.md#reserved-namespaces) are contained in one share sequence. ## Overview @@ -23,6 +23,12 @@ User submitted transactions are split into shares (see [share splitting](#share- ## Share Format +### Share Version + +The share version is a 7-bit big-endian unsigned integer that is used to indicate the version of the [share format](#share-format). A new share version MUST be introduced if the share format changes in a way that is not backwards compatible. There are two share versions [share version 0](#share-version-0) and [share version 1](#share-version-1). + +### Share Version 0 + Every share has a fixed size [`SHARE_SIZE`](./consensus.md#constants). The share format below is consistent for all shares: - The first [`NAMESPACE_VERSION_SIZE`](./consensus.md#constants) bytes of a share's raw data is the namespace version of that share (denoted by "namespace version" in the figure below). @@ -31,7 +37,7 @@ Every share has a fixed size [`SHARE_SIZE`](./consensus.md#constants). The share - The first 7 bits represent the [share version](#share-version) in big endian form (initially, this will be `0000000` for version `0`); - The last bit is a sequence start indicator. The indicator is `1` if this share is the first share in a sequence or `0` if this share is a continuation share in a sequence. - If this share is the first share in a sequence, it will include the length of the sequence in bytes. The next [`SEQUENCE_BYTES`](./consensus.md#constants) represent a big-endian uint32 value (denoted by "sequence length" in the figure below). This length is placed immediately after the `SHARE_INFO_BYTES` field. It's important to note that shares that are not the first share in a sequence do not contain this field. -- The remaining [`SHARE_SIZE`](./consensus.md#constants)`-`[`NAMESPACE_SIZE`](./consensus.md#constants)`-`[`SHARE_INFO_BYTES`](./consensus.md#constants)`-`[`SEQUENCE_BYTES`](./consensus.md#constants) bytes (if first share) or [`SHARE_SIZE`](./consensus.md#constants)`-`[`NAMESPACE_SIZE`](./consensus.md#constants)`-`[`SHARE_INFO_BYTES`](./consensus.md#constants) bytes (if continuation share) are raw data (denoted by "blob1" in the figure below). Typically raw data is the blob payload that user's submit in a [BlobTx](../../../x/blob/README.md). However, raw data can also be transaction data (see [transaction shares](#transaction-shares) below). +- The remaining [`SHARE_SIZE`](./consensus.md#constants)`-`[`NAMESPACE_SIZE`](./consensus.md#constants)`-`[`SHARE_INFO_BYTES`](./consensus.md#constants)`-`[`SEQUENCE_BYTES`](./consensus.md#constants) bytes (if first share) or [`SHARE_SIZE`](./consensus.md#constants)`-`[`NAMESPACE_SIZE`](./consensus.md#constants)`-`[`SHARE_INFO_BYTES`](./consensus.md#constants) bytes (if continuation share) are raw data (denoted by "blob1" in the figure below). Typically raw data is the blob payload that user's submit in a [BlobTx](../../x/blob/README.md). However, raw data can also be transaction data (see [transaction shares](#transaction-shares) below). - If there is insufficient raw data to fill the share, the remaining bytes are filled with `0`. First share in a sequence: @@ -44,9 +50,17 @@ Continuation share in a sequence: Since raw data that exceeds [`SHARE_SIZE`](./consensus.md#constants)`-`[`NAMESPACE_SIZE`](./consensus.md#constants)`-`[`SHARE_INFO_BYTES`](./consensus.md#constants) `-` [`SEQUENCE_BYTES`](./consensus.md#constants) bytes will span more than one share, developers MAY choose to encode additional metadata in their raw blob data prior to inclusion in a Celestia block. For example, Celestia transaction shares encode additional metadata in the form of "reserved bytes". -### Share Version +### Share Version 1 + +Share version 1 is similar to share version 0 with the addition of a `signer` field. The signer is located after the sequence length in the first share. The signer is [`SIGNER_SIZE`](./consensus.md#constants) bytes. + +First share in a sequence with signer: + +![figure 3: first share with signer](./figures/first_share_with_signer.svg) + +Continuation share in a sequence: -The share version is a 7-bit big-endian unsigned integer that is used to indicate the version of the [share format](#share-format). The only supported share version is `0`. A new share version MUST be introduced if the share format changes in a way that is not backwards compatible. +![figure 4: share continuation](./figures/share_continuation.svg) ## Transaction Shares @@ -116,6 +130,6 @@ See [go-square/shares](https://github.com/celestiaorg/go-square/tree/be3c2801e90 ## References -1. [ADR-012](../../../docs/architecture/adr-012-sequence-length-encoding.md) -1. [ADR-014](../../../docs/architecture/adr-014-versioned-namespaces.md) -1. [ADR-015](../../../docs/architecture/adr-015-namespace-id-size.md) +1. [ADR-012](../../docs/architecture/adr-012-sequence-length-encoding.md) +1. [ADR-014](../../docs/architecture/adr-014-versioned-namespaces.md) +1. [ADR-015](../../docs/architecture/adr-015-namespace-id-size.md) diff --git a/specs/src/specs/index.md b/specs/src/specs/index.md deleted file mode 100644 index d7bda658a9..0000000000 --- a/specs/src/specs/index.md +++ /dev/null @@ -1,18 +0,0 @@ -# Specification - -- [Data Structures](./data_structures.md) -- [Namespace](./namespace.md) -- [Shares](./shares.md) -- [Consensus](./consensus.md) - - [CAT Pool](./cat_pool.md) -- [Block Proposer](./block_proposer.md) -- [Block Validity Rules](./block_validity_rules.md) -- [AnteHandler](./ante_handler.md) - - [AnteHandler v1](./ante_handler_v1.md) - - [AnteHandler v2](./ante_handler_v2.md) -- [Fraud Proofs](./fraud_proofs.md) -- [Networking](./networking.md) -- [Public-Key Cryptography](./public_key_cryptography.md) -- [Data Square Layout](./data_square_layout.md) -- [Resource Pricing](./resource_pricing.md) -- [Multisig](./multisig.md) diff --git a/specs/src/specs/state_machine_modules.md b/specs/src/state_machine_modules.md similarity index 100% rename from specs/src/specs/state_machine_modules.md rename to specs/src/state_machine_modules.md diff --git a/specs/src/specs/state_machine_modules_v1.md b/specs/src/state_machine_modules_v1.md similarity index 100% rename from specs/src/specs/state_machine_modules_v1.md rename to specs/src/state_machine_modules_v1.md diff --git a/specs/src/specs/state_machine_modules_v2.md b/specs/src/state_machine_modules_v2.md similarity index 100% rename from specs/src/specs/state_machine_modules_v2.md rename to specs/src/state_machine_modules_v2.md diff --git a/test/cmd/txsim/cli.go b/test/cmd/txsim/cli.go index 62988c3eae..55cac6d4fd 100644 --- a/test/cmd/txsim/cli.go +++ b/test/cmd/txsim/cli.go @@ -40,6 +40,8 @@ var ( send, sendIterations, sendAmount int stake, stakeValue, blob int useFeegrant, suppressLogs bool + upgradeSchedule string + blobShareVersion int ) func main() { @@ -101,8 +103,8 @@ well funded account that can act as the master account. The command runs until a masterAccName = os.Getenv(TxsimMasterAccName) } - if stake == 0 && send == 0 && blob == 0 { - return errors.New("no sequences specified. Use --stake, --send or --blob") + if stake == 0 && send == 0 && blob == 0 && upgradeSchedule == "" { + return errors.New("no sequences specified. Use --stake, --send, --upgrade-schedule or --blob") } // setup the sequences @@ -127,7 +129,21 @@ well funded account that can act as the master account. The command runs until a return fmt.Errorf("invalid blob amounts: %w", err) } - sequences = append(sequences, txsim.NewBlobSequence(sizes, blobsPerPFB).Clone(blob)...) + sequence := txsim.NewBlobSequence(sizes, blobsPerPFB) + if blobShareVersion >= 0 { + sequence.WithShareVersion(uint8(blobShareVersion)) + } + + sequences = append(sequences, sequence.Clone(blob)...) + } + + upgradeScheduleMap, err := parseUpgradeSchedule(upgradeSchedule) + if err != nil { + return fmt.Errorf("invalid upgrade schedule: %w", err) + } + + for height, version := range upgradeScheduleMap { + sequences = append(sequences, txsim.NewUpgradeSequence(version, height)) } if seed == 0 { @@ -195,10 +211,12 @@ func flags() *flag.FlagSet { flags.IntVar(&stake, "stake", 0, "number of stake sequences to run") flags.IntVar(&stakeValue, "stake-value", 1000, "amount of initial stake per sequence") flags.IntVar(&blob, "blob", 0, "number of blob sequences to run") + flags.StringVar(&upgradeSchedule, "upgrade-schedule", "", "upgrade schedule for the network in format height:version i.e. 100:3,200:4") flags.StringVar(&blobSizes, "blob-sizes", "100-1000", "range of blob sizes to send") flags.StringVar(&blobAmounts, "blob-amounts", "1", "range of blobs per PFB specified as a single value or a min-max range (e.g., 10 or 5-10). A single value indicates the exact number of blobs to be created.") flags.BoolVar(&useFeegrant, "feegrant", false, "use the feegrant module to pay for fees") flags.BoolVar(&suppressLogs, "suppressLogs", false, "disable logging") + flags.IntVar(&blobShareVersion, "blob-share-version", -1, "optionally specify a share version to use for the blob sequences") return flags } @@ -224,3 +242,27 @@ func readRange(r string) (txsim.Range, error) { return txsim.NewRange(n, m), nil } + +func parseUpgradeSchedule(schedule string) (map[int64]uint64, error) { + scheduleMap := make(map[int64]uint64) + if schedule == "" { + return nil, nil + } + scheduleParts := strings.Split(schedule, ",") + for _, part := range scheduleParts { + parts := strings.Split(part, ":") + if len(parts) != 2 { + return nil, fmt.Errorf("invalid upgrade schedule format: %s", part) + } + height, err := strconv.ParseInt(parts[0], 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid height in upgrade schedule: %s", parts[0]) + } + version, err := strconv.ParseUint(parts[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid version in upgrade schedule: %s", parts[1]) + } + scheduleMap[height] = version + } + return scheduleMap, nil +} diff --git a/test/cmd/txsim/cli_test.go b/test/cmd/txsim/cli_test.go index 3520221af0..ad6d1c2268 100644 --- a/test/cmd/txsim/cli_test.go +++ b/test/cmd/txsim/cli_test.go @@ -29,6 +29,7 @@ func TestTxsimCommandFlags(t *testing.T) { "--grpc-endpoint", grpcAddr, "--blob", "5", "--seed", "1234", + "--upgrade-schedule", "10:3", }) err := cmd.ExecuteContext(ctx) require.NoError(t, err) diff --git a/test/e2e/benchmark/benchmark.go b/test/e2e/benchmark/benchmark.go index 456f8da0dd..5af7b8539e 100644 --- a/test/e2e/benchmark/benchmark.go +++ b/test/e2e/benchmark/benchmark.go @@ -7,64 +7,90 @@ import ( "log" "time" + "github.com/tendermint/tendermint/pkg/trace" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/test/e2e/testnet" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" - "github.com/tendermint/tendermint/pkg/trace" + "github.com/celestiaorg/knuu/pkg/knuu" ) +const timeFormat = "20060102_150405" + type BenchmarkTest struct { *testnet.Testnet manifest *Manifest } +// NewBenchmarkTest wraps around testnet.New to create a new benchmark test. +// It may modify genesis consensus parameters based on manifest. func NewBenchmarkTest(name string, manifest *Manifest) (*BenchmarkTest, error) { - // create a new testnet - testNet, err := testnet.New(name, seed, - testnet.GetGrafanaInfoFromEnvVar(), manifest.ChainID, - manifest.GetGenesisModifiers()...) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + scope := fmt.Sprintf("%s_%s", name, time.Now().Format(timeFormat)) + kn, err := knuu.New(ctx, knuu.Options{ + Scope: scope, + ProxyEnabled: true, + }) if err != nil { return nil, err } + // context.Background() is used to allow the stopSignal to be functional even after this function returns + kn.HandleStopSignal(context.Background()) + + log.Printf("Knuu initialized with scope %s", kn.Scope) + + testNet, err := testnet.New(kn, testnet.Options{ + Grafana: testnet.GetGrafanaInfoFromEnvVar(), + ChainID: manifest.ChainID, + GenesisModifiers: manifest.GetGenesisModifiers(), + }) + testnet.NoError("failed to create testnet", err) + testNet.SetConsensusParams(manifest.GetConsensusParams()) return &BenchmarkTest{Testnet: testNet, manifest: manifest}, nil } // SetupNodes creates genesis nodes and tx clients based on the manifest. -// There will be manifest.Validators validators and manifest.TxClients tx clients. +// There will be manifest.Validators many validators and manifest.TxClients many tx clients. // Each tx client connects to one validator. If TxClients are fewer than Validators, some validators will not have a tx client. func (b *BenchmarkTest) SetupNodes() error { + ctx := context.Background() testnet.NoError("failed to create genesis nodes", - b.CreateGenesisNodes(b.manifest.Validators, + b.CreateGenesisNodes(ctx, b.manifest.Validators, b.manifest.CelestiaAppVersion, b.manifest.SelfDelegation, - b.manifest.UpgradeHeight, b.manifest.ValidatorResource)) + b.manifest.UpgradeHeight, b.manifest.ValidatorResource, b.manifest.DisableBBR)) // enable latency if specified in the manifest if b.manifest.EnableLatency { for _, node := range b.Nodes() { - if err := node.Instance.EnableBitTwister(); err != nil { - return fmt.Errorf("failed to enable bit twister: %v", err) - } + node.EnableNetShaper() } } // obtain the GRPC endpoints of the validators - gRPCEndpoints, err := b.RemoteGRPCEndpoints() + gRPCEndpoints, err := b.RemoteGRPCEndpoints(ctx) testnet.NoError("failed to get validators GRPC endpoints", err) log.Println("validators GRPC endpoints", gRPCEndpoints) // create tx clients and point them to the validators log.Println("Creating tx clients") - err = b.CreateTxClients(b.manifest.TxClientVersion, + err = b.CreateTxClients( + ctx, + b.manifest.TxClientVersion, b.manifest.BlobSequences, b.manifest.BlobSizes, b.manifest.BlobsPerSeq, - b.manifest.TxClientsResource, gRPCEndpoints) + b.manifest.TxClientsResource, + gRPCEndpoints, + map[int64]uint64{}, // upgrade schedule + ) testnet.NoError("failed to create tx clients", err) log.Println("Setting up testnet") - testnet.NoError("failed to setup testnet", b.Setup( + testnet.NoError("failed to setup testnet", b.Setup(ctx, testnet.WithPerPeerBandwidth(b.manifest.PerPeerBandwidth), testnet.WithTimeoutPropose(b.manifest.TimeoutPropose), testnet.WithTimeoutCommit(b.manifest.TimeoutCommit), @@ -78,21 +104,18 @@ func (b *BenchmarkTest) SetupNodes() error { log.Println("reading trace push config") if pushConfig, err := trace.GetPushConfigFromEnv(); err == nil { log.Print("Setting up trace push config") + envVars := map[string]string{ + trace.PushBucketName: pushConfig.BucketName, + trace.PushRegion: pushConfig.Region, + trace.PushAccessKey: pushConfig.AccessKey, + trace.PushKey: pushConfig.SecretKey, + trace.PushDelay: fmt.Sprintf("%d", pushConfig.PushDelay), + } for _, node := range b.Nodes() { - if err = node.Instance.SetEnvironmentVariable(trace.PushBucketName, pushConfig.BucketName); err != nil { - return fmt.Errorf("failed to set TRACE_PUSH_BUCKET_NAME: %v", err) - } - if err = node.Instance.SetEnvironmentVariable(trace.PushRegion, pushConfig.Region); err != nil { - return fmt.Errorf("failed to set TRACE_PUSH_REGION: %v", err) - } - if err = node.Instance.SetEnvironmentVariable(trace.PushAccessKey, pushConfig.AccessKey); err != nil { - return fmt.Errorf("failed to set TRACE_PUSH_ACCESS_KEY: %v", err) - } - if err = node.Instance.SetEnvironmentVariable(trace.PushKey, pushConfig.SecretKey); err != nil { - return fmt.Errorf("failed to set TRACE_PUSH_SECRET_KEY: %v", err) - } - if err = node.Instance.SetEnvironmentVariable(trace.PushDelay, fmt.Sprintf("%d", pushConfig.PushDelay)); err != nil { - return fmt.Errorf("failed to set TRACE_PUSH_DELAY: %v", err) + for key, value := range envVars { + if err = node.Instance.Build().SetEnvironmentVariable(key, value); err != nil { + return fmt.Errorf("failed to set %s: %v", key, err) + } } } } @@ -101,20 +124,22 @@ func (b *BenchmarkTest) SetupNodes() error { } // Run runs the benchmark test for the specified duration in the manifest. -func (b *BenchmarkTest) Run() error { +func (b *BenchmarkTest) Run(ctx context.Context) error { log.Println("Starting benchmark testnet") log.Println("Starting nodes") - err := b.StartNodes() - if err != nil { + if err := b.StartNodes(ctx); err != nil { return fmt.Errorf("failed to start testnet: %v", err) } // add latency if specified in the manifest if b.manifest.EnableLatency { for _, node := range b.Nodes() { - if err = node.Instance.SetLatencyAndJitter(b.manifest.LatencyParams. - Latency, b.manifest.LatencyParams.Jitter); err != nil { + err := node.SetLatencyAndJitter( + b.manifest.LatencyParams.Latency, + b.manifest.LatencyParams.Jitter, + ) + if err != nil { return fmt.Errorf("failed to set latency and jitter: %v", err) } } @@ -122,15 +147,13 @@ func (b *BenchmarkTest) Run() error { // wait for the nodes to sync log.Println("Waiting for nodes to sync") - err = b.WaitToSync() - if err != nil { + if err := b.WaitToSync(ctx); err != nil { return err } // start tx clients log.Println("Starting tx clients") - err = b.StartTxClients() - if err != nil { + if err := b.StartTxClients(ctx); err != nil { return fmt.Errorf("failed to start tx clients: %v", err) } diff --git a/test/e2e/benchmark/manifest.go b/test/e2e/benchmark/manifest.go index f130069657..b212ff85c4 100644 --- a/test/e2e/benchmark/manifest.go +++ b/test/e2e/benchmark/manifest.go @@ -78,6 +78,10 @@ type Manifest struct { UpgradeHeight int64 GovMaxSquareSize int64 + + DisableBBR bool + + GenesisAppVersion uint64 } func (m *Manifest) GetGenesisModifiers() []genesis.Modifier { @@ -86,6 +90,7 @@ func (m *Manifest) GetGenesisModifiers() []genesis.Modifier { blobParams := blobtypes.DefaultParams() blobParams.GovMaxSquareSize = uint64(m.GovMaxSquareSize) + modifiers = append(modifiers, genesis.SetBlobParams(ecfg.Codec, blobParams)) return modifiers @@ -94,6 +99,7 @@ func (m *Manifest) GetGenesisModifiers() []genesis.Modifier { func (m *Manifest) GetConsensusParams() *tmproto.ConsensusParams { cparams := app.DefaultConsensusParams() cparams.Block.MaxBytes = m.MaxBlockBytes + cparams.Version.AppVersion = m.GenesisAppVersion return cparams } @@ -103,12 +109,16 @@ func (m *Manifest) summary() string { if m.EnableLatency { latency = 1 } + bbr := 1 + if m.DisableBBR { + bbr = 0 + } maxBlockMB := m.MaxBlockBytes / testnet.MB - summary := fmt.Sprintf("v%d-t%d-b%d-bw%dmb-tc%d-tp%d-l%d-%s-%dmb", + summary := fmt.Sprintf("v%d-t%d-b%d-bw%dmb-tc%d-tp%d-l%d-%s-br%d-%dmb", m.Validators, m.TxClients, m.BlobSequences, m.PerPeerBandwidth/testnet.MB, m.TimeoutCommit/time.Second, m.TimeoutPropose/time.Second, - latency, m.Mempool, maxBlockMB) + latency, m.Mempool, bbr, maxBlockMB) if len(summary) > 50 { return summary[:50] } diff --git a/test/e2e/benchmark/throughput.go b/test/e2e/benchmark/throughput.go index b919093d8a..75bf1bdf6c 100644 --- a/test/e2e/benchmark/throughput.go +++ b/test/e2e/benchmark/throughput.go @@ -1,15 +1,13 @@ package main import ( + "context" "log" "time" "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/test/e2e/testnet" -) - -const ( - seed = 42 + "k8s.io/apimachinery/pkg/api/resource" ) var bigBlockManifest = Manifest{ @@ -17,16 +15,16 @@ var bigBlockManifest = Manifest{ Validators: 2, TxClients: 2, ValidatorResource: testnet.Resources{ - MemoryRequest: "12Gi", - MemoryLimit: "12Gi", - CPU: "8", - Volume: "20Gi", + MemoryRequest: resource.MustParse("12Gi"), + MemoryLimit: resource.MustParse("12Gi"), + CPU: resource.MustParse("8"), + Volume: resource.MustParse("20Gi"), }, TxClientsResource: testnet.Resources{ - MemoryRequest: "1Gi", - MemoryLimit: "3Gi", - CPU: "2", - Volume: "1Gi", + MemoryRequest: resource.MustParse("1Gi"), + MemoryLimit: resource.MustParse("3Gi"), + CPU: resource.MustParse("2"), + Volume: resource.MustParse("1Gi"), }, SelfDelegation: 10000000, // @TODO Update the CelestiaAppVersion and TxClientVersion to the latest @@ -51,6 +49,7 @@ var bigBlockManifest = Manifest{ TestDuration: 5 * time.Minute, LocalTracingType: "local", PushTrace: true, + DisableBBR: true, } func TwoNodeSimple(logger *log.Logger) error { @@ -88,19 +87,23 @@ func TwoNodeSimple(logger *log.Logger) error { DownloadTraces: false, TestDuration: 3 * time.Minute, TxClients: 2, + DisableBBR: true, } benchTest, err := NewBenchmarkTest(testName, &manifest) testnet.NoError("failed to create benchmark test", err) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + defer func() { log.Print("Cleaning up testnet") - benchTest.Cleanup() + benchTest.Cleanup(ctx) }() testnet.NoError("failed to setup nodes", benchTest.SetupNodes()) - testnet.NoError("failed to run the benchmark test", benchTest.Run()) + testnet.NoError("failed to run the benchmark test", benchTest.Run(ctx)) testnet.NoError("failed to check results", benchTest.CheckResults(1*testnet.MB)) @@ -114,13 +117,16 @@ func runBenchmarkTest(logger *log.Logger, testName string, manifest Manifest) er benchTest, err := NewBenchmarkTest(testName, &manifest) testnet.NoError("failed to create benchmark test", err) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + defer func() { log.Print("Cleaning up testnet") - benchTest.Cleanup() + benchTest.Cleanup(ctx) }() testnet.NoError("failed to setup nodes", benchTest.SetupNodes()) - testnet.NoError("failed to run the benchmark test", benchTest.Run()) + testnet.NoError("failed to run the benchmark test", benchTest.Run(ctx)) expectedBlockSize := int64(0.90 * float64(manifest.MaxBlockBytes)) testnet.NoError("failed to check results", benchTest.CheckResults(expectedBlockSize)) diff --git a/test/e2e/main.go b/test/e2e/main.go index c133e00a6d..768907e2cf 100644 --- a/test/e2e/main.go +++ b/test/e2e/main.go @@ -7,10 +7,10 @@ import ( ) const ( - seed = 42 + timeFormat = "20060102_150405" ) -type TestFunc func(*log.Logger) error +type TestFunc func(logger *log.Logger) error type Test struct { Name string @@ -23,6 +23,7 @@ func main() { tests := []Test{ {"MinorVersionCompatibility", MinorVersionCompatibility}, {"MajorUpgradeToV2", MajorUpgradeToV2}, + {"MajorUpgradeToV3", MajorUpgradeToV3}, {"E2ESimple", E2ESimple}, } diff --git a/test/e2e/major_upgrade_v2.go b/test/e2e/major_upgrade_v2.go index f595be542d..3e44eb0bc3 100644 --- a/test/e2e/major_upgrade_v2.go +++ b/test/e2e/major_upgrade_v2.go @@ -17,46 +17,59 @@ import ( ) func MajorUpgradeToV2(logger *log.Logger) error { - latestVersion, err := testnet.GetLatestVersion() - testnet.NoError("failed to get latest version", err) - - logger.Println("Running major upgrade to v2 test", "version", latestVersion) - + testName := "MajorUpgradeToV2" numNodes := 4 upgradeHeight := int64(10) + ctx, cancel := context.WithCancel(context.Background()) defer cancel() + scope := fmt.Sprintf("%s_%s", testName, time.Now().Format(timeFormat)) + kn, err := knuu.New(ctx, knuu.Options{ + Scope: scope, + ProxyEnabled: true, + }) + testnet.NoError("failed to initialize Knuu", err) + + kn.HandleStopSignal(ctx) + logger.Printf("Knuu initialized with scope %s", kn.Scope) + logger.Println("Creating testnet") - testNet, err := testnet.New("runMajorUpgradeToV2", seed, nil, "test") + testNet, err := testnet.New(kn, testnet.Options{}) testnet.NoError("failed to create testnet", err) - defer testNet.Cleanup() + defer testNet.Cleanup(ctx) + + latestVersion, err := testnet.GetLatestVersion() + testnet.NoError("failed to get latest version", err) + + logger.Printf("Running %s test with version %s", testName, latestVersion) testNet.SetConsensusParams(app.DefaultInitialConsensusParams()) - preloader, err := knuu.NewPreloader() + preloader, err := testNet.NewPreloader() testnet.NoError("failed to create preloader", err) - defer func() { _ = preloader.EmptyImages() }() - testnet.NoError("failed to add image", preloader.AddImage(testnet.DockerImageName(latestVersion))) + defer func() { _ = preloader.EmptyImages(ctx) }() + testnet.NoError("failed to add image", preloader.AddImage(ctx, testnet.DockerImageName(latestVersion))) logger.Println("Creating genesis nodes") for i := 0; i < numNodes; i++ { - err := testNet.CreateGenesisNode(latestVersion, 10000000, upgradeHeight, testnet.DefaultResources) + err := testNet.CreateGenesisNode(ctx, latestVersion, 10000000, upgradeHeight, testnet.DefaultResources, true) testnet.NoError("failed to create genesis node", err) } logger.Println("Creating txsim") - endpoints, err := testNet.RemoteGRPCEndpoints() + endpoints, err := testNet.RemoteGRPCEndpoints(ctx) testnet.NoError("failed to get remote gRPC endpoints", err) - err = testNet.CreateTxClient("txsim", testnet.TxsimVersion, 1, "100-2000", 100, testnet.DefaultResources, endpoints[0]) + upgradeSchedule := map[int64]uint64{} + err = testNet.CreateTxClient(ctx, "txsim", testnet.TxsimVersion, 1, "100-2000", 100, testnet.DefaultResources, endpoints[0], upgradeSchedule) testnet.NoError("failed to create tx client", err) logger.Println("Setting up testnet") - testnet.NoError("Failed to setup testnet", testNet.Setup()) + testnet.NoError("Failed to setup testnet", testNet.Setup(ctx)) logger.Println("Starting testnet") - testnet.NoError("Failed to start testnet", testNet.Start()) + testnet.NoError("Failed to start testnet", testNet.Start(ctx)) heightBefore := upgradeHeight - 1 for i := 0; i < numNodes; i++ { @@ -90,7 +103,7 @@ func MajorUpgradeToV2(logger *log.Logger) error { return fmt.Errorf("failed to get height: %w", err) } - if err := node.Upgrade(latestVersion); err != nil { + if err := node.Upgrade(ctx, latestVersion); err != nil { return fmt.Errorf("failed to restart node: %w", err) } diff --git a/test/e2e/major_upgrade_v3.go b/test/e2e/major_upgrade_v3.go new file mode 100644 index 0000000000..35cb79b045 --- /dev/null +++ b/test/e2e/major_upgrade_v3.go @@ -0,0 +1,190 @@ +package main + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" + "github.com/celestiaorg/celestia-app/v3/test/e2e/testnet" + "github.com/celestiaorg/knuu/pkg/knuu" + tmtypes "github.com/tendermint/tendermint/types" +) + +func MajorUpgradeToV3(logger *log.Logger) error { + testName := "MajorUpgradeToV3" + numNodes := 4 + upgradeHeightV3 := int64(40) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + scope := fmt.Sprintf("%s_%s", testName, time.Now().Format(timeFormat)) + kn, err := knuu.New(ctx, knuu.Options{ + Scope: scope, + ProxyEnabled: true, + }) + testnet.NoError("failed to initialize Knuu", err) + + kn.HandleStopSignal(ctx) + logger.Printf("Knuu initialized with scope %s", kn.Scope) + + logger.Println("Creating testnet") + testNet, err := testnet.New(kn, testnet.Options{}) + testnet.NoError("failed to create testnet", err) + + defer testNet.Cleanup(ctx) + + latestVersion, err := testnet.GetLatestVersion() + testnet.NoError("failed to get latest version", err) + + consensusParams := app.DefaultConsensusParams() + consensusParams.Version.AppVersion = v2.Version // Start the test on v2 + testNet.SetConsensusParams(consensusParams) + + preloader, err := testNet.NewPreloader() + testnet.NoError("failed to create preloader", err) + + err = preloader.AddImage(ctx, testnet.DockerImageName(latestVersion)) + testnet.NoError("failed to add image", err) + defer func() { _ = preloader.EmptyImages(ctx) }() + + logger.Println("Creating genesis nodes") + for i := 0; i < numNodes; i++ { + err := testNet.CreateGenesisNode(ctx, latestVersion, 10000000, 0, testnet.DefaultResources, true) + testnet.NoError("failed to create genesis node", err) + } + + logger.Println("Creating txsim") + endpoints, err := testNet.RemoteGRPCEndpoints(ctx) + testnet.NoError("failed to get remote gRPC endpoints", err) + upgradeSchedule := map[int64]uint64{ + upgradeHeightV3: v3.Version, + } + + err = testNet.CreateTxClient(ctx, "txsim", latestVersion, 1, "100-2000", 100, testnet.DefaultResources, endpoints[0], upgradeSchedule) + testnet.NoError("failed to create tx client", err) + + logger.Println("Setting up testnet") + testnet.NoError("Failed to setup testnet", testNet.Setup(ctx)) + logger.Println("Starting testnet") + testnet.NoError("Failed to start testnet", testNet.Start(ctx)) + + timer := time.NewTimer(20 * time.Minute) + defer timer.Stop() + ticker := time.NewTicker(3 * time.Second) + defer ticker.Stop() + + logger.Println("waiting for upgrade") + + // wait for the upgrade to complete + var upgradedHeight int64 + for _, node := range testNet.Nodes() { + client, err := node.Client() + testnet.NoError("failed to get client", err) + upgradeComplete := false + lastHeight := int64(0) + for !upgradeComplete { + select { + case <-timer.C: + return fmt.Errorf("failed to upgrade to v3, last height: %d", lastHeight) + case <-ticker.C: + resp, err := client.Header(ctx, nil) + testnet.NoError("failed to get header", err) + if resp.Header.Version.App == v3.Version { + upgradeComplete = true + if upgradedHeight == 0 { + upgradedHeight = resp.Header.Height + } + } + logger.Printf("height %v", resp.Header.Height) + lastHeight = resp.Header.Height + } + } + } + + // check if the timeouts are set correctly + rpcNode := testNet.Nodes()[0] + client, err := rpcNode.Client() + testnet.NoError("failed to get client", err) + + startHeight := upgradeHeightV3 - 5 + endHeight := upgradedHeight + 5 + + type versionDuration struct { + dur time.Duration + block *tmtypes.Block + } + + blockSummaries := make([]versionDuration, 0, endHeight-startHeight) + var prevBlockTime time.Time + + for h := startHeight; h < endHeight; h++ { + resp, err := client.Block(ctx, &h) + testnet.NoError("failed to get header", err) + blockTime := resp.Block.Time + + if h == startHeight { + if resp.Block.Version.App != v2.Version { + return fmt.Errorf("expected start height %v was app version 2", startHeight) + } + prevBlockTime = blockTime + continue + } + + blockDur := blockTime.Sub(prevBlockTime) + prevBlockTime = blockTime + blockSummaries = append(blockSummaries, versionDuration{dur: blockDur, block: resp.Block}) + } + + preciseUpgradeHeight := 0 + multipleRounds := 0 + for _, b := range blockSummaries { + + // check for the precise upgrade height and skip, as the block time + // won't match due to the off by 1 nature of the block time. + if b.block.Version.App == v3.Version && preciseUpgradeHeight == 0 { + preciseUpgradeHeight = int(b.block.Height) + continue + } + + // don't test heights with multiple rounds as the times are off and fail + // later if there are too many + if b.block.LastCommit.Round > 0 { + multipleRounds++ + continue + } + + if b.dur < appconsts.GetTimeoutCommit(b.block.Version.App) { + return fmt.Errorf( + "block was too fast for corresponding version: version %v duration %v upgrade height %v height %v", + b.block.Version.App, + b.dur, + preciseUpgradeHeight, + b.block.Height, + ) + } + + // check if the time decreased for v3 + if b.block.Version.App == v3.Version && b.dur > appconsts.GetTimeoutCommit(b.block.Version.App)+5 { + return fmt.Errorf( + "block was too slow for corresponding version: version %v duration %v upgrade height %v height %v", + b.block.Version.App, + b.dur, + preciseUpgradeHeight, + b.block.Height, + ) + } + + } + + if multipleRounds > 2 { + return fmt.Errorf("too many multiple rounds for test to be reliable: %d", multipleRounds) + } + + return nil +} diff --git a/test/e2e/minor_version_compatibility.go b/test/e2e/minor_version_compatibility.go index d0fd6314e9..bb81d5e021 100644 --- a/test/e2e/minor_version_compatibility.go +++ b/test/e2e/minor_version_compatibility.go @@ -19,6 +19,11 @@ import ( ) func MinorVersionCompatibility(logger *log.Logger) error { + const ( + testName = "MinorVersionCompatibility" + numNodes = 4 + ) + versionStr, err := getAllVersions() testnet.NoError("failed to get versions", err) versions1 := testnet.ParseVersions(versionStr).FilterMajor(v1.Version).FilterOutReleaseCandidates() @@ -28,47 +33,60 @@ func MinorVersionCompatibility(logger *log.Logger) error { if len(versions) == 0 { logger.Fatal("no versions to test") } - numNodes := 4 + seed := testnet.DefaultSeed r := rand.New(rand.NewSource(seed)) - logger.Println("Running minor version compatibility test", "versions", versions) - - testNet, err := testnet.New("runMinorVersionCompatibility", seed, nil, "test") - testnet.NoError("failed to create testnet", err) + logger.Printf("Running %s test with versions %s", testName, versions) ctx, cancel := context.WithCancel(context.Background()) defer cancel() - defer testNet.Cleanup() + identifier := fmt.Sprintf("%s_%s", testName, time.Now().Format(timeFormat)) + kn, err := knuu.New(ctx, knuu.Options{ + Scope: identifier, + ProxyEnabled: true, + }) + testnet.NoError("failed to initialize Knuu", err) + + kn.HandleStopSignal(ctx) + logger.Printf("Knuu initialized with scope %s", kn.Scope) + + testNet, err := testnet.New(kn, testnet.Options{Seed: seed}) + testnet.NoError("failed to create testnet", err) + + defer testNet.Cleanup(ctx) testNet.SetConsensusParams(app.DefaultInitialConsensusParams()) // preload all docker images - preloader, err := knuu.NewPreloader() + preloader, err := testNet.NewPreloader() testnet.NoError("failed to create preloader", err) - defer func() { _ = preloader.EmptyImages() }() + defer func() { _ = preloader.EmptyImages(ctx) }() for _, v := range versions { - testnet.NoError("failed to add image", preloader.AddImage(testnet.DockerImageName(v.String()))) + testnet.NoError("failed to add image", preloader.AddImage(ctx, testnet.DockerImageName(v.String()))) } for i := 0; i < numNodes; i++ { // each node begins with a random version within the same major version set v := versions.Random(r).String() logger.Println("Starting node", "node", i, "version", v) - testnet.NoError("failed to create genesis node", testNet.CreateGenesisNode(v, 10000000, 0, testnet.DefaultResources)) + + testnet.NoError("failed to create genesis node", + testNet.CreateGenesisNode(ctx, v, 10000000, 0, testnet.DefaultResources, false)) } logger.Println("Creating txsim") - endpoints, err := testNet.RemoteGRPCEndpoints() + endpoints, err := testNet.RemoteGRPCEndpoints(ctx) testnet.NoError("failed to get remote gRPC endpoints", err) - err = testNet.CreateTxClient("txsim", testnet.TxsimVersion, 1, "100-2000", 100, testnet.DefaultResources, endpoints[0]) + upgradeSchedule := map[int64]uint64{} + err = testNet.CreateTxClient(ctx, "txsim", testnet.TxsimVersion, 1, "100-2000", 100, testnet.DefaultResources, endpoints[0], upgradeSchedule) testnet.NoError("failed to create tx client", err) // start the testnet logger.Println("Setting up testnet") - testnet.NoError("Failed to setup testnet", testNet.Setup()) + testnet.NoError("Failed to setup testnet", testNet.Setup(ctx)) logger.Println("Starting testnet") - testnet.NoError("Failed to start testnet", testNet.Start()) + testnet.NoError("Failed to start testnet", testNet.Start(ctx)) for i := 0; i < len(versions)*2; i++ { // FIXME: skip the first node because we need them available to @@ -84,10 +102,10 @@ func MinorVersionCompatibility(logger *log.Logger) error { newVersion := versions.Random(r).String() logger.Println("Upgrading node", "node", i%numNodes+1, "version", newVersion) - testnet.NoError("failed to upgrade node", testNet.Node(i%numNodes).Upgrade(newVersion)) + testnet.NoError("failed to upgrade node", testNet.Node(i%numNodes).Upgrade(ctx, newVersion)) time.Sleep(10 * time.Second) // wait for the node to reach two more heights - testnet.NoError("failed to wait for height", waitForHeight(ctx, client, heightBefore+2, 30*time.Second)) + testnet.NoError("failed to wait for height", waitForHeight(ctx, client, heightBefore+2, time.Minute)) } heights := make([]int64, 4) diff --git a/test/e2e/simple.go b/test/e2e/simple.go index 6673129f41..8dab0278eb 100644 --- a/test/e2e/simple.go +++ b/test/e2e/simple.go @@ -9,43 +9,58 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/test/e2e/testnet" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + "github.com/celestiaorg/knuu/pkg/knuu" ) -// This test runs a simple testnet with 4 validators. It submits both MsgPayForBlobs +// E2ESimple runs a simple testnet with 4 validators. It submits both MsgPayForBlobs // and MsgSends over 30 seconds and then asserts that at least 10 transactions were // committed. func E2ESimple(logger *log.Logger) error { - latestVersion, err := testnet.GetLatestVersion() - testnet.NoError("failed to get latest version", err) + const testName = "E2ESimple" + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - logger.Println("Running simple e2e test", "version", latestVersion) + identifier := fmt.Sprintf("%s_%s", testName, time.Now().Format(timeFormat)) + kn, err := knuu.New(ctx, knuu.Options{ + Scope: identifier, + ProxyEnabled: true, + }) + testnet.NoError("failed to initialize Knuu", err) + kn.HandleStopSignal(ctx) + logger.Printf("Knuu initialized with scope %s", kn.Scope) - testNet, err := testnet.New("E2ESimple", seed, nil, "test") + testNet, err := testnet.New(kn, testnet.Options{}) testnet.NoError("failed to create testnet", err) - defer testNet.Cleanup() + defer testNet.Cleanup(ctx) + + latestVersion, err := testnet.GetLatestVersion() + testnet.NoError("failed to get latest version", err) + logger.Printf("Running %s test with version %s", testName, latestVersion) logger.Println("Creating testnet validators") - testnet.NoError("failed to create genesis nodes", testNet.CreateGenesisNodes(4, latestVersion, 10000000, 0, testnet.DefaultResources)) + testnet.NoError("failed to create genesis nodes", + testNet.CreateGenesisNodes(ctx, 4, latestVersion, 10000000, 0, testnet.DefaultResources, true)) logger.Println("Creating txsim") - endpoints, err := testNet.RemoteGRPCEndpoints() + endpoints, err := testNet.RemoteGRPCEndpoints(ctx) testnet.NoError("failed to get remote gRPC endpoints", err) - err = testNet.CreateTxClient("txsim", testnet.TxsimVersion, 10, - "100-2000", 100, testnet.DefaultResources, endpoints[0]) + upgradeSchedule := map[int64]uint64{} + err = testNet.CreateTxClient(ctx, "txsim", testnet.TxsimVersion, 10, "100-2000", 100, testnet.DefaultResources, endpoints[0], upgradeSchedule) testnet.NoError("failed to create tx client", err) logger.Println("Setting up testnets") - testnet.NoError("failed to setup testnets", testNet.Setup()) + testnet.NoError("failed to setup testnets", testNet.Setup(ctx)) logger.Println("Starting testnets") - testnet.NoError("failed to start testnets", testNet.Start()) + testnet.NoError("failed to start testnets", testNet.Start(ctx)) logger.Println("Waiting for 30 seconds to produce blocks") time.Sleep(30 * time.Second) logger.Println("Reading blockchain headers") - blockchain, err := testnode.ReadBlockchainHeaders(context.Background(), testNet.Node(0).AddressRPC()) + blockchain, err := testnode.ReadBlockchainHeaders(ctx, testNet.Node(0).AddressRPC()) testnet.NoError("failed to read blockchain headers", err) totalTxs := 0 diff --git a/test/e2e/testnet/defaults.go b/test/e2e/testnet/defaults.go index 1ea4bbb585..6c6da2cbf9 100644 --- a/test/e2e/testnet/defaults.go +++ b/test/e2e/testnet/defaults.go @@ -1,10 +1,12 @@ package testnet +import "k8s.io/apimachinery/pkg/api/resource" + var DefaultResources = Resources{ - MemoryRequest: "400Mi", - MemoryLimit: "400Mi", - CPU: "300m", - Volume: "1Gi", + MemoryRequest: resource.MustParse("400Mi"), + MemoryLimit: resource.MustParse("400Mi"), + CPU: resource.MustParse("300m"), + Volume: resource.MustParse("1Gi"), } const ( diff --git a/test/e2e/testnet/key_generator.go b/test/e2e/testnet/key_generator.go new file mode 100644 index 0000000000..cfaa39e866 --- /dev/null +++ b/test/e2e/testnet/key_generator.go @@ -0,0 +1,37 @@ +package testnet + +import ( + "io" + "math/rand" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/secp256k1" +) + +type keyGenerator struct { + random *rand.Rand +} + +func newKeyGenerator(seed int64) *keyGenerator { + return &keyGenerator{ + random: rand.New(rand.NewSource(seed)), //nolint:gosec + } +} + +func (g *keyGenerator) Generate(keyType string) crypto.PrivKey { + seed := make([]byte, ed25519.SeedSize) + + _, err := io.ReadFull(g.random, seed) + if err != nil { + panic(err) // this shouldn't happen + } + switch keyType { + case "secp256k1": + return secp256k1.GenPrivKeySecp256k1(seed) + case "", "ed25519": + return ed25519.GenPrivKeyFromSecret(seed) + default: + panic("KeyType not supported") // should not make it this far + } +} diff --git a/test/e2e/testnet/node.go b/test/e2e/testnet/node.go index addbc98066..cf96ee905d 100644 --- a/test/e2e/testnet/node.go +++ b/test/e2e/testnet/node.go @@ -2,12 +2,11 @@ package testnet import ( + "context" "fmt" "os" "path/filepath" - "github.com/celestiaorg/celestia-app/v3/test/util/genesis" - "github.com/celestiaorg/knuu/pkg/knuu" serverconfig "github.com/cosmos/cosmos-sdk/server/config" "github.com/rs/zerolog/log" "github.com/tendermint/tendermint/config" @@ -18,6 +17,13 @@ import ( "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/rpc/client/http" "github.com/tendermint/tendermint/types" + "k8s.io/apimachinery/pkg/api/resource" + + "github.com/celestiaorg/celestia-app/v3/test/util/genesis" + "github.com/celestiaorg/knuu/pkg/instance" + "github.com/celestiaorg/knuu/pkg/knuu" + "github.com/celestiaorg/knuu/pkg/sidecars/netshaper" + "github.com/celestiaorg/knuu/pkg/sidecars/observability" ) const ( @@ -41,7 +47,9 @@ type Node struct { SignerKey crypto.PrivKey NetworkKey crypto.PrivKey SelfDelegation int64 - Instance *knuu.Instance + Instance *instance.Instance + sidecars []instance.SidecarManager + netShaper *netshaper.NetShaper // a reference to the netshaper sidecar rpcProxyHost string // FIXME: This does not work currently with the reverse proxy @@ -51,8 +59,7 @@ type Node struct { // PullRoundStateTraces retrieves the round state traces from a node. // It will save them to the provided path. -func (n *Node) PullRoundStateTraces(path string) ([]trace.Event[schema.RoundState], error, -) { +func (n *Node) PullRoundStateTraces(path string) ([]trace.Event[schema.RoundState], error) { addr := n.AddressTracing() log.Info().Str("Address", addr).Msg("Pulling round state traces") @@ -65,8 +72,7 @@ func (n *Node) PullRoundStateTraces(path string) ([]trace.Event[schema.RoundStat // PullBlockSummaryTraces retrieves the block summary traces from a node. // It will save them to the provided path. -func (n *Node) PullBlockSummaryTraces(path string) ([]trace.Event[schema.BlockSummary], error, -) { +func (n *Node) PullBlockSummaryTraces(path string) ([]trace.Event[schema.BlockSummary], error) { addr := n.AddressTracing() log.Info().Str("Address", addr).Msg("Pulling block summary traces") @@ -80,96 +86,114 @@ func (n *Node) PullBlockSummaryTraces(path string) ([]trace.Event[schema.BlockSu // Resources defines the resource requirements for a Node. type Resources struct { // MemoryRequest specifies the initial memory allocation for the Node. - MemoryRequest string + MemoryRequest resource.Quantity // MemoryLimit specifies the maximum memory allocation for the Node. - MemoryLimit string + MemoryLimit resource.Quantity // CPU specifies the CPU allocation for the Node. - CPU string + CPU resource.Quantity // Volume specifies the storage volume allocation for the Node. - Volume string + Volume resource.Quantity } func NewNode( - name, version string, - startHeight, selfDelegation int64, + ctx context.Context, + name string, + version string, + startHeight int64, + selfDelegation int64, peers []string, - signerKey, networkKey crypto.PrivKey, - upgradeHeight int64, + signerKey crypto.PrivKey, + networkKey crypto.PrivKey, + upgradeHeightV2 int64, resources Resources, grafana *GrafanaInfo, + kn *knuu.Knuu, + disableBBR bool, ) (*Node, error) { - instance, err := knuu.NewInstance(name) + knInstance, err := kn.NewInstance(name) if err != nil { return nil, err } - err = instance.SetImage(DockerImageName(version)) + err = knInstance.Build().SetImage(ctx, DockerImageName(version)) if err != nil { return nil, err } - if err := instance.AddPortTCP(rpcPort); err != nil { - return nil, err - } - if err := instance.AddPortTCP(p2pPort); err != nil { - return nil, err - } - if err := instance.AddPortTCP(grpcPort); err != nil { - return nil, err - } - if err := instance.AddPortTCP(tracingPort); err != nil { - return nil, err + for _, port := range []int{rpcPort, p2pPort, grpcPort, tracingPort} { + if err := knInstance.Network().AddPortTCP(port); err != nil { + return nil, err + } } + var sidecars []instance.SidecarManager if grafana != nil { + obsySc := observability.New() + // add support for metrics - if err := instance.SetPrometheusEndpoint(prometheusPort, fmt.Sprintf("knuu-%s", knuu.Scope()), "1m"); err != nil { + if err := obsySc.SetPrometheusEndpoint(prometheusPort, fmt.Sprintf("knuu-%s", kn.Scope), "1m"); err != nil { return nil, fmt.Errorf("setting prometheus endpoint: %w", err) } - if err := instance.SetJaegerEndpoint(14250, 6831, 14268); err != nil { + if err := obsySc.SetJaegerEndpoint(14250, 6831, 14268); err != nil { return nil, fmt.Errorf("error setting jaeger endpoint: %v", err) } - if err := instance.SetOtlpExporter(grafana.Endpoint, grafana.Username, grafana.Token); err != nil { + if err := obsySc.SetOtlpExporter(grafana.Endpoint, grafana.Username, grafana.Token); err != nil { return nil, fmt.Errorf("error setting otlp exporter: %v", err) } - if err := instance.SetJaegerExporter("jaeger-collector.jaeger-cluster.svc.cluster.local:14250"); err != nil { + if err := obsySc.SetJaegerExporter("jaeger-collector.jaeger-cluster.svc.cluster.local:14250"); err != nil { return nil, fmt.Errorf("error setting jaeger exporter: %v", err) } + sidecars = append(sidecars, obsySc) } - err = instance.SetMemory(resources.MemoryRequest, resources.MemoryLimit) + err = knInstance.Resources().SetMemory(resources.MemoryRequest, resources.MemoryLimit) if err != nil { return nil, err } - err = instance.SetCPU(resources.CPU) + err = knInstance.Resources().SetCPU(resources.CPU) if err != nil { return nil, err } - err = instance.AddVolumeWithOwner(remoteRootDir, resources.Volume, 10001) + err = knInstance.Storage().AddVolumeWithOwner(remoteRootDir, resources.Volume, 10001) if err != nil { return nil, err } args := []string{"start", fmt.Sprintf("--home=%s", remoteRootDir), "--rpc.laddr=tcp://0.0.0.0:26657"} - if upgradeHeight != 0 { - args = append(args, fmt.Sprintf("--v2-upgrade-height=%d", upgradeHeight)) + if disableBBR { + args = append(args, "--force-no-bbr") + } + if upgradeHeightV2 != 0 { + args = append(args, fmt.Sprintf("--v2-upgrade-height=%d", upgradeHeightV2)) } - err = instance.SetArgs(args...) - if err != nil { + if err := knInstance.Build().SetArgs(args...); err != nil { return nil, err } return &Node{ Name: name, - Instance: instance, + Instance: knInstance, Version: version, StartHeight: startHeight, InitialPeers: peers, SignerKey: signerKey, NetworkKey: networkKey, SelfDelegation: selfDelegation, + sidecars: sidecars, }, nil } -func (n *Node) Init(genesis *types.GenesisDoc, peers []string, configOptions ...Option) error { +func (n *Node) EnableNetShaper() { + n.netShaper = netshaper.New() + n.sidecars = append(n.sidecars, n.netShaper) +} + +func (n *Node) SetLatencyAndJitter(latency, jitter int64) error { + if n.netShaper == nil { + return fmt.Errorf("netshaper is not enabled") + } + return n.netShaper.SetLatencyAndJitter(latency, jitter) +} + +func (n *Node) Init(ctx context.Context, genesis *types.GenesisDoc, peers []string, configOptions ...Option) error { if len(peers) == 0 { return fmt.Errorf("no peers provided") } @@ -190,7 +214,7 @@ func (n *Node) Init(genesis *types.GenesisDoc, peers []string, configOptions ... } // Create and write the config file - cfg, err := MakeConfig(n, configOptions...) + cfg, err := MakeConfig(ctx, n, configOptions...) if err != nil { return fmt.Errorf("making config: %w", err) } @@ -235,12 +259,17 @@ func (n *Node) Init(genesis *types.GenesisDoc, peers []string, configOptions ... return fmt.Errorf("writing address book: %w", err) } - err = n.Instance.Commit() - if err != nil { + if err := n.Instance.Build().Commit(ctx); err != nil { return fmt.Errorf("committing instance: %w", err) } - if err = n.Instance.AddFolder(nodeDir, remoteRootDir, "10001:10001"); err != nil { + for _, sc := range n.sidecars { + if err := n.Instance.Sidecars().Add(ctx, sc); err != nil { + return fmt.Errorf("adding sidecar: %w", err) + } + } + + if err = n.Instance.Storage().AddFolder(nodeDir, remoteRootDir, "10001:10001"); err != nil { return fmt.Errorf("copying over node %s directory: %w", n.Name, err) } return nil @@ -249,8 +278,8 @@ func (n *Node) Init(genesis *types.GenesisDoc, peers []string, configOptions ... // AddressP2P returns a P2P endpoint address for the node. This is used for // populating the address book. This will look something like: // 3314051954fc072a0678ec0cbac690ad8676ab98@61.108.66.220:26656 -func (n Node) AddressP2P(withID bool) string { - ip, err := n.Instance.GetIP() +func (n Node) AddressP2P(ctx context.Context, withID bool) string { + ip, err := n.Instance.Network().GetIP(ctx) if err != nil { panic(err) } @@ -275,8 +304,8 @@ func (n Node) AddressRPC() string { // } // RemoteAddressGRPC retrieves the gRPC endpoint address of a node within the cluster. -func (n Node) RemoteAddressGRPC() (string, error) { - ip, err := n.Instance.GetIP() +func (n Node) RemoteAddressGRPC(ctx context.Context) (string, error) { + ip, err := n.Instance.Network().GetIP(ctx) if err != nil { return "", err } @@ -284,8 +313,8 @@ func (n Node) RemoteAddressGRPC() (string, error) { } // RemoteAddressRPC retrieves the RPC endpoint address of a node within the cluster. -func (n Node) RemoteAddressRPC() (string, error) { - ip, err := n.Instance.GetIP() +func (n Node) RemoteAddressRPC(ctx context.Context) (string, error) { + ip, err := n.Instance.Network().GetIP(ctx) if err != nil { return "", err } @@ -296,8 +325,8 @@ func (n Node) AddressTracing() string { return n.traceProxyHost } -func (n Node) RemoteAddressTracing() (string, error) { - ip, err := n.Instance.GetIP() +func (n Node) RemoteAddressTracing(ctx context.Context) (string, error) { + ip, err := n.Instance.Network().GetIP(ctx) if err != nil { return "", err } @@ -313,24 +342,25 @@ func (n Node) Client() (*http.HTTP, error) { return http.New(n.AddressRPC(), "/websocket") } -func (n *Node) Start() error { - if err := n.StartAsync(); err != nil { +func (n *Node) Start(ctx context.Context) error { + if err := n.StartAsync(ctx); err != nil { return err } - return n.WaitUntilStartedAndForwardPorts() + return n.WaitUntilStartedAndCreateProxy(ctx) } -func (n *Node) StartAsync() error { - return n.Instance.StartAsync() +func (n *Node) StartAsync(ctx context.Context) error { + return n.Instance.Execution().StartAsync(ctx) } -func (n *Node) WaitUntilStartedAndForwardPorts() error { - if err := n.Instance.WaitInstanceIsRunning(); err != nil { +func (n *Node) WaitUntilStartedAndCreateProxy(ctx context.Context) error { + if err := n.Instance.Execution().WaitInstanceIsRunning(ctx); err != nil { return err } - err, rpcProxyHost := n.Instance.AddHost(rpcPort) + // TODO: It is recommended to use AddHostWithReadyCheck for the proxy + rpcProxyHost, err := n.Instance.Network().AddHost(ctx, rpcPort) if err != nil { return err } @@ -343,7 +373,8 @@ func (n *Node) WaitUntilStartedAndForwardPorts() error { // } // n.grpcProxyHost = grpcProxyHost - err, traceProxyHost := n.Instance.AddHost(tracingPort) + // TODO: It is recommended to use AddHostWithReadyCheck for the proxy + traceProxyHost, err := n.Instance.Network().AddHost(ctx, tracingPort) if err != nil { return err } @@ -364,12 +395,22 @@ func (n *Node) GenesisValidator() genesis.Validator { } } -func (n *Node) Upgrade(version string) error { - if err := n.Instance.SetImageInstant(DockerImageName(version)); err != nil { +func (n *Node) Upgrade(ctx context.Context, version string) error { + if err := n.Instance.Execution().Stop(ctx); err != nil { + return err + } + + if err := n.Instance.Execution().SetImage(ctx, DockerImageName(version)); err != nil { return err } - return n.Instance.WaitInstanceIsRunning() + // New set of args can be set here + // Or/and the start command can also be set here + + if err := n.Instance.Build().Commit(ctx); err != nil { + return err + } + return n.Instance.Execution().Start(ctx) } func DockerImageName(version string) string { diff --git a/test/e2e/testnet/setup.go b/test/e2e/testnet/setup.go index 620b46cb66..d7db215c34 100644 --- a/test/e2e/testnet/setup.go +++ b/test/e2e/testnet/setup.go @@ -1,6 +1,7 @@ package testnet import ( + "context" "fmt" "strings" "time" @@ -12,14 +13,14 @@ import ( "github.com/tendermint/tendermint/p2p/pex" ) -func MakeConfig(node *Node, opts ...Option) (*config.Config, error) { +func MakeConfig(ctx context.Context, node *Node, opts ...Option) (*config.Config, error) { cfg := app.DefaultConsensusConfig() cfg.TxIndex.Indexer = "kv" cfg.Consensus.TimeoutPropose = config.DefaultConsensusConfig().TimeoutPropose cfg.Consensus.TimeoutCommit = config.DefaultConsensusConfig().TimeoutCommit cfg.Moniker = node.Name cfg.RPC.ListenAddress = "tcp://0.0.0.0:26657" - cfg.P2P.ExternalAddress = fmt.Sprintf("tcp://%v", node.AddressP2P(false)) + cfg.P2P.ExternalAddress = fmt.Sprintf("tcp://%v", node.AddressP2P(ctx, false)) cfg.P2P.PersistentPeers = strings.Join(node.InitialPeers, ",") cfg.Instrumentation.Prometheus = true diff --git a/test/e2e/testnet/testnet.go b/test/e2e/testnet/testnet.go index 4b3beebe99..7cc74fb011 100644 --- a/test/e2e/testnet/testnet.go +++ b/test/e2e/testnet/testnet.go @@ -13,12 +13,18 @@ import ( "github.com/celestiaorg/celestia-app/v3/app/encoding" "github.com/celestiaorg/celestia-app/v3/test/util/genesis" "github.com/celestiaorg/knuu/pkg/knuu" + "github.com/celestiaorg/knuu/pkg/preloader" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/rs/zerolog/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) +const ( + DefaultSeed int64 = 42 + DefaultChainID = "test-chain-id" +) + type Testnet struct { seed int64 nodes []*Node @@ -26,26 +32,37 @@ type Testnet struct { keygen *keyGenerator grafana *GrafanaInfo txClients []*TxSim + knuu *knuu.Knuu } -func New(name string, seed int64, grafana *GrafanaInfo, chainID string, - genesisModifiers ...genesis.Modifier) ( - *Testnet, error, -) { - identifier := fmt.Sprintf("%s_%s", name, time.Now().Format("20060102_150405")) - if err := knuu.InitializeWithScope(identifier); err != nil { - return nil, err - } +type Options struct { + Seed int64 + Grafana *GrafanaInfo + ChainID string + GenesisModifiers []genesis.Modifier +} +func New(knuu *knuu.Knuu, opts Options) (*Testnet, error) { + opts.setDefaults() return &Testnet{ - seed: seed, + seed: opts.Seed, nodes: make([]*Node, 0), - genesis: genesis.NewDefaultGenesis().WithChainID(chainID).WithModifiers(genesisModifiers...), - keygen: newKeyGenerator(seed), - grafana: grafana, + genesis: genesis.NewDefaultGenesis().WithChainID(opts.ChainID).WithModifiers(opts.GenesisModifiers...), + keygen: newKeyGenerator(opts.Seed), + grafana: opts.Grafana, + knuu: knuu, }, nil } +func (t *Testnet) NewPreloader() (*preloader.Preloader, error) { + if t.knuu == nil { + return nil, errors.New("knuu is not initialized") + } + // Since there is one dedicated knuu object for the testnet, each one has its own namespace, and + // there is one preloader per testnet, can use the same preloader name for all nodes + return preloader.New("preloader", t.knuu.SystemDependencies) +} + func (t *Testnet) SetConsensusParams(params *tmproto.ConsensusParams) { t.genesis.WithConsensusParams(params) } @@ -54,12 +71,10 @@ func (t *Testnet) SetConsensusMaxBlockSize(size int64) { t.genesis.ConsensusParams.Block.MaxBytes = size } -func (t *Testnet) CreateGenesisNode(version string, selfDelegation, upgradeHeight int64, resources Resources) error { +func (t *Testnet) CreateGenesisNode(ctx context.Context, version string, selfDelegation, upgradeHeightV2 int64, resources Resources, disableBBR bool) error { signerKey := t.keygen.Generate(ed25519Type) networkKey := t.keygen.Generate(ed25519Type) - node, err := NewNode(fmt.Sprintf("val%d", len(t.nodes)), version, 0, - selfDelegation, nil, signerKey, networkKey, upgradeHeight, resources, - t.grafana) + node, err := NewNode(ctx, fmt.Sprintf("val%d", len(t.nodes)), version, 0, selfDelegation, nil, signerKey, networkKey, upgradeHeightV2, resources, t.grafana, t.knuu, disableBBR) if err != nil { return err } @@ -70,26 +85,27 @@ func (t *Testnet) CreateGenesisNode(version string, selfDelegation, upgradeHeigh return nil } -func (t *Testnet) CreateGenesisNodes(num int, version string, selfDelegation, upgradeHeight int64, resources Resources) error { +func (t *Testnet) CreateGenesisNodes(ctx context.Context, num int, version string, selfDelegation, upgradeHeightV2 int64, resources Resources, disableBBR bool) error { for i := 0; i < num; i++ { - if err := t.CreateGenesisNode(version, selfDelegation, upgradeHeight, resources); err != nil { + if err := t.CreateGenesisNode(ctx, version, selfDelegation, upgradeHeightV2, resources, disableBBR); err != nil { return err } } return nil } -func (t *Testnet) CreateTxClients(version string, +func (t *Testnet) CreateTxClients(ctx context.Context, + version string, sequences int, blobRange string, blobPerSequence int, resources Resources, grpcEndpoints []string, + upgradeSchedule map[int64]uint64, ) error { for i, grpcEndpoint := range grpcEndpoints { name := fmt.Sprintf("txsim%d", i) - err := t.CreateTxClient(name, version, sequences, - blobRange, blobPerSequence, resources, grpcEndpoint) + err := t.CreateTxClient(ctx, name, version, sequences, blobRange, blobPerSequence, resources, grpcEndpoint, upgradeSchedule) if err != nil { log.Err(err).Str("name", name). Str("grpc endpoint", grpcEndpoint). @@ -104,46 +120,77 @@ func (t *Testnet) CreateTxClients(version string, return nil } -// CreateTxClient creates a txsim node and sets it up -// name: name of the txsim knuu instance -// version: version of the txsim docker image to be pulled from the registry -// specified by txsimDockerSrcURL -// seed: seed for the txsim -// sequences: number of sequences to be run by the txsim -// blobRange: range of blob sizes to be used by the txsim in bytes -// pollTime: time in seconds between each sequence -// resources: resources to be allocated to the txsim -// grpcEndpoint: grpc endpoint of the node to which the txsim will connect and send transactions -func (t *Testnet) CreateTxClient(name, +// CreateTxClient creates a txsim node and sets it up. +// +// Parameters: +// ctx: Context for managing the lifecycle. +// name: Name of the txsim knuu instance. +// version: Version of the txsim Docker image to pull. +// blobSequences: Number of blob sequences to run by the txsim. +// blobRange: Range of blob sizes in bytes used by the txsim. +// blobPerSequence: Number of blobs per sequence. +// resources: Resources allocated to the txsim. +// grpcEndpoint: gRPC endpoint of the node for transaction submission. +// upgradeSchedule: Map from height to version for scheduled upgrades (v3 and onwards). +func (t *Testnet) CreateTxClient( + ctx context.Context, + name string, version string, - sequences int, + blobSequences int, blobRange string, blobPerSequence int, resources Resources, grpcEndpoint string, + upgradeSchedule map[int64]uint64, ) error { - // create an account, and store it in a temp directory and add the account as genesis account to - // the testnet txsimKeyringDir := filepath.Join(os.TempDir(), name) - log.Info(). - Str("name", name). - Str("directory", txsimKeyringDir). - Msg("txsim keyring directory created") - _, err := t.CreateAccount(name, 1e16, txsimKeyringDir) + defer os.RemoveAll(txsimKeyringDir) + + config := encoding.MakeConfig(app.ModuleEncodingRegisters...).Codec + txsimKeyring, err := keyring.New(app.Name, keyring.BackendTest, txsimKeyringDir, nil, config) if err != nil { - return err + return fmt.Errorf("failed to create keyring: %w", err) + } + + key, _, err := txsimKeyring.NewMnemonic(name, keyring.English, "", "", hd.Secp256k1) + if err != nil { + return fmt.Errorf("failed to create mnemonic: %w", err) + } + pk, err := key.GetPubKey() + if err != nil { + return fmt.Errorf("failed to get public key: %w", err) + } + err = t.genesis.AddAccount(genesis.Account{ + PubKey: pk, + Balance: 1e16, + Name: name, + }) + if err != nil { + return fmt.Errorf("failed to add account to genesis: %w", err) + } + + // Copy the keys from the genesis keyring to the txsim keyring so that txsim + // can submit MsgSignalVersion on behalf of the validators. + for _, node := range t.Nodes() { + armor, err := t.Genesis().Keyring().ExportPrivKeyArmor(node.Name, "") + if err != nil { + return fmt.Errorf("failed to export key: %w", err) + } + err = txsimKeyring.ImportPrivKey(node.Name, armor, "") + if err != nil { + return fmt.Errorf("failed to import key: %w", err) + } } - // Create a txsim node using the key stored in the txsimKeyringDir - txsim, err := CreateTxClient(name, version, grpcEndpoint, t.seed, - sequences, blobRange, blobPerSequence, 1, resources, txsimRootDir) + txsim, err := CreateTxClient(ctx, name, version, grpcEndpoint, t.seed, blobSequences, blobRange, blobPerSequence, 1, resources, txsimKeyringDir, t.knuu, upgradeSchedule) if err != nil { log.Err(err). Str("name", name). Msg("error creating txsim") return err } - err = txsim.Instance.Commit() + + err = txsim.Instance.Build().Commit(ctx) if err != nil { log.Err(err). Str("name", name). @@ -152,7 +199,7 @@ func (t *Testnet) CreateTxClient(name, } // copy over the keyring directory to the txsim instance - err = txsim.Instance.AddFolder(txsimKeyringDir, txsimRootDir, "10001:10001") + err = txsim.Instance.Storage().AddFolder(txsimKeyringDir, txsimKeyringDir, "10001:10001") if err != nil { log.Err(err). Str("directory", txsimKeyringDir). @@ -165,9 +212,9 @@ func (t *Testnet) CreateTxClient(name, return nil } -func (t *Testnet) StartTxClients() error { +func (t *Testnet) StartTxClients(ctx context.Context) error { for _, txsim := range t.txClients { - err := txsim.Instance.StartWithoutWait() + err := txsim.Instance.Execution().StartAsync(ctx) if err != nil { log.Err(err). Str("name", txsim.Name). @@ -180,7 +227,7 @@ func (t *Testnet) StartTxClients() error { } // wait for txsims to start for _, txsim := range t.txClients { - err := txsim.Instance.WaitInstanceIsRunning() + err := txsim.Instance.Execution().WaitInstanceIsRunning(ctx) if err != nil { return fmt.Errorf("txsim %s failed to run: %w", txsim.Name, err) } @@ -201,8 +248,7 @@ func (t *Testnet) CreateAccount(name string, tokens int64, txsimKeyringDir strin if txsimKeyringDir == "" { kr = keyring.NewInMemory(cdc) } else { // create a keyring with the specified directory - kr, err = keyring.New(app.Name, keyring.BackendTest, - txsimKeyringDir, nil, cdc) + kr, err = keyring.New(app.Name, keyring.BackendTest, txsimKeyringDir, nil, cdc) if err != nil { return nil, err } @@ -232,12 +278,10 @@ func (t *Testnet) CreateAccount(name string, tokens int64, txsimKeyringDir strin return kr, nil } -func (t *Testnet) CreateNode(version string, startHeight, upgradeHeight int64, resources Resources) error { +func (t *Testnet) CreateNode(ctx context.Context, version string, startHeight, upgradeHeight int64, resources Resources, disableBBR bool) error { signerKey := t.keygen.Generate(ed25519Type) networkKey := t.keygen.Generate(ed25519Type) - node, err := NewNode(fmt.Sprintf("val%d", len(t.nodes)), version, - startHeight, 0, nil, signerKey, networkKey, upgradeHeight, resources, - t.grafana) + node, err := NewNode(ctx, fmt.Sprintf("val%d", len(t.nodes)), version, startHeight, 0, nil, signerKey, networkKey, upgradeHeight, resources, t.grafana, t.knuu, disableBBR) if err != nil { return err } @@ -245,7 +289,7 @@ func (t *Testnet) CreateNode(version string, startHeight, upgradeHeight int64, r return nil } -func (t *Testnet) Setup(configOpts ...Option) error { +func (t *Testnet) Setup(ctx context.Context, configOpts ...Option) error { genesis, err := t.genesis.Export() if err != nil { return err @@ -257,11 +301,11 @@ func (t *Testnet) Setup(configOpts ...Option) error { peers := make([]string, 0, len(t.nodes)-1) for _, peer := range t.nodes { if peer.Name != node.Name { - peers = append(peers, peer.AddressP2P(true)) + peers = append(peers, peer.AddressP2P(ctx, true)) } } - err := node.Init(genesis, peers, configOpts...) + err := node.Init(ctx, genesis, peers, configOpts...) if err != nil { return err } @@ -289,10 +333,10 @@ func (t *Testnet) RPCEndpoints() []string { // RemoteGRPCEndpoints retrieves the gRPC endpoint addresses of the // testnet's validator nodes. -func (t *Testnet) RemoteGRPCEndpoints() ([]string, error) { +func (t *Testnet) RemoteGRPCEndpoints(ctx context.Context) ([]string, error) { grpcEndpoints := make([]string, len(t.nodes)) for idx, node := range t.nodes { - grpcEP, err := node.RemoteAddressGRPC() + grpcEP, err := node.RemoteAddressGRPC(ctx) if err != nil { return nil, err } @@ -311,10 +355,10 @@ func (t *Testnet) GetGenesisValidators() []genesis.Validator { // RemoteRPCEndpoints retrieves the RPC endpoint addresses of the testnet's // validator nodes. -func (t *Testnet) RemoteRPCEndpoints() ([]string, error) { +func (t *Testnet) RemoteRPCEndpoints(ctx context.Context) ([]string, error) { rpcEndpoints := make([]string, len(t.nodes)) for idx, node := range t.nodes { - grpcEP, err := node.RemoteAddressRPC() + grpcEP, err := node.RemoteAddressRPC(ctx) if err != nil { return nil, err } @@ -325,13 +369,14 @@ func (t *Testnet) RemoteRPCEndpoints() ([]string, error) { // WaitToSync waits for the started nodes to sync with the network and move // past the genesis block. -func (t *Testnet) WaitToSync() error { +func (t *Testnet) WaitToSync(ctx context.Context) error { genesisNodes := make([]*Node, 0) for _, node := range t.nodes { if node.StartHeight == 0 { genesisNodes = append(genesisNodes, node) } } + for _, node := range genesisNodes { log.Info().Str("name", node.Name).Msg( "waiting for node to sync") @@ -340,7 +385,7 @@ func (t *Testnet) WaitToSync() error { return fmt.Errorf("failed to initialize client for node %s: %w", node.Name, err) } for i := 0; i < 10; i++ { - resp, err := client.Status(context.Background()) + resp, err := client.Status(ctx) if err == nil { if resp.SyncInfo.LatestBlockHeight > 0 { log.Info().Int("attempts", i).Str("name", node.Name).Msg( @@ -361,68 +406,57 @@ func (t *Testnet) WaitToSync() error { return nil } -// StartNodes starts the testnet nodes and forwards the ports. +// StartNodes starts the testnet nodes and setup proxies. // It does not wait for the nodes to produce blocks. // For that, use WaitToSync. -func (t *Testnet) StartNodes() error { +func (t *Testnet) StartNodes(ctx context.Context) error { genesisNodes := make([]*Node, 0) + // identify genesis nodes for _, node := range t.nodes { if node.StartHeight == 0 { genesisNodes = append(genesisNodes, node) } - } - // start genesis nodes asynchronously - for _, node := range genesisNodes { - err := node.StartAsync() + + err := node.StartAsync(ctx) if err != nil { return fmt.Errorf("node %s failed to start: %w", node.Name, err) } } - log.Info().Msg("forwarding ports for genesis nodes") + + log.Info().Msg("create endpoint proxies for genesis nodes") // wait for instances to be running for _, node := range genesisNodes { - err := node.WaitUntilStartedAndForwardPorts() + err := node.WaitUntilStartedAndCreateProxy(ctx) if err != nil { + log.Err(err).Str("name", node.Name).Str("version", + node.Version).Msg("failed to start and forward ports") return fmt.Errorf("node %s failed to start: %w", node.Name, err) } + log.Info().Str("name", node.Name).Str("version", + node.Version).Msg("started and ports forwarded") } return nil } -func (t *Testnet) Start() error { - // start nodes and forward ports - err := t.StartNodes() +func (t *Testnet) Start(ctx context.Context) error { + // start nodes and setup proxies + err := t.StartNodes(ctx) if err != nil { return err } // wait for nodes to sync log.Info().Msg("waiting for genesis nodes to sync") - err = t.WaitToSync() + err = t.WaitToSync(ctx) if err != nil { return err } - return t.StartTxClients() + return t.StartTxClients(ctx) } -func (t *Testnet) Cleanup() { - // cleanup txsim - for _, txsim := range t.txClients { - err := txsim.Instance.Destroy() - if err != nil { - log.Err(err). - Str("name", txsim.Name). - Msg("txsim failed to cleanup") - } - } - // cleanup nodes - for _, node := range t.nodes { - err := node.Instance.Destroy() - if err != nil { - log.Err(err). - Str("name", node.Name). - Msg("node failed to cleanup") - } +func (t *Testnet) Cleanup(ctx context.Context) { + if err := t.knuu.CleanUp(ctx); err != nil { + log.Err(err).Msg("failed to cleanup knuu") } } @@ -433,3 +467,16 @@ func (t *Testnet) Node(i int) *Node { func (t *Testnet) Nodes() []*Node { return t.nodes } + +func (t *Testnet) Genesis() *genesis.Genesis { + return t.genesis +} + +func (o *Options) setDefaults() { + if o.ChainID == "" { + o.ChainID = DefaultChainID + } + if o.Seed == 0 { + o.Seed = DefaultSeed + } +} diff --git a/test/e2e/testnet/txsimNode.go b/test/e2e/testnet/txsimNode.go index 994d87a831..c63062598b 100644 --- a/test/e2e/testnet/txsimNode.go +++ b/test/e2e/testnet/txsimNode.go @@ -2,8 +2,12 @@ package testnet import ( + "context" "fmt" + "strings" + "github.com/celestiaorg/go-square/v2/share" + "github.com/celestiaorg/knuu/pkg/instance" "github.com/celestiaorg/knuu/pkg/knuu" "github.com/rs/zerolog/log" ) @@ -18,19 +22,24 @@ func txsimDockerImageName(version string) string { type TxSim struct { Name string - Instance *knuu.Instance + Instance *instance.Instance } +// CreateTxClient returns a new TxSim instance. func CreateTxClient( - name, version string, + ctx context.Context, + name string, + version string, endpoint string, seed int64, - sequences int, + blobSequences int, blobRange string, blobsPerSeq int, pollTime int, resources Resources, volumePath string, + knuu *knuu.Knuu, + upgradeSchedule map[int64]uint64, ) (*TxSim, error) { instance, err := knuu.NewInstance(name) if err != nil { @@ -41,7 +50,7 @@ func CreateTxClient( Str("name", name). Str("image", image). Msg("setting image for tx client") - err = instance.SetImage(image) + err = instance.Build().SetImage(ctx, image) if err != nil { log.Err(err). Str("name", name). @@ -49,35 +58,56 @@ func CreateTxClient( Msg("failed to set image for tx client") return nil, err } - err = instance.SetMemory(resources.MemoryRequest, resources.MemoryLimit) + err = instance.Resources().SetMemory(resources.MemoryRequest, resources.MemoryLimit) if err != nil { return nil, err } - err = instance.SetCPU(resources.CPU) + err = instance.Resources().SetCPU(resources.CPU) if err != nil { return nil, err } - err = instance.AddVolumeWithOwner(volumePath, resources.Volume, 10001) + err = instance.Storage().AddVolumeWithOwner(volumePath, resources.Volume, 10001) if err != nil { return nil, err } args := []string{ - fmt.Sprintf("-k %d", 0), - fmt.Sprintf("-g %s", endpoint), - fmt.Sprintf("-t %ds", pollTime), - fmt.Sprintf("-b %d ", sequences), - fmt.Sprintf("-d %d ", seed), - fmt.Sprintf("-a %d ", blobsPerSeq), - fmt.Sprintf("-s %s ", blobRange), + fmt.Sprintf("--key-path %s", volumePath), + fmt.Sprintf("--grpc-endpoint %s", endpoint), + fmt.Sprintf("--poll-time %ds", pollTime), + fmt.Sprintf("--seed %d", seed), + fmt.Sprintf("--blob %d", blobSequences), + fmt.Sprintf("--blob-amounts %d", blobsPerSeq), + fmt.Sprintf("--blob-sizes %s", blobRange), + fmt.Sprintf("--blob-share-version %d", share.ShareVersionZero), } - err = instance.SetArgs(args...) - if err != nil { + if len(upgradeSchedule) > 0 { + args = append(args, fmt.Sprintf("--upgrade-schedule %s", stringifyUpgradeSchedule(upgradeSchedule))) + } + + if err := instance.Build().SetArgs(args...); err != nil { return nil, err } + log.Info(). + Str("name", name). + Str("image", image). + Str("args", strings.Join(args, " ")). + Msg("created tx client") + return &TxSim{ Name: name, Instance: instance, }, nil } + +func stringifyUpgradeSchedule(schedule map[int64]uint64) string { + if schedule == nil { + return "" + } + scheduleParts := make([]string, 0, len(schedule)) + for height, version := range schedule { + scheduleParts = append(scheduleParts, fmt.Sprintf("%d:%d", height, version)) + } + return strings.Join(scheduleParts, ",") +} diff --git a/test/e2e/testnet/util.go b/test/e2e/testnet/util.go index 0d89494858..edf89aceda 100644 --- a/test/e2e/testnet/util.go +++ b/test/e2e/testnet/util.go @@ -1,43 +1,11 @@ package testnet import ( - "io" - "math/rand" "os" "github.com/rs/zerolog/log" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/crypto/secp256k1" ) -type keyGenerator struct { - random *rand.Rand -} - -func newKeyGenerator(seed int64) *keyGenerator { - return &keyGenerator{ - random: rand.New(rand.NewSource(seed)), //nolint:gosec - } -} - -func (g *keyGenerator) Generate(keyType string) crypto.PrivKey { - seed := make([]byte, ed25519.SeedSize) - - _, err := io.ReadFull(g.random, seed) - if err != nil { - panic(err) // this shouldn't happen - } - switch keyType { - case "secp256k1": - return secp256k1.GenPrivKeySecp256k1(seed) - case "", "ed25519": - return ed25519.GenPrivKeyFromSecret(seed) - default: - panic("KeyType not supported") // should not make it this far - } -} - type GrafanaInfo struct { Endpoint string Username string diff --git a/test/interchain/go.mod b/test/interchain/go.mod index 8bdd1bf22d..2b6b52b585 100644 --- a/test/interchain/go.mod +++ b/test/interchain/go.mod @@ -1,6 +1,6 @@ module github.com/celestiaorg/celestia-app/test/interchain -go 1.22.6 +go 1.23.1 require ( cosmossdk.io/math v1.3.0 @@ -33,7 +33,7 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/celestiaorg/nmt v0.21.0 // indirect + github.com/celestiaorg/nmt v0.22.0 // indirect github.com/centrifuge/go-substrate-rpc-client/v4 v4.0.10 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -229,5 +229,5 @@ replace ( github.com/docker/docker => github.com/docker/docker v24.0.1+incompatible github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.38.0-tm-v0.34.29 + github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.40.0-tm-v0.34.29 ) diff --git a/test/interchain/go.sum b/test/interchain/go.sum index 3f306fe454..c24352cb35 100644 --- a/test/interchain/go.sum +++ b/test/interchain/go.sum @@ -249,12 +249,12 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOF github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/celestiaorg/celestia-core v1.38.0-tm-v0.34.29 h1:HwbA4OegRvXX0aNchBA7Cmu+oIxnH7xRcOhISuDP0ak= -github.com/celestiaorg/celestia-core v1.38.0-tm-v0.34.29/go.mod h1:MyElURdWAOJkOp84WZnfEUJ+OLvTwOOHG2lbK9E8XRI= +github.com/celestiaorg/celestia-core v1.40.0-tm-v0.34.29 h1:J79TAjizxwIvm7/k+WI3PPH1aFj4AjOSjajoq5UzAwI= +github.com/celestiaorg/celestia-core v1.40.0-tm-v0.34.29/go.mod h1:5jJ5magtH7gQOwSYfS/m5fliIS7irKunLV7kLNaD8o0= github.com/celestiaorg/cosmos-sdk v1.24.0-sdk-v0.46.16 h1:AlBZS4WykzrwfcNbKD+yQQM1RTMz7lYDC1NS7ClAidM= github.com/celestiaorg/cosmos-sdk v1.24.0-sdk-v0.46.16/go.mod h1:Bpl1LSWiDpQumgOhhMTZBMopqa0j7fRasIhvTZB44P0= -github.com/celestiaorg/nmt v0.21.0 h1:81MBqxNn3orByoiCtdNVjwi5WsLgMkzHwP02ZMhTBHM= -github.com/celestiaorg/nmt v0.21.0/go.mod h1:ia/EpCk0enD5yO5frcxoNoFToz2Ghtk2i+blmCRjIY8= +github.com/celestiaorg/nmt v0.22.0 h1:AGtfmBiVgreR1KkIV5R7XFNeMp/H4IUDLlBbLjZZ3zk= +github.com/celestiaorg/nmt v0.22.0/go.mod h1:ia/EpCk0enD5yO5frcxoNoFToz2Ghtk2i+blmCRjIY8= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= diff --git a/test/txsim/account.go b/test/txsim/account.go index e01264c68d..9796f60b04 100644 --- a/test/txsim/account.go +++ b/test/txsim/account.go @@ -240,7 +240,7 @@ func (am *AccountManager) Submit(ctx context.Context, op Operation) error { } var ( - res *types.TxResponse + res *user.TxResponse err error ) if len(op.Blobs) > 0 { diff --git a/test/txsim/run_test.go b/test/txsim/run_test.go index 46e4523710..d4cbdf22ba 100644 --- a/test/txsim/run_test.go +++ b/test/txsim/run_test.go @@ -12,12 +12,17 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" "github.com/celestiaorg/celestia-app/v3/test/txsim" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" "github.com/cosmos/cosmos-sdk/crypto/keyring" sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" blob "github.com/celestiaorg/celestia-app/v3/x/blob/types" + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" bank "github.com/cosmos/cosmos-sdk/x/bank/types" distribution "github.com/cosmos/cosmos-sdk/x/distribution/types" staking "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -152,3 +157,52 @@ func Setup(t testing.TB) (keyring.Keyring, string, string) { return cctx.Keyring, rpcAddr, grpcAddr } + +func TestTxSimUpgrade(t *testing.T) { + if testing.Short() { + t.Skip("skipping TestTxSimUpgrade in short mode.") + } + cp := app.DefaultConsensusParams() + cp.Version.AppVersion = v2.Version + cfg := testnode.DefaultConfig(). + WithTimeoutCommit(300 * time.Millisecond). + WithConsensusParams(cp). + WithFundedAccounts("txsim-master") + cctx, _, grpcAddr := testnode.NewNetwork(t, cfg) + + require.NoError(t, cctx.WaitForNextBlock()) + + // updrade to v3 at height 20 + sequences := []txsim.Sequence{ + txsim.NewUpgradeSequence(v3.Version, 20), + } + + opts := txsim.DefaultOptions(). + // SuppressLogs(). + WithPollTime(time.Millisecond * 100) + + err := txsim.Run( + cctx.GoContext(), + grpcAddr, + cctx.Keyring, + encoding.MakeConfig(app.ModuleEncodingRegisters...), + opts, + sequences..., + ) + require.NoError(t, err) + + conn, err := grpc.NewClient(grpcAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) + require.NoError(t, err) + defer conn.Close() + + querier := signaltypes.NewQueryClient(conn) + + // We can't check that the upgrade was successful because the upgrade height is thousands of blocks away + // and even at 300 millisecond block times, it would take too long. Instead we just want to assert + // that the upgrade is ready to be performed + require.Eventually(t, func() bool { + upgradePlan, err := querier.GetUpgrade(cctx.GoContext(), &signaltypes.QueryGetUpgradeRequest{}) + require.NoError(t, err) + return upgradePlan.Upgrade != nil && upgradePlan.Upgrade.AppVersion == v3.Version + }, time.Second*20, time.Millisecond*100) +} diff --git a/test/txsim/upgrade.go b/test/txsim/upgrade.go new file mode 100644 index 0000000000..e2015b98d1 --- /dev/null +++ b/test/txsim/upgrade.go @@ -0,0 +1,90 @@ +package txsim + +import ( + "context" + "errors" + "math/rand" + + signaltypes "github.com/celestiaorg/celestia-app/v3/x/signal/types" + "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/gogo/protobuf/grpc" +) + +var _ Sequence = &UpgradeSequence{} + +const fundsForUpgrade = 100_000 + +// UpgradeSequence simulates a sequence of validators submitting +// MsgSignalVersions for a particular version and then eventually a +// MsgTryUpgrade. +type UpgradeSequence struct { + // signalled is a map from validator address to a boolean indicating if they have signalled. + signalled map[string]bool + // height is the first height at which the upgrade sequence is run. + height int64 + // version is the version that validators are signalling for. + version uint64 + // account is the address of the account that submits the MsgTryUpgrade. + account types.AccAddress + // hasUpgraded is true if the MsgTryUpgrade has been submitted. + hasUpgraded bool +} + +func NewUpgradeSequence(version uint64, height int64) *UpgradeSequence { + return &UpgradeSequence{version: version, height: height, signalled: make(map[string]bool)} +} + +func (s *UpgradeSequence) Clone(_ int) []Sequence { + panic("cloning not supported for upgrade sequence. Only a single sequence is needed") +} + +// this is a no-op for the upgrade sequence +func (s *UpgradeSequence) Init(_ context.Context, _ grpc.ClientConn, allocateAccounts AccountAllocator, _ *rand.Rand, _ bool) { + s.account = allocateAccounts(1, fundsForUpgrade)[0] +} + +func (s *UpgradeSequence) Next(ctx context.Context, querier grpc.ClientConn, _ *rand.Rand) (Operation, error) { + if s.hasUpgraded { + return Operation{}, ErrEndOfSequence + } + + stakingQuerier := stakingtypes.NewQueryClient(querier) + validatorsResp, err := stakingQuerier.Validators(ctx, &stakingtypes.QueryValidatorsRequest{}) + if err != nil { + return Operation{}, err + } + + if len(validatorsResp.Validators) == 0 { + return Operation{}, errors.New("no validators found") + } + + delay := uint64(0) + // apply a delay to the first signal only + if len(s.signalled) == 0 { + delay = uint64(s.height) + } + + // Choose a random validator to be the authority + for _, validator := range validatorsResp.Validators { + if !s.signalled[validator.OperatorAddress] { + s.signalled[validator.OperatorAddress] = true + msg := &signaltypes.MsgSignalVersion{ + ValidatorAddress: validator.OperatorAddress, + Version: s.version, + } + return Operation{ + Msgs: []types.Msg{msg}, + Delay: delay, + }, nil + } + } + + // if all validators have voted, we can now try to upgrade. + s.hasUpgraded = true + msg := signaltypes.NewMsgTryUpgrade(s.account) + return Operation{ + Msgs: []types.Msg{msg}, + Delay: delay, + }, nil +} diff --git a/test/util/blobfactory/payforblob_factory.go b/test/util/blobfactory/payforblob_factory.go index 1a4aa6d10c..f9b05359bc 100644 --- a/test/util/blobfactory/payforblob_factory.go +++ b/test/util/blobfactory/payforblob_factory.go @@ -245,10 +245,10 @@ func ManyMultiBlobTx( accounts []string, accInfos []AccountInfo, blobs [][]*share.Blob, + opts ...user.TxOption, ) [][]byte { t.Helper() txs := make([][]byte, len(accounts)) - opts := DefaultTxOpts() for i, acc := range accounts { signer, err := user.NewSigner(kr, enc, chainid, appconsts.LatestVersion, user.NewAccount(acc, accInfos[i].AccountNum, accInfos[i].Sequence)) require.NoError(t, err) diff --git a/test/util/genesis/document.go b/test/util/genesis/document.go index 3cc61f08b9..f45921431b 100644 --- a/test/util/genesis/document.go +++ b/test/util/genesis/document.go @@ -24,6 +24,7 @@ func Document( chainID string, gentxs []json.RawMessage, accounts []Account, + genesisTime time.Time, mods ...Modifier, ) (*coretypes.GenesisDoc, error) { genutilGenState := genutiltypes.DefaultGenesisState() @@ -73,7 +74,7 @@ func Document( // Create the genesis doc genesisDoc := &coretypes.GenesisDoc{ ChainID: chainID, - GenesisTime: time.Now(), + GenesisTime: genesisTime, ConsensusParams: params, AppState: stateBz, } @@ -101,7 +102,6 @@ func accountsToSDKTypes(accounts []Account) ([]banktypes.Balance, []authtypes.Ge ) genBals[i] = banktypes.Balance{Address: addr.String(), Coins: balances.Sort()} - genAccs[i] = authtypes.NewBaseAccount(addr, account.PubKey, uint64(i), 0) } return genBals, genAccs, nil diff --git a/test/util/genesis/files.go b/test/util/genesis/files.go index c8de7eec03..6d2452187b 100644 --- a/test/util/genesis/files.go +++ b/test/util/genesis/files.go @@ -5,65 +5,71 @@ import ( "os" "path/filepath" + srvconfig "github.com/cosmos/cosmos-sdk/server/config" "github.com/tendermint/tendermint/config" tmos "github.com/tendermint/tendermint/libs/os" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/privval" ) -// InitFiles initializes the files for a new tendermint node with the provided +// InitFiles initializes the files for a new Comet node with the provided // genesis. It will use the validatorIndex to save the validator's consensus // key. func InitFiles( - dir string, - tmCfg *config.Config, - g *Genesis, + rootDir string, + tmConfig *config.Config, + appCfg *srvconfig.Config, + genesis *Genesis, validatorIndex int, -) (string, error) { - val, has := g.Validator(validatorIndex) +) error { + val, has := genesis.Validator(validatorIndex) if !has { - return "", fmt.Errorf("validator %d not found", validatorIndex) + return fmt.Errorf("validator %d not found", validatorIndex) } - basePath := filepath.Join(dir, ".celestia-app") - tmCfg.SetRoot(basePath) + tmConfig.SetRoot(rootDir) // save the genesis file - configPath := filepath.Join(basePath, "config") + configPath := filepath.Join(rootDir, "config") err := os.MkdirAll(configPath, os.ModePerm) if err != nil { - return "", err + return err } - gDoc, err := g.Export() + genesisDoc, err := genesis.Export() if err != nil { - return "", fmt.Errorf("exporting genesis: %w", err) + return fmt.Errorf("exporting genesis: %w", err) } - err = gDoc.SaveAs(tmCfg.GenesisFile()) + err = genesisDoc.SaveAs(tmConfig.GenesisFile()) if err != nil { - return "", err + return err } - pvStateFile := tmCfg.PrivValidatorStateFile() + pvStateFile := tmConfig.PrivValidatorStateFile() if err := tmos.EnsureDir(filepath.Dir(pvStateFile), 0o777); err != nil { - return "", err + return err } - pvKeyFile := tmCfg.PrivValidatorKeyFile() + pvKeyFile := tmConfig.PrivValidatorKeyFile() if err := tmos.EnsureDir(filepath.Dir(pvKeyFile), 0o777); err != nil { - return "", err + return err } filePV := privval.NewFilePV(val.ConsensusKey, pvKeyFile, pvStateFile) filePV.Save() - nodeKeyFile := tmCfg.NodeKeyFile() + nodeKeyFile := tmConfig.NodeKeyFile() if err := tmos.EnsureDir(filepath.Dir(nodeKeyFile), 0o777); err != nil { - return "", err + return err } nodeKey := &p2p.NodeKey{ PrivKey: val.NetworkKey, } if err := nodeKey.SaveAs(nodeKeyFile); err != nil { - return "", err + return err } - return basePath, nil + appConfigFilePath := filepath.Join(rootDir, "config", "app.toml") + srvconfig.WriteConfigFile(appConfigFilePath, appCfg) + + config.WriteConfigFile(filepath.Join(rootDir, "config", "config.toml"), tmConfig) + + return nil } diff --git a/test/util/genesis/genesis.go b/test/util/genesis/genesis.go index 5a52fdbb29..f0fadf0b59 100644 --- a/test/util/genesis/genesis.go +++ b/test/util/genesis/genesis.go @@ -73,7 +73,7 @@ func NewDefaultGenesis() *Genesis { return g } -// WithModifier adds a genesis modifier to the genesis. +// WithModifiers adds a genesis modifier to the genesis. func (g *Genesis) WithModifiers(ops ...Modifier) *Genesis { g.genOps = append(g.genOps, ops...) return g @@ -97,7 +97,7 @@ func (g *Genesis) WithGenesisTime(genesisTime time.Time) *Genesis { return g } -// WithAccounts adds the given validators to the genesis. +// WithValidators adds the given validators to the genesis. func (g *Genesis) WithValidators(vals ...Validator) *Genesis { for _, val := range vals { err := g.NewValidator(val) @@ -120,6 +120,11 @@ func (g *Genesis) WithKeyringAccounts(accs ...KeyringAccount) *Genesis { return g } +func (g *Genesis) WithKeyring(kr keyring.Keyring) *Genesis { + g.kr = kr + return g +} + // AddAccount adds an existing account to the genesis. func (g *Genesis) AddAccount(account Account) error { if err := account.ValidateBasic(); err != nil { @@ -175,7 +180,7 @@ func (g *Genesis) AddValidator(val Validator) error { return nil } -// Creates a new validator account and adds it to the genesis. +// NewValidator creates a new validator account and adds it to the genesis. func (g *Genesis) NewValidator(val Validator) error { // Add the validator's genesis account if err := g.NewAccount(val.KeyringAccount); err != nil { @@ -208,6 +213,7 @@ func (g *Genesis) Export() (*coretypes.GenesisDoc, error) { g.ChainID, gentxs, g.accounts, + g.GenesisTime, g.genOps..., ) } @@ -220,3 +226,7 @@ func (g *Genesis) Validator(i int) (Validator, bool) { } return Validator{}, false } + +func (g *Genesis) EncodingConfig() encoding.Config { + return g.ecfg +} diff --git a/test/util/test_app.go b/test/util/test_app.go index 8b4a433e9c..f9f40ef91c 100644 --- a/test/util/test_app.go +++ b/test/util/test_app.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "strings" "testing" "time" @@ -43,7 +44,10 @@ import ( const ChainID = testfactory.ChainID -var GenesisTime = time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC() +var ( + GenesisTime = time.Date(2023, 1, 1, 1, 1, 1, 1, time.UTC).UTC() + TestAppLogger = log.NewTMLogger(os.Stdout) +) // Get flags every time the simulator is run func init() { @@ -63,10 +67,21 @@ func (ao EmptyAppOptions) Get(_ string) interface{} { // of the app from first genesis account. A no-op logger is set in app. func SetupTestAppWithGenesisValSet(cparams *tmproto.ConsensusParams, genAccounts ...string) (*app.App, keyring.Keyring) { testApp, valSet, kr := NewTestAppWithGenesisSet(cparams, genAccounts...) + initialiseTestApp(testApp, valSet, cparams) + return testApp, kr +} +func SetupTestAppWithGenesisValSetAndMaxSquareSize(cparams *tmproto.ConsensusParams, maxSquareSize int, genAccounts ...string) (*app.App, keyring.Keyring) { + testApp, valSet, kr := NewTestAppWithGenesisSetAndMaxSquareSize(cparams, maxSquareSize, genAccounts...) + initialiseTestApp(testApp, valSet, cparams) + return testApp, kr +} + +func initialiseTestApp(testApp *app.App, valSet *tmtypes.ValidatorSet, cparams *tmproto.ConsensusParams) { // commit genesis changes testApp.Commit() testApp.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{ + Time: time.Now(), ChainID: ChainID, Height: testApp.LastBlockHeight() + 1, AppHash: testApp.LastCommitID().Hash, @@ -76,8 +91,6 @@ func SetupTestAppWithGenesisValSet(cparams *tmproto.ConsensusParams, genAccounts App: cparams.Version.AppVersion, }, }}) - - return testApp, kr } // NewTestApp creates a new app instance with an empty memDB and a no-op logger. @@ -90,7 +103,7 @@ func NewTestApp() *app.App { encCfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) return app.New( - log.NewTMLogger(os.Stdout), db, nil, + TestAppLogger, db, nil, cast.ToUint(emptyOpts.Get(server.FlagInvCheckPeriod)), encCfg, 0, @@ -178,7 +191,27 @@ func SetupDeterministicGenesisState(testApp *app.App, pubKeys []cryptotypes.PubK func NewTestAppWithGenesisSet(cparams *tmproto.ConsensusParams, genAccounts ...string) (*app.App, *tmtypes.ValidatorSet, keyring.Keyring) { testApp := NewTestApp() genesisState, valSet, kr := GenesisStateWithSingleValidator(testApp, genAccounts...) + testApp = InitialiseTestAppWithGenesis(testApp, cparams, genesisState) + return testApp, valSet, kr +} + +// NewTestAppWithGenesisSetAndMaxSquareSize initializes a new app with genesis accounts and a specific max square size +// and returns the testApp, validator set and keyring. +func NewTestAppWithGenesisSetAndMaxSquareSize(cparams *tmproto.ConsensusParams, maxSquareSize int, genAccounts ...string) (*app.App, *tmtypes.ValidatorSet, keyring.Keyring) { + testApp := NewTestApp() + genesisState, valSet, kr := GenesisStateWithSingleValidator(testApp, genAccounts...) + + // hacky way of changing the gov max square size without changing the consts + blobJSON := string(genesisState["blob"]) + replace := strings.Replace(blobJSON, fmt.Sprintf("%d", appconsts.DefaultGovMaxSquareSize), fmt.Sprintf("%d", maxSquareSize), 1) + genesisState["blob"] = json.RawMessage(replace) + testApp = InitialiseTestAppWithGenesis(testApp, cparams, genesisState) + return testApp, valSet, kr +} + +// InitialiseTestAppWithGenesis initializes the provided app with the provided genesis. +func InitialiseTestAppWithGenesis(testApp *app.App, cparams *tmproto.ConsensusParams, genesisState app.GenesisState) *app.App { stateBytes, err := json.MarshalIndent(genesisState, "", " ") if err != nil { panic(err) @@ -208,7 +241,7 @@ func NewTestAppWithGenesisSet(cparams *tmproto.ConsensusParams, genAccounts ...s ChainId: ChainID, }, ) - return testApp, valSet, kr + return testApp } // AddDeterministicValidatorToGenesis adds a set of five validators to the genesis. diff --git a/test/util/testnode/app_wrapper.go b/test/util/testnode/app_wrapper.go new file mode 100644 index 0000000000..e885f4c4ed --- /dev/null +++ b/test/util/testnode/app_wrapper.go @@ -0,0 +1,21 @@ +package testnode + +import ( + "time" + + "github.com/celestiaorg/celestia-app/v3/app" + sdk "github.com/cosmos/cosmos-sdk/types" + abci "github.com/tendermint/tendermint/abci/types" +) + +// wrapEndBlocker overrides the app's endblocker to set the timeout commit to a +// different value for testnode. +func wrapEndBlocker(app *app.App, timeoutCommit time.Duration) func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + endBlocker := func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { + resp := app.EndBlocker(ctx, req) + resp.Timeouts.TimeoutCommit = timeoutCommit + return resp + } + + return endBlocker +} diff --git a/test/util/testnode/comet_node.go b/test/util/testnode/comet_node.go new file mode 100644 index 0000000000..da0e566b37 --- /dev/null +++ b/test/util/testnode/comet_node.go @@ -0,0 +1,47 @@ +package testnode + +import ( + "path/filepath" + + "github.com/cosmos/cosmos-sdk/client/flags" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/proxy" + tmdb "github.com/tendermint/tm-db" +) + +// NewCometNode creates a ready to use comet node that operates a single +// validator celestia-app network. It expects that all configuration files are +// already initialized and saved to the baseDir. +func NewCometNode(baseDir string, config *UniversalTestingConfig) (*node.Node, servertypes.Application, error) { + logger := NewLogger(config) + dbPath := filepath.Join(config.TmConfig.RootDir, "data") + db, err := tmdb.NewGoLevelDB("application", dbPath) + if err != nil { + return nil, nil, err + } + + config.AppOptions.Set(flags.FlagHome, baseDir) + + app := config.AppCreator(logger, db, nil, config.AppOptions) + + nodeKey, err := p2p.LoadOrGenNodeKey(config.TmConfig.NodeKeyFile()) + if err != nil { + return nil, nil, err + } + + cometNode, err := node.NewNode( + config.TmConfig, + privval.LoadOrGenFilePV(config.TmConfig.PrivValidatorKeyFile(), config.TmConfig.PrivValidatorStateFile()), + nodeKey, + proxy.NewLocalClientCreator(app), + node.DefaultGenesisDocProviderFunc(config.TmConfig), + node.DefaultDBProvider, + node.DefaultMetricsProvider(config.TmConfig.Instrumentation), + logger, + ) + + return cometNode, app, err +} diff --git a/test/util/testnode/full_node_test.go b/test/util/testnode/comet_node_test.go similarity index 97% rename from test/util/testnode/full_node_test.go rename to test/util/testnode/comet_node_test.go index 5a62602b65..a011992f79 100644 --- a/test/util/testnode/full_node_test.go +++ b/test/util/testnode/comet_node_test.go @@ -11,7 +11,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/test/util/genesis" blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" - appns "github.com/celestiaorg/go-square/v2/share" + "github.com/celestiaorg/go-square/v2/share" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -72,7 +72,7 @@ func (s *IntegrationTestSuite) Test_verifyTimeIotaMs() { func (s *IntegrationTestSuite) TestPostData() { require := s.Require() - _, err := s.cctx.PostData(s.accounts[0], flags.BroadcastBlock, appns.RandomBlobNamespace(), tmrand.Bytes(kibibyte)) + _, err := s.cctx.PostData(s.accounts[0], flags.BroadcastBlock, share.RandomBlobNamespace(), tmrand.Bytes(kibibyte)) require.NoError(err) } diff --git a/test/util/testnode/config.go b/test/util/testnode/config.go index 947df61fa9..0ec6e7920e 100644 --- a/test/util/testnode/config.go +++ b/test/util/testnode/config.go @@ -174,7 +174,7 @@ func DefaultTendermintConfig() *tmconfig.Config { func DefaultAppCreator() srvtypes.AppCreator { return func(_ log.Logger, _ tmdb.DB, _ io.Writer, _ srvtypes.AppOptions) srvtypes.Application { encodingConfig := encoding.MakeConfig(app.ModuleEncodingRegisters...) - return app.New( + app := app.New( log.NewNopLogger(), tmdb.NewMemDB(), nil, // trace store @@ -184,13 +184,15 @@ func DefaultAppCreator() srvtypes.AppCreator { simapp.EmptyAppOptions{}, baseapp.SetMinGasPrices(fmt.Sprintf("%v%v", appconsts.DefaultMinGasPrice, app.BondDenom)), ) + app.SetEndBlocker(wrapEndBlocker(app, time.Millisecond*30)) + return app } } func CustomAppCreator(minGasPrice string) srvtypes.AppCreator { return func(_ log.Logger, _ tmdb.DB, _ io.Writer, _ srvtypes.AppOptions) srvtypes.Application { encodingConfig := encoding.MakeConfig(app.ModuleEncodingRegisters...) - return app.New( + app := app.New( log.NewNopLogger(), tmdb.NewMemDB(), nil, // trace store @@ -200,5 +202,16 @@ func CustomAppCreator(minGasPrice string) srvtypes.AppCreator { simapp.EmptyAppOptions{}, baseapp.SetMinGasPrices(minGasPrice), ) + app.SetEndBlocker(wrapEndBlocker(app, time.Millisecond*0)) + return app } } + +// DefaultAppConfig wraps the default config described in the server +func DefaultAppConfig() *srvconfig.Config { + appCfg := srvconfig.DefaultConfig() + appCfg.GRPC.Address = fmt.Sprintf("127.0.0.1:%d", mustGetFreePort()) + appCfg.API.Address = fmt.Sprintf("tcp://127.0.0.1:%d", mustGetFreePort()) + appCfg.MinGasPrices = fmt.Sprintf("%v%s", appconsts.DefaultMinGasPrice, appconsts.BondDenom) + return appCfg +} diff --git a/test/util/testnode/full_node.go b/test/util/testnode/full_node.go deleted file mode 100644 index 2a7b6e12c5..0000000000 --- a/test/util/testnode/full_node.go +++ /dev/null @@ -1,58 +0,0 @@ -package testnode - -import ( - "os" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/client/flags" - srvtypes "github.com/cosmos/cosmos-sdk/server/types" - "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/p2p" - "github.com/tendermint/tendermint/privval" - "github.com/tendermint/tendermint/proxy" - dbm "github.com/tendermint/tm-db" -) - -// NewCometNode creates a ready to use comet node that operates a single -// validator celestia-app network. It expects that all configuration files are -// already initialized and saved to the baseDir. -func NewCometNode(baseDir string, cfg *UniversalTestingConfig) (*node.Node, srvtypes.Application, error) { - logger := newLogger(cfg) - dbPath := filepath.Join(cfg.TmConfig.RootDir, "data") - db, err := dbm.NewGoLevelDB("application", dbPath) - if err != nil { - return nil, nil, err - } - - cfg.AppOptions.Set(flags.FlagHome, baseDir) - - app := cfg.AppCreator(logger, db, nil, cfg.AppOptions) - - nodeKey, err := p2p.LoadOrGenNodeKey(cfg.TmConfig.NodeKeyFile()) - if err != nil { - return nil, nil, err - } - - tmNode, err := node.NewNode( - cfg.TmConfig, - privval.LoadOrGenFilePV(cfg.TmConfig.PrivValidatorKeyFile(), cfg.TmConfig.PrivValidatorStateFile()), - nodeKey, - proxy.NewLocalClientCreator(app), - node.DefaultGenesisDocProviderFunc(cfg.TmConfig), - node.DefaultDBProvider, - node.DefaultMetricsProvider(cfg.TmConfig.Instrumentation), - logger, - ) - - return tmNode, app, err -} - -func newLogger(cfg *UniversalTestingConfig) log.Logger { - if cfg.SuppressLogs { - return log.NewNopLogger() - } - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - logger = log.NewFilter(logger, log.AllowError()) - return logger -} diff --git a/test/util/testnode/logger.go b/test/util/testnode/logger.go new file mode 100644 index 0000000000..36f80e249b --- /dev/null +++ b/test/util/testnode/logger.go @@ -0,0 +1,24 @@ +package testnode + +import ( + "os" + + "github.com/tendermint/tendermint/libs/log" +) + +func NewLogger(config *UniversalTestingConfig) log.Logger { + if config.SuppressLogs { + return log.NewNopLogger() + } + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + switch config.TmConfig.LogLevel { + case "error": + return log.NewFilter(logger, log.AllowError()) + case "info": + return log.NewFilter(logger, log.AllowInfo()) + case "debug": + return log.NewFilter(logger, log.AllowDebug()) + default: + return logger + } +} diff --git a/test/util/testnode/network.go b/test/util/testnode/network.go index 34a013a524..eab7384c91 100644 --- a/test/util/testnode/network.go +++ b/test/util/testnode/network.go @@ -2,7 +2,7 @@ package testnode import ( "context" - "net" + "path/filepath" "testing" "github.com/celestiaorg/celestia-app/v3/test/util/genesis" @@ -16,14 +16,15 @@ import ( // accessed via the returned client.Context or via the returned rpc and grpc // addresses. Configured genesis options will be applied after all accounts have // been initialized. -func NewNetwork(t testing.TB, cfg *Config) (cctx Context, rpcAddr, grpcAddr string) { +func NewNetwork(t testing.TB, config *Config) (cctx Context, rpcAddr, grpcAddr string) { t.Helper() // initialize the genesis file and validator files for the first validator. - baseDir, err := genesis.InitFiles(t.TempDir(), cfg.TmConfig, cfg.Genesis, 0) + baseDir := filepath.Join(t.TempDir(), "testnode") + err := genesis.InitFiles(baseDir, config.TmConfig, config.AppConfig, config.Genesis, 0) require.NoError(t, err) - tmNode, app, err := NewCometNode(baseDir, &cfg.UniversalTestingConfig) + tmNode, app, err := NewCometNode(baseDir, &config.UniversalTestingConfig) require.NoError(t, err) ctx, cancel := context.WithCancel(context.Background()) @@ -31,15 +32,16 @@ func NewNetwork(t testing.TB, cfg *Config) (cctx Context, rpcAddr, grpcAddr stri cancel() }) - cctx = NewContext(ctx, cfg.Genesis.Keyring(), cfg.TmConfig, cfg.Genesis.ChainID, cfg.AppConfig.API.Address) + cctx = NewContext(ctx, config.Genesis.Keyring(), config.TmConfig, config.Genesis.ChainID, config.AppConfig.API.Address) + cctx.tmNode = tmNode cctx, stopNode, err := StartNode(tmNode, cctx) require.NoError(t, err) - cctx, cleanupGRPC, err := StartGRPCServer(app, cfg.AppConfig, cctx) + cctx, cleanupGRPC, err := StartGRPCServer(app, config.AppConfig, cctx) require.NoError(t, err) - apiServer, err := StartAPIServer(app, *cfg.AppConfig, cctx) + apiServer, err := StartAPIServer(app, *config.AppConfig, cctx) require.NoError(t, err) t.Cleanup(func() { @@ -64,30 +66,5 @@ func NewNetwork(t testing.TB, cfg *Config) (cctx Context, rpcAddr, grpcAddr stri } }) - return cctx, cfg.TmConfig.RPC.ListenAddress, cfg.AppConfig.GRPC.Address -} - -// getFreePort returns a free port and optionally an error. -func getFreePort() (int, error) { - a, err := net.ResolveTCPAddr("tcp", "localhost:0") - if err != nil { - return 0, err - } - - l, err := net.ListenTCP("tcp", a) - if err != nil { - return 0, err - } - defer l.Close() - return l.Addr().(*net.TCPAddr).Port, nil -} - -// mustGetFreePort returns a free port. Panics if no free ports are available or -// an error is encountered. -func mustGetFreePort() int { - port, err := getFreePort() - if err != nil { - panic(err) - } - return port + return cctx, config.TmConfig.RPC.ListenAddress, config.AppConfig.GRPC.Address } diff --git a/test/util/testnode/node_interaction_api.go b/test/util/testnode/node_interaction_api.go index 3695ee2a99..a5c175e86d 100644 --- a/test/util/testnode/node_interaction_api.go +++ b/test/util/testnode/node_interaction_api.go @@ -22,6 +22,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" tmconfig "github.com/tendermint/tendermint/config" tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/node" rpctypes "github.com/tendermint/tendermint/rpc/core/types" ) @@ -30,28 +31,29 @@ const ( ) type Context struct { - rootCtx context.Context + goContext context.Context client.Context apiAddress string + tmNode *node.Node } -func NewContext(goCtx context.Context, kr keyring.Keyring, tmCfg *tmconfig.Config, chainID, apiAddress string) Context { - ecfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) - cctx := client.Context{}. - WithKeyring(kr). - WithHomeDir(tmCfg.RootDir). +func NewContext(goContext context.Context, keyring keyring.Keyring, tmConfig *tmconfig.Config, chainID, apiAddress string) Context { + config := encoding.MakeConfig(app.ModuleEncodingRegisters...) + clientContext := client.Context{}. + WithKeyring(keyring). + WithHomeDir(tmConfig.RootDir). WithChainID(chainID). - WithInterfaceRegistry(ecfg.InterfaceRegistry). - WithCodec(ecfg.Codec). - WithLegacyAmino(ecfg.Amino). - WithTxConfig(ecfg.TxConfig). + WithInterfaceRegistry(config.InterfaceRegistry). + WithCodec(config.Codec). + WithLegacyAmino(config.Amino). + WithTxConfig(config.TxConfig). WithAccountRetriever(authtypes.AccountRetriever{}) - return Context{rootCtx: goCtx, Context: cctx, apiAddress: apiAddress} + return Context{goContext: goContext, Context: clientContext, apiAddress: apiAddress} } func (c *Context) GoContext() context.Context { - return c.rootCtx + return c.goContext } // GenesisTime returns the genesis block time. @@ -92,7 +94,7 @@ func (c *Context) WaitForHeightWithTimeout(h int64, t time.Duration) (int64, err ticker := time.NewTicker(time.Second) defer ticker.Stop() - ctx, cancel := context.WithTimeout(c.rootCtx, t) + ctx, cancel := context.WithTimeout(c.goContext, t) defer cancel() var ( @@ -102,8 +104,8 @@ func (c *Context) WaitForHeightWithTimeout(h int64, t time.Duration) (int64, err for { select { case <-ctx.Done(): - if c.rootCtx.Err() != nil { - return latestHeight, c.rootCtx.Err() + if c.goContext.Err() != nil { + return latestHeight, c.goContext.Err() } return latestHeight, fmt.Errorf("timeout (%v) exceeded waiting for network to reach height %d. Got to height %d", t, h, latestHeight) case <-ticker.C: @@ -123,7 +125,7 @@ func (c *Context) WaitForTimestampWithTimeout(t time.Time, d time.Duration) (tim ticker := time.NewTicker(time.Second) defer ticker.Stop() - ctx, cancel := context.WithTimeout(c.rootCtx, d) + ctx, cancel := context.WithTimeout(c.goContext, d) defer cancel() var latestTimestamp time.Time @@ -193,7 +195,7 @@ func (c *Context) WaitForTx(hashHexStr string, blocks int) (*rpctypes.ResultTx, return nil, err } - ctx, cancel := context.WithTimeout(c.rootCtx, DefaultTimeout) + ctx, cancel := context.WithTimeout(c.goContext, DefaultTimeout) defer cancel() for { diff --git a/test/util/testnode/rpc_client.go b/test/util/testnode/rpc_client.go index 835ced0eb5..c6299af62a 100644 --- a/test/util/testnode/rpc_client.go +++ b/test/util/testnode/rpc_client.go @@ -1,13 +1,10 @@ package testnode import ( - "fmt" - "os" "path" "strings" "time" - "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server/api" srvconfig "github.com/cosmos/cosmos-sdk/server/config" @@ -24,35 +21,33 @@ import ( // performs no operation. var noOpCleanup = func() error { return nil } -// StartNode starts the tendermint node along with a local core rpc client. The -// rpc is returned via the client.Context. The function returned should be +// StartNode starts the Comet node along with a local core RPC client. The +// RPC is returned via the client.Context. The function returned should be // called during cleanup to teardown the node, core client, along with canceling // the internal context.Context in the returned Context. -func StartNode(tmNode *node.Node, cctx Context) (Context, func() error, error) { - if err := tmNode.Start(); err != nil { +func StartNode(cometNode *node.Node, cctx Context) (Context, func() error, error) { + if err := cometNode.Start(); err != nil { return cctx, noOpCleanup, err } - - coreClient := local.New(tmNode) - - cctx.Context = cctx.WithClient(coreClient) + client := local.New(cometNode) + cctx.Context = cctx.WithClient(client) cleanup := func() error { - err := tmNode.Stop() + err := cometNode.Stop() if err != nil { return err } - tmNode.Wait() + cometNode.Wait() if err = removeDir(path.Join([]string{cctx.HomeDir, "config"}...)); err != nil { return err } - return removeDir(path.Join([]string{cctx.HomeDir, tmNode.Config().DBPath}...)) + return removeDir(path.Join([]string{cctx.HomeDir, cometNode.Config().DBPath}...)) } return cctx, cleanup, nil } -// StartGRPCServer starts the grpc server using the provided application and -// config. A grpc client connection to that server is also added to the client +// StartGRPCServer starts the GRPC server using the provided application and +// config. A GRPC client connection to that server is also added to the client // context. The returned function should be used to shutdown the server. func StartGRPCServer(app srvtypes.Application, appCfg *srvconfig.Config, cctx Context) (Context, func() error, error) { emptycleanup := func() error { return nil } @@ -91,35 +86,6 @@ func StartGRPCServer(app srvtypes.Application, appCfg *srvconfig.Config, cctx Co }, nil } -// DefaultAppConfig wraps the default config described in the server -func DefaultAppConfig() *srvconfig.Config { - appCfg := srvconfig.DefaultConfig() - appCfg.GRPC.Address = fmt.Sprintf("127.0.0.1:%d", mustGetFreePort()) - appCfg.API.Address = fmt.Sprintf("tcp://127.0.0.1:%d", mustGetFreePort()) - appCfg.MinGasPrices = fmt.Sprintf("%v%s", appconsts.DefaultMinGasPrice, appconsts.BondDenom) - return appCfg -} - -// removeDir removes the directory `rootDir`. -// The main use of this is to reduce the flakiness of the CI when it's unable to delete -// the config folder of the tendermint node. -// This will manually go over the files contained inside the provided `rootDir` -// and delete them one by one. -func removeDir(rootDir string) error { - dir, err := os.ReadDir(rootDir) - if err != nil { - return err - } - for _, d := range dir { - path := path.Join([]string{rootDir, d.Name()}...) - err := os.RemoveAll(path) - if err != nil { - return err - } - } - return os.RemoveAll(rootDir) -} - func StartAPIServer(app srvtypes.Application, appCfg srvconfig.Config, cctx Context) (*api.Server, error) { apiSrv := api.New(cctx.Context, log.NewNopLogger()) app.RegisterAPIRoutes(apiSrv, appCfg.API) diff --git a/test/util/testnode/utils.go b/test/util/testnode/utils.go index bf71aaa951..b17c0db6c8 100644 --- a/test/util/testnode/utils.go +++ b/test/util/testnode/utils.go @@ -3,6 +3,9 @@ package testnode import ( "context" "encoding/hex" + "net" + "os" + "path" "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" @@ -88,3 +91,48 @@ func GenerateAccounts(count int) []string { } return accs } + +// getFreePort returns a free port and optionally an error. +func getFreePort() (int, error) { + a, err := net.ResolveTCPAddr("tcp", "localhost:0") + if err != nil { + return 0, err + } + + l, err := net.ListenTCP("tcp", a) + if err != nil { + return 0, err + } + defer l.Close() + return l.Addr().(*net.TCPAddr).Port, nil +} + +// mustGetFreePort returns a free port. Panics if no free ports are available or +// an error is encountered. +func mustGetFreePort() int { + port, err := getFreePort() + if err != nil { + panic(err) + } + return port +} + +// removeDir removes the directory `rootDir`. +// The main use of this is to reduce the flakiness of the CI when it's unable to delete +// the config folder of the tendermint node. +// This will manually go over the files contained inside the provided `rootDir` +// and delete them one by one. +func removeDir(rootDir string) error { + dir, err := os.ReadDir(rootDir) + if err != nil { + return err + } + for _, d := range dir { + path := path.Join([]string{rootDir, d.Name()}...) + err := os.RemoveAll(path) + if err != nil { + return err + } + } + return os.RemoveAll(rootDir) +} diff --git a/tools/blocketa/README.md b/tools/blocketa/README.md new file mode 100644 index 0000000000..f7de7539b5 --- /dev/null +++ b/tools/blocketa/README.md @@ -0,0 +1,18 @@ +# Block ETA (Estimated Time of Arrival) + +blocketa is a tool that estimates the time of arrival of a block height. + +## Usage + +```shell +$ go run main.go https://celestia-mocha-rpc.publicnode.com:443 2585031 +chainID: mocha-4 +currentHeight: 2580660 +currentTime: 2024-08-28 02:46:32.933542677 +0000 UTC +diffInBlockHeight: 4371 +diffInTime: 14h37m50.55s +arrivalTime: 2024-08-28 17:24:23.483542677 +0000 UTC +``` + +> [!NOTE] +> The block time is currently hard-coded. If you're running this for a network with a different block time, you'll need to update the `blockTime` constant in the main.go file. You can use [https://www.mintscan.io/celestia/block](https://www.mintscan.io/celestia/block/) or the blocktime tool. diff --git a/tools/blocketa/main.go b/tools/blocketa/main.go new file mode 100644 index 0000000000..7706ffd431 --- /dev/null +++ b/tools/blocketa/main.go @@ -0,0 +1,88 @@ +package main + +import ( + "context" + "fmt" + "os" + "strconv" + "time" + + "github.com/tendermint/tendermint/rpc/client/http" +) + +const ( + // blockTime is the observed average time between blocks. You can update this + // value based on the block time on https://www.mintscan.io/celestia/block/ or + // the output from the blocktime tool. + blockTime = 11.75 // seconds between blocks on Mainnet Beta. + + // exampleArabicaRPC is an example node RPC endpoint for the Arabica testnet. + exampleArabicaRPC = "https://rpc.celestia-arabica-11.com:443" + + // exampleMochaRPC is an example node RPC endpoint for the Mocha testnet. + exampleMochaRPC = "https://celestia-mocha-rpc.publicnode.com:443" + + // exampleMainnetHeight is an example node RPC endpoint for Mainnet Beta. + exampleMainnetRPC = "https://celestia-rpc.publicnode.com:443" + + // exampleArabicaHeight is an example block height for the Arabica testnet. + exampleArabicaHeight = 1751707 + + // exampleMochaHeight is an example block height for the Mocha testnet. + exampleMochaHeight = 2585031 + + // exampleMainnetHeight is an example block height for Mainnet Beta. + exampleMainnetHeight = 2371495 +) + +func main() { + if err := Run(); err != nil { + fmt.Printf("ERROR: %s", err.Error()) + } +} + +func Run() error { + if len(os.Args) < 3 { + fmt.Printf("Usage: %s \n", os.Args[0]) + fmt.Printf("Example: %s %s %v\n", os.Args[0], exampleArabicaRPC, exampleArabicaHeight) + fmt.Printf("Example: %s %s %v\n", os.Args[0], exampleMochaRPC, exampleMochaHeight) + fmt.Printf("Example: %s %s %v\n", os.Args[0], exampleMainnetRPC, exampleMainnetHeight) + return nil + } + + _, nodeRPC, targetBlockHeightArg := os.Args[0], os.Args[1], os.Args[2] + targetBlockHeight, err := strconv.ParseInt(targetBlockHeightArg, 10, 64) + if err != nil { + return err + } + c, err := http.New(nodeRPC, "/websocket") + if err != nil { + return err + } + resp, err := c.Status(context.Background()) + if err != nil { + return err + } + chainID := resp.NodeInfo.Network + currentHeight := resp.SyncInfo.LatestBlockHeight + currentTime := resp.SyncInfo.LatestBlockTime + + if currentHeight >= targetBlockHeight { + return fmt.Errorf("current height %v is already after target height %v", currentHeight, targetBlockHeight) + } + diffInBlockHeight := targetBlockHeight - currentHeight + diffInSeconds := blockTime * float64(diffInBlockHeight) + diffInTime, err := time.ParseDuration(fmt.Sprintf("%.0fs", diffInSeconds)) + if err != nil { + return err + } + arrivalTime := currentTime.Add(diffInTime) + + fmt.Printf("chainID: %v\n", chainID) + fmt.Printf("currentHeight: %v\n", currentHeight) + fmt.Printf("currentTime: %v\n", currentTime.String()) + fmt.Printf("diffInBlockHeight: %v\n", diffInBlockHeight) + fmt.Printf("diffInTime: %v\n", diffInTime) + fmt.Printf("arrivalTime: %v\n", arrivalTime) + return nil +} diff --git a/tools/blockheight/main.go b/tools/blockheight/main.go index c20342aec9..e309b29b6f 100644 --- a/tools/blockheight/main.go +++ b/tools/blockheight/main.go @@ -14,13 +14,25 @@ const ( // blockTime is the observed average time between blocks. You can update this // value based on the block time on https://www.mintscan.io/celestia/block/ or // the output from the blocktime tool. - blockTime = 11.30 // seconds between blocks for Arabica + blockTime = 11.75 // seconds between blocks on Mainnet Beta. - // exampleNodeRPC is an example node RPC endpoint for the Arabica testnet. - exampleNodeRPC = "https://rpc.celestia-arabica-11.com:443" + // exampleArabicaRPC is an example node RPC endpoint for the Arabica testnet. + exampleArabicaRPC = "https://rpc.celestia-arabica-11.com:443" - // targetTime is an example target time for the block height prediction. - targetTime = "2024-08-14T14:00:00" + // exampleMochaRPC is an example node RPC endpoint for the Mocha testnet. + exampleMochaRPC = "https://celestia-mocha-rpc.publicnode.com:443" + + // exampleMainnetHeight is an example node RPC endpoint for Mainnet Beta. + exampleMainnetRPC = "https://celestia-rpc.publicnode.com:443" + + // exampleArabicaTime is an example target time for the block height prediction. + exampleArabicaTime = "2024-08-19T14:00:00" + + // exampleMochaTime is an example target time for the block height prediction. + exampleMochaTime = "2024-08-28T14:00:00" + + // exampleMainnetTime is an example target time for the block height prediction. + exampleMainnetTime = "2024-09-18T14:00:00" // layout is the expected time format for targetTime. layout = "2006-01-02T15:04:05" @@ -35,7 +47,9 @@ func main() { func Run() error { if len(os.Args) < 3 { fmt.Printf("Usage: %s \n", os.Args[0]) - fmt.Printf("Example: %s %s %s\n", os.Args[0], exampleNodeRPC, targetTime) + fmt.Printf("Example: %s %s %s\n", os.Args[0], exampleArabicaRPC, exampleArabicaTime) + fmt.Printf("Example: %s %s %s\n", os.Args[0], exampleMochaRPC, exampleMochaTime) + fmt.Printf("Example: %s %s %s\n", os.Args[0], exampleMainnetRPC, exampleMainnetTime) return nil } diff --git a/tools/chainbuilder/README.md b/tools/chainbuilder/README.md new file mode 100644 index 0000000000..50ceb3c06d --- /dev/null +++ b/tools/chainbuilder/README.md @@ -0,0 +1,27 @@ +# Chainbuilder + +`chainbuilder` is a tool for building a Celestia chain for testing and development purposes. + +## Usage + +Use `go` to run the binary as follows: + +```shell +go run ./tools/chainbuilder +``` + +This will create a directory with the name `testnode-{chainID}`. All files will be populated and blocks generated based on specified input. You can run a validator on the file system afterwards by calling: + +```shell +celestia-appd start --home /path/to/testnode-{chainID} +``` + +The following are the set of options when generating a chain: + +- `num-blocks` the number of blocks to be generated (default: 100) +- `block-size` the size of the blocks to be generated (default <2MB). This will be a single PFB transaction +- `square-size` the size of the max square (default: 128) +- `existing-dir` point this to a directory if you want to extend an existing chain rather than create a new one +- `namespace` allows you to pick a custom v0 namespace. By default "test" will be chosen. + +This tool takes roughly 60-70ms per 2MB block. diff --git a/tools/chainbuilder/benchmark_test.go b/tools/chainbuilder/benchmark_test.go new file mode 100644 index 0000000000..b72d9297e5 --- /dev/null +++ b/tools/chainbuilder/benchmark_test.go @@ -0,0 +1,25 @@ +package main + +import ( + "context" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" +) + +func BenchmarkRun(b *testing.B) { + cfg := BuilderConfig{ + NumBlocks: 100, + BlockSize: appconsts.DefaultMaxBytes, + BlockInterval: time.Second, + } + + dir := b.TempDir() + b.ResetTimer() + for i := 0; i < b.N; i++ { + if err := Run(context.Background(), cfg, dir); err != nil { + b.Fatal(err) + } + } +} diff --git a/tools/chainbuilder/integration_test.go b/tools/chainbuilder/integration_test.go new file mode 100644 index 0000000000..eb671cd1f0 --- /dev/null +++ b/tools/chainbuilder/integration_test.go @@ -0,0 +1,103 @@ +package main + +import ( + "context" + "fmt" + "path/filepath" + "testing" + "time" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/tendermint/tendermint/libs/log" + tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/p2p" + "github.com/tendermint/tendermint/privval" + "github.com/tendermint/tendermint/proxy" + "github.com/tendermint/tendermint/rpc/client/local" + tmdbm "github.com/tendermint/tm-db" + + "github.com/stretchr/testify/require" +) + +func TestRun(t *testing.T) { + if testing.Short() { + t.Skip("skipping chainbuilder tool test") + } + + numBlocks := 10 + + cfg := BuilderConfig{ + NumBlocks: numBlocks, + BlockSize: appconsts.DefaultMaxBytes, + BlockInterval: time.Second, + ChainID: tmrand.Str(6), + Namespace: defaultNamespace, + } + + dir := t.TempDir() + + // First run + err := Run(context.Background(), cfg, dir) + require.NoError(t, err) + + // Second run with existing directory + cfg.ExistingDir = filepath.Join(dir, fmt.Sprintf("testnode-%s", cfg.ChainID)) + err = Run(context.Background(), cfg, dir) + require.NoError(t, err) + + tmCfg := testnode.DefaultTendermintConfig() + tmCfg.SetRoot(cfg.ExistingDir) + + appDB, err := tmdbm.NewDB("application", tmdbm.GoLevelDBBackend, tmCfg.DBDir()) + require.NoError(t, err) + + encCfg := encoding.MakeConfig(app.ModuleBasics) + + app := app.New( + log.NewNopLogger(), + appDB, + nil, + 0, + encCfg, + 0, + util.EmptyAppOptions{}, + baseapp.SetMinGasPrices(fmt.Sprintf("%f%s", appconsts.DefaultMinGasPrice, appconsts.BondDenom)), + ) + + nodeKey, err := p2p.LoadNodeKey(tmCfg.NodeKeyFile()) + require.NoError(t, err) + + cometNode, err := node.NewNode( + tmCfg, + privval.LoadOrGenFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()), + nodeKey, + proxy.NewLocalClientCreator(app), + node.DefaultGenesisDocProviderFunc(tmCfg), + node.DefaultDBProvider, + node.DefaultMetricsProvider(tmCfg.Instrumentation), + log.NewNopLogger(), + ) + require.NoError(t, err) + + require.NoError(t, cometNode.Start()) + defer func() { _ = cometNode.Stop() }() + + client := local.New(cometNode) + status, err := client.Status(context.Background()) + require.NoError(t, err) + require.NotNil(t, status) + // assert that the new node eventually makes progress in the chain + require.Eventually(t, func() bool { + status, err := client.Status(context.Background()) + require.NoError(t, err) + return status.SyncInfo.LatestBlockHeight >= int64(numBlocks*2) + }, time.Second*10, time.Millisecond*100) + require.NoError(t, cometNode.Stop()) + cometNode.Wait() +} diff --git a/tools/chainbuilder/main.go b/tools/chainbuilder/main.go new file mode 100644 index 0000000000..fe385084b3 --- /dev/null +++ b/tools/chainbuilder/main.go @@ -0,0 +1,547 @@ +package main + +import ( + "context" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/celestiaorg/go-square/v2" + "github.com/celestiaorg/go-square/v2/share" + dbm "github.com/cometbft/cometbft-db" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/merkle" + "github.com/tendermint/tendermint/libs/log" + tmrand "github.com/tendermint/tendermint/libs/rand" + "github.com/tendermint/tendermint/privval" + smproto "github.com/tendermint/tendermint/proto/tendermint/state" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + sm "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/store" + "github.com/tendermint/tendermint/types" + tmdbm "github.com/tendermint/tm-db" + + "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/pkg/da" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + "github.com/celestiaorg/celestia-app/v3/test/util" + "github.com/celestiaorg/celestia-app/v3/test/util/genesis" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" + blobtypes "github.com/celestiaorg/celestia-app/v3/x/blob/types" +) + +var defaultNamespace share.Namespace + +const ( + defaultNamespaceStr = "test" + maxSquareSize = 512 +) + +func init() { + defaultNamespace = share.MustNewV0Namespace([]byte(defaultNamespaceStr)) +} + +func main() { + rootCmd := &cobra.Command{ + Use: "chainbuilder", + Short: "Build a Celestia chain", + RunE: func(cmd *cobra.Command, _ []string) error { + numBlocks, _ := cmd.Flags().GetInt("num-blocks") + blockSize, _ := cmd.Flags().GetInt("block-size") + blockInterval, _ := cmd.Flags().GetDuration("block-interval") + existingDir, _ := cmd.Flags().GetString("existing-dir") + namespaceStr, _ := cmd.Flags().GetString("namespace") + upToTime, _ := cmd.Flags().GetBool("up-to-now") + appVersion, _ := cmd.Flags().GetUint64("app-version") + chainID, _ := cmd.Flags().GetString("chain-id") + var namespace share.Namespace + if namespaceStr == "" { + namespace = defaultNamespace + } else { + var err error + namespace, err = share.NewV0Namespace([]byte(namespaceStr)) + if err != nil { + return fmt.Errorf("invalid namespace: %w", err) + } + } + + cfg := BuilderConfig{ + NumBlocks: numBlocks, + BlockSize: blockSize, + BlockInterval: blockInterval, + ExistingDir: existingDir, + Namespace: namespace, + ChainID: tmrand.Str(6), + UpToTime: upToTime, + AppVersion: appVersion, + } + + if chainID != "" { + cfg.ChainID = chainID + } + + dir, err := os.Getwd() + if err != nil { + return fmt.Errorf("failed to get current working directory: %w", err) + } + + return Run(cmd.Context(), cfg, dir) + }, + } + + rootCmd.Flags().Int("num-blocks", 100, "Number of blocks to generate") + rootCmd.Flags().Int("block-size", appconsts.DefaultMaxBytes, "Size of each block in bytes") + rootCmd.Flags().Duration("block-interval", time.Second, "Interval between blocks") + rootCmd.Flags().String("existing-dir", "", "Existing directory to load chain from") + rootCmd.Flags().String("namespace", "", "Custom namespace for the chain") + rootCmd.Flags().Bool("up-to-now", false, "Tool will terminate if the block time reaches the current time") + rootCmd.Flags().Uint64("app-version", appconsts.LatestVersion, "App version to use for the chain") + rootCmd.Flags().String("chain-id", "", "Chain ID to use for the chain. Defaults to a random 6 character string") + rootCmd.SilenceUsage = true + rootCmd.SilenceErrors = true + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +type BuilderConfig struct { + NumBlocks int + BlockSize int + BlockInterval time.Duration + ExistingDir string + Namespace share.Namespace + ChainID string + AppVersion uint64 + UpToTime bool +} + +func Run(ctx context.Context, cfg BuilderConfig, dir string) error { + startTime := time.Now().Add(-1 * cfg.BlockInterval * time.Duration(cfg.NumBlocks)).UTC() + currentTime := startTime + + encCfg := encoding.MakeConfig(app.ModuleBasics) + tmCfg := app.DefaultConsensusConfig() + var ( + gen *genesis.Genesis + kr keyring.Keyring + err error + ) + if cfg.ExistingDir == "" { + dir = filepath.Join(dir, fmt.Sprintf("testnode-%s", cfg.ChainID)) + kr, err = keyring.New(app.Name, keyring.BackendTest, dir, nil, encCfg.Codec) + if err != nil { + return fmt.Errorf("failed to create keyring: %w", err) + } + + validator := genesis.NewDefaultValidator(testnode.DefaultValidatorAccountName) + appCfg := app.DefaultAppConfig() + appCfg.Pruning = "everything" // we just want the last two states + appCfg.StateSync.SnapshotInterval = 0 + cp := app.DefaultConsensusParams() + + cp.Version.AppVersion = cfg.AppVersion // set the app version + gen = genesis.NewDefaultGenesis(). + WithConsensusParams(cp). + WithKeyring(kr). + WithChainID(cfg.ChainID). + WithGenesisTime(startTime). + WithValidators(validator) + + if err := genesis.InitFiles(dir, tmCfg, appCfg, gen, 0); err != nil { + return fmt.Errorf("failed to initialize genesis files: %w", err) + } + fmt.Println("Creating chain from scratch with Chain ID:", gen.ChainID) + } else { + cfgPath := filepath.Join(cfg.ExistingDir, "config/config.toml") + if _, err := os.Stat(cfgPath); os.IsNotExist(err) { + return fmt.Errorf("config file for existing chain not found at %s", cfgPath) + } + fmt.Println("Loading chain from existing directory:", cfg.ExistingDir) + tmCfg.SetRoot(cfg.ExistingDir) + kr, err = keyring.New(app.Name, keyring.BackendTest, cfg.ExistingDir, nil, encCfg.Codec) + if err != nil { + return fmt.Errorf("failed to load keyring: %w", err) + } + } + + validatorKey := privval.LoadFilePV(tmCfg.PrivValidatorKeyFile(), tmCfg.PrivValidatorStateFile()) + validatorAddr := validatorKey.Key.Address + + blockDB, err := dbm.NewDB("blockstore", dbm.GoLevelDBBackend, tmCfg.DBDir()) + if err != nil { + return fmt.Errorf("failed to create block database: %w", err) + } + + blockStore := store.NewBlockStore(blockDB) + + stateDB, err := dbm.NewDB("state", dbm.GoLevelDBBackend, tmCfg.DBDir()) + if err != nil { + return fmt.Errorf("failed to create state database: %w", err) + } + + stateStore := sm.NewStore(stateDB, sm.StoreOptions{ + DiscardABCIResponses: true, + }) + + appDB, err := tmdbm.NewDB("application", tmdbm.GoLevelDBBackend, tmCfg.DBDir()) + if err != nil { + return fmt.Errorf("failed to create application database: %w", err) + } + + simApp := app.New( + log.NewNopLogger(), + appDB, + nil, + 0, + encCfg, + 0, + util.EmptyAppOptions{}, + baseapp.SetMinGasPrices(fmt.Sprintf("%f%s", appconsts.DefaultMinGasPrice, appconsts.BondDenom)), + ) + + infoResp := simApp.Info(abci.RequestInfo{}) + + lastHeight := blockStore.Height() + if infoResp.LastBlockHeight != lastHeight { + return fmt.Errorf("last application height is %d, but the block store height is %d", infoResp.LastBlockHeight, lastHeight) + } + + if lastHeight == 0 { + if gen == nil { + return fmt.Errorf("non empty directory but no blocks found") + } + + genDoc, err := gen.Export() + if err != nil { + return fmt.Errorf("failed to export genesis document: %w", err) + } + + state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc) + if err != nil { + return fmt.Errorf("failed to load state from database or genesis document: %w", err) + } + + validators := make([]*types.Validator, len(genDoc.Validators)) + for i, val := range genDoc.Validators { + validators[i] = types.NewValidator(val.PubKey, val.Power) + } + validatorSet := types.NewValidatorSet(validators) + nextVals := types.TM2PB.ValidatorUpdates(validatorSet) + csParams := types.TM2PB.ConsensusParams(genDoc.ConsensusParams) + res := simApp.InitChain(abci.RequestInitChain{ + ChainId: genDoc.ChainID, + Time: genDoc.GenesisTime, + ConsensusParams: csParams, + Validators: nextVals, + AppStateBytes: genDoc.AppState, + InitialHeight: genDoc.InitialHeight, + }) + + vals, err := types.PB2TM.ValidatorUpdates(res.Validators) + if err != nil { + return fmt.Errorf("failed to convert validator updates: %w", err) + } + state.Validators = types.NewValidatorSet(vals) + state.NextValidators = types.NewValidatorSet(vals).CopyIncrementProposerPriority(1) + state.AppHash = res.AppHash + state.LastResultsHash = merkle.HashFromByteSlices(nil) + if err := stateStore.Save(state); err != nil { + return fmt.Errorf("failed to save initial state: %w", err) + } + currentTime = currentTime.Add(cfg.BlockInterval) + } else { + fmt.Println("Starting from height", lastHeight) + } + state, err := stateStore.Load() + if err != nil { + return fmt.Errorf("failed to load state: %w", err) + } + if cfg.ExistingDir != "" { + // if this is extending an existing chain, we want to start + // the time to be where the existing chain left off + currentTime = state.LastBlockTime.Add(cfg.BlockInterval) + } + + if state.ConsensusParams.Version.AppVersion != cfg.AppVersion { + return fmt.Errorf("app version mismatch: state has %d, but cfg has %d", state.ConsensusParams.Version.AppVersion, cfg.AppVersion) + } + + if state.LastBlockHeight != lastHeight { + return fmt.Errorf("last block height mismatch: state has %d, but block store has %d", state.LastBlockHeight, lastHeight) + } + + validatorPower := state.Validators.Validators[0].VotingPower + + signer, err := user.NewSigner( + kr, + encCfg.TxConfig, + state.ChainID, + state.ConsensusParams.Version.AppVersion, + user.NewAccount(testnode.DefaultValidatorAccountName, 0, uint64(lastHeight)+1), + ) + if err != nil { + return fmt.Errorf("failed to create new signer: %w", err) + } + + var ( + errCh = make(chan error, 2) + dataCh = make(chan *tmproto.Data, 100) + persistCh = make(chan persistData, 100) + commit = types.NewCommit(0, 0, types.BlockID{}, nil) + ) + if lastHeight > 0 { + commit = blockStore.LoadSeenCommit(lastHeight) + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + go func() { + errCh <- generateSquareRoutine(ctx, signer, cfg, dataCh) + }() + + go func() { + errCh <- persistDataRoutine(ctx, stateStore, blockStore, persistCh) + }() + + lastBlock := blockStore.LoadBlock(blockStore.Height()) + + for height := lastHeight + 1; height <= int64(cfg.NumBlocks)+lastHeight; height++ { + if cfg.UpToTime && lastBlock != nil && lastBlock.Time.Add(cfg.BlockInterval).After(time.Now().UTC()) { + fmt.Printf("blocks cannot be generated into the future, stopping at height %d\n", lastBlock.Height) + break + } + + select { + case <-ctx.Done(): + return ctx.Err() + case dataPB := <-dataCh: + data, err := types.DataFromProto(dataPB) + if err != nil { + return fmt.Errorf("failed to convert data from protobuf: %w", err) + } + block, blockParts := state.MakeBlock(height, data, commit, nil, validatorAddr) + blockID := types.BlockID{ + Hash: block.Hash(), + PartSetHeader: blockParts.Header(), + } + + precommitVote := &tmproto.Vote{ + Height: height, + Round: 0, + Type: tmproto.PrecommitType, + BlockID: blockID.ToProto(), + ValidatorAddress: validatorAddr, + Timestamp: currentTime, + Signature: nil, + } + + if err := validatorKey.SignVote(state.ChainID, precommitVote); err != nil { + return fmt.Errorf("failed to sign precommit vote (%s): %w", precommitVote.String(), err) + } + + commitSig := types.CommitSig{ + BlockIDFlag: types.BlockIDFlagCommit, + ValidatorAddress: validatorAddr, + Timestamp: currentTime, + Signature: precommitVote.Signature, + } + commit = types.NewCommit(height, 0, blockID, []types.CommitSig{commitSig}) + + var lastCommitInfo abci.LastCommitInfo + if height > 1 { + lastCommitInfo = abci.LastCommitInfo{ + Round: 0, + Votes: []abci.VoteInfo{ + { + Validator: abci.Validator{ + Address: validatorAddr, + Power: validatorPower, + }, + SignedLastBlock: true, + }, + }, + } + } + + beginBlockResp := simApp.BeginBlock(abci.RequestBeginBlock{ + Hash: block.Hash(), + Header: *block.Header.ToProto(), + LastCommitInfo: lastCommitInfo, + }) + + deliverTxResponses := make([]*abci.ResponseDeliverTx, len(block.Data.Txs)) + + for idx, tx := range block.Data.Txs { + blobTx, isBlobTx := types.UnmarshalBlobTx(tx) + if isBlobTx { + tx = blobTx.Tx + } + deliverTxResponse := simApp.DeliverTx(abci.RequestDeliverTx{ + Tx: tx, + }) + if deliverTxResponse.Code != abci.CodeTypeOK { + return fmt.Errorf("failed to deliver tx: %s", deliverTxResponse.Log) + } + deliverTxResponses[idx] = &deliverTxResponse + } + + endBlockResp := simApp.EndBlock(abci.RequestEndBlock{ + Height: block.Height, + }) + + commitResp := simApp.Commit() + state.LastBlockHeight = height + state.LastBlockID = blockID + state.LastBlockTime = block.Time + state.LastValidators = state.Validators + state.Validators = state.NextValidators + state.NextValidators = state.NextValidators.CopyIncrementProposerPriority(1) + state.AppHash = commitResp.Data + state.LastResultsHash = sm.ABCIResponsesResultsHash(&smproto.ABCIResponses{ + DeliverTxs: deliverTxResponses, + BeginBlock: &beginBlockResp, + EndBlock: &endBlockResp, + }) + currentTime = currentTime.Add(cfg.BlockInterval) + persistCh <- persistData{ + state: state.Copy(), + block: block, + seenCommit: &types.Commit{ + Height: commit.Height, + Round: commit.Round, + BlockID: commit.BlockID, + Signatures: []types.CommitSig{commitSig}, + }, + } + } + } + + close(dataCh) + close(persistCh) + + var firstErr error + for i := 0; i < cap(errCh); i++ { + err := <-errCh + if err != nil && firstErr == nil { + firstErr = err + } + } + + if err := blockDB.Close(); err != nil { + return fmt.Errorf("failed to close block database: %w", err) + } + if err := stateDB.Close(); err != nil { + return fmt.Errorf("failed to close state database: %w", err) + } + if err := appDB.Close(); err != nil { + return fmt.Errorf("failed to close application database: %w", err) + } + + fmt.Println("Chain built successfully", state.LastBlockHeight) + + return firstErr +} + +func generateSquareRoutine( + ctx context.Context, + signer *user.Signer, + cfg BuilderConfig, + dataCh chan<- *tmproto.Data, +) error { + for i := 0; i < cfg.NumBlocks; i++ { + select { + case <-ctx.Done(): + return ctx.Err() + default: + } + + account := signer.Accounts()[0] + + blob, err := share.NewV0Blob(cfg.Namespace, crypto.CRandBytes(cfg.BlockSize)) + if err != nil { + return err + } + + blobGas := blobtypes.DefaultEstimateGas([]uint32{uint32(cfg.BlockSize)}) + fee := float64(blobGas) * appconsts.DefaultMinGasPrice * 2 + tx, _, err := signer.CreatePayForBlobs(account.Name(), []*share.Blob{blob}, user.SetGasLimit(blobGas), user.SetFee(uint64(fee))) + if err != nil { + return err + } + if err := signer.IncrementSequence(account.Name()); err != nil { + return err + } + + dataSquare, txs, err := square.Build( + [][]byte{tx}, + maxSquareSize, + appconsts.SubtreeRootThreshold(1), + ) + if err != nil { + return err + } + + eds, err := da.ExtendShares(share.ToBytes(dataSquare)) + if err != nil { + return err + } + + dah, err := da.NewDataAvailabilityHeader(eds) + if err != nil { + return err + } + + select { + case dataCh <- &tmproto.Data{ + Txs: txs, + Hash: dah.Hash(), + SquareSize: uint64(dataSquare.Size()), + }: + case <-ctx.Done(): + return ctx.Err() + } + } + return nil +} + +type persistData struct { + state sm.State + block *types.Block + seenCommit *types.Commit +} + +func persistDataRoutine( + ctx context.Context, + stateStore sm.Store, + blockStore *store.BlockStore, + dataCh <-chan persistData, +) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + case data, ok := <-dataCh: + if !ok { + return nil + } + blockParts := data.block.MakePartSet(types.BlockPartSizeBytes) + blockStore.SaveBlock(data.block, blockParts, data.seenCommit) + if blockStore.Height()%100 == 0 { + fmt.Println("Reached height", blockStore.Height()) + } + + if err := stateStore.Save(data.state); err != nil { + return err + } + } + } +} diff --git a/x/blob/README.md b/x/blob/README.md index c39250b33b..efa1f74858 100644 --- a/x/blob/README.md +++ b/x/blob/README.md @@ -13,9 +13,9 @@ To use the blob module, users create and submit a `BlobTx` that is composed of: After the `BlobTx` is submitted to the network, a block producer separates the `sdk.Tx` from the blob(s). Both components get included in the -[data square](../../specs/src/specs/data_square_layout.md) in different namespaces: +[data square](../../specs/src/data_square_layout.md) in different namespaces: -1. The `sdk.Tx` and some metadata about the separated blobs gets included in the `PayForBlobNamespace` (one of the [reserved namespaces](../../specs/src/specs/namespace.md#reserved-namespaces)). +1. The `sdk.Tx` and some metadata about the separated blobs gets included in the `PayForBlobNamespace` (one of the [reserved namespaces](../../specs/src/namespace.md#reserved-namespaces)). 1. The blob(s) get included in the namespace specified by each blob. After a block has been created, the user can verify that their data was included @@ -49,6 +49,7 @@ message Params { `GasPerBlobByte` is the amount of gas that is consumed per byte of blob data when a `MsgPayForBlobs` is processed. Currently, the default value is 8. This value is set below that of normal transaction gas consumption, which is 10. +`GasPerBlobByte` was a governance-modifiable parameter in v1 and v2. In app v3 and above, it is a versioned parameter, meaning it can only be changed through hard fork upgrades. #### `GovMaxSquareSize` @@ -89,10 +90,9 @@ message MsgPayForBlobs { The share commitment is the commitment to share encoded blobs. It can be used for cheap inclusion checks for some data by light clients. More information and -rational can be found in the [data square layout -specs](../../specs/src/specs/data_square_layout.md). +rational can be found in the [data square layout](../../specs/src/data_square_layout.md) specification. -1. Split the blob into shares of size [`shareSize`](../../specs/src/specs/data_structures.md#consensus-parameters) +1. Split the blob into shares of size [`shareSize`](../../specs/src/data_structures.md#consensus-parameters) 1. Determine the [`SubtreeWidth`](https://github.com/celestiaorg/celestia-app/blob/v1.0.0-rc2/pkg/shares/non_interactive_defaults.go#L94-L116) by dividing the length in shares by the `SubtreeRootThreshold`. @@ -106,8 +106,7 @@ specs](../../specs/src/specs/data_square_layout.md). See [`CreateCommitment`](https://github.com/celestiaorg/celestia-app/blob/v1.0.0-rc2/x/blob/types/payforblob.go#L169-L236) -for an implementation. See [data square -layout](../../specs/src/specs/data_square_layout.md) and +for an implementation. See [data square layout](../../specs/src/data_square_layout.md) and [ADR013](../../docs/architecture/adr-013-non-interactive-default-rules-for-zero-padding.md) for details on the rational of the square layout. @@ -145,9 +144,7 @@ each PFB, to be included in a block must follow a set of validity rules. When a block producer is preparing a block, they must perform an extra step for `BlobTx`s so that end-users can find the blob shares relevant to their submitted `BlobTx`. In particular, block proposers wrap the `BlobTx` in the PFB namespace -with the index of the first share of the blob in the data square. See [Blob -share commitment -rules](../../specs/src/specs/data_square_layout.md#blob-share-commitment-rules) +with the index of the first share of the blob in the data square. See [Blob share commitment rules](../../specs/src/data_square_layout.md#blob-share-commitment-rules) for more details. Since `BlobTx`s can contain multiple blobs, the `sdk.Tx` portion of the `BlobTx` diff --git a/x/blob/ante/ante.go b/x/blob/ante/ante.go index fe58eae87c..3c5249b291 100644 --- a/x/blob/ante/ante.go +++ b/x/blob/ante/ante.go @@ -1,6 +1,8 @@ package ante import ( + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "cosmossdk.io/errors" @@ -33,8 +35,12 @@ func (d MinGasPFBDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool // NOTE: here we assume only one PFB per transaction if pfb, ok := m.(*types.MsgPayForBlobs); ok { if gasPerByte == 0 { - // lazily fetch the gas per byte param - gasPerByte = d.k.GasPerBlobByte(ctx) + if ctx.BlockHeader().Version.App <= v2.Version { + // lazily fetch the gas per byte param + gasPerByte = d.k.GasPerBlobByte(ctx) + } else { + gasPerByte = appconsts.GasPerBlobByte(ctx.BlockHeader().Version.App) + } } gasToConsume := pfb.Gas(gasPerByte) if gasToConsume > txGas { diff --git a/x/blob/ante/ante_test.go b/x/blob/ante/ante_test.go index e1f16e2b7a..6be76d77d9 100644 --- a/x/blob/ante/ante_test.go +++ b/x/blob/ante/ante_test.go @@ -1,15 +1,20 @@ package ante_test import ( + "fmt" "testing" "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" ante "github.com/celestiaorg/celestia-app/v3/x/blob/ante" blob "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/celestiaorg/go-square/v2/share" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/proto/tendermint/version" ) const ( @@ -22,8 +27,9 @@ func TestPFBAnteHandler(t *testing.T) { testCases := []struct { name string pfb *blob.MsgPayForBlobs - txGas uint64 + txGas func(uint32) uint32 gasConsumed uint64 + versions []uint64 wantErr bool }{ { @@ -32,8 +38,11 @@ func TestPFBAnteHandler(t *testing.T) { // 1 share = 512 bytes = 5120 gas BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1))}, }, - txGas: share.ShareSize * testGasPerBlobByte, + txGas: func(testGasPerBlobByte uint32) uint32 { + return share.ShareSize * testGasPerBlobByte + }, gasConsumed: 0, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: false, }, { @@ -41,8 +50,11 @@ func TestPFBAnteHandler(t *testing.T) { pfb: &blob.MsgPayForBlobs{ BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1)), uint32(share.AvailableBytesFromSparseShares(2))}, }, - txGas: 3 * share.ShareSize * testGasPerBlobByte, + txGas: func(testGasPerBlobByte uint32) uint32 { + return 3 * share.ShareSize * testGasPerBlobByte + }, gasConsumed: 0, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: false, }, { @@ -51,8 +63,11 @@ func TestPFBAnteHandler(t *testing.T) { // 2 share = 1024 bytes = 10240 gas BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1) + 1)}, }, - txGas: 2*share.ShareSize*testGasPerBlobByte - 1, + txGas: func(testGasPerBlobByte uint32) uint32 { + return 2*share.ShareSize*testGasPerBlobByte - 1 + }, gasConsumed: 0, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: true, }, { @@ -60,8 +75,11 @@ func TestPFBAnteHandler(t *testing.T) { pfb: &blob.MsgPayForBlobs{ BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1)), uint32(share.AvailableBytesFromSparseShares(2))}, }, - txGas: 3*share.ShareSize*testGasPerBlobByte - 1, + txGas: func(testGasPerBlobByte uint32) uint32 { + return 3*share.ShareSize*testGasPerBlobByte - 1 + }, gasConsumed: 0, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: true, }, { @@ -70,8 +88,11 @@ func TestPFBAnteHandler(t *testing.T) { // 1 share = 512 bytes = 5120 gas BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1))}, }, - txGas: share.ShareSize*testGasPerBlobByte + 10000 - 1, + txGas: func(testGasPerBlobByte uint32) uint32 { + return share.ShareSize*testGasPerBlobByte + 10000 - 1 + }, gasConsumed: 10000, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: true, }, { @@ -80,26 +101,43 @@ func TestPFBAnteHandler(t *testing.T) { // 1 share = 512 bytes = 5120 gas BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(10))}, }, - txGas: 1000000, + txGas: func(_ uint32) uint32 { + return 1000000 + }, gasConsumed: 10000, + versions: []uint64{v2.Version, appconsts.LatestVersion}, wantErr: false, }, } for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - anteHandler := ante.NewMinGasPFBDecorator(mockBlobKeeper{}) - ctx := sdk.Context{}.WithGasMeter(sdk.NewGasMeter(tc.txGas)).WithIsCheckTx(true) - ctx.GasMeter().ConsumeGas(tc.gasConsumed, "test") - txBuilder := txConfig.NewTxBuilder() - require.NoError(t, txBuilder.SetMsgs(tc.pfb)) - tx := txBuilder.GetTx() - _, err := anteHandler.AnteHandle(ctx, tx, false, func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { return ctx, nil }) - if tc.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) + for _, currentVersion := range tc.versions { + t.Run(fmt.Sprintf("%s v%d", tc.name, currentVersion), func(t *testing.T) { + anteHandler := ante.NewMinGasPFBDecorator(mockBlobKeeper{}) + var gasPerBlobByte uint32 + if currentVersion == v2.Version { + gasPerBlobByte = testGasPerBlobByte + } else { + gasPerBlobByte = appconsts.GasPerBlobByte(currentVersion) + } + + ctx := sdk.NewContext(nil, tmproto.Header{ + Version: version.Consensus{ + App: currentVersion, + }, + }, true, nil).WithGasMeter(sdk.NewGasMeter(uint64(tc.txGas(gasPerBlobByte)))).WithIsCheckTx(true) + + ctx.GasMeter().ConsumeGas(tc.gasConsumed, "test") + txBuilder := txConfig.NewTxBuilder() + require.NoError(t, txBuilder.SetMsgs(tc.pfb)) + tx := txBuilder.GetTx() + _, err := anteHandler.AnteHandle(ctx, tx, false, func(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { return ctx, nil }) + if tc.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } } } diff --git a/x/blob/ante/blob_share_decorator.go b/x/blob/ante/blob_share_decorator.go index 3a23f45588..90eb7780c6 100644 --- a/x/blob/ante/blob_share_decorator.go +++ b/x/blob/ante/blob_share_decorator.go @@ -36,7 +36,7 @@ func (d BlobShareDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool maxBlobShares := d.getMaxBlobShares(ctx) for _, m := range tx.GetMsgs() { if pfb, ok := m.(*blobtypes.MsgPayForBlobs); ok { - if sharesNeeded := getSharesNeeded(pfb.BlobSizes); sharesNeeded > maxBlobShares { + if sharesNeeded := getSharesNeeded(uint32(len(ctx.TxBytes())), pfb.BlobSizes); sharesNeeded > maxBlobShares { return ctx, errors.Wrapf(blobtypes.ErrBlobsTooLarge, "the number of shares occupied by blobs in this MsgPayForBlobs %d exceeds the max number of shares available for blob data %d", sharesNeeded, maxBlobShares) } } @@ -49,10 +49,8 @@ func (d BlobShareDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool func (d BlobShareDecorator) getMaxBlobShares(ctx sdk.Context) int { squareSize := d.getMaxSquareSize(ctx) totalShares := squareSize * squareSize - // The PFB tx share must occupy at least one share so the number of blob shares - // is at most one less than totalShares. - blobShares := totalShares - 1 - return blobShares + // the shares used up by the tx are calculated in `getSharesNeeded` + return totalShares } // getMaxSquareSize returns the maximum square size based on the current values @@ -74,8 +72,9 @@ func (d BlobShareDecorator) getMaxSquareSize(ctx sdk.Context) int { } // getSharesNeeded returns the total number of shares needed to represent all of -// the blobs described by blobSizes. -func getSharesNeeded(blobSizes []uint32) (sum int) { +// the blobs described by blobSizes along with the shares used by the tx +func getSharesNeeded(txSize uint32, blobSizes []uint32) (sum int) { + sum = share.CompactSharesNeeded(txSize) for _, blobSize := range blobSizes { sum += share.SparseSharesNeeded(blobSize) } diff --git a/x/blob/ante/blob_share_decorator_test.go b/x/blob/ante/blob_share_decorator_test.go index 6c788e1935..e65dca6c3f 100644 --- a/x/blob/ante/blob_share_decorator_test.go +++ b/x/blob/ante/blob_share_decorator_test.go @@ -7,12 +7,18 @@ import ( "github.com/celestiaorg/celestia-app/v3/app/encoding" v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + "github.com/celestiaorg/celestia-app/v3/pkg/user" + "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" + "github.com/celestiaorg/celestia-app/v3/test/util/testfactory" + "github.com/celestiaorg/celestia-app/v3/test/util/testnode" ante "github.com/celestiaorg/celestia-app/v3/x/blob/ante" blob "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/celestiaorg/go-square/v2/share" + blobtx "github.com/celestiaorg/go-square/v2/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" version "github.com/tendermint/tendermint/proto/tendermint/version" ) @@ -24,141 +30,137 @@ const ( func TestBlobShareDecorator(t *testing.T) { type testCase struct { - name string - pfb *blob.MsgPayForBlobs - appVersion uint64 - wantErr error + name string + blobsPerPFB, blobSize int + appVersion uint64 + wantErr error } + rand := tmrand.NewRand() + testCases := []testCase{ { - name: "want no error if appVersion v1 and 8 MiB blob", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{8 * mebibyte}, - }, - appVersion: v1.Version, + name: "want no error if appVersion v1 and 8 MiB blob", + blobsPerPFB: 1, + blobSize: 8 * mebibyte, + appVersion: v1.Version, }, { - name: "PFB with 1 blob that is 1 byte", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{1}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that is 1 byte", + blobsPerPFB: 1, + blobSize: 1, + appVersion: v2.Version, }, { - name: "PFB with 1 blob that is 1 MiB", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{mebibyte}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that is 1 MiB", + blobsPerPFB: 1, + blobSize: 1 * mebibyte, + appVersion: v2.Version, }, { - name: "PFB with 1 blob that is 2 MiB", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{2 * mebibyte}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that is 2 MiB", + blobsPerPFB: 1, + blobSize: 2 * mebibyte, + appVersion: v2.Version, // This test case should return an error because a square size of 64 // has exactly 2 MiB of total capacity so the total blob capacity // will be slightly smaller than 2 MiB. wantErr: blob.ErrBlobsTooLarge, }, { - name: "PFB with 2 blobs that are 1 byte each", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{1, 1}, - }, - appVersion: v2.Version, + name: "PFB with 2 blobs that are 1 byte each", + blobsPerPFB: 2, + blobSize: 1, + appVersion: v2.Version, }, { - name: "PFB with 2 blobs that are 1 MiB each", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{mebibyte, mebibyte}, - }, - appVersion: v2.Version, + name: "PFB with 2 blobs that are 1 MiB each", + blobsPerPFB: 2, + blobSize: 1 * mebibyte, + appVersion: v2.Version, // This test case should return an error for the same reason a // single blob that is 2 MiB returns an error. wantErr: blob.ErrBlobsTooLarge, }, { - name: "PFB with many single byte blobs should fit", - pfb: &blob.MsgPayForBlobs{ - // 4095 blobs each of size 1 byte should occupy 4095 shares. - // When square size is 64, there are 4095 shares available to - // blob shares so we don't expect an error for this test case. - BlobSizes: repeat(4095, 1), - }, - appVersion: v2.Version, + name: "PFB with many single byte blobs should fit", + blobsPerPFB: 3000, + blobSize: 1, + appVersion: v2.Version, }, { - name: "PFB with too many single byte blobs should not fit", - pfb: &blob.MsgPayForBlobs{ - // 4096 blobs each of size 1 byte should occupy 4096 shares. - // When square size is 64, there are 4095 shares available to - // blob shares so we expect an error for this test case. - BlobSizes: repeat(4096, 1), - }, - appVersion: v2.Version, - wantErr: blob.ErrBlobsTooLarge, + name: "PFB with too many single byte blobs should not fit", + blobsPerPFB: 4000, + blobSize: 1, + appVersion: v2.Version, + wantErr: blob.ErrBlobsTooLarge, }, { - name: "PFB with 1 blob that is 1 share", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(1))}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that is 1 share", + blobsPerPFB: 1, + blobSize: 100, + appVersion: v2.Version, }, { - name: "PFB with 1 blob that occupies total square - 1", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares((squareSize * squareSize) - 1))}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that occupies total square - 1", + blobsPerPFB: 1, + blobSize: share.AvailableBytesFromSparseShares(squareSize*squareSize - 1), + appVersion: v2.Version, }, { - name: "PFB with 1 blob that occupies total square", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{uint32(share.AvailableBytesFromSparseShares(squareSize * squareSize))}, - }, - appVersion: v2.Version, + name: "PFB with 1 blob that occupies total square", + blobsPerPFB: 1, + blobSize: share.AvailableBytesFromSparseShares(squareSize * squareSize), + appVersion: v2.Version, // This test case should return an error because if the blob // occupies the total square, there is no space for the PFB tx // share. wantErr: blob.ErrBlobsTooLarge, }, { - name: "PFB with 2 blobs that are 1 share each", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{ - uint32(share.AvailableBytesFromSparseShares(1)), - uint32(share.AvailableBytesFromSparseShares(1)), - }, - }, - appVersion: v2.Version, + name: "PFB with 2 blobs that are 1 share each", + blobsPerPFB: 2, + blobSize: 100, + appVersion: v2.Version, }, { - name: "PFB with 2 blobs that occupy half the square each", - pfb: &blob.MsgPayForBlobs{ - BlobSizes: []uint32{ - uint32(share.AvailableBytesFromSparseShares(squareSize * squareSize / 2)), - uint32(share.AvailableBytesFromSparseShares(squareSize * squareSize / 2)), - }, - }, - appVersion: v2.Version, - wantErr: blob.ErrBlobsTooLarge, + name: "PFB with 2 blobs that occupy half the square each", + blobsPerPFB: 2, + blobSize: share.AvailableBytesFromSparseShares(squareSize * squareSize / 2), + appVersion: v2.Version, + wantErr: blob.ErrBlobsTooLarge, }, } - txConfig := encoding.MakeConfig(app.ModuleEncodingRegisters...).TxConfig + ecfg := encoding.MakeConfig(app.ModuleEncodingRegisters...) + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - txBuilder := txConfig.NewTxBuilder() - require.NoError(t, txBuilder.SetMsgs(tc.pfb)) - tx := txBuilder.GetTx() + kr, _ := testnode.NewKeyring(testfactory.TestAccName) + signer, err := user.NewSigner( + kr, + ecfg.TxConfig, + testfactory.ChainID, + tc.appVersion, + user.NewAccount(testfactory.TestAccName, 1, 0), + ) + require.NoError(t, err) + + blobTx := blobfactory.RandBlobTxs(signer, rand, 1, tc.blobsPerPFB, tc.blobSize) + + btx, isBlob, err := blobtx.UnmarshalBlobTx([]byte(blobTx[0])) + require.NoError(t, err) + require.True(t, isBlob) + + sdkTx, err := ecfg.TxConfig.TxDecoder()(btx.Tx) + require.NoError(t, err) decorator := ante.NewBlobShareDecorator(mockBlobKeeper{}) - ctx := sdk.Context{}.WithIsCheckTx(true).WithBlockHeader(tmproto.Header{Version: version.Consensus{App: tc.appVersion}}) - _, err := decorator.AnteHandle(ctx, tx, false, mockNext) + ctx := sdk.Context{}. + WithIsCheckTx(true). + WithBlockHeader(tmproto.Header{Version: version.Consensus{App: tc.appVersion}}). + WithTxBytes(btx.Tx) + _, err = decorator.AnteHandle(ctx, sdkTx, false, mockNext) assert.ErrorIs(t, tc.wantErr, err) }) } @@ -167,12 +169,3 @@ func TestBlobShareDecorator(t *testing.T) { func mockNext(ctx sdk.Context, _ sdk.Tx, _ bool) (sdk.Context, error) { return ctx, nil } - -// repeat returns a slice of length n with each element set to val. -func repeat(n int, val uint32) []uint32 { - result := make([]uint32, n) - for i := range result { - result[i] = val - } - return result -} diff --git a/x/blob/client/testutil/integration_test.go b/x/blob/client/testutil/integration_test.go index d29de7f658..b5f6c24db2 100644 --- a/x/blob/client/testutil/integration_test.go +++ b/x/blob/client/testutil/integration_test.go @@ -143,7 +143,6 @@ func (s *IntegrationTestSuite) TestSubmitPayForBlob() { } for _, tc := range testCases { - tc := tc require.NoError(s.ctx.WaitForNextBlock()) s.Run(tc.name, func() { cmd := paycli.CmdPayForBlob() diff --git a/x/blob/keeper/gas_test.go b/x/blob/keeper/gas_test.go index 8c7bd534ff..a1e17a2bdd 100644 --- a/x/blob/keeper/gas_test.go +++ b/x/blob/keeper/gas_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "testing" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/celestiaorg/go-square/v2/share" sdk "github.com/cosmos/cosmos-sdk/types" @@ -23,33 +24,33 @@ func TestPayForBlobGas(t *testing.T) { { name: "1 byte blob", // occupies 1 share msg: types.MsgPayForBlobs{BlobSizes: []uint32{1}}, - wantGasConsumed: uint64(1*share.ShareSize*types.DefaultGasPerBlobByte + paramLookUpCost), // 1 share * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 5156 gas + wantGasConsumed: uint64(1*share.ShareSize*appconsts.GasPerBlobByte(appconsts.LatestVersion) + paramLookUpCost), // 1 share * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 5156 gas }, { name: "100 byte blob", // occupies 1 share msg: types.MsgPayForBlobs{BlobSizes: []uint32{100}}, - wantGasConsumed: uint64(1*share.ShareSize*types.DefaultGasPerBlobByte + paramLookUpCost), + wantGasConsumed: uint64(1*share.ShareSize*appconsts.GasPerBlobByte(appconsts.LatestVersion) + paramLookUpCost), }, { name: "1024 byte blob", // occupies 3 shares because share prefix (e.g. namespace, info byte) msg: types.MsgPayForBlobs{BlobSizes: []uint32{1024}}, - wantGasConsumed: uint64(3*share.ShareSize*types.DefaultGasPerBlobByte + paramLookUpCost), // 3 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 13348 gas + wantGasConsumed: uint64(3*share.ShareSize*appconsts.GasPerBlobByte(appconsts.LatestVersion) + paramLookUpCost), // 3 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 13348 gas }, { name: "3 blobs, 1 share each", msg: types.MsgPayForBlobs{BlobSizes: []uint32{1, 1, 1}}, - wantGasConsumed: uint64(3*share.ShareSize*types.DefaultGasPerBlobByte + paramLookUpCost), // 3 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 13348 gas + wantGasConsumed: uint64(3*share.ShareSize*appconsts.GasPerBlobByte(appconsts.LatestVersion) + paramLookUpCost), // 3 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 13348 gas }, { name: "3 blobs, 6 shares total", msg: types.MsgPayForBlobs{BlobSizes: []uint32{1024, 800, 100}}, - wantGasConsumed: uint64(6*share.ShareSize*types.DefaultGasPerBlobByte + paramLookUpCost), // 6 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 25636 gas + wantGasConsumed: uint64(6*share.ShareSize*appconsts.GasPerBlobByte(appconsts.LatestVersion) + paramLookUpCost), // 6 shares * 512 bytes per share * 8 gas per byte + 1060 gas for fetching param = 25636 gas }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - k, stateStore, _ := CreateKeeper(t) + k, stateStore, _ := CreateKeeper(t, appconsts.LatestVersion) ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, nil) _, err := k.PayForBlobs(sdk.WrapSDKContext(ctx), &tc.msg) require.NoError(t, err) @@ -62,7 +63,7 @@ func TestPayForBlobGas(t *testing.T) { func TestChangingGasParam(t *testing.T) { msg := types.MsgPayForBlobs{BlobSizes: []uint32{1024}} - k, stateStore, _ := CreateKeeper(t) + k, stateStore, _ := CreateKeeper(t, appconsts.LatestVersion) tempCtx := sdk.NewContext(stateStore, tmproto.Header{}, false, nil) ctx1 := sdk.NewContext(stateStore, tmproto.Header{}, false, nil) diff --git a/x/blob/keeper/genesis_test.go b/x/blob/keeper/genesis_test.go index d291deebf8..120f9cb21e 100644 --- a/x/blob/keeper/genesis_test.go +++ b/x/blob/keeper/genesis_test.go @@ -3,6 +3,7 @@ package keeper_test import ( "testing" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/blob" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/stretchr/testify/require" @@ -13,7 +14,7 @@ func TestGenesis(t *testing.T) { Params: types.DefaultParams(), } - k, _, ctx := CreateKeeper(t) + k, _, ctx := CreateKeeper(t, appconsts.LatestVersion) blob.InitGenesis(ctx, *k, genesisState) got := blob.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/blob/keeper/grpc_query_params_test.go b/x/blob/keeper/grpc_query_params_test.go index 70f60860ee..e8c367cd35 100644 --- a/x/blob/keeper/grpc_query_params_test.go +++ b/x/blob/keeper/grpc_query_params_test.go @@ -3,13 +3,14 @@ package keeper_test import ( "testing" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/blob/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) func TestParamsQuery(t *testing.T) { - keeper, _, ctx := CreateKeeper(t) + keeper, _, ctx := CreateKeeper(t, appconsts.LatestVersion) wctx := sdk.WrapSDKContext(ctx) params := types.DefaultParams() keeper.SetParams(ctx, params) diff --git a/x/blob/keeper/keeper.go b/x/blob/keeper/keeper.go index 72a3fb7605..a7e0f3cc71 100644 --- a/x/blob/keeper/keeper.go +++ b/x/blob/keeper/keeper.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -43,7 +45,14 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) PayForBlobs(goCtx context.Context, msg *types.MsgPayForBlobs) (*types.MsgPayForBlobsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - gasToConsume := types.GasToConsume(msg.BlobSizes, k.GasPerBlobByte(ctx)) + // GasPerBlobByte is a versioned param from version 3 onwards. + var gasToConsume uint64 + if ctx.BlockHeader().Version.App <= v2.Version { + gasToConsume = types.GasToConsume(msg.BlobSizes, k.GasPerBlobByte(ctx)) + } else { + gasToConsume = types.GasToConsume(msg.BlobSizes, appconsts.GasPerBlobByte(ctx.BlockHeader().Version.App)) + } + ctx.GasMeter().ConsumeGas(gasToConsume, payForBlobGasDescriptor) err := ctx.EventManager().EmitTypedEvent( diff --git a/x/blob/keeper/keeper_test.go b/x/blob/keeper/keeper_test.go index e3da5cb12a..8fee7f81a8 100644 --- a/x/blob/keeper/keeper_test.go +++ b/x/blob/keeper/keeper_test.go @@ -27,7 +27,7 @@ import ( // TestPayForBlobs verifies the attributes on the emitted event. func TestPayForBlobs(t *testing.T) { - k, _, ctx := CreateKeeper(t) + k, _, ctx := CreateKeeper(t, appconsts.LatestVersion) signer := "celestia15drmhzw5kwgenvemy30rqqqgq52axf5wwrruf7" namespace := share.MustNewV0Namespace(bytes.Repeat([]byte{1}, share.NamespaceVersionZeroIDSize)) namespaces := [][]byte{namespace.Bytes()} @@ -72,7 +72,7 @@ func createMsgPayForBlob(t *testing.T, signer string, namespace share.Namespace, return msg } -func CreateKeeper(t *testing.T) (*keeper.Keeper, store.CommitMultiStore, sdk.Context) { +func CreateKeeper(t *testing.T, version uint64) (*keeper.Keeper, store.CommitMultiStore, sdk.Context) { storeKey := sdk.NewKVStoreKey(paramtypes.StoreKey) tStoreKey := storetypes.NewTransientStoreKey(paramtypes.TStoreKey) @@ -87,7 +87,7 @@ func CreateKeeper(t *testing.T) (*keeper.Keeper, store.CommitMultiStore, sdk.Con ctx := sdk.NewContext(stateStore, tmproto.Header{ Version: tmversion.Consensus{ Block: 1, - App: 1, + App: version, }, }, false, nil) diff --git a/x/blob/keeper/params_test.go b/x/blob/keeper/params_test.go index 9431ef3828..53f5dbca20 100644 --- a/x/blob/keeper/params_test.go +++ b/x/blob/keeper/params_test.go @@ -3,12 +3,13 @@ package keeper_test import ( "testing" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" "github.com/celestiaorg/celestia-app/v3/x/blob/types" "github.com/stretchr/testify/require" ) func TestGetParams(t *testing.T) { - k, _, ctx := CreateKeeper(t) + k, _, ctx := CreateKeeper(t, appconsts.LatestVersion) params := types.DefaultParams() k.SetParams(ctx, params) diff --git a/x/blob/types/blob_tx.go b/x/blob/types/blob_tx.go index 1f6273f10c..8089e247ef 100644 --- a/x/blob/types/blob_tx.go +++ b/x/blob/types/blob_tx.go @@ -3,6 +3,7 @@ package types import ( "bytes" + v3 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v3" "github.com/celestiaorg/go-square/v2/inclusion" "github.com/celestiaorg/go-square/v2/share" "github.com/celestiaorg/go-square/v2/tx" @@ -35,7 +36,7 @@ func NewV1Blob(ns share.Namespace, data []byte, signer sdk.AccAddress) (*share.B // ValidateBlobTx performs stateless checks on the BlobTx to ensure that the // blobs attached to the transaction are valid. -func ValidateBlobTx(txcfg client.TxEncodingConfig, bTx *tx.BlobTx, subtreeRootThreshold int) error { +func ValidateBlobTx(txcfg client.TxEncodingConfig, bTx *tx.BlobTx, subtreeRootThreshold int, appVersion uint64) error { if bTx == nil { return ErrNoBlobs } @@ -79,6 +80,9 @@ func ValidateBlobTx(txcfg client.TxEncodingConfig, bTx *tx.BlobTx, subtreeRootTh // If share version is 1, assert that the signer in the blob // matches the signer in the msgPFB. if blob.ShareVersion() == share.ShareVersionOne { + if appVersion < v3.Version { + return ErrUnsupportedShareVersion.Wrapf("share version %d is not supported in %d. Supported from v3 onwards", blob.ShareVersion(), appVersion) + } if !bytes.Equal(blob.Signer(), signer) { return ErrInvalidBlobSigner.Wrapf("blob signer %s does not match msgPFB signer %s", sdk.AccAddress(blob.Signer()).String(), msgPFB.Signer) } diff --git a/x/blob/types/blob_tx_test.go b/x/blob/types/blob_tx_test.go index 1a2d8295dc..a1867e2d92 100644 --- a/x/blob/types/blob_tx_test.go +++ b/x/blob/types/blob_tx_test.go @@ -251,7 +251,7 @@ func TestValidateBlobTx(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := types.ValidateBlobTx(encCfg.TxConfig, tt.getTx(), appconsts.DefaultSubtreeRootThreshold) + err := types.ValidateBlobTx(encCfg.TxConfig, tt.getTx(), appconsts.DefaultSubtreeRootThreshold, appconsts.LatestVersion) if tt.expectedErr != nil { assert.ErrorIs(t, err, tt.expectedErr, tt.name) } diff --git a/x/blob/types/payforblob.go b/x/blob/types/payforblob.go index 92eca0a4d7..b49eb05394 100644 --- a/x/blob/types/payforblob.go +++ b/x/blob/types/payforblob.go @@ -10,7 +10,6 @@ import ( "github.com/celestiaorg/go-square/v2/share" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - auth "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/tendermint/tendermint/crypto/merkle" "golang.org/x/exp/slices" ) @@ -162,10 +161,9 @@ func EstimateGas(blobSizes []uint32, gasPerByte uint32, txSizeCost uint64) uint6 return GasToConsume(blobSizes, gasPerByte) + (txSizeCost * BytesPerBlobInfo * uint64(len(blobSizes))) + PFBGasFixedCost } -// DefaultEstimateGas runs EstimateGas with the system defaults. The network may change these values -// through governance, thus this function should predominantly be used in testing. +// DefaultEstimateGas runs EstimateGas with the system defaults. func DefaultEstimateGas(blobSizes []uint32) uint64 { - return EstimateGas(blobSizes, appconsts.DefaultGasPerBlobByte, auth.DefaultTxSizeCostPerByte) + return EstimateGas(blobSizes, appconsts.DefaultGasPerBlobByte, appconsts.DefaultTxSizeCostPerByte) } // ValidateBlobNamespace returns an error if the provided namespace is an diff --git a/x/blobstream/integration_test.go b/x/blobstream/integration_test.go index 08a96ecd56..7bb03a49ee 100644 --- a/x/blobstream/integration_test.go +++ b/x/blobstream/integration_test.go @@ -11,6 +11,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/test/util/testnode" blobstreamtypes "github.com/celestiaorg/celestia-app/v3/x/blobstream/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdktx "github.com/cosmos/cosmos-sdk/types/tx" staking "github.com/cosmos/cosmos-sdk/x/staking/types" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" @@ -45,6 +46,8 @@ func (s *BlobstreamIntegrationSuite) SetupSuite() { cctx, _, _ := testnode.NewNetwork(t, cfg) s.ecfg = encoding.MakeConfig(app.ModuleEncodingRegisters...) s.cctx = cctx + + require.NoError(t, s.cctx.WaitForBlocks(10)) } func (s *BlobstreamIntegrationSuite) TestBlobstream() { @@ -80,17 +83,26 @@ func (s *BlobstreamIntegrationSuite) TestBlobstream() { // sign and submit the transactions for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + serviceClient := sdktx.NewServiceClient(s.cctx.GRPCClient) msgs, _ := tt.msgFunc() txClient, err := user.SetupTxClient(s.cctx.GoContext(), s.cctx.Keyring, s.cctx.GRPCClient, s.ecfg) require.NoError(t, err) res, err := txClient.SubmitTx(s.cctx.GoContext(), msgs, blobfactory.DefaultTxOpts()...) if tt.expectedTxCode == abci.CodeTypeOK { require.NoError(t, err) + require.NotNil(t, res) + getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: res.TxHash}) + require.NoError(t, err) + require.Equal(t, tt.expectedTxCode, res.Code, getTxResp.TxResponse.RawLog) } else { require.Error(t, err) + require.Nil(t, res) + txHash := err.(*user.ExecutionError).TxHash + code := err.(*user.ExecutionError).Code + getTxResp, err := serviceClient.GetTx(s.cctx.GoContext(), &sdktx.GetTxRequest{Hash: txHash}) + require.NoError(t, err) + require.Equal(t, tt.expectedTxCode, code, getTxResp.TxResponse.RawLog) } - require.NotNil(t, res) - require.Equal(t, tt.expectedTxCode, res.Code, res.RawLog) }) } } diff --git a/x/blobstream/keeper/keeper_data_commitment.go b/x/blobstream/keeper/keeper_data_commitment.go index 0b0d656992..19bfc6d01c 100644 --- a/x/blobstream/keeper/keeper_data_commitment.go +++ b/x/blobstream/keeper/keeper_data_commitment.go @@ -109,7 +109,7 @@ func (k Keeper) GetLatestDataCommitment(ctx sdk.Context) (types.DataCommitment, return types.DataCommitment{}, err } if !found { - return types.DataCommitment{}, errors.Wrapf(types.ErrAttestationNotFound, fmt.Sprintf("nonce %d", i)) + return types.DataCommitment{}, errors.Wrapf(types.ErrAttestationNotFound, "nonce %d", i) } dcc, ok := att.(*types.DataCommitment) if !ok { @@ -136,7 +136,7 @@ func (k Keeper) HasDataCommitmentInStore(ctx sdk.Context) (bool, error) { return false, err } if !found { - return false, errors.Wrapf(types.ErrAttestationNotFound, fmt.Sprintf("nonce %d", i)) + return false, errors.Wrapf(types.ErrAttestationNotFound, "nonce %d", i) } _, ok := att.(*types.DataCommitment) if !ok { diff --git a/x/blobstream/keeper/keeper_valset_test.go b/x/blobstream/keeper/keeper_valset_test.go index d4b72406bf..6a73da03eb 100644 --- a/x/blobstream/keeper/keeper_valset_test.go +++ b/x/blobstream/keeper/keeper_valset_test.go @@ -57,7 +57,6 @@ func TestCurrentValsetNormalization(t *testing.T) { }, } for msg, spec := range specs { - spec := spec t.Run(msg, func(t *testing.T) { input, ctx := testutil.SetupTestChain(t, spec.srcPowers) r, err := input.BlobstreamKeeper.GetCurrentValset(ctx) diff --git a/x/blobstream/overview.md b/x/blobstream/overview.md index afd3b4c1f8..bfe07a59e4 100644 --- a/x/blobstream/overview.md +++ b/x/blobstream/overview.md @@ -99,7 +99,7 @@ These signatures are then verified in the smart contract using the [`verifySig() ## Security assumptions -The security of the Blobstream relies on an honest majority of the Celestia validator set. This assumption indicates that more than 2/3s of the voting power follows each [block validity rule](../../specs/src/specs/block_validity_rules.md). Additionally, over 2/3s of the voting power sign valid validator set updates and data commitments, as outlined above. +The security of the Blobstream relies on an honest majority of the Celestia validator set. This assumption indicates that more than 2/3s of the voting power follows each [block validity rule](../../specs/src/block_validity_rules.md). Additionally, over 2/3s of the voting power sign valid validator set updates and data commitments, as outlined above. If more than 1/3rd of the validator set stops running their orchestrators, then the Blobstream halts. And, if more than 2/3rds sign invalid data, then the Blobstream contract will commit to invalid data. The only recovery from such a state is to revert to social consensus, potentially slashing the guilty validators and redeploying the smart contracts. diff --git a/x/minfee/grpc_query_test.go b/x/minfee/grpc_query_test.go index a7ab0fdfef..9e797ee828 100644 --- a/x/minfee/grpc_query_test.go +++ b/x/minfee/grpc_query_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/celestiaorg/celestia-app/v3/app" - v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" testutil "github.com/celestiaorg/celestia-app/v3/test/util" "github.com/celestiaorg/celestia-app/v3/x/minfee" sdk "github.com/cosmos/cosmos-sdk/types" @@ -24,5 +24,5 @@ func TestQueryNetworkMinGasPrice(t *testing.T) { require.NoError(t, err) // Check the response - require.Equal(t, v2.NetworkMinGasPrice, resp.NetworkMinGasPrice.MustFloat64()) + require.Equal(t, appconsts.DefaultNetworkMinGasPrice, resp.NetworkMinGasPrice.MustFloat64()) } diff --git a/x/minfee/params.go b/x/minfee/params.go index ef17044d7c..2f1edc3ee8 100644 --- a/x/minfee/params.go +++ b/x/minfee/params.go @@ -3,7 +3,7 @@ package minfee import ( "fmt" - v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" ) @@ -18,7 +18,7 @@ var ( ) func init() { - DefaultNetworkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", v2.NetworkMinGasPrice)) + DefaultNetworkMinGasPriceDec, err := sdk.NewDecFromStr(fmt.Sprintf("%f", appconsts.DefaultNetworkMinGasPrice)) if err != nil { panic(err) } diff --git a/x/mint/client/testutil/suite_test.go b/x/mint/client/testutil/suite_test.go index 9be2f45fc8..4910fcc99d 100644 --- a/x/mint/client/testutil/suite_test.go +++ b/x/mint/client/testutil/suite_test.go @@ -68,8 +68,6 @@ func (s *IntegrationTestSuite) TestGetCmdQueryInflationRate() { } for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { cmd := cli.GetCmdQueryInflationRate() @@ -103,8 +101,6 @@ func (s *IntegrationTestSuite) TestGetCmdQueryAnnualProvisions() { expectedAnnualProvision := mint.InitialInflationRateAsDec().MulInt(sdk.NewInt(testnode.DefaultInitialBalance)) for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { cmd := cli.GetCmdQueryAnnualProvisions() out, err := clitestutil.ExecTestCLICmd(s.cctx.Context, cmd, tc.args) @@ -134,8 +130,6 @@ func (s *IntegrationTestSuite) TestGetCmdQueryGenesisTime() { } for _, tc := range testCases { - tc := tc - s.Run(tc.name, func() { cmd := cli.GetCmdQueryGenesisTime() out, err := clitestutil.ExecTestCLICmd(s.cctx.Context, cmd, tc.args) diff --git a/x/mint/simulation/decoder_test.go b/x/mint/simulation/decoder_test.go index 74a634db87..c4122a316a 100644 --- a/x/mint/simulation/decoder_test.go +++ b/x/mint/simulation/decoder_test.go @@ -51,7 +51,6 @@ func TestDecodeStore(t *testing.T) { } for i, tt := range tests { - i, tt := i, tt t.Run(tt.name, func(t *testing.T) { if tt.expectPanic { require.Panics(t, func() { decoder(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name) diff --git a/x/signal/cli/cli_test.go b/x/signal/cli/cli_test.go index a789090591..0fa3399037 100644 --- a/x/signal/cli/cli_test.go +++ b/x/signal/cli/cli_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/celestiaorg/celestia-app/v3/test/util/testnode" - "github.com/celestiaorg/celestia-app/x/signal/cli" + "github.com/celestiaorg/celestia-app/v3/x/signal/cli" testutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/stretchr/testify/suite" ) diff --git a/x/signal/cli/query.go b/x/signal/cli/query.go index d93dbe721d..a0548c8376 100644 --- a/x/signal/cli/query.go +++ b/x/signal/cli/query.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" diff --git a/x/signal/cli/tx.go b/x/signal/cli/tx.go index 1f4e771d80..0c3e49eeaa 100644 --- a/x/signal/cli/tx.go +++ b/x/signal/cli/tx.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" diff --git a/x/signal/go.mod b/x/signal/go.mod deleted file mode 100644 index 95d8ca707e..0000000000 --- a/x/signal/go.mod +++ /dev/null @@ -1,208 +0,0 @@ -module github.com/celestiaorg/celestia-app/x/signal - -go 1.22.6 - -replace ( - // replace cosmos-sdk with a local copy that exposes config.IsSealed(). - github.com/cosmos/cosmos-sdk => ../../../cosmos-sdk - // Pin to ledger-cosmos-go v0.12.4 to avoid a breaking change introduced in v0.13.0 - // The following replace statement can be removed when we upgrade to cosmos-sdk >= v0.50.0 - github.com/cosmos/ledger-cosmos-go => github.com/cosmos/ledger-cosmos-go v0.12.4 - github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29 -) - -require ( - cosmossdk.io/errors v1.0.1 - cosmossdk.io/math v1.3.0 - github.com/celestiaorg/celestia-app/v3 v3.0.0-20240816121537-a28b9e7160cc - github.com/cosmos/cosmos-sdk v0.46.16 - github.com/cosmos/ibc-go/v6 v6.3.1 - github.com/gogo/protobuf v1.3.3 - github.com/golang/protobuf v1.5.4 - github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - github.com/tendermint/tendermint v0.34.29 - github.com/tendermint/tm-db v0.6.7 - google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 - google.golang.org/grpc v1.65.0 -) - -require ( - cloud.google.com/go v0.112.1 // indirect - cloud.google.com/go/compute/metadata v0.3.0 // indirect - cloud.google.com/go/iam v1.1.6 // indirect - cloud.google.com/go/storage v1.38.0 // indirect - filippo.io/edwards25519 v1.0.0-rc.1 // indirect - github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/99designs/keyring v1.2.2 // indirect - github.com/ChainSafe/go-schnorrkel v1.0.0 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/StackExchange/wmi v1.2.1 // indirect - github.com/Workiva/go-datastructures v1.0.53 // indirect - github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go v1.44.122 // indirect - github.com/beorn7/perks v1.0.1 // indirect - github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/bgentry/speakeasy v0.1.0 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect - github.com/celestiaorg/blobstream-contracts/v3 v3.1.0 // indirect - github.com/celestiaorg/go-square/v2 v2.0.0-rc2 // indirect - github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 // indirect - github.com/celestiaorg/nmt v0.22.1 // indirect - github.com/celestiaorg/rsmt2d v0.14.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect - github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chzyer/readline v1.5.1 // indirect - github.com/cockroachdb/apd/v2 v2.0.2 // indirect - github.com/coinbase/rosetta-sdk-go v0.7.9 // indirect - github.com/cometbft/cometbft-db v0.7.0 // indirect - github.com/confio/ics23/go v0.9.1 // indirect - github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect - github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/cosmos/gogoproto v1.5.0 // indirect - github.com/cosmos/gorocksdb v1.2.0 // indirect - github.com/cosmos/iavl v0.19.6 // indirect - github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 // indirect - github.com/cosmos/ledger-cosmos-go v0.13.2 // indirect - github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect - github.com/creachadair/taskgroup v0.3.2 // indirect - github.com/danieljoos/wincred v1.1.2 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.6.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect - github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect - github.com/dgraph-io/badger/v2 v2.2007.4 // indirect - github.com/dgraph-io/ristretto v0.1.1 // indirect - github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect - github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.6.0 // indirect - github.com/ethereum/c-kzg-4844 v1.0.0 // indirect - github.com/ethereum/go-ethereum v1.14.7 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/go-kit/kit v0.12.0 // indirect - github.com/go-kit/log v0.2.1 // indirect - github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.3.0 // indirect - github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gogo/gateway v1.1.0 // indirect - github.com/golang/glog v1.2.1 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/btree v1.1.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/orderedcode v0.0.1 // indirect - github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect - github.com/googleapis/gax-go/v2 v2.12.2 // indirect - github.com/gorilla/handlers v1.5.2 // indirect - github.com/gorilla/mux v1.8.1 // indirect - github.com/gorilla/websocket v1.5.0 // indirect - github.com/grafana/otel-profiling-go v0.5.1 // indirect - github.com/grafana/pyroscope-go v1.1.1 // indirect - github.com/grafana/pyroscope-go/godeltaprof v0.1.6 // indirect - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/gtank/merlin v0.1.1 // indirect - github.com/gtank/ristretto255 v0.1.2 // indirect - github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.4 // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-safetemp v1.0.0 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/hashicorp/hcl v1.0.0 // indirect - github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect - github.com/holiman/uint256 v1.3.0 // indirect - github.com/iancoleman/orderedmap v0.2.0 // indirect - github.com/improbable-eng/grpc-web v0.15.0 // indirect - github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.6 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect - github.com/klauspost/reedsolomon v1.12.1 // indirect - github.com/lib/pq v1.10.7 // indirect - github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/magiconair/properties v1.8.7 // indirect - github.com/manifoldco/promptui v0.9.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect - github.com/minio/highwayhash v1.0.2 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/mtibben/percent v0.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.53.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect - github.com/rakyll/statik v0.1.7 // indirect - github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/regen-network/cosmos-proto v0.3.1 // indirect - github.com/rs/cors v1.8.3 // indirect - github.com/rs/zerolog v1.33.0 // indirect - github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/shirou/gopsutil v3.21.6+incompatible // indirect - github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.15.0 // indirect - github.com/subosito/gotenv v1.6.0 // indirect - github.com/supranational/blst v0.3.11 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect - github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect - github.com/tendermint/go-amino v0.16.0 // indirect - github.com/tidwall/btree v1.5.0 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect - github.com/ulikunitz/xz v0.5.10 // indirect - github.com/zondax/hid v0.9.2 // indirect - github.com/zondax/ledger-go v0.14.3 // indirect - go.etcd.io/bbolt v1.3.6 // indirect - go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.26.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0 // indirect - go.opentelemetry.io/otel/metric v1.26.0 // indirect - go.opentelemetry.io/otel/sdk v1.26.0 // indirect - go.opentelemetry.io/otel/trace v1.26.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/oauth2 v0.20.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/term v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect - google.golang.org/api v0.169.0 // indirect - google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect - google.golang.org/protobuf v1.34.2 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - nhooyr.io/websocket v1.8.6 // indirect - rsc.io/tmplfunc v0.0.3 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect -) diff --git a/x/signal/go.sum b/x/signal/go.sum deleted file mode 100644 index 7fa747ef82..0000000000 --- a/x/signal/go.sum +++ /dev/null @@ -1,2023 +0,0 @@ -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= -cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -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.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= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -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.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 v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= -cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= -cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= -cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= -cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= -cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= -cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= -cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= -cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= -cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= -cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= -cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= -cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= -cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= -cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= -cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= -cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= -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/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= -cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= -cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= -cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= -cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= -cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= -cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= -cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= -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/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= -cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= -cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= -cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= -cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= -cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= -cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= -cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= -cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= -cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= -cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= -cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= -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/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= -cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= -cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= -cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= -cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= -cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= -cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= -cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= -cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= -cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= -cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= -cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= -cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= -cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= -cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= -cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= -cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= -cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= -cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= -cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= -cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= -cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= -cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= -cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= -cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= -cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= -cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= -cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= -cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= -cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= -cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= -cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= -cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= -cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= -cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= -cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= -cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= -cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= -cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= -cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= -cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= -cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= -cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= -cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= -cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= -cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= -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/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= -cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= -cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= -cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= -cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= -cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= -cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= -cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= -cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= -cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= -cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= -cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= -cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= -cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= -cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= -cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= -cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= -cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= -cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= -cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= -cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= -cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= -cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= -cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= -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.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= -cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= -cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= -cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= -cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= -cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= -cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= -cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= -cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= -cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= -cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= -cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= -cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= -cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= -cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= -filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= -git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= -github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= -github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= -github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= -github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM= -github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4= -github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= -github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -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/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= -github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= -github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= -github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/Workiva/go-datastructures v1.0.53 h1:J6Y/52yX10Xc5JjXmGtWoSSxs3mZnGSaq37xZZh7Yig= -github.com/Workiva/go-datastructures v1.0.53/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= -github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20201201074141-dd0ecada1be6/go.mod h1:eSYp2T6f0apnuW8TzhV3f6Aff2SE8Dwio++U4ha4yEM= -github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= -github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= -github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -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= -github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= -github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo= -github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= -github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= -github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= -github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= -github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= -github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= -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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= -github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= -github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= -github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= -github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= -github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= -github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= -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/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= -github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= -github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -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-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= -github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= -github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= -github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= -github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= -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/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg= -github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/celestiaorg/blobstream-contracts/v3 v3.1.0 h1:h1Y4V3EMQ2mFmNtWt2sIhZIuyASInj1a9ExI8xOsTOw= -github.com/celestiaorg/blobstream-contracts/v3 v3.1.0/go.mod h1:x4DKyfKOSv1ZJM9NwV+Pw01kH2CD7N5zTFclXIVJ6GQ= -github.com/celestiaorg/celestia-app/v3 v3.0.0-20240816121537-a28b9e7160cc h1:PKAXYmJNaPD4v7dOy/zj1p19XjI02aMTxQCa2dkiBrY= -github.com/celestiaorg/celestia-app/v3 v3.0.0-20240816121537-a28b9e7160cc/go.mod h1:/GdHBBUhu27XWq4tghYjYqiOi8AqdoqqgI3Hne2lZ08= -github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29 h1:9Co/2peu4+9S6KMVNPFS0NTI/RYIRirNpM4N7dmi9ak= -github.com/celestiaorg/celestia-core v1.39.0-tm-v0.34.29/go.mod h1:5jJ5magtH7gQOwSYfS/m5fliIS7irKunLV7kLNaD8o0= -github.com/celestiaorg/go-square/v2 v2.0.0-rc2 h1:4D+ASgZGYVCsffc2uhPagACrvNiLZu9/CqNYvnlHCgg= -github.com/celestiaorg/go-square/v2 v2.0.0-rc2/go.mod h1:eeaU8f8jBpk3ZS/gaDZIlTesJR2F51QAmveNzWH6aEU= -github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4 h1:CJdIpo8n5MFP2MwK0gSRcOVlDlFdQJO1p+FqdxYzmvc= -github.com/celestiaorg/merkletree v0.0.0-20210714075610-a84dc3ddbbe4/go.mod h1:fzuHnhzj1pUygGz+1ZkB3uQbEUL4htqCGJ4Qs2LwMZA= -github.com/celestiaorg/nmt v0.22.1 h1:t7fqoP5MJ8mBns5DB2XjfcPxQpS3CKMkY+v+BEkDxYc= -github.com/celestiaorg/nmt v0.22.1/go.mod h1:ia/EpCk0enD5yO5frcxoNoFToz2Ghtk2i+blmCRjIY8= -github.com/celestiaorg/rsmt2d v0.14.0 h1:L7XJ3tRJDY8sQcvCjzHq0L7JmsmaSD+VItymIYFLqYc= -github.com/celestiaorg/rsmt2d v0.14.0/go.mod h1:4kxqiTdFev49sGiKXTDjohbWYOG5GlcIfftTgaBJnpc= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.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/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= -github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= -github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= -github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= -github.com/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= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= -github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= -github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= -github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= -github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= -github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= -github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= -github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= -github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= -github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= -github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= -github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= -github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= -github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= -github.com/confio/ics23/go v0.9.1 h1:3MV46eeWwO3xCauKyAtuAdJYMyPnnchW4iLr2bTw6/U= -github.com/confio/ics23/go v0.9.1/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e/mYVRak= -github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= -github.com/consensys/bavard v0.1.8-0.20210915155054-088da2f7f54a/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= -github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= -github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.5.3/go.mod h1:hOdPlWQV1gDLp7faZVeg8Y0iEPFaOUnCc4XeCCk96p0= -github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= -github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= -github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= -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-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -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/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= -github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= -github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= -github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= -github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= -github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o= -github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I= -github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= -github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.6 h1:XY78yEeNPrEYyNCKlqr9chrwoeSDJ0bV2VjocTk//OU= -github.com/cosmos/iavl v0.19.6/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= -github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 h1:Hz4nkpStoXIHrC77CIEyu2mRiN2qysGEZPFRf0fpv7w= -github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2/go.mod h1:Jo934o/sW7fNxuOa/TjCalSalz+1Fd649eLyANaJx8g= -github.com/cosmos/ibc-go/v6 v6.3.1 h1:/5ur3AsmNW8WuOevfODHlaY5Ze236PBNE3vVo9o3fQA= -github.com/cosmos/ibc-go/v6 v6.3.1/go.mod h1:Dm14j9s094bGyCEE8W4fD+2t8IneHv+cz+80Mvwjr1w= -github.com/cosmos/ledger-cosmos-go v0.12.4 h1:drvWt+GJP7Aiw550yeb3ON/zsrgW0jgh5saFCr7pDnw= -github.com/cosmos/ledger-cosmos-go v0.12.4/go.mod h1:fjfVWRf++Xkygt9wzCsjEBdjcf7wiiY35fv3ctT+k4M= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= -github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= -github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= -github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= -github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= -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/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= -github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= -github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= -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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= -github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= -github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= -github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= -github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= -github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= -github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= -github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.0.3/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= -github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= -github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11 h1:IPrmumsT9t5BS7XcPhgsCTlkWbYg80SEXUzDpReaU6Y= -github.com/docker/go-connections v0.4.1-0.20210727194412-58542c764a11/go.mod h1:a6bNUGTbQBsY6VRHTr4h/rkOXjl244DyRD0tx3fgq4Q= -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/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= -github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.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.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= -github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.10.17/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0= -github.com/ethereum/go-ethereum v1.14.7 h1:EHpv3dE8evQmpVEQ/Ne2ahB06n2mQptdwqaMNhAT29g= -github.com/ethereum/go-ethereum v1.14.7/go.mod h1:Mq0biU2jbdmKSZoqOj29017ygFrMnB5/Rifwp980W4o= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 h1:KrE8I4reeVvf7C1tm8elRjj4BdscTYzz/WAbYyf/JI4= -github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0/go.mod h1:D9AJLVXSyZQXJQVk8oh1EwjISE+sJTn2duYIZC0dy3w= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= -github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= -github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= -github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= -github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -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.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -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.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= -github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= -github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= -github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.4/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 v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= -github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= -github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -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= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -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= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= -github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -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= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= -github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -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-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-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-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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -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.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.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/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= -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/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= -github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= -github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= -github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -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.4.2/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/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= -github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= -github.com/grafana/pyroscope-go v1.1.1 h1:PQoUU9oWtO3ve/fgIiklYuGilvsm8qaGhlY4Vw6MAcQ= -github.com/grafana/pyroscope-go v1.1.1/go.mod h1:Mw26jU7jsL/KStNSGGuuVYdUq7Qghem5P8aXYXSXG88= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6 h1:nEdZ8louGAplSvIJi1HVp7kWvFvdiiYg3COLlTwJiFo= -github.com/grafana/pyroscope-go/godeltaprof v0.1.6/go.mod h1:Tk376Nbldo4Cha9RgiU7ik8WKFkNpfds98aUzS8omLE= -github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= -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-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.8.5/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.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -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= -github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -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.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.4 h1:3yQjWuxICvSpYwqSayAdKRFcvBl1y/vogCxczWSmix0= -github.com/hashicorp/go-getter v1.7.4/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -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= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= -github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -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-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.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/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= -github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 h1:aSVUgRRRtOrZOC1fYmY9gV0e9z/Iu+xNVSASWjsuyGU= -github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3/go.mod h1:5PC6ZNPde8bBqU/ewGZig35+UIZtw9Ytxez8/q5ZyFE= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= -github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= -github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.3.0 h1:4wdcm/tnd0xXdu7iS3ruNvxkWwrb4aeBQv19ayYn8F4= -github.com/holiman/uint256 v1.3.0/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= -github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= -github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= -github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= -github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= -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/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= -github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -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/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= -github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= -github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= -github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= -github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= -github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= -github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= -github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= -github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= -github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -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.8/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.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -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/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= -github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= -github.com/klauspost/reedsolomon v1.12.1 h1:NhWgum1efX1x58daOBGCFWcxtEhOhXKKl1HAPQUp03Q= -github.com/klauspost/reedsolomon v1.12.1/go.mod h1:nEi5Kjb6QqtbofI6s+cbG/j1da11c96IBYBSnVGtuBs= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= -github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= -github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= -github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= -github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.3/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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= -github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -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.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -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-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= -github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -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.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/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= -github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= -github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= -github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -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/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= -github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= -github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -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 h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= -github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= -github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -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.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.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -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.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= -github.com/onsi/gomega v1.20.0/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= -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.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8= -github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= -github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -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/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= -github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= -github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= -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/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -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.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -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.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= -github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -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= -github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= -github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= -github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/regen-network/cosmos-proto v0.3.1 h1:rV7iM4SSFAagvy8RiyhiACbWEGotmqzywPxOvwMdxcg= -github.com/regen-network/cosmos-proto v0.3.1/go.mod h1:jO0sVX6a1B36nmE8C9xBFXpNwWejXC7QqCOnH3O0+YM= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= -github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= -github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= -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.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= -github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= -github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= -github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= -github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil v3.21.6+incompatible h1:mmZtAlWSd8U2HeRTjswbnDLPxqsEoK01NK+GZ1P+nEM= -github.com/shirou/gopsutil v3.21.6+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -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.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -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.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= -github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= -github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= -github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= -github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8= -github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= -github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -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= -github.com/tidwall/btree v1.5.0 h1:iV0yVY/frd7r6qGBXfEYs7DH0gTDgrKTrDjS7xt/IyQ= -github.com/tidwall/btree v1.5.0/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYmsObdKE= -github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= -github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= -github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -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/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= -github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.9 h1:rmenucSohSTiyL09Y+l2OCk+FrMxGMzho2+tjr5ticU= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= -github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= -github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/ybbus/jsonrpc v2.1.2+incompatible/go.mod h1:XJrh1eMSzdIYFbM08flv0wp5G35eRniyeGut1z+LSiE= -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.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= -github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= -github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= -github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= -gitlab.com/NebulousLabs/errors v0.0.0-20171229012116-7ead97ef90b8/go.mod h1:ZkMZ0dpQyWwlENaeZVBiQRjhMEZvk6VTXquzl3FOFP8= -gitlab.com/NebulousLabs/errors v0.0.0-20200929122200-06c536cf6975 h1:L/ENs/Ar1bFzUeKx6m3XjlmBgIUlykX9dzvp5k9NGxc= -gitlab.com/NebulousLabs/errors v0.0.0-20200929122200-06c536cf6975/go.mod h1:ZkMZ0dpQyWwlENaeZVBiQRjhMEZvk6VTXquzl3FOFP8= -gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 h1:dizWJqTWjwyD8KGcMOwgrkqu1JIkofYgKkmDeNE7oAs= -gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -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-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -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= -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.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs= -go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0 h1:hSWWvDjXHVLq9DkmB+77fl8v7+t+yYiS+eNkiplDK54= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.18.0/go.mod h1:zG7KQql1WjZCaUJd+L/ReSYx4bjbYJxg5ws9ws+mYes= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30= -go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8= -go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA= -go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.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/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= -go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/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= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200109152110-61a87790db17/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -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-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/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.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -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-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -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-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-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= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -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= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/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-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.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/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.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= -golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -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-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= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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-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.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20190813064441-fde4db37ae7a/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-20191220142924-d4481acd189f/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-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/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-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/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-20211216021012-1d35b9e2eb4e/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-20220328115105-d36c6a25d886/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-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-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-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= -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= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/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-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-20190311212946-11955173bddd/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-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-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-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-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-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-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200108203644-89082a384178/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-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= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -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-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-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/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-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -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.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= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -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.77.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.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= -google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= -google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= -google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -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.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-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-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= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -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-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= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -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-20200324203455-a04cca1dde73/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-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= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -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= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/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-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -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-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-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= -google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= -google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= -google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= -google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= -google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= -google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= -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.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -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.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.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= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -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.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.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-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.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= -gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -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.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -nhooyr.io/websocket v1.8.6 h1:s+C3xAMLwGmlI31Nyn/eAehUlZPwfYZu2JXM621Q5/k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= -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= -rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= -rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/x/signal/integration_test.go b/x/signal/integration_test.go index 4e391b2037..c3dd2419dd 100644 --- a/x/signal/integration_test.go +++ b/x/signal/integration_test.go @@ -4,9 +4,10 @@ import ( "testing" "github.com/celestiaorg/celestia-app/v3/app" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" testutil "github.com/celestiaorg/celestia-app/v3/test/util" - "github.com/celestiaorg/celestia-app/x/signal" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" @@ -19,17 +20,19 @@ import ( // simulates an upgrade scenario with a single validator which signals for the version change, checks the quorum // has been reached and then calls TryUpgrade, asserting that the upgrade module returns the new app version func TestUpgradeIntegration(t *testing.T) { - app, _ := testutil.SetupTestAppWithGenesisValSet(app.DefaultConsensusParams()) + cp := app.DefaultConsensusParams() + cp.Version.AppVersion = v2.Version + app, _ := testutil.SetupTestAppWithGenesisValSet(cp) ctx := sdk.NewContext(app.CommitMultiStore(), tmtypes.Header{ Version: tmversion.Consensus{ - App: 1, + App: v2.Version, }, }, false, tmlog.NewNopLogger()) goCtx := sdk.WrapSDKContext(ctx) ctx = sdk.UnwrapSDKContext(goCtx) res, err := app.SignalKeeper.VersionTally(goCtx, &types.QueryVersionTallyRequest{ - Version: 2, + Version: 3, }) require.NoError(t, err) require.EqualValues(t, 0, res.VotingPower) @@ -40,12 +43,12 @@ func TestUpgradeIntegration(t *testing.T) { _, err = app.SignalKeeper.SignalVersion(ctx, &types.MsgSignalVersion{ ValidatorAddress: valAddr.String(), - Version: 2, + Version: 3, }) require.NoError(t, err) res, err = app.SignalKeeper.VersionTally(goCtx, &types.QueryVersionTallyRequest{ - Version: 2, + Version: 3, }) require.NoError(t, err) require.EqualValues(t, 1, res.VotingPower) @@ -65,7 +68,7 @@ func TestUpgradeIntegration(t *testing.T) { // returns an error because an upgrade is pending. _, err = app.SignalKeeper.SignalVersion(ctx, &types.MsgSignalVersion{ ValidatorAddress: valAddr.String(), - Version: 3, + Version: 4, }) require.Error(t, err) require.ErrorIs(t, err, types.ErrUpgradePending) @@ -74,9 +77,9 @@ func TestUpgradeIntegration(t *testing.T) { require.False(t, shouldUpgrade) require.EqualValues(t, 0, version) - ctx = ctx.WithBlockHeight(ctx.BlockHeight() + signal.DefaultUpgradeHeightDelay) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + appconsts.UpgradeHeightDelay(version)) shouldUpgrade, version = app.SignalKeeper.ShouldUpgrade(ctx) require.True(t, shouldUpgrade) - require.EqualValues(t, 2, version) + require.EqualValues(t, 3, version) } diff --git a/x/signal/keeper.go b/x/signal/keeper.go index 774522541d..3ee13a9708 100644 --- a/x/signal/keeper.go +++ b/x/signal/keeper.go @@ -5,18 +5,14 @@ import ( "encoding/binary" sdkmath "cosmossdk.io/math" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/cosmos/cosmos-sdk/codec" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// DefaultUpgradeHeightDelay is the number of blocks after a quorum has been -// reached that the chain should upgrade to the new version. Assuming a block -// interval of 12 seconds, this is 7 days. -const DefaultUpgradeHeightDelay = int64(7 * 24 * 60 * 60 / 12) // 7 days * 24 hours * 60 minutes * 60 seconds / 12 seconds per block = 50,400 blocks. - // Keeper implements the MsgServer and QueryServer interfaces var ( _ types.MsgServer = &Keeper{} @@ -108,7 +104,7 @@ func (k *Keeper) TryUpgrade(ctx context.Context, _ *types.MsgTryUpgrade) (*types } upgrade := types.Upgrade{ AppVersion: version, - UpgradeHeight: sdkCtx.BlockHeader().Height + DefaultUpgradeHeightDelay, + UpgradeHeight: sdkCtx.BlockHeader().Height + appconsts.UpgradeHeightDelay(version), } k.setUpgrade(sdkCtx, upgrade) } diff --git a/x/signal/keeper_test.go b/x/signal/keeper_test.go index 88566753ee..f79d1c3884 100644 --- a/x/signal/keeper_test.go +++ b/x/signal/keeper_test.go @@ -12,10 +12,11 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/appconsts" v1 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v1" v2 "github.com/celestiaorg/celestia-app/v3/pkg/appconsts/v2" - "github.com/celestiaorg/celestia-app/x/signal" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -182,7 +183,7 @@ func TestTallyingLogic(t *testing.T) { require.False(t, shouldUpgrade) // should be false because upgrade height hasn't been reached. require.Equal(t, uint64(0), version) - ctx = ctx.WithBlockHeight(ctx.BlockHeight() + signal.DefaultUpgradeHeightDelay) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + appconsts.UpgradeHeightDelay(version)) shouldUpgrade, version = upgradeKeeper.ShouldUpgrade(ctx) require.True(t, shouldUpgrade) // should be true because upgrade height has been reached. @@ -425,7 +426,7 @@ func TestGetUpgrade(t *testing.T) { got, err := upgradeKeeper.GetUpgrade(ctx, &types.QueryGetUpgradeRequest{}) require.NoError(t, err) assert.Equal(t, v2.Version, got.Upgrade.AppVersion) - assert.Equal(t, signal.DefaultUpgradeHeightDelay, got.Upgrade.UpgradeHeight) + assert.Equal(t, appconsts.UpgradeHeightDelay(v2.Version), got.Upgrade.UpgradeHeight) }) } diff --git a/x/signal/legacy_test.go b/x/signal/legacy_test.go index 3c202cd50f..21f2695aa0 100644 --- a/x/signal/legacy_test.go +++ b/x/signal/legacy_test.go @@ -8,6 +8,7 @@ import ( "github.com/celestiaorg/celestia-app/v3/app" "github.com/celestiaorg/celestia-app/v3/app/encoding" + "github.com/celestiaorg/celestia-app/v3/pkg/user" testutil "github.com/celestiaorg/celestia-app/v3/test/util" "github.com/celestiaorg/celestia-app/v3/test/util/blobfactory" "github.com/celestiaorg/celestia-app/v3/test/util/genesis" @@ -120,14 +121,14 @@ func (s *LegacyUpgradeTestSuite) TestLegacyGovUpgradeFailure() { require.NoError(t, err) // submit the transaction and wait a block for it to be included - signer, err := testnode.NewTxClientFromContext(s.cctx) + txClient, err := testnode.NewTxClientFromContext(s.cctx) require.NoError(t, err) subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute) defer cancel() - res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) - require.Error(t, err) + _, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) + code := err.(*user.BroadcastTxError).Code // As the type is not registered, the message will fail with unable to resolve type URL - require.EqualValues(t, 2, res.Code, res.RawLog) + require.EqualValues(t, 2, code, err.Error()) } // TestNewGovUpgradeFailure verifies that a transaction with a @@ -149,14 +150,15 @@ func (s *LegacyUpgradeTestSuite) TestNewGovUpgradeFailure() { require.NoError(t, err) // submit the transaction and wait a block for it to be included - signer, err := testnode.NewTxClientFromContext(s.cctx) + txClient, err := testnode.NewTxClientFromContext(s.cctx) require.NoError(t, err) subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute) defer cancel() - res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) - require.Error(t, err) + _, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) // As the type is not registered, the message will fail with unable to resolve type URL - require.EqualValues(t, 2, res.Code, res.RawLog) + require.Error(t, err) + code := err.(*user.BroadcastTxError).Code + require.EqualValues(t, 2, code, err.Error()) } func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() { @@ -178,14 +180,15 @@ func (s *LegacyUpgradeTestSuite) TestIBCUpgradeFailure() { require.NoError(t, err) // submit the transaction and wait a block for it to be included - signer, err := testnode.NewTxClientFromContext(s.cctx) + txClient, err := testnode.NewTxClientFromContext(s.cctx) require.NoError(t, err) subCtx, cancel := context.WithTimeout(s.cctx.GoContext(), time.Minute) defer cancel() - res, err := signer.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) + _, err = txClient.SubmitTx(subCtx, []sdk.Msg{msg}, blobfactory.DefaultTxOpts()...) require.Error(t, err) - require.EqualValues(t, 9, res.Code, res.RawLog) // we're only submitting the tx, so we expect everything to work - assert.Contains(t, res.RawLog, "ibc upgrade proposal not supported") + code := err.(*user.ExecutionError).Code + require.EqualValues(t, 9, code) // we're only submitting the tx, so we expect everything to work + assert.Contains(t, err.Error(), "ibc upgrade proposal not supported") } func getAddress(account string, kr keyring.Keyring) sdk.AccAddress { diff --git a/x/signal/module.go b/x/signal/module.go index 54174725d1..9423824e28 100644 --- a/x/signal/module.go +++ b/x/signal/module.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/cobra" abci "github.com/tendermint/tendermint/abci/types" - "github.com/celestiaorg/celestia-app/x/signal/cli" - "github.com/celestiaorg/celestia-app/x/signal/types" + "github.com/celestiaorg/celestia-app/v3/x/signal/cli" + "github.com/celestiaorg/celestia-app/v3/x/signal/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types"