diff --git a/.github/ISSUE_TEMPLATE/proposal.md b/.github/ISSUE_TEMPLATE/proposal.md
new file mode 100644
index 0000000000..45f0bff42f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/proposal.md
@@ -0,0 +1,37 @@
+---
+name: Protocol Change Proposal
+about: Create a proposal to request a change to the protocol
+
+---
+
+
+
+# Protocol Change Proposal
+
+## Summary
+
+
+
+## Problem Definition
+
+
+
+## Proposal
+
+
+
+____
+
+#### For Admin Use
+
+- [ ] Not duplicate issue
+- [ ] Appropriate labels applied
+- [ ] Appropriate contributors tagged
+- [ ] Contributor assigned/self-assigned
diff --git a/.github/workflows/check-generated.yml b/.github/workflows/check-generated.yml
index 5b08611ccb..4fa68cf13b 100644
--- a/.github/workflows/check-generated.yml
+++ b/.github/workflows/check-generated.yml
@@ -18,14 +18,14 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
- name: "Check generated mocks"
run: |
set -euo pipefail
- readonly MOCKERY=2.12.3 # N.B. no leading "v"
+ readonly MOCKERY=2.14.0 # N.B. no leading "v"
curl -sL "https://github.com/vektra/mockery/releases/download/v${MOCKERY}/mockery_${MOCKERY}_Linux_x86_64.tar.gz" | tar -C /usr/local/bin -xzf -
make mockery 2>/dev/null
if ! git diff --stat --exit-code ; then
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 9a1d38ff03..64a4bc2436 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -44,7 +44,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: "1.17"
+ go-version: "1.18"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
@@ -66,7 +66,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: "1.17"
+ go-version: "1.18"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
diff --git a/.github/workflows/e2e-manual.yml b/.github/workflows/e2e-manual.yml
index f90f88cd3a..405f4c5175 100644
--- a/.github/workflows/e2e-manual.yml
+++ b/.github/workflows/e2e-manual.yml
@@ -16,7 +16,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
diff --git a/.github/workflows/e2e-nightly-34x.yml b/.github/workflows/e2e-nightly-34x.yml
index bb671af9ce..5b7e655df3 100644
--- a/.github/workflows/e2e-nightly-34x.yml
+++ b/.github/workflows/e2e-nightly-34x.yml
@@ -23,7 +23,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
with:
diff --git a/.github/workflows/e2e-nightly-master.yml b/.github/workflows/e2e-nightly-master.yml
index c90df00500..c98ed504df 100644
--- a/.github/workflows/e2e-nightly-master.yml
+++ b/.github/workflows/e2e-nightly-master.yml
@@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 1c361667e5..8e0a4f4be9 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -15,7 +15,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '^1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
diff --git a/.github/workflows/fuzz-nightly.yml b/.github/workflows/fuzz-nightly.yml
index dd9e875134..815b482fe9 100644
--- a/.github/workflows/fuzz-nightly.yml
+++ b/.github/workflows/fuzz-nightly.yml
@@ -11,7 +11,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- uses: actions/checkout@v3
diff --git a/.github/workflows/linkchecker.yml b/.github/workflows/linkchecker.yml
deleted file mode 100644
index e2ba808617..0000000000
--- a/.github/workflows/linkchecker.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-name: Check Markdown links
-on:
- schedule:
- - cron: '* */24 * * *'
-jobs:
- markdown-link-check:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: creachadair/github-action-markdown-link-check@master
- with:
- folder-path: "docs"
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index d5a720dfc8..d7ddfb2410 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -14,9 +14,8 @@ jobs:
timeout-minutes: 8
steps:
- uses: actions/setup-go@v3
- with:
- go-version: 1.17.1
- - uses: actions/checkout@v3
+ with:
+ go-version: '1.18'
- uses: technote-space/get-diff-action@v6
with:
PATTERNS: |
@@ -25,8 +24,10 @@ jobs:
go.sum
- uses: golangci/golangci-lint-action@v3.2.0
with:
- # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
- version: v1.45
+ # Required: the version of golangci-lint is required and
+ # must be specified without patch version: we always use the
+ # latest patch version.
+ version: v1.50.1
args: --timeout 10m
github-token: ${{ secrets.github_token }}
if: env.GIT_DIFF
diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml
index e6c2b927e4..1b7cdc3963 100644
--- a/.github/workflows/proto-lint.yml
+++ b/.github/workflows/proto-lint.yml
@@ -15,7 +15,7 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@v3
- - uses: bufbuild/buf-setup-action@v1.6.0
+ - uses: bufbuild/buf-setup-action@v1.8.0
- uses: bufbuild/buf-lint-action@v1
with:
input: 'proto'
diff --git a/.github/workflows/proto.yml b/.github/workflows/proto.yml
deleted file mode 100644
index 6eec3f46f5..0000000000
--- a/.github/workflows/proto.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: Protobuf
-# Protobuf runs buf (https://buf.build/) lint and check-breakage
-# This workflow is only run when a .proto file has been modified
-on:
- pull_request:
- paths:
- - "**.proto"
-jobs:
- proto-lint:
- runs-on: ubuntu-latest
- timeout-minutes: 4
- steps:
- - uses: actions/checkout@v3
- - name: lint
- run: make proto-lint
- proto-breakage:
- runs-on: ubuntu-latest
- timeout-minutes: 4
- steps:
- - uses: actions/checkout@v3
- - name: check-breakage
- run: make proto-check-breaking-ci
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7ddd7dee8a..194399586f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -16,7 +16,7 @@ jobs:
- uses: actions/setup-go@v3
with:
- go-version: '1.17'
+ go-version: '1.18'
- run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG.md#${GITHUB_REF#refs/tags/} > ../release_notes.md
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 6a03003cc8..c30fbebd4a 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -7,7 +7,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- - uses: actions/stale@v5
+ - uses: actions/stale@v6
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-pr-message: "This pull request has been automatically marked as stale because it has not had
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index bcbe7d5d42..f6ac3a1975 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -25,7 +25,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: "1.17"
+ go-version: "1.18"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
@@ -57,7 +57,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: "1.17"
+ go-version: "^1.18"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
@@ -89,7 +89,7 @@ jobs:
steps:
- uses: actions/setup-go@v3
with:
- go-version: "1.17"
+ go-version: "^1.18"
- uses: actions/checkout@v3
- uses: technote-space/get-diff-action@v6
with:
diff --git a/.gitignore b/.gitignore
index 1986b10c80..4583d098bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@ docs/.vuepress/dist
*.log
abci-cli
docs/node_modules/
+docs/.vuepress/public/rpc
index.html.md
scripts/wal2json/wal2json
@@ -46,6 +47,8 @@ terraform.tfstate
terraform.tfstate.backup
terraform.tfstate.d
profile\.out
+test/app/grpc_client
+test/loadtime/build
test/e2e/build
test/e2e/networks/*/
test/logs
@@ -56,3 +59,11 @@ test/fuzz/**/corpus
test/fuzz/**/crashers
test/fuzz/**/suppressions
test/fuzz/**/*.zip
+*.aux
+*.bbl
+*.blg
+*.pdf
+*.gz
+*.dvi
+# Python virtual environments
+.venv
diff --git a/.golangci.yml b/.golangci.yml
index 2bca6f0934..215344765e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -2,20 +2,12 @@ linters:
enable:
- asciicheck
- bodyclose
- - deadcode
- depguard
- dogsled
- dupl
- errcheck
- exportloopref
- # - funlen
- # - gochecknoglobals
- # - gochecknoinits
- # - gocognit
- goconst
- # - gocritic
- # - gocyclo
- # - godox
- gofmt
- goimports
- revive
@@ -23,44 +15,36 @@ linters:
- gosimple
- govet
- ineffassign
- # - interfacer
- - lll
- # - maligned
- # - misspell
+ - misspell
- nakedret
- nolintlint
- prealloc
- staticcheck
- - structcheck
+ # - structcheck // to be fixed by golangci-lint
- stylecheck
- # - typecheck
+ - typecheck
- unconvert
- # - unparam
- unused
- - varcheck
- # - whitespace
- # - wsl
issues:
exclude-rules:
- path: _test\.go
linters:
- gosec
- - linters:
- - lll
- source: "https://"
max-same-issues: 50
linters-settings:
dogsled:
max-blank-identifiers: 3
- maligned:
- suggest-new: true
- # govet:
- # check-shadowing: true
- revive:
+ golint:
min-confidence: 0
misspell:
locale: US
ignore-words:
- behaviour
+ maligned:
+ suggest-new: true
+
+run:
+ skip-files:
+ - libs/pubsub/query/query.peg.go
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 339abb8aab..da1a648a03 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -25,4 +25,13 @@ checksum:
algorithm: sha256
release:
- name_template: "{{.Version}} (WARNING: BETA SOFTWARE)"
+ prerelease: auto
+ name_template: "{{.Version}}"
+
+archives:
+ - files:
+ - LICENSE
+ - README.md
+ - UPGRADING.md
+ - SECURITY.md
+ - CHANGELOG.md
diff --git a/.markdownlint.yml b/.markdownlint.yml
index 1637001cc2..80e3be4edb 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -1,8 +1,11 @@
-default: true,
-MD007: { "indent": 4 }
+default: true
+MD001: false
+MD007: {indent: 4}
MD013: false
-MD024: { siblings_only: true }
+MD024: {siblings_only: true}
MD025: false
-MD033: { no-inline-html: false }
-no-hard-tabs: false
-whitespace: false
+MD033: false
+MD036: false
+MD010: false
+MD012: false
+MD028: false
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 3a42e525f1..2fdab83508 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,4 +5,5 @@
"--proto_path=${workspaceRoot}/third_party/proto"
]
}
+
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e37ab67cce..145eba32bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,108 @@
Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos).
+## v0.34.23
+
+*Nov 9, 2022*
+
+This release introduces some new Prometheus metrics to help in determining what
+kinds of messages are consuming the most P2P bandwidth. This builds towards our
+broader goal of optimizing Tendermint bandwidth consumption, and will give us
+meaningful insights once we can establish these metrics for a number of chains.
+
+We now also return `Cache-Control` headers for select RPC endpoints to help
+facilitate caching.
+
+Special thanks to external contributors on this release: @JayT106
+
+### IMPROVEMENTS
+- `[p2p]` [\#9641](https://github.com/tendermint/tendermint/issues/9641) Add new
+ Envelope type and associated methods for sending and receiving Envelopes
+ instead of raw bytes. This also adds new metrics,
+ `tendermint_p2p_message_send_bytes_total` and
+ `tendermint_p2p_message_receive_bytes_total`, that expose how many bytes of
+ each message type have been sent.
+- `[rpc]` [\#9666](https://github.com/tendermint/tendermint/issues/9666) Enable
+ caching of RPC responses (@JayT106)
+
+ The following RPC endpoints will return `Cache-Control` headers with a maximum
+ age of 1 day:
+
+ - `/abci_info`
+ - `/block`, if `height` is supplied
+ - `/block_by_hash`
+ - `/block_results`, if `height` is supplied
+ - `/blockchain`
+ - `/check_tx`
+ - `/commit`, if `height` is supplied
+ - `/consensus_params`, if `height` is supplied
+ - `/genesis`
+ - `/genesis_chunked`
+ - `/tx`
+ - `/validators`, if `height` is supplied
+
+## v0.34.22
+
+This release includes several bug fixes, [one of
+which](https://github.com/tendermint/tendermint/pull/9518) we discovered while
+building up a baseline for v0.34 against which to compare our upcoming v0.37
+release during our [QA process](./docs/qa/).
+
+Special thanks to external contributors on this release: @RiccardoM
+
+### FEATURES
+
+- [rpc] [\#9423](https://github.com/tendermint/tendermint/pull/9423) Support
+ HTTPS URLs from the WebSocket client (@RiccardoM, @cmwaters)
+
+### BUG FIXES
+
+- [config] [\#9483](https://github.com/tendermint/tendermint/issues/9483)
+ Calling `tendermint init` would incorrectly leave out the new `[storage]`
+ section delimiter in the generated configuration file - this has now been
+ fixed
+- [p2p] [\#9500](https://github.com/tendermint/tendermint/issues/9500) Prevent
+ peers who have errored being added to the peer set (@jmalicevic)
+- [indexer] [\#9473](https://github.com/tendermint/tendermint/issues/9473) Fix
+ bug that caused the psql indexer to index empty blocks whenever one of the
+ transactions returned a non zero code. The relevant deduplication logic has
+ been moved within the kv indexer only (@cmwaters)
+- [blocksync] [\#9518](https://github.com/tendermint/tendermint/issues/9518) A
+ block sync stall was observed during our QA process whereby the node was
+ unable to make progress. Retrying block requests after a timeout fixes this.
+
+## v0.34.21
+
+Release highlights include:
+
+- A new `[storage]` configuration section and flag `discard_abci_responses`,
+ which, if enabled, discards all ABCI responses except the latest one in order
+ to reduce disk space usage in the state store. When enabled, the
+ `block_results` RPC endpoint can no longer function and will return an error.
+- A new CLI command, `reindex-event`, to re-index block and tx events to the
+ event sinks. You can run this command when the event store backend
+ dropped/disconnected or you want to replace the backend. When
+ `discard_abci_responses` is enabled, you will not be able to use this command.
+
+Special thanks to external contributors on this release: @rootwarp & @animart
+
+### FEATURES
+
+- [cli] [\#9083](https://github.com/tendermint/tendermint/issues/9083) Backport command to reindex missed events (@cmwaters)
+- [cli] [\#9107](https://github.com/tendermint/tendermint/issues/9107) Add the `p2p.external-address` argument to set the node P2P external address (@amimart)
+
+### IMPROVEMENTS
+
+- [config] [\#9054](https://github.com/tendermint/tendermint/issues/9054) `discard_abci_responses` flag added to discard all ABCI
+ responses except the last in order to save on storage space in the state
+ store (@samricotta)
+
+### BUG FIXES
+
+- [mempool] [\#9033](https://github.com/tendermint/tendermint/issues/9033) Rework lock discipline to mitigate callback deadlocks in the
+ priority mempool
+- [cli] [\#9103](https://github.com/tendermint/tendermint/issues/9103) fix unsafe-reset-all for working with home path (@rootwarp)
+
## v0.34.20
Special thanks to external contributors on this release: @joeabbey @yihuang
@@ -438,7 +540,7 @@ Special thanks to external contributors on this release: @james-ray, @fedekunze,
- [abci] [\#5174](https://github.com/tendermint/tendermint/pull/5174) Remove `MockEvidence` in favor of testing with actual evidence types (`DuplicateVoteEvidence` & `LightClientAttackEvidence`) (@cmwaters)
- [abci] [\#5191](https://github.com/tendermint/tendermint/pull/5191) Add `InitChain.InitialHeight` field giving the initial block height (@erikgrinaker)
- [abci] [\#5227](https://github.com/tendermint/tendermint/pull/5227) Add `ResponseInitChain.app_hash` which is recorded in genesis block (@erikgrinaker)
-- [config] [\#5147](https://github.com/tendermint/tendermint/pull/5147) Add `--consensus.double_sign_check_height` flag and `DoubleSignCheckHeight` config variable. See [ADR-51](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-051-double-signing-risk-reduction.md) (@dongsam)
+- [config] [\#5147](https://github.com/tendermint/tendermint/pull/5147) Add `--consensus.double_sign_check_height` flag and `DoubleSignCheckHeight` config variable. See [ADR-51](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-051-double-signing-risk-reduction.md) (@dongsam)
- [db] [\#5233](https://github.com/tendermint/tendermint/pull/5233) Add support for `badgerdb` database backend (@erikgrinaker)
- [evidence] [\#4532](https://github.com/tendermint/tendermint/pull/4532) Handle evidence from light clients (@melekes)
- [evidence] [#4821](https://github.com/tendermint/tendermint/pull/4821) Amnesia (light client attack) evidence can be detected, verified and committed (@cmwaters)
@@ -452,7 +554,7 @@ Special thanks to external contributors on this release: @james-ray, @fedekunze,
- [rpc] [\#5017](https://github.com/tendermint/tendermint/pull/5017) Add `/check_tx` endpoint to check transactions without executing them or adding them to the mempool (@melekes)
- [rpc] [\#5108](https://github.com/tendermint/tendermint/pull/5108) Subscribe using the websocket for new evidence events (@cmwaters)
- [statesync] Add state sync support, where a new node can be rapidly bootstrapped by fetching state snapshots from peers instead of replaying blocks. See the `[statesync]` config section.
-- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and refactor evidence lifecycle - for more information see [ADR-059](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-059-evidence-composition-and-lifecycle.md) (@cmwaters)
+- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and refactor evidence lifecycle - for more information see [ADR-059](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-059-evidence-composition-and-lifecycle.md) (@cmwaters)
### IMPROVEMENTS
@@ -532,7 +634,7 @@ This security release fixes:
Tendermint 0.33.0 and above allow block proposers to include signatures for the
wrong block. This may happen naturally if you start a network, have it run for
some time and restart it **without changing the chainID**. (It is a
-[misconfiguration](https://docs.tendermint.com/master/tendermint-core/using-tendermint.html)
+[misconfiguration](https://docs.tendermint.com/v0.33/tendermint-core/using-tendermint.html)
to reuse chainIDs.) Correct block proposers will accidentally include signatures
for the wrong block if they see these signatures, and then commits won't validate,
making all proposed blocks invalid. A malicious validator (even with a minimal
@@ -831,7 +933,7 @@ and a validator address plus a timestamp. Note we may remove the validator
address & timestamp fields in the future (see ADR-25).
`lite2` package has been added to solve `lite` issues and introduce weak
-subjectivity interface. Refer to the [spec](https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md) for complete details.
+subjectivity interface. Refer to the [spec](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client.md) for complete details.
`lite` package is now deprecated and will be removed in v0.34 release.
### BREAKING CHANGES:
@@ -1192,7 +1294,7 @@ Special thanks to external contributors on this release: @jon-certik, @gracenoah
*August 28, 2019*
@climber73 wrote the [Writing a Tendermint Core application in Java
-(gRPC)](https://github.com/tendermint/tendermint/blob/master/docs/guides/java.md)
+(gRPC)](https://github.com/tendermint/tendermint/blob/v0.32.x/docs/guides/java.md)
guide.
Special thanks to external contributors on this release:
@@ -1225,7 +1327,7 @@ Special thanks to external contributors on this release:
### FEATURES:
-- [blockchain] [\#3561](https://github.com/tendermint/tendermint/issues/3561) Add early version of the new blockchain reactor, which is supposed to be more modular and testable compared to the old version. To try it, you'll have to change `version` in the config file, [here](https://github.com/tendermint/tendermint/blob/master/config/toml.go#L303) NOTE: It's not ready for a production yet. For further information, see [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md) & [ADR-43](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-043-blockchain-riri-org.md)
+- [blockchain] [\#3561](https://github.com/tendermint/tendermint/issues/3561) Add early version of the new blockchain reactor, which is supposed to be more modular and testable compared to the old version. To try it, you'll have to change `version` in the config file, [here](https://github.com/tendermint/tendermint/blob/v0.34.x/config/toml.go#L303) NOTE: It's not ready for a production yet. For further information, see [ADR-40](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-040-blockchain-reactor-refactor.md) & [ADR-43](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-043-blockchain-riri-org.md)
- [mempool] [\#3826](https://github.com/tendermint/tendermint/issues/3826) Make `max_msg_bytes` configurable(@bluele)
- [node] [\#3846](https://github.com/tendermint/tendermint/pull/3846) Allow replacing existing p2p.Reactor(s) using [`CustomReactors`
option](https://godoc.org/github.com/tendermint/tendermint/node#CustomReactors).
@@ -1542,7 +1644,7 @@ Special thanks to external contributors on this release:
- [libs/db] [\#3611](https://github.com/tendermint/tendermint/issues/3611) Conditional compilation
* Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
use `make build_c` / `make install_c` (full instructions can be found at
- https://docs.tendermint.com/master/introduction/install.html#compile-with-cleveldb-support)
+ )
* Use `boltdb` tag to compile Tendermint with bolt db
- [node] [\#3362](https://github.com/tendermint/tendermint/issues/3362) Return an error if `persistent_peers` list is invalid (except
when IP lookup fails)
@@ -1766,7 +1868,7 @@ more details.
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique clientIDs with open subscriptions. Configurable via `rpc.max_subscription_clients`
- [rpc] [\#3269](https://github.com/tendermint/tendermint/issues/2826) Limit number of unique queries a given client can subscribe to at once. Configurable via `rpc.max_subscriptions_per_client`.
- [rpc] [\#3435](https://github.com/tendermint/tendermint/issues/3435) Default ReadTimeout and WriteTimeout changed to 10s. WriteTimeout can increased by setting `rpc.timeout_broadcast_tx_commit` in the config.
- - [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
+ - [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods.
* Apps
- [abci] [\#3403](https://github.com/tendermint/tendermint/issues/3403) Remove `time_iota_ms` from BlockParams. This is a
@@ -1819,7 +1921,7 @@ more details.
- [blockchain] [\#3358](https://github.com/tendermint/tendermint/pull/3358) Fix timer leak in `BlockPool` (@guagualvcha)
- [cmd] [\#3408](https://github.com/tendermint/tendermint/issues/3408) Fix `testnet` command's panic when creating non-validator configs (using `--n` flag) (@srmo)
- [libs/db/remotedb/grpcdb] [\#3402](https://github.com/tendermint/tendermint/issues/3402) Close Iterator/ReverseIterator after use
-- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-033-pubsub.md)
+- [libs/pubsub] [\#951](https://github.com/tendermint/tendermint/issues/951), [\#1880](https://github.com/tendermint/tendermint/issues/1880) Use non-blocking send when dispatching messages [ADR-33](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-033-pubsub.md)
- [lite] [\#3364](https://github.com/tendermint/tendermint/issues/3364) Fix `/validators` and `/abci_query` proxy endpoints
(@guagualvcha)
- [p2p/conn] [\#3347](https://github.com/tendermint/tendermint/issues/3347) Reject all-zero shared secrets in the Diffie-Hellman step of secret-connection
@@ -2517,7 +2619,7 @@ Special thanks to external contributors on this release:
This release is mostly about the ConsensusParams - removing fields and enforcing MaxGas.
It also addresses some issues found via security audit, removes various unused
functions from `libs/common`, and implements
-[ADR-012](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-012-peer-transport.md).
+[ADR-012](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-012-peer-transport.md).
BREAKING CHANGES:
@@ -2598,7 +2700,7 @@ BREAKING CHANGES:
- [abci] Added address of the original proposer of the block to Header
- [abci] Change ABCI Header to match Tendermint exactly
- [abci] [\#2159](https://github.com/tendermint/tendermint/issues/2159) Update use of `Validator` (see
- [ADR-018](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-018-ABCI-Validators.md)):
+ [ADR-018](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-018-ABCI-Validators.md)):
- Remove PubKey from `Validator` (so it's just Address and Power)
- Introduce `ValidatorUpdate` (with just PubKey and Power)
- InitChain and EndBlock use ValidatorUpdate
@@ -2620,7 +2722,7 @@ BREAKING CHANGES:
- [state] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Validator set changes are now delayed by one block (!)
- Add NextValidatorSet to State, changes on-disk representation of state
- [state] [\#2184](https://github.com/tendermint/tendermint/issues/2184) Enforce ConsensusParams.BlockSize.MaxBytes (See
- [ADR-020](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-020-block-size.md)).
+ [ADR-020](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-020-block-size.md)).
- Remove ConsensusParams.BlockSize.MaxTxs
- Introduce maximum sizes for all components of a block, including ChainID
- [types] Updates to the block Header:
@@ -2631,7 +2733,7 @@ BREAKING CHANGES:
- [consensus] [\#2203](https://github.com/tendermint/tendermint/issues/2203) Implement BFT time
- Timestamp in block must be monotonic and equal the median of timestamps in block's LastCommit
- [crypto] [\#2239](https://github.com/tendermint/tendermint/issues/2239) Secp256k1 signature changes (See
- [ADR-014](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-014-secp-malleability.md)):
+ [ADR-014](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-014-secp-malleability.md)):
- format changed from DER to `r || s`, both little endian encoded as 32 bytes.
- malleability removed by requiring `s` to be in canonical form.
@@ -3431,7 +3533,7 @@ Also includes the Grand Repo-Merge of 2017.
BREAKING CHANGES:
- Config and Flags:
- - The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/master/config/config.go#L11),
+ - The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/v0.10.0/config/config.go#L11),
containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusConfig`, `RPCConfig`
- This affects the following flags:
- `--seeds` is now `--p2p.seeds`
diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md
index b88d1cbd1f..1b36756d7f 100644
--- a/CHANGELOG_PENDING.md
+++ b/CHANGELOG_PENDING.md
@@ -1,10 +1,6 @@
# Unreleased Changes
-## v0.34.21
-
-Special thanks to external contributors on this release:
-
-Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint).
+## v0.34.24
### BREAKING CHANGES
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 715019e90a..afb9da3de9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -26,7 +26,7 @@ will indicate their support with a heartfelt emoji.
If the issue would benefit from thorough discussion, maintainers may
request that you create a [Request For
-Comment](https://github.com/tendermint/spec/tree/master/rfc). Discussion
+Comment](https://github.com/tendermint/tendermint/tree/main/rfc). Discussion
at the RFC stage will build collective understanding of the dimensions
of the problems and help structure conversations around trade-offs.
diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile
index ecb0c8066f..cc387db4b6 100644
--- a/DOCKER/Dockerfile
+++ b/DOCKER/Dockerfile
@@ -1,5 +1,5 @@
# stage 1 Generate Tendermint Binary
-FROM golang:1.17-alpine as builder
+FROM golang:1.18-alpine as builder
RUN apk update && \
apk upgrade && \
apk --no-cache add make
@@ -9,7 +9,7 @@ WORKDIR /tendermint
RUN make build-linux
# stage 2
-FROM golang:1.17-alpine
+FROM golang:1.18-alpine
LABEL maintainer="hello@tendermint.com"
# Tendermint will be looking for the genesis file in /tendermint/config/genesis.json
diff --git a/DOCKER/README.md b/DOCKER/README.md
index 5cd39446f6..d7ca6d37fe 100644
--- a/DOCKER/README.md
+++ b/DOCKER/README.md
@@ -6,7 +6,7 @@ DockerHub tags for official releases are [here](https://hub.docker.com/r/tenderm
Official releases can be found [here](https://github.com/tendermint/tendermint/releases).
-The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/master/DOCKER/Dockerfile).
+The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/main/DOCKER/Dockerfile).
Respective versioned files can be found (replace the Xs with the version number).
@@ -20,9 +20,9 @@ Respective versioned files can be found Running linter"
- @golangci-lint run
+ @go run github.com/golangci/golangci-lint/cmd/golangci-lint run
.PHONY: lint
DESTINATION = ./index.html.md
diff --git a/SECURITY.md b/SECURITY.md
index 351f5606c3..61f02e10a1 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,98 +2,146 @@
## Reporting a Bug
-As part of our [Coordinated Vulnerability Disclosure
-Policy](https://tendermint.com/security), we operate a [bug
-bounty](https://hackerone.com/tendermint).
-See the policy for more details on submissions and rewards, and see "Example Vulnerabilities" (below) for examples of the kinds of bugs we're most interested in.
+As part of our [Coordinated Vulnerability Disclosure Policy](https://tendermint.com/security),
+we operate a [bug bounty][hackerone]. See the policy for more
+details on submissions and rewards, and see "Example Vulnerabilities" (below)
+for examples of the kinds of bugs we're most interested in.
-### Guidelines
+### Guidelines
We require that all researchers:
-* Use the bug bounty to disclose all vulnerabilities, and avoid posting vulnerability information in public places, including Github Issues, Discord channels, and Telegram groups
-* Make every effort to avoid privacy violations, degradation of user experience, disruption to production systems (including but not limited to the Cosmos Hub), and destruction of data
-* Keep any information about vulnerabilities that you’ve discovered confidential between yourself and the Tendermint Core engineering team until the issue has been resolved and disclosed
+* Use the bug bounty to disclose all vulnerabilities, and avoid posting
+ vulnerability information in public places, including Github Issues, Discord
+ channels, and Telegram groups
+* Make every effort to avoid privacy violations, degradation of user experience,
+ disruption to production systems (including but not limited to the Cosmos
+ Hub), and destruction of data
+* Keep any information about vulnerabilities that you’ve discovered confidential
+ between yourself and the Tendermint Core engineering team until the issue has
+ been resolved and disclosed
* Avoid posting personally identifiable information, privately or publicly
If you follow these guidelines when reporting an issue to us, we commit to:
-* Not pursue or support any legal action related to your research on this vulnerability
-* Work with you to understand, resolve and ultimately disclose the issue in a timely fashion
+* Not pursue or support any legal action related to your research on this
+ vulnerability
+* Work with you to understand, resolve and ultimately disclose the issue in a
+ timely fashion
-## Disclosure Process
+## Disclosure Process
Tendermint Core uses the following disclosure process:
-1. Once a security report is received, the Tendermint Core team works to verify the issue and confirm its severity level using CVSS.
-2. The Tendermint Core team collaborates with the Gaia team to determine the vulnerability’s potential impact on the Cosmos Hub.
-3. Patches are prepared for eligible releases of Tendermint in private repositories. See “Supported Releases” below for more information on which releases are considered eligible.
-4. If it is determined that a CVE-ID is required, we request a CVE through a CVE Numbering Authority.
-5. We notify the community that a security release is coming, to give users time to prepare their systems for the update. Notifications can include forum posts, tweets, and emails to partners and validators, including emails sent to the [Tendermint Security Mailing List](https://berlin.us4.list-manage.com/subscribe?u=431b35421ff7edcc77df5df10&id=3fe93307bc).
-6. 24 hours following this notification, the fixes are applied publicly and new releases are issued.
-7. Cosmos SDK and Gaia update their Tendermint Core dependencies to use these releases, and then themselves issue new releases.
-8. Once releases are available for Tendermint Core, Cosmos SDK and Gaia, we notify the community, again, through the same channels as above. We also publish a Security Advisory on Github and publish the CVE, as long as neither the Security Advisory nor the CVE include any information on how to exploit these vulnerabilities beyond what information is already available in the patch itself.
-9. Once the community is notified, we will pay out any relevant bug bounties to submitters.
-10. One week after the releases go out, we will publish a post with further details on the vulnerability as well as our response to it.
-
-This process can take some time. Every effort will be made to handle the bug in as timely a manner as possible, however it's important that we follow the process described above to ensure that disclosures are handled consistently and to keep Tendermint Core and its downstream dependent projects--including but not limited to Gaia and the Cosmos Hub--as secure as possible.
-
-### Example Timeline
-
-The following is an example timeline for the triage and response. The required roles and team members are described in parentheses after each task; however, multiple people can play each role and each person may play multiple roles.
-
-#### > 24 Hours Before Release Time
-
-1. Request CVE number (ADMIN)
-2. Gather emails and other contact info for validators (COMMS LEAD)
-3. Test fixes on a testnet (TENDERMINT ENG, COSMOS ENG)
-4. Write “Security Advisory” for forum (TENDERMINT LEAD)
+1. Once a security report is received, the Tendermint Core team works to verify
+ the issue and confirm its severity level using CVSS.
+2. The Tendermint Core team collaborates with the Gaia team to determine the
+ vulnerability’s potential impact on the Cosmos Hub.
+3. Patches are prepared for eligible releases of Tendermint in private
+ repositories. See “Supported Releases” below for more information on which
+ releases are considered eligible.
+4. If it is determined that a CVE-ID is required, we request a CVE through a CVE
+ Numbering Authority.
+5. We notify the community that a security release is coming, to give users time
+ to prepare their systems for the update. Notifications can include forum
+ posts, tweets, and emails to partners and validators, including emails sent
+ to the [Tendermint Security Mailing List][tmsec-mailing].
+6. 24 hours following this notification, the fixes are applied publicly and new
+ releases are issued.
+7. Cosmos SDK and Gaia update their Tendermint Core dependencies to use these
+ releases, and then themselves issue new releases.
+8. Once releases are available for Tendermint Core, Cosmos SDK and Gaia, we
+ notify the community, again, through the same channels as above. We also
+ publish a Security Advisory on Github and publish the CVE, as long as neither
+ the Security Advisory nor the CVE include any information on how to exploit
+ these vulnerabilities beyond what information is already available in the
+ patch itself.
+9. Once the community is notified, we will pay out any relevant bug bounties to
+ submitters.
+10. One week after the releases go out, we will publish a post with further
+ details on the vulnerability as well as our response to it.
+
+This process can take some time. Every effort will be made to handle the bug in
+as timely a manner as possible, however it's important that we follow the
+process described above to ensure that disclosures are handled consistently and
+to keep Tendermint Core and its downstream dependent projects--including but not
+limited to Gaia and the Cosmos Hub--as secure as possible.
+
+### Example Timeline
+
+The following is an example timeline for the triage and response. The required
+roles and team members are described in parentheses after each task; however,
+multiple people can play each role and each person may play multiple roles.
+
+#### 24+ Hours Before Release Time
+
+1. Request CVE number (ADMIN)
+2. Gather emails and other contact info for validators (COMMS LEAD)
+3. Create patches in a private security repo, and ensure that PRs are open
+ targeting all relevant release branches (TENDERMINT ENG, TENDERMINT LEAD)
+4. Test fixes on a testnet (TENDERMINT ENG, COSMOS SDK ENG)
+5. Write “Security Advisory” for forum (TENDERMINT LEAD)
#### 24 Hours Before Release Time
-1. Post “Security Advisory” pre-notification on forum (TENDERMINT LEAD)
-2. Post Tweet linking to forum post (COMMS LEAD)
-3. Announce security advisory/link to post in various other social channels (Telegram, Discord) (COMMS LEAD)
-4. Send emails to validators or other users (PARTNERSHIPS LEAD)
+1. Post “Security Advisory” pre-notification on forum (TENDERMINT LEAD)
+2. Post Tweet linking to forum post (COMMS LEAD)
+3. Announce security advisory/link to post in various other social channels
+ (Telegram, Discord) (COMMS LEAD)
+4. Send emails to validators or other users (PARTNERSHIPS LEAD)
#### Release Time
-1. Cut Tendermint releases for eligible versions (TENDERMINT ENG, TENDERMINT LEAD)
+1. Cut Tendermint releases for eligible versions (TENDERMINT ENG, TENDERMINT
+ LEAD)
2. Cut Cosmos SDK release for eligible versions (COSMOS ENG)
3. Cut Gaia release for eligible versions (GAIA ENG)
4. Post “Security releases” on forum (TENDERMINT LEAD)
5. Post new Tweet linking to forum post (COMMS LEAD)
-6. Remind everyone via social channels (Telegram, Discord) that the release is out (COMMS LEAD)
-7. Send emails to validators or other users (COMMS LEAD)
-8. Publish Security Advisory and CVE, if CVE has no sensitive information (ADMIN)
+6. Remind everyone via social channels (Telegram, Discord) that the release is
+ out (COMMS LEAD)
+7. Send emails to validators or other users (COMMS LEAD)
+8. Publish Security Advisory and CVE, if CVE has no sensitive information
+ (ADMIN)
#### After Release Time
1. Write forum post with exploit details (TENDERMINT LEAD)
-2. Approve pay-out on HackerOne for submitter (ADMIN)
+2. Approve pay-out on HackerOne for submitter (ADMIN)
#### 7 Days After Release Time
-1. Publish CVE if it has not yet been published (ADMIN)
+1. Publish CVE if it has not yet been published (ADMIN)
2. Publish forum post with exploit details (TENDERMINT ENG, TENDERMINT LEAD)
## Supported Releases
-The Tendermint Core team commits to releasing security patch releases for both the latest minor release as well for the major/minor release that the Cosmos Hub is running.
+The Tendermint Core team commits to releasing security patch releases for both
+the latest minor release as well for the major/minor release that the Cosmos Hub
+is running.
-If you are running older versions of Tendermint Core, we encourage you to upgrade at your earliest opportunity so that you can receive security patches directly from the Tendermint repo. While you are welcome to backport security patches to older versions for your own use, we will not publish or promote these backports.
+If you are running older versions of Tendermint Core, we encourage you to
+upgrade at your earliest opportunity so that you can receive security patches
+directly from the Tendermint repo. While you are welcome to backport security
+patches to older versions for your own use, we will not publish or promote these
+backports.
## Scope
-The full scope of our bug bounty program is outlined on our [Hacker One program page](https://hackerone.com/tendermint). Please also note that, in the interest of the safety of our users and staff, a few things are explicitly excluded from scope:
+The full scope of our bug bounty program is outlined on our
+[Hacker One program page][hackerone]. Please also note that, in the interest of
+the safety of our users and staff, a few things are explicitly excluded from
+scope:
-* Any third-party services
-* Findings from physical testing, such as office access
+* Any third-party services
+* Findings from physical testing, such as office access
* Findings derived from social engineering (e.g., phishing)
-## Example Vulnerabilities
+## Example Vulnerabilities
-The following is a list of examples of the kinds of vulnerabilities that we’re most interested in. It is not exhaustive: there are other kinds of issues we may also be interested in!
+The following is a list of examples of the kinds of vulnerabilities that we’re
+most interested in. It is not exhaustive: there are other kinds of issues we may
+also be interested in!
### Specification
@@ -105,7 +153,8 @@ The following is a list of examples of the kinds of vulnerabilities that we’re
Assuming less than 1/3 of the voting power is Byzantine (malicious):
-* Validation of blockchain data structures, including blocks, block parts, votes, and so on
+* Validation of blockchain data structures, including blocks, block parts,
+ votes, and so on
* Execution of blocks
* Validator set changes
* Proposer round robin
@@ -114,6 +163,9 @@ Assuming less than 1/3 of the voting power is Byzantine (malicious):
* A node halting (liveness failure)
* Syncing new and old nodes
+Assuming more than 1/3 the voting power is Byzantine:
+
+* Attacks that go unpunished (unhandled evidence)
### Networking
@@ -139,7 +191,7 @@ Attacks may come through the P2P network or the RPC layer:
### Libraries
-* Serialization (Amino)
+* Serialization
* Reading/Writing files and databases
### Cryptography
@@ -150,5 +202,8 @@ Attacks may come through the P2P network or the RPC layer:
### Light Client
-* Core verification
+* Core verification
* Bisection/sequential algorithms
+
+[hackerone]: https://hackerone.com/cosmos
+[tmsec-mailing]: https://berlin.us4.list-manage.com/subscribe?u=431b35421ff7edcc77df5df10&id=3fe93307bc
diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
index 98e81d7235..0ed354f6b8 100644
--- a/STYLE_GUIDE.md
+++ b/STYLE_GUIDE.md
@@ -98,7 +98,7 @@ Sometimes it's necessary to rename libraries to avoid naming collisions or ambig
* Make use of table driven testing where possible and not-cumbersome
* [Inspiration](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go)
* Make use of [assert](https://godoc.org/github.com/stretchr/testify/assert) and [require](https://godoc.org/github.com/stretchr/testify/require)
-* When using mocks, it is recommended to use Testify [mock] (
+* When using mocks, it is recommended to use Testify [mock](
) along with [Mockery](https://github.com/vektra/mockery) for autogeneration
## Errors
diff --git a/UPGRADING.md b/UPGRADING.md
index da2b4661bb..056a94b40c 100644
--- a/UPGRADING.md
+++ b/UPGRADING.md
@@ -1,6 +1,22 @@
# Upgrading Tendermint Core
-This guide provides instructions for upgrading to specific versions of Tendermint Core.
+This guide provides instructions for upgrading to specific versions of
+Tendermint Core.
+
+## v0.34.20
+
+### Feature: Priority Mempool
+
+This release backports an implementation of the Priority Mempool from the v0.35
+branch. This implementation of the mempool permits the application to set a
+priority on each transaction during CheckTx, and during block selection the
+highest-priority transactions are chosen (subject to the constraints on size
+and gas cost).
+
+Operators can enable the priority mempool by setting `mempool.version` to
+`"v1"` in the `config.toml`. For more technical details about the priority
+mempool, see [ADR 067: Mempool
+Refactor](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-067-mempool-refactor.md).
## v0.34.20
@@ -23,7 +39,7 @@ Refactor](https://github.com/tendermint/tendermint/blob/master/docs/architecture
This release is not compatible with previous blockchains due to changes to
the encoding format (see "Protocol Buffers," below) and the block header (see "Blockchain Protocol").
-Note also that Tendermint 0.34 also requires Go 1.15 or higher.
+Note also that Tendermint 0.34 also requires Go 1.18 or higher.
### ABCI Changes
@@ -33,7 +49,7 @@ Note also that Tendermint 0.34 also requires Go 1.15 or higher.
were added to support the new State Sync feature.
Previously, syncing a new node to a preexisting network could take days; but with State Sync,
new nodes are able to join a network in a matter of seconds.
- Read [the spec](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync)
+ Read [the spec](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#state-sync)
if you want to learn more about State Sync, or if you'd like your application to use it.
(If you don't want to support State Sync in your application, you can just implement these new
ABCI methods as no-ops, leaving them empty.)
@@ -49,7 +65,7 @@ Note also that Tendermint 0.34 also requires Go 1.15 or higher.
Applications should be able to handle these evidence types
(i.e., through slashing or other accountability measures).
-* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/crypto/keys.proto#L13-L15)
+* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/v0.34.x/proto/tendermint/crypto/keys.proto#L13-L15)
(used in ABCI as part of `ValidatorUpdate`) now uses a `oneof` protobuf type.
Note that since Tendermint only supports ed25519 validator keys, there's only one
option in the `oneof`. For more, see "Protocol Buffers," below.
@@ -64,12 +80,9 @@ directory. For more, see "Protobuf," below.
### Blockchain Protocol
-* `Header#LastResultsHash` previously was the root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data)` responses.
- As of 0.34,`Header#LastResultsHash` is now the root hash of a Merkle tree built from:
- * `BeginBlock#Events`
- * Root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data,
- GasWanted, GasUsed, Events)` responses
- * `BeginBlock#Events`
+* `Header#LastResultsHash`, which is the root hash of a Merkle tree built from
+ `ResponseDeliverTx(Code, Data)` as of v0.34 also includes `GasWanted` and `GasUsed`
+ fields.
* Merkle hashes of empty trees previously returned nothing, but now return the hash of an empty input,
to conform with [RFC-6962](https://tools.ietf.org/html/rfc6962).
@@ -159,7 +172,7 @@ The `bech32` package has moved to the Cosmos SDK:
### CLI
The `tendermint lite` command has been renamed to `tendermint light` and has a slightly different API.
-See [the docs](https://docs.tendermint.com/master/tendermint-core/light-client-protocol.html#http-proxy) for details.
+See [the docs](https://docs.tendermint.com/v0.33/tendermint-core/light-client-protocol.html#http-proxy) for details.
### Light Client
@@ -173,6 +186,7 @@ Other user-relevant changes include:
* The `Verifier` was broken up into two pieces:
* Core verification logic (pure `VerifyX` functions)
* `Client` object, which represents the complete light client
+* The new light client stores headers and validator sets as `LightBlock`s
* The RPC client can be found in the `/rpc` directory.
* The HTTP(S) proxy is located in the `/proxy` directory.
@@ -314,7 +328,7 @@ Evidence Params has been changed to include duration.
### RPC Changes
* `/validators` is now paginated (default: 30 vals per page)
-* `/block_results` response format updated [see RPC docs for details](https://docs.tendermint.com/master/rpc/#/Info/block_results)
+* `/block_results` response format updated [see RPC docs for details](https://docs.tendermint.com/v0.33/rpc/#/Info/block_results)
* Event suffix has been removed from the ID in event responses
* IDs are now integers not `json-client-XYZ`
@@ -433,11 +447,11 @@ the compilation tag:
Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
use `make build_c` / `make install_c` (full instructions can be found at
-)
+)
## v0.31.0
-This release contains a breaking change to the behaviour of the pubsub system.
+This release contains a breaking change to the behavior of the pubsub system.
It also contains some minor breaking changes in the Go API and ABCI.
There are no changes to the block or p2p protocols, so v0.31.0 should work fine
with blockchains created from the v0.30 series.
@@ -455,7 +469,7 @@ In this case, the WS client will receive an error with description:
"error": {
"code": -32000,
"msg": "Server error",
- "data": "subscription was cancelled (reason: client is not pulling messages fast enough)" // or "subscription was cancelled (reason: Tendermint exited)"
+ "data": "subscription was canceled (reason: client is not pulling messages fast enough)" // or "subscription was canceled (reason: Tendermint exited)"
}
}
@@ -508,14 +522,14 @@ due to changes in how various data structures are hashed.
Any implementations of Tendermint blockchain verification, including lite clients,
will need to be updated. For specific details:
-* [Merkle tree](https://github.com/tendermint/spec/blob/master/spec/blockchain/encoding.md#merkle-trees)
-* [ConsensusParams](https://github.com/tendermint/spec/blob/master/spec/blockchain/state.md#consensusparams)
+* [Merkle tree](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/encoding.md#merkle-trees)
+* [ConsensusParams](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/state.md#consensusparams)
There was also a small change to field ordering in the vote struct. Any
implementations of an out-of-process validator (like a Key-Management Server)
will need to be updated. For specific details:
-* [Vote](https://github.com/tendermint/spec/blob/master/spec/consensus/signing.md#votes)
+* [Vote](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/signing.md#votes)
Finally, the proposer selection algorithm continues to evolve. See the
[work-in-progress
@@ -636,7 +650,7 @@ to `timeout_propose = "3s"`.
### RPC Changes
-The default behaviour of `/abci_query` has been changed to not return a proof,
+The default behavior of `/abci_query` has been changed to not return a proof,
and the name of the parameter that controls this has been changed from `trusted`
to `prove`. To get proofs with your queries, ensure you set `prove=true`.
diff --git a/abci/README.md b/abci/README.md
index 6399f59017..71cc787507 100644
--- a/abci/README.md
+++ b/abci/README.md
@@ -19,7 +19,7 @@ To get up and running quickly, see the [getting started guide](../docs/app-dev/g
A detailed description of the ABCI methods and message types is contained in:
-- [The main spec](https://github.com/tendermint/spec/blob/master/spec/abci/abci.md)
+- [The main spec](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/abci.md)
- [A protobuf file](./types/types.proto)
- [A Go interface](./types/application.go)
diff --git a/abci/client/mocks/client.go b/abci/client/mocks/client.go
index 9dcb9a3cf3..f463579a51 100644
--- a/abci/client/mocks/client.go
+++ b/abci/client/mocks/client.go
@@ -781,13 +781,13 @@ func (_m *Client) String() string {
return r0
}
-type NewClientT interface {
+type mockConstructorTestingTNewClient interface {
mock.TestingT
Cleanup(func())
}
// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-func NewClient(t NewClientT) *Client {
+func NewClient(t mockConstructorTestingTNewClient) *Client {
mock := &Client{}
mock.Mock.Test(t)
diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go
index dafa882378..3f912bbee7 100644
--- a/abci/example/kvstore/kvstore_test.go
+++ b/abci/example/kvstore/kvstore_test.go
@@ -2,7 +2,7 @@ package kvstore
import (
"fmt"
- "io/ioutil"
+ "os"
"sort"
"testing"
@@ -71,7 +71,7 @@ func TestKVStoreKV(t *testing.T) {
}
func TestPersistentKVStoreKV(t *testing.T) {
- dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
+ dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -87,7 +87,7 @@ func TestPersistentKVStoreKV(t *testing.T) {
}
func TestPersistentKVStoreInfo(t *testing.T) {
- dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
+ dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -114,12 +114,11 @@ func TestPersistentKVStoreInfo(t *testing.T) {
if resInfo.LastBlockHeight != height {
t.Fatalf("expected height of %d, got %d", height, resInfo.LastBlockHeight)
}
-
}
// add a validator, remove a validator, update a validator
func TestValUpdates(t *testing.T) {
- dir, err := ioutil.TempDir("/tmp", "abci-kvstore-test") // TODO
+ dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO
if err != nil {
t.Fatal(err)
}
@@ -162,7 +161,7 @@ func TestValUpdates(t *testing.T) {
makeApplyBlock(t, kvstore, 2, diff, tx1, tx2, tx3)
- vals1 = append(vals[:nInit-2], vals[nInit+1]) // nolint: gocritic
+ vals1 = append(vals[:nInit-2], vals[nInit+1]) //nolint: gocritic
vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2)
@@ -181,7 +180,6 @@ func TestValUpdates(t *testing.T) {
vals1 = append([]types.ValidatorUpdate{v1}, vals1[1:]...)
vals2 = kvstore.Validators()
valsEqual(t, vals1, vals2)
-
}
func makeApplyBlock(
@@ -189,7 +187,8 @@ func makeApplyBlock(
kvstore types.Application,
heightInt int,
diff []types.ValidatorUpdate,
- txs ...[]byte) {
+ txs ...[]byte,
+) {
// make and apply block
height := int64(heightInt)
hash := []byte("foo")
@@ -207,7 +206,6 @@ func makeApplyBlock(
kvstore.Commit()
valsEqual(t, diff, resEndBlock.ValidatorUpdates)
-
}
// order doesn't matter
diff --git a/abci/server/server.go b/abci/server/server.go
index 6dd13ad020..4b70545b21 100644
--- a/abci/server/server.go
+++ b/abci/server/server.go
@@ -2,9 +2,8 @@
Package server is used to start a new ABCI server.
It contains two server implementation:
- * gRPC server
- * socket server
-
+ - gRPC server
+ - socket server
*/
package server
diff --git a/behaviour/doc.go b/behaviour/doc.go
index 40061e0958..7b00ae1eb3 100644
--- a/behaviour/doc.go
+++ b/behaviour/doc.go
@@ -8,35 +8,34 @@ There are four different behaviours a reactor can report.
1. bad message
-type badMessage struct {
- explanation string
-}
+ type badMessage struct {
+ explanation string
+ }
-This message will request the peer be stopped for an error
+# This message will request the peer be stopped for an error
2. message out of order
-type messageOutOfOrder struct {
- explanation string
-}
+ type messageOutOfOrder struct {
+ explanation string
+ }
-This message will request the peer be stopped for an error
+# This message will request the peer be stopped for an error
3. consesnsus Vote
-type consensusVote struct {
- explanation string
-}
+ type consensusVote struct {
+ explanation string
+ }
-This message will request the peer be marked as good
+# This message will request the peer be marked as good
4. block part
-type blockPart struct {
- explanation string
-}
+ type blockPart struct {
+ explanation string
+ }
This message will request the peer be marked as good
-
*/
package behaviour
diff --git a/blockchain/msgs.go b/blockchain/msgs.go
index 35868830b5..9b45e859c5 100644
--- a/blockchain/msgs.go
+++ b/blockchain/msgs.go
@@ -6,6 +6,7 @@ import (
"github.com/gogo/protobuf/proto"
+ "github.com/tendermint/tendermint/p2p"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
"github.com/tendermint/tendermint/types"
)
@@ -19,58 +20,6 @@ const (
BlockResponseMessageFieldKeySize
)
-// EncodeMsg encodes a Protobuf message
-func EncodeMsg(pb proto.Message) ([]byte, error) {
- msg := bcproto.Message{}
-
- switch pb := pb.(type) {
- case *bcproto.BlockRequest:
- msg.Sum = &bcproto.Message_BlockRequest{BlockRequest: pb}
- case *bcproto.BlockResponse:
- msg.Sum = &bcproto.Message_BlockResponse{BlockResponse: pb}
- case *bcproto.NoBlockResponse:
- msg.Sum = &bcproto.Message_NoBlockResponse{NoBlockResponse: pb}
- case *bcproto.StatusRequest:
- msg.Sum = &bcproto.Message_StatusRequest{StatusRequest: pb}
- case *bcproto.StatusResponse:
- msg.Sum = &bcproto.Message_StatusResponse{StatusResponse: pb}
- default:
- return nil, fmt.Errorf("unknown message type %T", pb)
- }
-
- bz, err := proto.Marshal(&msg)
- if err != nil {
- return nil, fmt.Errorf("unable to marshal %T: %w", pb, err)
- }
-
- return bz, nil
-}
-
-// DecodeMsg decodes a Protobuf message.
-func DecodeMsg(bz []byte) (proto.Message, error) {
- pb := &bcproto.Message{}
-
- err := proto.Unmarshal(bz, pb)
- if err != nil {
- return nil, err
- }
-
- switch msg := pb.Sum.(type) {
- case *bcproto.Message_BlockRequest:
- return msg.BlockRequest, nil
- case *bcproto.Message_BlockResponse:
- return msg.BlockResponse, nil
- case *bcproto.Message_NoBlockResponse:
- return msg.NoBlockResponse, nil
- case *bcproto.Message_StatusRequest:
- return msg.StatusRequest, nil
- case *bcproto.Message_StatusResponse:
- return msg.StatusResponse, nil
- default:
- return nil, fmt.Errorf("unknown message type %T", msg)
- }
-}
-
// ValidateMsg validates a message.
func ValidateMsg(pb proto.Message) error {
if pb == nil {
@@ -108,3 +57,31 @@ func ValidateMsg(pb proto.Message) error {
}
return nil
}
+
+// EncodeMsg encodes a Protobuf message
+//
+// Deprecated: Will be removed in v0.37.
+func EncodeMsg(pb proto.Message) ([]byte, error) {
+ if um, ok := pb.(p2p.Wrapper); ok {
+ pb = um.Wrap()
+ }
+ bz, err := proto.Marshal(pb)
+ if err != nil {
+ return nil, fmt.Errorf("unable to marshal %T: %w", pb, err)
+ }
+
+ return bz, nil
+}
+
+// DecodeMsg decodes a Protobuf message.
+//
+// Deprecated: Will be removed in v0.37.
+func DecodeMsg(bz []byte) (proto.Message, error) {
+ pb := &bcproto.Message{}
+
+ err := proto.Unmarshal(bz, pb)
+ if err != nil {
+ return nil, err
+ }
+ return pb.Unwrap()
+}
diff --git a/blockchain/msgs_test.go b/blockchain/msgs_test.go
index 1e90a58457..bba8fed73b 100644
--- a/blockchain/msgs_test.go
+++ b/blockchain/msgs_test.go
@@ -79,7 +79,7 @@ func TestBcStatusResponseMessageValidateBasic(t *testing.T) {
}
}
-// nolint:lll // ignore line length in tests
+//nolint:lll // ignore line length in tests
func TestBlockchainMessageVectors(t *testing.T) {
block := types.MakeBlock(int64(3), factory.MakeData([]types.Tx{types.Tx("Hello World")}, nil), nil, nil)
block.Version.Block = 11 // overwrite updated protocol version
diff --git a/blockchain/v0/pool.go b/blockchain/v0/pool.go
index 69e0b55c4a..e3923b0d9b 100644
--- a/blockchain/v0/pool.go
+++ b/blockchain/v0/pool.go
@@ -32,6 +32,7 @@ const (
maxTotalRequesters = 600
maxPendingRequests = maxTotalRequesters
maxPendingRequestsPerPeer = 20
+ requestRetrySeconds = 30
// Minimum recv rate to ensure we're receiving blocks from a peer fast
// enough. If a peer is not sending us data at at least that rate, we
@@ -410,6 +411,7 @@ func (pool *BlockPool) sendError(err error, peerID p2p.ID) {
}
// for debugging purposes
+//
//nolint:unused
func (pool *BlockPool) debug() string {
pool.mtx.Lock()
@@ -601,7 +603,7 @@ OUTER_LOOP:
}
peer = bpr.pool.pickIncrAvailablePeer(bpr.height)
if peer == nil {
- // log.Info("No peers available", "height", height)
+ bpr.Logger.Debug("No peers currently available; will retry shortly", "height", bpr.height)
time.Sleep(requestIntervalMS * time.Millisecond)
continue PICK_PEER_LOOP
}
@@ -611,6 +613,7 @@ OUTER_LOOP:
bpr.peerID = peer.id
bpr.mtx.Unlock()
+ to := time.NewTimer(requestRetrySeconds * time.Second)
// Send request and wait.
bpr.pool.sendRequest(bpr.height, peer.id)
WAIT_LOOP:
@@ -623,6 +626,11 @@ OUTER_LOOP:
return
case <-bpr.Quit():
return
+ case <-to.C:
+ bpr.Logger.Debug("Retrying block request after timeout", "height", bpr.height, "peer", bpr.peerID)
+ // Simulate a redo
+ bpr.reset()
+ continue OUTER_LOOP
case peerID := <-bpr.redoCh:
if peerID == bpr.peerID {
bpr.reset()
diff --git a/blockchain/v0/reactor.go b/blockchain/v0/reactor.go
index c14d2d34a6..0ac278041d 100644
--- a/blockchain/v0/reactor.go
+++ b/blockchain/v0/reactor.go
@@ -5,6 +5,8 @@ import (
"reflect"
"time"
+ "github.com/gogo/protobuf/proto"
+
bc "github.com/tendermint/tendermint/blockchain"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/p2p"
@@ -144,21 +146,20 @@ func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 1000,
RecvBufferCapacity: 50 * 4096,
RecvMessageCapacity: bc.MaxMsgSize,
+ MessageType: &bcproto.Message{},
},
}
}
// AddPeer implements Reactor by sending our state to peer.
func (bcR *BlockchainReactor) AddPeer(peer p2p.Peer) {
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusResponse{
- Base: bcR.store.Base(),
- Height: bcR.store.Height()})
- if err != nil {
- bcR.Logger.Error("could not convert msg to protobuf", "err", err)
- return
- }
-
- peer.Send(BlockchainChannel, msgBytes)
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusResponse{
+ Base: bcR.store.Base(),
+ Height: bcR.store.Height(),
+ },
+ }, bcR.Logger)
// it's OK if send fails. will try later in poolRoutine
// peer is added to the pool once we receive the first
@@ -182,75 +183,73 @@ func (bcR *BlockchainReactor) respondToPeer(msg *bcproto.BlockRequest,
bcR.Logger.Error("could not convert msg to protobuf", "err", err)
return false
}
-
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockResponse{Block: bl})
- if err != nil {
- bcR.Logger.Error("could not marshal msg", "err", err)
- return false
- }
-
- return src.TrySend(BlockchainChannel, msgBytes)
- }
-
- bcR.Logger.Info("Peer asking for a block we don't have", "src", src, "height", msg.Height)
-
- msgBytes, err := bc.EncodeMsg(&bcproto.NoBlockResponse{Height: msg.Height})
- if err != nil {
- bcR.Logger.Error("could not convert msg to protobuf", "err", err)
- return false
+ return p2p.TrySendEnvelopeShim(src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockResponse{Block: bl},
+ }, bcR.Logger)
}
- return src.TrySend(BlockchainChannel, msgBytes)
+ return p2p.TrySendEnvelopeShim(src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.NoBlockResponse{Height: msg.Height},
+ }, bcR.Logger)
}
-// Receive implements Reactor by handling 4 types of messages (look below).
-func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
- msg, err := bc.DecodeMsg(msgBytes)
- if err != nil {
- bcR.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err)
- bcR.Switch.StopPeerForError(src, err)
+func (bcR *BlockchainReactor) ReceiveEnvelope(e p2p.Envelope) {
+ if err := bc.ValidateMsg(e.Message); err != nil {
+ bcR.Logger.Error("Peer sent us invalid msg", "peer", e.Src, "msg", e.Message, "err", err)
+ bcR.Switch.StopPeerForError(e.Src, err)
return
}
- if err = bc.ValidateMsg(msg); err != nil {
- bcR.Logger.Error("Peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
- bcR.Switch.StopPeerForError(src, err)
- return
- }
+ bcR.Logger.Debug("Receive", "e.Src", e.Src, "chID", e.ChannelID, "msg", e.Message)
- bcR.Logger.Debug("Receive", "src", src, "chID", chID, "msg", msg)
-
- switch msg := msg.(type) {
+ switch msg := e.Message.(type) {
case *bcproto.BlockRequest:
- bcR.respondToPeer(msg, src)
+ bcR.respondToPeer(msg, e.Src)
case *bcproto.BlockResponse:
bi, err := types.BlockFromProto(msg.Block)
if err != nil {
bcR.Logger.Error("Block content is invalid", "err", err)
return
}
- bcR.pool.AddBlock(src.ID(), bi, len(msgBytes))
+ bcR.pool.AddBlock(e.Src.ID(), bi, msg.Block.Size())
case *bcproto.StatusRequest:
// Send peer our state.
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusResponse{
- Height: bcR.store.Height(),
- Base: bcR.store.Base(),
- })
- if err != nil {
- bcR.Logger.Error("could not convert msg to protobut", "err", err)
- return
- }
- src.TrySend(BlockchainChannel, msgBytes)
+ p2p.TrySendEnvelopeShim(e.Src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusResponse{
+ Height: bcR.store.Height(),
+ Base: bcR.store.Base(),
+ },
+ }, bcR.Logger)
case *bcproto.StatusResponse:
// Got a peer status. Unverified.
- bcR.pool.SetPeerRange(src.ID(), msg.Base, msg.Height)
+ bcR.pool.SetPeerRange(e.Src.ID(), msg.Base, msg.Height)
case *bcproto.NoBlockResponse:
- bcR.Logger.Debug("Peer does not have requested block", "peer", src, "height", msg.Height)
+ bcR.Logger.Debug("Peer does not have requested block", "peer", e.Src, "height", msg.Height)
default:
bcR.Logger.Error(fmt.Sprintf("Unknown message type %v", reflect.TypeOf(msg)))
}
}
+func (bcR *BlockchainReactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &bcproto.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+ bcR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
+}
+
// Handle messages from the poolReactor telling the reactor what to do.
// NOTE: Don't sleep in the FOR_LOOP or otherwise slow it down!
func (bcR *BlockchainReactor) poolRoutine(stateSynced bool) {
@@ -286,13 +285,10 @@ func (bcR *BlockchainReactor) poolRoutine(stateSynced bool) {
if peer == nil {
continue
}
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockRequest{Height: request.Height})
- if err != nil {
- bcR.Logger.Error("could not convert msg to proto", "err", err)
- continue
- }
-
- queued := peer.TrySend(BlockchainChannel, msgBytes)
+ queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockRequest{Height: request.Height},
+ }, bcR.Logger)
if !queued {
bcR.Logger.Debug("Send queue is full, drop block request", "peer", peer.ID(), "height", request.Height)
}
@@ -304,7 +300,7 @@ func (bcR *BlockchainReactor) poolRoutine(stateSynced bool) {
case <-statusUpdateTicker.C:
// ask for status updates
- go bcR.BroadcastStatusRequest() // nolint: errcheck
+ go bcR.BroadcastStatusRequest() //nolint: errcheck
}
}
@@ -425,13 +421,9 @@ FOR_LOOP:
// BroadcastStatusRequest broadcasts `BlockStore` base and height.
func (bcR *BlockchainReactor) BroadcastStatusRequest() error {
- bm, err := bc.EncodeMsg(&bcproto.StatusRequest{})
- if err != nil {
- bcR.Logger.Error("could not convert msg to proto", "err", err)
- return fmt.Errorf("could not convert msg to proto: %w", err)
- }
-
- bcR.Switch.Broadcast(BlockchainChannel, bm)
-
+ bcR.Switch.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusRequest{},
+ })
return nil
}
diff --git a/blockchain/v0/reactor_test.go b/blockchain/v0/reactor_test.go
index 4d23c9f2ce..b74cdf1a10 100644
--- a/blockchain/v0/reactor_test.go
+++ b/blockchain/v0/reactor_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -17,6 +18,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/mempool/mock"
"github.com/tendermint/tendermint/p2p"
+ bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
"github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/store"
@@ -71,7 +73,9 @@ func newBlockchainReactor(
blockDB := dbm.NewMemDB()
stateDB := dbm.NewMemDB()
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
blockStore := store.NewBlockStore(blockDB)
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
@@ -84,7 +88,9 @@ func newBlockchainReactor(
// pool.height is determined from the store.
fastSync := true
db := dbm.NewMemDB()
- stateStore = sm.NewStore(db)
+ stateStore = sm.NewStore(db, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
mock.Mempool{}, sm.EmptyEvidencePool{})
if err = stateStore.Save(state); err != nil {
@@ -189,6 +195,25 @@ func TestNoBlockResponse(t *testing.T) {
}
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config = cfg.ResetTestRoot("blockchain_reactor_test")
+ defer os.RemoveAll(config.RootDir)
+ genDoc, privVals := randGenesisDoc(1, false, 30)
+ reactor := newBlockchainReactor(log.TestingLogger(), genDoc, privVals, 10).reactor
+ peer := p2p.CreateRandomPeer(false)
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ m := &bcproto.StatusRequest{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(BlockchainChannel, peer, msg)
+ })
+}
+
// NOTE: This is too hard to test without
// an easy way to add test peer to switch
// or without significant refactoring of the module.
diff --git a/blockchain/v1/reactor.go b/blockchain/v1/reactor.go
index c4c61ec516..f6fb93ab8d 100644
--- a/blockchain/v1/reactor.go
+++ b/blockchain/v1/reactor.go
@@ -2,9 +2,10 @@ package v1
import (
"fmt"
- "reflect"
"time"
+ "github.com/gogo/protobuf/proto"
+
"github.com/tendermint/tendermint/behaviour"
bc "github.com/tendermint/tendermint/blockchain"
"github.com/tendermint/tendermint/libs/log"
@@ -172,21 +173,20 @@ func (bcR *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 2000,
RecvBufferCapacity: 50 * 4096,
RecvMessageCapacity: bc.MaxMsgSize,
+ MessageType: &bcproto.Message{},
},
}
}
// AddPeer implements Reactor by sending our state to peer.
func (bcR *BlockchainReactor) AddPeer(peer p2p.Peer) {
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusResponse{
- Base: bcR.store.Base(),
- Height: bcR.store.Height(),
- })
- if err != nil {
- bcR.Logger.Error("could not convert msg to protobuf", "err", err)
- return
- }
- peer.Send(BlockchainChannel, msgBytes)
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusResponse{
+ Base: bcR.store.Base(),
+ Height: bcR.store.Height(),
+ },
+ }, bcR.Logger)
// it's OK if send fails. will try later in poolRoutine
// peer is added to the pool once we receive the first
@@ -206,35 +206,28 @@ func (bcR *BlockchainReactor) sendBlockToPeer(msg *bcproto.BlockRequest,
bcR.Logger.Error("Could not send block message to peer", "err", err)
return false
}
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockResponse{Block: pbbi})
- if err != nil {
- bcR.Logger.Error("unable to marshal msg", "err", err)
- return false
- }
- return src.TrySend(BlockchainChannel, msgBytes)
+ return p2p.TrySendEnvelopeShim(src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockResponse{Block: pbbi},
+ }, bcR.Logger)
}
bcR.Logger.Info("peer asking for a block we don't have", "src", src, "height", msg.Height)
- msgBytes, err := bc.EncodeMsg(&bcproto.NoBlockResponse{Height: msg.Height})
- if err != nil {
- bcR.Logger.Error("unable to marshal msg", "err", err)
- return false
- }
- return src.TrySend(BlockchainChannel, msgBytes)
+ return p2p.TrySendEnvelopeShim(src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.NoBlockResponse{Height: msg.Height},
+ }, bcR.Logger)
}
func (bcR *BlockchainReactor) sendStatusResponseToPeer(msg *bcproto.StatusRequest, src p2p.Peer) (queued bool) {
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusResponse{
- Base: bcR.store.Base(),
- Height: bcR.store.Height(),
- })
- if err != nil {
- bcR.Logger.Error("unable to marshal msg", "err", err)
- return false
- }
-
- return src.TrySend(BlockchainChannel, msgBytes)
+ return p2p.TrySendEnvelopeShim(src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusResponse{
+ Base: bcR.store.Base(),
+ Height: bcR.store.Height(),
+ },
+ }, bcR.Logger)
}
// RemovePeer implements Reactor by removing peer from the pool.
@@ -250,34 +243,27 @@ func (bcR *BlockchainReactor) RemovePeer(peer p2p.Peer, reason interface{}) {
}
// Receive implements Reactor by handling 4 types of messages (look below).
-func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
- msg, err := bc.DecodeMsg(msgBytes)
- if err != nil {
- bcR.Logger.Error("error decoding message", "src", src, "chId", chID, "err", err)
- _ = bcR.swReporter.Report(behaviour.BadMessage(src.ID(), err.Error()))
- return
- }
-
- if err = bc.ValidateMsg(msg); err != nil {
- bcR.Logger.Error("peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
- _ = bcR.swReporter.Report(behaviour.BadMessage(src.ID(), err.Error()))
+func (bcR *BlockchainReactor) ReceiveEnvelope(e p2p.Envelope) {
+ if err := bc.ValidateMsg(e.Message); err != nil {
+ bcR.Logger.Error("peer sent us invalid msg", "peer", e.Src, "msg", e.Message, "err", err)
+ _ = bcR.swReporter.Report(behaviour.BadMessage(e.Src.ID(), err.Error()))
return
}
- bcR.Logger.Debug("Receive", "src", src, "chID", chID, "msg", msg)
+ bcR.Logger.Debug("Receive", "src", e.Src, "chID", e.ChannelID, "msg", e.Message)
- switch msg := msg.(type) {
+ switch msg := e.Message.(type) {
case *bcproto.BlockRequest:
- if queued := bcR.sendBlockToPeer(msg, src); !queued {
+ if queued := bcR.sendBlockToPeer(msg, e.Src); !queued {
// Unfortunately not queued since the queue is full.
- bcR.Logger.Error("Could not send block message to peer", "src", src, "height", msg.Height)
+ bcR.Logger.Error("Could not send block message to peer", "src", e.Src, "height", msg.Height)
}
case *bcproto.StatusRequest:
// Send peer our state.
- if queued := bcR.sendStatusResponseToPeer(msg, src); !queued {
+ if queued := bcR.sendStatusResponseToPeer(msg, e.Src); !queued {
// Unfortunately not queued since the queue is full.
- bcR.Logger.Error("Could not send status message to peer", "src", src)
+ bcR.Logger.Error("Could not send status message to peer", "src", e.Src)
}
case *bcproto.BlockResponse:
@@ -289,23 +275,23 @@ func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
msgForFSM := bcReactorMessage{
event: blockResponseEv,
data: bReactorEventData{
- peerID: src.ID(),
+ peerID: e.Src.ID(),
height: bi.Height,
block: bi,
- length: len(msgBytes),
+ length: msg.Size(),
},
}
- bcR.Logger.Info("Received", "src", src, "height", bi.Height)
+ bcR.Logger.Info("Received", "src", e.Src, "height", bi.Height)
bcR.messagesForFSMCh <- msgForFSM
case *bcproto.NoBlockResponse:
msgForFSM := bcReactorMessage{
event: noBlockResponseEv,
data: bReactorEventData{
- peerID: src.ID(),
+ peerID: e.Src.ID(),
height: msg.Height,
},
}
- bcR.Logger.Debug("Peer does not have requested block", "peer", src, "height", msg.Height)
+ bcR.Logger.Debug("Peer does not have requested block", "peer", e.Src, "height", msg.Height)
bcR.messagesForFSMCh <- msgForFSM
case *bcproto.StatusResponse:
@@ -313,16 +299,33 @@ func (bcR *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte)
msgForFSM := bcReactorMessage{
event: statusResponseEv,
data: bReactorEventData{
- peerID: src.ID(),
+ peerID: e.Src.ID(),
height: msg.Height,
- length: len(msgBytes),
+ length: msg.Size(),
},
}
bcR.messagesForFSMCh <- msgForFSM
default:
- bcR.Logger.Error(fmt.Sprintf("unknown message type %v", reflect.TypeOf(msg)))
+ bcR.Logger.Error(fmt.Sprintf("unknown message type %T", msg))
+ }
+}
+
+func (bcR *BlockchainReactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &bcproto.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
}
+ bcR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
}
// processBlocksRoutine processes blocks until signlaed to stop over the stopProcessing channel
@@ -492,11 +495,10 @@ func (bcR *BlockchainReactor) processBlock() error {
// Implements bcRNotifier
// sendStatusRequest broadcasts `BlockStore` height.
func (bcR *BlockchainReactor) sendStatusRequest() {
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusRequest{})
- if err != nil {
- panic(err)
- }
- bcR.Switch.Broadcast(BlockchainChannel, msgBytes)
+ bcR.Switch.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusRequest{},
+ })
}
// Implements bcRNotifier
@@ -507,11 +509,10 @@ func (bcR *BlockchainReactor) sendBlockRequest(peerID p2p.ID, height int64) erro
return errNilPeerForBlockRequest
}
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockRequest{Height: height})
- if err != nil {
- return err
- }
- queued := peer.TrySend(BlockchainChannel, msgBytes)
+ queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockRequest{Height: height},
+ }, bcR.Logger)
if !queued {
return errSendQueueFull
}
@@ -534,8 +535,8 @@ func (bcR *BlockchainReactor) switchToConsensus() {
// Called by FSM and pool:
// - pool calls when it detects slow peer or when peer times out
// - FSM calls when:
-// - adding a block (addBlock) fails
-// - reactor processing of a block reports failure and FSM sends back the peers of first and second blocks
+// - adding a block (addBlock) fails
+// - reactor processing of a block reports failure and FSM sends back the peers of first and second blocks
func (bcR *BlockchainReactor) sendPeerError(err error, peerID p2p.ID) {
bcR.Logger.Info("sendPeerError:", "peer", peerID, "error", err)
msgData := bcFsmMessage{
diff --git a/blockchain/v1/reactor_test.go b/blockchain/v1/reactor_test.go
index 7761d92f24..89e9ae9e73 100644
--- a/blockchain/v1/reactor_test.go
+++ b/blockchain/v1/reactor_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -18,6 +19,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/mempool/mock"
"github.com/tendermint/tendermint/p2p"
+ bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state"
@@ -103,7 +105,9 @@ func newBlockchainReactor(
blockDB := dbm.NewMemDB()
stateDB := dbm.NewMemDB()
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
blockStore := store.NewBlockStore(blockDB)
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
@@ -116,7 +120,9 @@ func newBlockchainReactor(
// pool.height is determined from the store.
fastSync := true
db := dbm.NewMemDB()
- stateStore = sm.NewStore(db)
+ stateStore = sm.NewStore(db, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
mock.Mempool{}, sm.EmptyEvidencePool{})
if err = stateStore.Save(state); err != nil {
@@ -346,6 +352,25 @@ outerFor:
assert.True(t, lastReactorPair.bcR.Switch.Peers().Size() < len(reactorPairs)-1)
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config = cfg.ResetTestRoot("blockchain_reactor_test")
+ defer os.RemoveAll(config.RootDir)
+ genDoc, privVals := randGenesisDoc(1, false, 30)
+ reactor := newBlockchainReactor(t, log.TestingLogger(), genDoc, privVals, 10)
+ peer := p2p.CreateRandomPeer(false)
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ m := &bcproto.StatusRequest{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(BlockchainChannel, peer, msg)
+ })
+}
+
//----------------------------------------------
// utility funcs
diff --git a/blockchain/v2/io.go b/blockchain/v2/io.go
index 4951573ce4..af9f037fe6 100644
--- a/blockchain/v2/io.go
+++ b/blockchain/v2/io.go
@@ -3,7 +3,6 @@ package v2
import (
"fmt"
- bc "github.com/tendermint/tendermint/blockchain"
"github.com/tendermint/tendermint/p2p"
bcproto "github.com/tendermint/tendermint/proto/tendermint/blockchain"
"github.com/tendermint/tendermint/state"
@@ -16,7 +15,7 @@ type iIO interface {
sendBlockNotFound(height int64, peerID p2p.ID) error
sendStatusResponse(base, height int64, peerID p2p.ID) error
- broadcastStatusRequest() error
+ broadcastStatusRequest()
trySwitchToConsensus(state state.State, skipWAL bool) bool
}
@@ -47,13 +46,10 @@ func (sio *switchIO) sendBlockRequest(peerID p2p.ID, height int64) error {
if peer == nil {
return fmt.Errorf("peer not found")
}
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockRequest{Height: height})
- if err != nil {
- return err
- }
-
- queued := peer.TrySend(BlockchainChannel, msgBytes)
- if !queued {
+ if queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockRequest{Height: height},
+ }, sio.sw.Logger); !queued {
return fmt.Errorf("send queue full")
}
return nil
@@ -65,12 +61,10 @@ func (sio *switchIO) sendStatusResponse(base int64, height int64, peerID p2p.ID)
return fmt.Errorf("peer not found")
}
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusResponse{Height: height, Base: base})
- if err != nil {
- return err
- }
-
- if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued {
+ if queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusRequest{},
+ }, sio.sw.Logger); !queued {
return fmt.Errorf("peer queue full")
}
@@ -91,11 +85,10 @@ func (sio *switchIO) sendBlockToPeer(block *types.Block, peerID p2p.ID) error {
return err
}
- msgBytes, err := bc.EncodeMsg(&bcproto.BlockResponse{Block: bpb})
- if err != nil {
- return err
- }
- if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued {
+ if queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.BlockResponse{Block: bpb},
+ }, sio.sw.Logger); !queued {
return fmt.Errorf("peer queue full")
}
@@ -107,12 +100,10 @@ func (sio *switchIO) sendBlockNotFound(height int64, peerID p2p.ID) error {
if peer == nil {
return fmt.Errorf("peer not found")
}
- msgBytes, err := bc.EncodeMsg(&bcproto.NoBlockResponse{Height: height})
- if err != nil {
- return err
- }
-
- if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued {
+ if queued := p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.NoBlockResponse{Height: height},
+ }, sio.sw.Logger); !queued {
return fmt.Errorf("peer queue full")
}
@@ -127,14 +118,10 @@ func (sio *switchIO) trySwitchToConsensus(state state.State, skipWAL bool) bool
return ok
}
-func (sio *switchIO) broadcastStatusRequest() error {
- msgBytes, err := bc.EncodeMsg(&bcproto.StatusRequest{})
- if err != nil {
- return err
- }
-
+func (sio *switchIO) broadcastStatusRequest() {
// XXX: maybe we should use an io specific peer list here
- sio.sw.Broadcast(BlockchainChannel, msgBytes)
-
- return nil
+ sio.sw.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: BlockchainChannel,
+ Message: &bcproto.StatusRequest{},
+ })
}
diff --git a/blockchain/v2/reactor.go b/blockchain/v2/reactor.go
index 9dea749d70..f428974858 100644
--- a/blockchain/v2/reactor.go
+++ b/blockchain/v2/reactor.go
@@ -5,6 +5,8 @@ import (
"fmt"
"time"
+ "github.com/gogo/protobuf/proto"
+
"github.com/tendermint/tendermint/behaviour"
bc "github.com/tendermint/tendermint/blockchain"
"github.com/tendermint/tendermint/libs/log"
@@ -215,7 +217,7 @@ type bcBlockResponse struct {
priorityNormal
time time.Time
peerID p2p.ID
- size int64
+ size int
block *types.Block
}
@@ -349,9 +351,7 @@ func (r *BlockchainReactor) demux(events <-chan Event) {
case <-doProcessBlockCh:
r.processor.send(rProcessBlock{})
case <-doStatusCh:
- if err := r.io.broadcastStatusRequest(); err != nil {
- r.logger.Error("Error broadcasting status request", "err", err)
- }
+ r.io.broadcastStatusRequest()
// Events from peers. Closing the channel signals event loop termination.
case event, ok := <-events:
@@ -455,39 +455,31 @@ func (r *BlockchainReactor) Stop() error {
}
// Receive implements Reactor by handling different message types.
-func (r *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
- msg, err := bc.DecodeMsg(msgBytes)
- if err != nil {
- r.logger.Error("error decoding message",
- "src", src.ID(), "chId", chID, "msg", msg, "err", err)
- _ = r.reporter.Report(behaviour.BadMessage(src.ID(), err.Error()))
- return
- }
-
- if err = bc.ValidateMsg(msg); err != nil {
- r.logger.Error("peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
- _ = r.reporter.Report(behaviour.BadMessage(src.ID(), err.Error()))
+func (r *BlockchainReactor) ReceiveEnvelope(e p2p.Envelope) {
+ if err := bc.ValidateMsg(e.Message); err != nil {
+ r.logger.Error("peer sent us invalid msg", "peer", e.Src, "msg", e.Message, "err", err)
+ _ = r.reporter.Report(behaviour.BadMessage(e.Src.ID(), err.Error()))
return
}
- r.logger.Debug("Receive", "src", src.ID(), "chID", chID, "msg", msg)
+ r.logger.Debug("Receive", "src", e.Src.ID(), "chID", e.ChannelID, "msg", e.Message)
- switch msg := msg.(type) {
+ switch msg := e.Message.(type) {
case *bcproto.StatusRequest:
- if err := r.io.sendStatusResponse(r.store.Base(), r.store.Height(), src.ID()); err != nil {
- r.logger.Error("Could not send status message to peer", "src", src)
+ if err := r.io.sendStatusResponse(r.store.Base(), r.store.Height(), e.Src.ID()); err != nil {
+ r.logger.Error("Could not send status message to peer", "src", e.Src)
}
case *bcproto.BlockRequest:
block := r.store.LoadBlock(msg.Height)
if block != nil {
- if err = r.io.sendBlockToPeer(block, src.ID()); err != nil {
+ if err := r.io.sendBlockToPeer(block, e.Src.ID()); err != nil {
r.logger.Error("Could not send block message to peer: ", err)
}
} else {
- r.logger.Info("peer asking for a block we don't have", "src", src, "height", msg.Height)
- peerID := src.ID()
- if err = r.io.sendBlockNotFound(msg.Height, peerID); err != nil {
+ r.logger.Info("peer asking for a block we don't have", "src", e.Src, "height", msg.Height)
+ peerID := e.Src.ID()
+ if err := r.io.sendBlockNotFound(msg.Height, peerID); err != nil {
r.logger.Error("Couldn't send block not found: ", err)
}
}
@@ -495,7 +487,7 @@ func (r *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
case *bcproto.StatusResponse:
r.mtx.RLock()
if r.events != nil {
- r.events <- bcStatusResponse{peerID: src.ID(), base: msg.Base, height: msg.Height}
+ r.events <- bcStatusResponse{peerID: e.Src.ID(), base: msg.Base, height: msg.Height}
}
r.mtx.RUnlock()
@@ -508,10 +500,10 @@ func (r *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
r.mtx.RLock()
if r.events != nil {
r.events <- bcBlockResponse{
- peerID: src.ID(),
+ peerID: e.Src.ID(),
block: bi,
- size: int64(len(msgBytes)),
time: time.Now(),
+ size: msg.Size(),
}
}
r.mtx.RUnlock()
@@ -519,12 +511,29 @@ func (r *BlockchainReactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
case *bcproto.NoBlockResponse:
r.mtx.RLock()
if r.events != nil {
- r.events <- bcNoBlockResponse{peerID: src.ID(), height: msg.Height, time: time.Now()}
+ r.events <- bcNoBlockResponse{peerID: e.Src.ID(), height: msg.Height, time: time.Now()}
}
r.mtx.RUnlock()
}
}
+func (r *BlockchainReactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &bcproto.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+ r.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
+}
+
// AddPeer implements Reactor interface
func (r *BlockchainReactor) AddPeer(peer p2p.Peer) {
err := r.io.sendStatusResponse(r.store.Base(), r.store.Height(), peer.ID())
@@ -559,6 +568,7 @@ func (r *BlockchainReactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 2000,
RecvBufferCapacity: 50 * 4096,
RecvMessageCapacity: bc.MaxMsgSize,
+ MessageType: &bcproto.Message{},
},
}
}
diff --git a/blockchain/v2/reactor_test.go b/blockchain/v2/reactor_test.go
index 660931e0ea..6ddf15936f 100644
--- a/blockchain/v2/reactor_test.go
+++ b/blockchain/v2/reactor_test.go
@@ -9,13 +9,13 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/behaviour"
- bc "github.com/tendermint/tendermint/blockchain"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/service"
@@ -54,34 +54,19 @@ func (mp mockPeer) NodeInfo() p2p.NodeInfo {
func (mp mockPeer) Status() conn.ConnectionStatus { return conn.ConnectionStatus{} }
func (mp mockPeer) SocketAddr() *p2p.NetAddress { return &p2p.NetAddress{} }
+func (mp mockPeer) SendEnvelope(e p2p.Envelope) bool { return true }
+func (mp mockPeer) TrySendEnvelope(e p2p.Envelope) bool { return true }
+
func (mp mockPeer) Send(byte, []byte) bool { return true }
func (mp mockPeer) TrySend(byte, []byte) bool { return true }
func (mp mockPeer) Set(string, interface{}) {}
func (mp mockPeer) Get(string) interface{} { return struct{}{} }
-// nolint:unused // ignore
-type mockBlockStore struct {
- blocks map[int64]*types.Block
-}
-
-// nolint:unused // ignore
-func (ml *mockBlockStore) Height() int64 {
- return int64(len(ml.blocks))
-}
-
-// nolint:unused // ignore
-func (ml *mockBlockStore) LoadBlock(height int64) *types.Block {
- return ml.blocks[height]
-}
-
-// nolint:unused // ignore
-func (ml *mockBlockStore) SaveBlock(block *types.Block, part *types.PartSet, commit *types.Commit) {
- ml.blocks[block.Height] = block
-}
+func (mp mockPeer) SetRemovalFailed() {}
+func (mp mockPeer) GetRemovalFailed() bool { return false }
-type mockBlockApplier struct {
-}
+type mockBlockApplier struct{}
// XXX: Add whitelist/blacklist?
func (mba *mockBlockApplier) ApplyBlock(
@@ -131,8 +116,7 @@ func (sio *mockSwitchIo) trySwitchToConsensus(state sm.State, skipWAL bool) bool
return true
}
-func (sio *mockSwitchIo) broadcastStatusRequest() error {
- return nil
+func (sio *mockSwitchIo) broadcastStatusRequest() {
}
type testReactorParams struct {
@@ -160,7 +144,9 @@ func newTestReactor(p testReactorParams) *BlockchainReactor {
panic(fmt.Errorf("error start app: %w", err))
}
db := dbm.NewMemDB()
- stateStore := sm.NewStore(db)
+ stateStore := sm.NewStore(db, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
appl = sm.NewBlockExecutor(stateStore, p.logger, proxyApp.Consensus(), mock.Mempool{}, sm.EmptyEvidencePool{})
if err = stateStore.Save(state); err != nil {
panic(err)
@@ -351,9 +337,7 @@ func newTestReactor(p testReactorParams) *BlockchainReactor {
// }
func TestReactorHelperMode(t *testing.T) {
- var (
- channelID = byte(0x40)
- )
+ channelID := byte(0x40)
config := cfg.ResetTestRoot("blockchain_reactor_v2_test")
defer os.RemoveAll(config.RootDir)
@@ -369,7 +353,7 @@ func TestReactorHelperMode(t *testing.T) {
type testEvent struct {
peer string
- event interface{}
+ event proto.Message
}
tests := []struct {
@@ -381,10 +365,10 @@ func TestReactorHelperMode(t *testing.T) {
name: "status request",
params: params,
msgs: []testEvent{
- {"P1", bcproto.StatusRequest{}},
- {"P1", bcproto.BlockRequest{Height: 13}},
- {"P1", bcproto.BlockRequest{Height: 20}},
- {"P1", bcproto.BlockRequest{Height: 22}},
+ {"P1", &bcproto.StatusRequest{}},
+ {"P1", &bcproto.BlockRequest{Height: 13}},
+ {"P1", &bcproto.BlockRequest{Height: 20}},
+ {"P1", &bcproto.BlockRequest{Height: 22}},
},
},
}
@@ -401,25 +385,27 @@ func TestReactorHelperMode(t *testing.T) {
for i := 0; i < len(tt.msgs); i++ {
step := tt.msgs[i]
switch ev := step.event.(type) {
- case bcproto.StatusRequest:
+ case *bcproto.StatusRequest:
old := mockSwitch.numStatusResponse
- msg, err := bc.EncodeMsg(&ev)
- assert.NoError(t, err)
- reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, msg)
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: channelID,
+ Src: mockPeer{id: p2p.ID(step.peer)},
+ Message: ev})
assert.Equal(t, old+1, mockSwitch.numStatusResponse)
- case bcproto.BlockRequest:
+ case *bcproto.BlockRequest:
if ev.Height > params.startHeight {
old := mockSwitch.numNoBlockResponse
- msg, err := bc.EncodeMsg(&ev)
- assert.NoError(t, err)
- reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, msg)
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: channelID,
+ Src: mockPeer{id: p2p.ID(step.peer)},
+ Message: ev})
assert.Equal(t, old+1, mockSwitch.numNoBlockResponse)
} else {
old := mockSwitch.numBlockResponse
- msg, err := bc.EncodeMsg(&ev)
- assert.NoError(t, err)
- assert.NoError(t, err)
- reactor.Receive(channelID, mockPeer{id: p2p.ID(step.peer)}, msg)
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: channelID,
+ Src: mockPeer{id: p2p.ID(step.peer)},
+ Message: ev})
assert.Equal(t, old+1, mockSwitch.numBlockResponse)
}
}
@@ -430,6 +416,34 @@ func TestReactorHelperMode(t *testing.T) {
}
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config := cfg.ResetTestRoot("blockchain_reactor_v2_test")
+ defer os.RemoveAll(config.RootDir)
+ genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30)
+ params := testReactorParams{
+ logger: log.TestingLogger(),
+ genDoc: genDoc,
+ privVals: privVals,
+ startHeight: 20,
+ mockA: true,
+ }
+ reactor := newTestReactor(params)
+ mockSwitch := &mockSwitchIo{switchedToConsensus: false}
+ reactor.io = mockSwitch
+ peer := p2p.CreateRandomPeer(false)
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ m := &bcproto.StatusRequest{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(BlockchainChannel, peer, msg)
+ })
+}
+
func TestReactorSetSwitchNil(t *testing.T) {
config := cfg.ResetTestRoot("blockchain_reactor_v2_test")
defer os.RemoveAll(config.RootDir)
@@ -472,7 +486,8 @@ type testApp struct {
}
func randGenesisDoc(chainID string, numValidators int, randPower bool, minPower int64) (
- *types.GenesisDoc, []types.PrivValidator) {
+ *types.GenesisDoc, []types.PrivValidator,
+) {
validators := make([]types.GenesisValidator, numValidators)
privValidators := make([]types.PrivValidator, numValidators)
for i := 0; i < numValidators; i++ {
@@ -497,7 +512,8 @@ func randGenesisDoc(chainID string, numValidators int, randPower bool, minPower
func newReactorStore(
genDoc *types.GenesisDoc,
privVals []types.PrivValidator,
- maxBlockHeight int64) (*store.BlockStore, sm.State, *sm.BlockExecutor) {
+ maxBlockHeight int64,
+) (*store.BlockStore, sm.State, *sm.BlockExecutor) {
if len(privVals) != 1 {
panic("only support one validator")
}
@@ -511,14 +527,19 @@ func newReactorStore(
stateDB := dbm.NewMemDB()
blockStore := store.NewBlockStore(dbm.NewMemDB())
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
if err != nil {
panic(fmt.Errorf("error constructing state from genesis file: %w", err))
}
db := dbm.NewMemDB()
- stateStore = sm.NewStore(db)
+ stateStore = sm.NewStore(db, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ },
+ )
blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(),
mock.Mempool{}, sm.EmptyEvidencePool{})
if err = stateStore.Save(state); err != nil {
diff --git a/blockchain/v2/routine.go b/blockchain/v2/routine.go
index dad0e737fa..119ca22e2d 100644
--- a/blockchain/v2/routine.go
+++ b/blockchain/v2/routine.go
@@ -52,11 +52,6 @@ func (rt *Routine) setLogger(logger log.Logger) {
rt.logger = logger
}
-// nolint:unused
-func (rt *Routine) setMetrics(metrics *Metrics) {
- rt.metrics = metrics
-}
-
func (rt *Routine) start() {
rt.logger.Info("routine start", "msg", log.NewLazySprintf("%s: run", rt.name))
running := atomic.CompareAndSwapUint32(rt.running, uint32(0), uint32(1))
diff --git a/blockchain/v2/scheduler.go b/blockchain/v2/scheduler.go
index 75fe9d46dc..35166764fe 100644
--- a/blockchain/v2/scheduler.go
+++ b/blockchain/v2/scheduler.go
@@ -366,7 +366,7 @@ func (sc *scheduler) setStateAtHeight(height int64, state blockState) {
}
// CONTRACT: peer exists and in Ready state.
-func (sc *scheduler) markReceived(peerID p2p.ID, height int64, size int64, now time.Time) error {
+func (sc *scheduler) markReceived(peerID p2p.ID, height int64, size int, now time.Time) error {
peer := sc.peers[peerID]
if state := sc.getStateAtHeight(height); state != blockStatePending || sc.pendingBlocks[height] != peerID {
@@ -379,7 +379,7 @@ func (sc *scheduler) markReceived(peerID p2p.ID, height int64, size int64, now t
height, pendingTime, now)
}
- peer.lastRate = size / now.Sub(pendingTime).Nanoseconds()
+ peer.lastRate = int64(size) / now.Sub(pendingTime).Nanoseconds()
sc.setStateAtHeight(height, blockStateReceived)
delete(sc.pendingBlocks, height)
@@ -532,7 +532,7 @@ func (sc *scheduler) handleBlockResponse(event bcBlockResponse) (Event, error) {
return noOp, nil
}
- err = sc.markReceived(event.peerID, event.block.Height, event.size, event.time)
+ err = sc.markReceived(event.peerID, event.block.Height, event.block.Size(), event.time)
if err != nil {
sc.removePeer(event.peerID)
return scPeerError{peerID: event.peerID, reason: err}, nil
diff --git a/blockchain/v2/scheduler_test.go b/blockchain/v2/scheduler_test.go
index 762ffd2c53..bed01bafc6 100644
--- a/blockchain/v2/scheduler_test.go
+++ b/blockchain/v2/scheduler_test.go
@@ -853,7 +853,7 @@ func TestScMarkReceived(t *testing.T) {
type args struct {
peerID p2p.ID
height int64
- size int64
+ size int
tm time.Time
}
tests := []struct {
diff --git a/cmd/tendermint/commands/debug/dump.go b/cmd/tendermint/commands/debug/dump.go
index 678f707918..67025ea5f5 100644
--- a/cmd/tendermint/commands/debug/dump.go
+++ b/cmd/tendermint/commands/debug/dump.go
@@ -3,7 +3,6 @@ package debug
import (
"errors"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"time"
@@ -82,7 +81,7 @@ func dumpCmdHandler(_ *cobra.Command, args []string) error {
func dumpDebugData(outDir string, conf *cfg.Config, rpc *rpchttp.HTTP) {
start := time.Now().UTC()
- tmpDir, err := ioutil.TempDir(outDir, "tendermint_debug_tmp")
+ tmpDir, err := os.MkdirTemp(outDir, "tendermint_debug_tmp")
if err != nil {
logger.Error("failed to create temporary directory", "dir", tmpDir, "error", err)
return
diff --git a/cmd/tendermint/commands/debug/io.go b/cmd/tendermint/commands/debug/io.go
index dcfff50c89..e5444a7359 100644
--- a/cmd/tendermint/commands/debug/io.go
+++ b/cmd/tendermint/commands/debug/io.go
@@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
- "io/ioutil"
"os"
"path"
"path/filepath"
@@ -68,7 +67,6 @@ func zipDir(src, dest string) error {
_, err = io.Copy(headerWriter, file)
return err
})
-
}
// copyFile copies a file from src to dest and returns an error upon failure. The
@@ -111,5 +109,5 @@ func writeStateJSONToFile(state interface{}, dir, filename string) error {
return fmt.Errorf("failed to encode state dump: %w", err)
}
- return ioutil.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm)
+ return os.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm)
}
diff --git a/cmd/tendermint/commands/debug/kill.go b/cmd/tendermint/commands/debug/kill.go
index a2c7a5fe14..f1670b150e 100644
--- a/cmd/tendermint/commands/debug/kill.go
+++ b/cmd/tendermint/commands/debug/kill.go
@@ -3,7 +3,6 @@ package debug
import (
"errors"
"fmt"
- "io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -56,7 +55,7 @@ func killCmdHandler(cmd *cobra.Command, args []string) error {
// Create a temporary directory which will contain all the state dumps and
// relevant files and directories that will be compressed into a file.
- tmpDir, err := ioutil.TempDir(os.TempDir(), "tendermint_debug_tmp")
+ tmpDir, err := os.MkdirTemp(os.TempDir(), "tendermint_debug_tmp")
if err != nil {
return fmt.Errorf("failed to create temporary directory: %w", err)
}
@@ -105,7 +104,7 @@ func killProc(pid uint64, dir string) error {
// pipe STDERR output from tailing the Tendermint process to a file
//
// NOTE: This will only work on UNIX systems.
- cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) // nolint: gosec
+ cmd := exec.Command("tail", "-f", fmt.Sprintf("/proc/%d/fd/2", pid)) //nolint: gosec
outFile, err := os.Create(filepath.Join(dir, "stacktrace.out"))
if err != nil {
diff --git a/cmd/tendermint/commands/debug/util.go b/cmd/tendermint/commands/debug/util.go
index 226bfadc79..f29fd5a81e 100644
--- a/cmd/tendermint/commands/debug/util.go
+++ b/cmd/tendermint/commands/debug/util.go
@@ -3,7 +3,7 @@ package debug
import (
"context"
"fmt"
- "io/ioutil"
+ "io"
"net/http"
"os"
"path"
@@ -67,16 +67,17 @@ func copyConfig(home, dir string) error {
func dumpProfile(dir, addr, profile string, debug int) error {
endpoint := fmt.Sprintf("%s/debug/pprof/%s?debug=%d", addr, profile, debug)
- resp, err := http.Get(endpoint) // nolint: gosec
+ //nolint:gosec,nolintlint
+ resp, err := http.Get(endpoint)
if err != nil {
return fmt.Errorf("failed to query for %s profile: %w", profile, err)
}
defer resp.Body.Close()
- body, err := ioutil.ReadAll(resp.Body)
+ body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read %s profile response body: %w", profile, err)
}
- return ioutil.WriteFile(path.Join(dir, fmt.Sprintf("%s.out", profile)), body, os.ModePerm)
+ return os.WriteFile(path.Join(dir, fmt.Sprintf("%s.out", profile)), body, os.ModePerm)
}
diff --git a/cmd/tendermint/commands/reindex_event.go b/cmd/tendermint/commands/reindex_event.go
index 32cb709e79..4ccfd91b37 100644
--- a/cmd/tendermint/commands/reindex_event.go
+++ b/cmd/tendermint/commands/reindex_event.go
@@ -32,14 +32,17 @@ var (
// ReIndexEventCmd constructs a command to re-index events in a block height interval.
var ReIndexEventCmd = &cobra.Command{
Use: "reindex-event",
- Short: "reindex events to the event store backends",
+ Short: "Re-index events to the event store backends",
Long: `
-reindex-event is an offline tooling to re-index block and tx events to the eventsinks,
-you can run this command when the event store backend dropped/disconnected or you want to
+reindex-event is an offline tooling to re-index block and tx events to the eventsinks.
+You can run this command when the event store backend dropped/disconnected or you want to
replace the backend. The default start-height is 0, meaning the tooling will start
reindex from the base block height(inclusive); and the default end-height is 0, meaning
the tooling will reindex until the latest block height(inclusive). User can omit
either or both arguments.
+
+Note: This operation requires ABCIResponses. Do not set DiscardABCIResponses to true if you
+want to use this command.
`,
Example: `
tendermint reindex-event
diff --git a/cmd/tendermint/commands/reindex_event_test.go b/cmd/tendermint/commands/reindex_event_test.go
index 716f4167a5..87ff80ddcf 100644
--- a/cmd/tendermint/commands/reindex_event_test.go
+++ b/cmd/tendermint/commands/reindex_event_test.go
@@ -9,6 +9,8 @@ import (
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+ dbm "github.com/tendermint/tm-db"
+
abcitypes "github.com/tendermint/tendermint/abci/types"
tmcfg "github.com/tendermint/tendermint/config"
prototmstate "github.com/tendermint/tendermint/proto/tendermint/state"
@@ -16,7 +18,6 @@ import (
"github.com/tendermint/tendermint/state/mocks"
txmocks "github.com/tendermint/tendermint/state/txindex/mocks"
"github.com/tendermint/tendermint/types"
- dbm "github.com/tendermint/tm-db"
)
const (
diff --git a/cmd/tendermint/commands/reset.go b/cmd/tendermint/commands/reset.go
index dd022060bd..86beb6a56f 100644
--- a/cmd/tendermint/commands/reset.go
+++ b/cmd/tendermint/commands/reset.go
@@ -29,7 +29,7 @@ var ResetStateCmd = &cobra.Command{
Short: "Remove all the data and WAL",
PreRun: deprecateSnakeCase,
RunE: func(cmd *cobra.Command, args []string) (err error) {
- config, err = ParseConfig()
+ config, err = ParseConfig(cmd)
if err != nil {
return err
}
@@ -54,7 +54,7 @@ var ResetPrivValidatorCmd = &cobra.Command{
// XXX: this is totally unsafe.
// it's only suitable for testnets.
func resetAllCmd(cmd *cobra.Command, args []string) (err error) {
- config, err = ParseConfig()
+ config, err = ParseConfig(cmd)
if err != nil {
return err
}
@@ -71,7 +71,7 @@ func resetAllCmd(cmd *cobra.Command, args []string) (err error) {
// XXX: this is totally unsafe.
// it's only suitable for testnets.
func resetPrivValidator(cmd *cobra.Command, args []string) (err error) {
- config, err = ParseConfig()
+ config, err = ParseConfig(cmd)
if err != nil {
return err
}
diff --git a/cmd/tendermint/commands/rollback.go b/cmd/tendermint/commands/rollback.go
index 912e1b3898..7e7190fb55 100644
--- a/cmd/tendermint/commands/rollback.go
+++ b/cmd/tendermint/commands/rollback.go
@@ -77,7 +77,9 @@ func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store,
if err != nil {
return nil, nil, err
}
- stateStore := state.NewStore(stateDB)
+ stateStore := state.NewStore(stateDB, state.StoreOptions{
+ DiscardABCIResponses: config.Storage.DiscardABCIResponses,
+ })
return blockStore, stateStore, nil
}
diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go
index 2478f95a58..46c9ac7c7b 100644
--- a/cmd/tendermint/commands/root.go
+++ b/cmd/tendermint/commands/root.go
@@ -29,12 +29,25 @@ func registerFlagsRootCmd(cmd *cobra.Command) {
// ParseConfig retrieves the default environment configuration,
// sets up the Tendermint root and ensures that the root exists
-func ParseConfig() (*cfg.Config, error) {
+func ParseConfig(cmd *cobra.Command) (*cfg.Config, error) {
conf := cfg.DefaultConfig()
err := viper.Unmarshal(conf)
if err != nil {
return nil, err
}
+
+ var home string
+ if os.Getenv("TMHOME") != "" {
+ home = os.Getenv("TMHOME")
+ } else {
+ home, err = cmd.Flags().GetString(cli.HomeFlag)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ conf.RootDir = home
+
conf.SetRoot(conf.RootDir)
cfg.EnsureRoot(conf.RootDir)
if err := conf.ValidateBasic(); err != nil {
@@ -52,7 +65,7 @@ var RootCmd = &cobra.Command{
return nil
}
- config, err = ParseConfig()
+ config, err = ParseConfig(cmd)
if err != nil {
return err
}
diff --git a/cmd/tendermint/commands/root_test.go b/cmd/tendermint/commands/root_test.go
index d1e5964b25..3de7620c21 100644
--- a/cmd/tendermint/commands/root_test.go
+++ b/cmd/tendermint/commands/root_test.go
@@ -2,7 +2,6 @@ package commands
import (
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"strconv"
@@ -18,9 +17,7 @@ import (
tmos "github.com/tendermint/tendermint/libs/os"
)
-var (
- defaultRoot = os.ExpandEnv("$HOME/.some/test/dir")
-)
+var defaultRoot = os.ExpandEnv("$HOME/.some/test/dir")
// clearConfig clears env vars, the given root dir, and resets viper.
func clearConfig(dir string) {
@@ -88,7 +85,6 @@ func TestRootHome(t *testing.T) {
}
func TestRootFlagsEnv(t *testing.T) {
-
// defaults
defaults := cfg.DefaultConfig()
defaultLogLvl := defaults.LogLevel
@@ -116,7 +112,6 @@ func TestRootFlagsEnv(t *testing.T) {
}
func TestRootConfig(t *testing.T) {
-
// write non-default config
nonDefaultLogLvl := "abc:debug"
cvals := map[string]string{
@@ -140,7 +135,7 @@ func TestRootConfig(t *testing.T) {
// XXX: path must match cfg.defaultConfigPath
configFilePath := filepath.Join(defaultRoot, "config")
- err := tmos.EnsureDir(configFilePath, 0700)
+ err := tmos.EnsureDir(configFilePath, 0o700)
require.Nil(t, err)
// write the non-defaults to a different path
@@ -168,5 +163,5 @@ func WriteConfigVals(dir string, vals map[string]string) error {
data += fmt.Sprintf("%s = \"%s\"\n", k, v)
}
cfile := filepath.Join(dir, "config.toml")
- return ioutil.WriteFile(cfile, []byte(data), 0600)
+ return os.WriteFile(cfile, []byte(data), 0o600)
}
diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go
index fd4408c5ab..7773f8daa6 100644
--- a/cmd/tendermint/commands/run_node.go
+++ b/cmd/tendermint/commands/run_node.go
@@ -63,6 +63,8 @@ func AddNodeFlags(cmd *cobra.Command) {
"p2p.laddr",
config.P2P.ListenAddress,
"node listen address. (0.0.0.0:0 means any interface, any port)")
+ cmd.Flags().String("p2p.external-address",
+ config.P2P.ExternalAddress, "ip:port address to advertise to peers for them to dial")
cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "comma-delimited ID@host:port seed nodes")
cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "comma-delimited ID@host:port persistent peers")
cmd.Flags().String("p2p.unconditional_peer_ids",
diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go
index d1a7fba582..d33a7c3a35 100644
--- a/cmd/tendermint/commands/version.go
+++ b/cmd/tendermint/commands/version.go
@@ -1,6 +1,7 @@
package commands
import (
+ "encoding/json"
"fmt"
"github.com/spf13/cobra"
@@ -13,6 +14,25 @@ var VersionCmd = &cobra.Command{
Use: "version",
Short: "Show version info",
Run: func(cmd *cobra.Command, args []string) {
- fmt.Println(version.TMCoreSemVer)
+ if verbose {
+ values, _ := json.MarshalIndent(struct {
+ Tendermint string `json:"tendermint"`
+ ABCI string `json:"abci"`
+ BlockProtocol uint64 `json:"block_protocol"`
+ P2PProtocol uint64 `json:"p2p_protocol"`
+ }{
+ Tendermint: version.TMCoreSemVer,
+ ABCI: version.ABCIVersion,
+ BlockProtocol: version.BlockProtocol,
+ P2PProtocol: version.P2PProtocol,
+ }, "", " ")
+ fmt.Println(string(values))
+ } else {
+ fmt.Println(version.TMCoreSemVer)
+ }
},
}
+
+func init() {
+ VersionCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Show protocol and library versions")
+}
diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go
index 59e7a1b128..04665a88f9 100644
--- a/cmd/tendermint/main.go
+++ b/cmd/tendermint/main.go
@@ -18,6 +18,7 @@ func main() {
cmd.InitFilesCmd,
cmd.ProbeUpnpCmd,
cmd.LightCmd,
+ cmd.ReIndexEventCmd,
cmd.ReplayCmd,
cmd.ReplayConsoleCmd,
cmd.ResetAllCmd,
diff --git a/config/config.go b/config/config.go
index d052b40ae1..d7250e00e7 100644
--- a/config/config.go
+++ b/config/config.go
@@ -74,6 +74,7 @@ type Config struct {
StateSync *StateSyncConfig `mapstructure:"statesync"`
FastSync *FastSyncConfig `mapstructure:"fastsync"`
Consensus *ConsensusConfig `mapstructure:"consensus"`
+ Storage *StorageConfig `mapstructure:"storage"`
TxIndex *TxIndexConfig `mapstructure:"tx_index"`
Instrumentation *InstrumentationConfig `mapstructure:"instrumentation"`
}
@@ -88,6 +89,7 @@ func DefaultConfig() *Config {
StateSync: DefaultStateSyncConfig(),
FastSync: DefaultFastSyncConfig(),
Consensus: DefaultConsensusConfig(),
+ Storage: DefaultStorageConfig(),
TxIndex: DefaultTxIndexConfig(),
Instrumentation: DefaultInstrumentationConfig(),
}
@@ -103,6 +105,7 @@ func TestConfig() *Config {
StateSync: TestStateSyncConfig(),
FastSync: TestFastSyncConfig(),
Consensus: TestConsensusConfig(),
+ Storage: TestStorageConfig(),
TxIndex: TestTxIndexConfig(),
Instrumentation: TestInstrumentationConfig(),
}
@@ -1071,11 +1074,41 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
}
//-----------------------------------------------------------------------------
+// StorageConfig
+
+// StorageConfig allows more fine-grained control over certain storage-related
+// behavior.
+type StorageConfig struct {
+ // Set to false to ensure ABCI responses are persisted. ABCI responses are
+ // required for `/block_results` RPC queries, and to reindex events in the
+ // command-line tool.
+ DiscardABCIResponses bool `mapstructure:"discard_abci_responses"`
+}
+
+// DefaultStorageConfig returns the default configuration options relating to
+// Tendermint storage optimization.
+func DefaultStorageConfig() *StorageConfig {
+ return &StorageConfig{
+ DiscardABCIResponses: false,
+ }
+}
+
+// TestStorageConfig returns storage configuration that can be used for
+// testing.
+func TestStorageConfig() *StorageConfig {
+ return &StorageConfig{
+ DiscardABCIResponses: false,
+ }
+}
+
+// -----------------------------------------------------------------------------
// TxIndexConfig
// Remember that Event has the following structure:
// type: [
-// key: value,
-// ...
+//
+// key: value,
+// ...
+//
// ]
//
// CompositeKeys are constructed by `type.key`
diff --git a/config/config_test.go b/config/config_test.go
index 6a46933bcb..f19c7b1c7c 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -27,7 +27,6 @@ func TestDefaultConfig(t *testing.T) {
assert.Equal("/foo/bar", cfg.GenesisFile())
assert.Equal("/opt/data", cfg.DBDir())
assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir())
-
}
func TestConfigValidateBasic(t *testing.T) {
@@ -140,8 +139,8 @@ func TestFastSyncConfigValidateBasic(t *testing.T) {
assert.Error(t, cfg.ValidateBasic())
}
+//nolint:lll
func TestConsensusConfig_ValidateBasic(t *testing.T) {
- // nolint: lll
testcases := map[string]struct {
modify func(*ConsensusConfig)
expectErr bool
@@ -166,6 +165,7 @@ func TestConsensusConfig_ValidateBasic(t *testing.T) {
"PeerQueryMaj23SleepDuration negative": {func(c *ConsensusConfig) { c.PeerQueryMaj23SleepDuration = -1 }, true},
"DoubleSignCheckHeight negative": {func(c *ConsensusConfig) { c.DoubleSignCheckHeight = -1 }, true},
}
+
for desc, tc := range testcases {
tc := tc // appease linter
t.Run(desc, func(t *testing.T) {
diff --git a/config/toml.go b/config/toml.go
index ad40b1efcf..f6e9434d35 100644
--- a/config/toml.go
+++ b/config/toml.go
@@ -3,7 +3,7 @@ package config
import (
"bytes"
"fmt"
- "io/ioutil"
+ "os"
"path/filepath"
"strings"
"text/template"
@@ -12,7 +12,7 @@ import (
)
// DefaultDirPerm is the default permissions used when creating directories.
-const DefaultDirPerm = 0700
+const DefaultDirPerm = 0o700
var configTemplate *template.Template
@@ -63,7 +63,7 @@ func WriteConfigFile(configFilePath string, config *Config) {
panic(err)
}
- tmos.MustWriteFile(configFilePath, buffer.Bytes(), 0644)
+ tmos.MustWriteFile(configFilePath, buffer.Bytes(), 0o644)
}
// Note: any changes to the comments/variables/mapstructure
@@ -480,6 +480,17 @@ create_empty_blocks_interval = "{{ .Consensus.CreateEmptyBlocksInterval }}"
peer_gossip_sleep_duration = "{{ .Consensus.PeerGossipSleepDuration }}"
peer_query_maj23_sleep_duration = "{{ .Consensus.PeerQueryMaj23SleepDuration }}"
+#######################################################
+### Storage Configuration Options ###
+#######################################################
+[storage]
+
+# Set to true to discard ABCI responses from the state store, which can save a
+# considerable amount of disk space. Set to false to ensure ABCI responses are
+# persisted. ABCI responses are required for /block_results RPC queries, and to
+# reindex events in the command-line tool.
+discard_abci_responses = {{ .Storage.DiscardABCIResponses}}
+
#######################################################
### Transaction Indexer Configuration Options ###
#######################################################
@@ -533,7 +544,7 @@ func ResetTestRoot(testName string) *Config {
func ResetTestRootWithChainID(testName string, chainID string) *Config {
// create a unique, concurrency-safe test directory under os.TempDir()
- rootDir, err := ioutil.TempDir("", fmt.Sprintf("%s-%s_", chainID, testName))
+ rootDir, err := os.MkdirTemp("", fmt.Sprintf("%s-%s_", chainID, testName))
if err != nil {
panic(err)
}
@@ -560,11 +571,11 @@ func ResetTestRootWithChainID(testName string, chainID string) *Config {
chainID = "tendermint_test"
}
testGenesis := fmt.Sprintf(testGenesisFmt, chainID)
- tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
+ tmos.MustWriteFile(genesisFilePath, []byte(testGenesis), 0o644)
}
// we always overwrite the priv val
- tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0644)
- tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0644)
+ tmos.MustWriteFile(privKeyFilePath, []byte(testPrivValidatorKey), 0o644)
+ tmos.MustWriteFile(privStateFilePath, []byte(testPrivValidatorState), 0o644)
config := TestConfig().SetRoot(rootDir)
return config
diff --git a/config/toml_test.go b/config/toml_test.go
index f197106872..678cf6a9bb 100644
--- a/config/toml_test.go
+++ b/config/toml_test.go
@@ -1,7 +1,6 @@
package config
import (
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -23,7 +22,7 @@ func TestEnsureRoot(t *testing.T) {
require := require.New(t)
// setup temp dir for test
- tmpDir, err := ioutil.TempDir("", "config-test")
+ tmpDir, err := os.MkdirTemp("", "config-test")
require.Nil(err)
defer os.RemoveAll(tmpDir)
@@ -31,7 +30,7 @@ func TestEnsureRoot(t *testing.T) {
EnsureRoot(tmpDir)
// make sure config is set properly
- data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath))
+ data, err := os.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath))
require.Nil(err)
if !checkConfig(string(data)) {
@@ -52,7 +51,7 @@ func TestEnsureTestRoot(t *testing.T) {
rootDir := cfg.RootDir
// make sure config is set properly
- data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultConfigFilePath))
+ data, err := os.ReadFile(filepath.Join(rootDir, defaultConfigFilePath))
require.Nil(err)
if !checkConfig(string(data)) {
@@ -68,7 +67,7 @@ func checkConfig(configFile string) bool {
var valid bool
// list of words we expect in the config
- var elems = []string{
+ elems := []string{
"moniker",
"seeds",
"proxy_app",
diff --git a/consensus/README.md b/consensus/README.md
index 44a36012ff..15687b6269 100644
--- a/consensus/README.md
+++ b/consensus/README.md
@@ -1,3 +1,3 @@
# Consensus
-See the [consensus spec](https://github.com/tendermint/spec/tree/master/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/spec/tree/master/spec/reactors/consensus) for more information.
+See the [consensus spec](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/reactors/consensus) for more information.
diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go
index f47a2d229f..7a82ab4ffe 100644
--- a/consensus/byzantine_test.go
+++ b/consensus/byzantine_test.go
@@ -26,6 +26,7 @@ import (
mempoolv0 "github.com/tendermint/tendermint/mempool/v0"
mempoolv1 "github.com/tendermint/tendermint/mempool/v1"
"github.com/tendermint/tendermint/p2p"
+ tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/store"
@@ -50,7 +51,9 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
for i := 0; i < nValidators; i++ {
logger := consensusLogger().With("test", "byzantine", "validator", i)
stateDB := dbm.NewMemDB() // each state needs its own db
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
defer os.RemoveAll(thisConfig.RootDir)
@@ -163,10 +166,16 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
for i, peer := range peerList {
if i < len(peerList)/2 {
bcs.Logger.Info("Signed and pushed vote", "vote", prevote1, "peer", peer)
- peer.Send(VoteChannel, MustEncode(&VoteMessage{prevote1}))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ Message: &tmcons.Vote{Vote: prevote1.ToProto()},
+ ChannelID: VoteChannel,
+ }, bcs.Logger)
} else {
bcs.Logger.Info("Signed and pushed vote", "vote", prevote2, "peer", peer)
- peer.Send(VoteChannel, MustEncode(&VoteMessage{prevote2}))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ Message: &tmcons.Vote{Vote: prevote2.ToProto()},
+ ChannelID: VoteChannel,
+ }, bcs.Logger)
}
}
} else {
@@ -420,7 +429,7 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) {
// wait for someone in the big partition (B) to make a block
<-blocksSubs[ind2].Out()
- t.Log("A block has been committed. Healing partition")
+ t.Logf("A block has been committed. Healing partition")
p2p.Connect2Switches(switches, ind0, ind1)
p2p.Connect2Switches(switches, ind0, ind2)
@@ -446,8 +455,8 @@ func TestByzantineConflictingProposalsWithPartition(t *testing.T) {
case <-done:
case <-tick.C:
for i, reactor := range reactors {
- t.Log(fmt.Sprintf("Consensus Reactor %v", i))
- t.Log(fmt.Sprintf("%v", reactor))
+ t.Logf(fmt.Sprintf("Consensus Reactor %v", i))
+ t.Logf(fmt.Sprintf("%v", reactor))
}
t.Fatalf("Timed out waiting for all validators to commit first block")
}
@@ -512,18 +521,26 @@ func sendProposalAndParts(
parts *types.PartSet,
) {
// proposal
- msg := &ProposalMessage{Proposal: proposal}
- peer.Send(DataChannel, MustEncode(msg))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.Proposal{Proposal: *proposal.ToProto()},
+ }, cs.Logger)
// parts
for i := 0; i < int(parts.Total()); i++ {
part := parts.GetPart(i)
- msg := &BlockPartMessage{
- Height: height, // This tells peer that this part applies to us.
- Round: round, // This tells peer that this part applies to us.
- Part: part,
+ pp, err := part.ToProto()
+ if err != nil {
+ panic(err) // TODO: wbanfield better error handling
}
- peer.Send(DataChannel, MustEncode(msg))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.BlockPart{
+ Height: height, // This tells peer that this part applies to us.
+ Round: round, // This tells peer that this part applies to us.
+ Part: *pp,
+ },
+ }, cs.Logger)
}
// votes
@@ -531,9 +548,14 @@ func sendProposalAndParts(
prevote, _ := cs.signVote(tmproto.PrevoteType, blockHash, parts.Header())
precommit, _ := cs.signVote(tmproto.PrecommitType, blockHash, parts.Header())
cs.mtx.Unlock()
-
- peer.Send(VoteChannel, MustEncode(&VoteMessage{prevote}))
- peer.Send(VoteChannel, MustEncode(&VoteMessage{precommit}))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: VoteChannel,
+ Message: &tmcons.Vote{Vote: prevote.ToProto()},
+ }, cs.Logger)
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: VoteChannel,
+ Message: &tmcons.Vote{Vote: precommit.ToProto()},
+ }, cs.Logger)
}
//----------------------------------------
@@ -571,7 +593,10 @@ func (br *ByzantineReactor) AddPeer(peer p2p.Peer) {
func (br *ByzantineReactor) RemovePeer(peer p2p.Peer, reason interface{}) {
br.reactor.RemovePeer(peer, reason)
}
-func (br *ByzantineReactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
- br.reactor.Receive(chID, peer, msgBytes)
+func (br *ByzantineReactor) ReceiveEnvelope(e p2p.Envelope) {
+ br.reactor.ReceiveEnvelope(e)
+}
+func (br *ByzantineReactor) Receive(chID byte, p p2p.Peer, m []byte) {
+ br.reactor.Receive(chID, p, m)
}
func (br *ByzantineReactor) InitPeer(peer p2p.Peer) p2p.Peer { return peer }
diff --git a/consensus/common_test.go b/consensus/common_test.go
index 4722e16000..5b4320f8ef 100644
--- a/consensus/common_test.go
+++ b/consensus/common_test.go
@@ -4,8 +4,8 @@ import (
"bytes"
"context"
"fmt"
- "io/ioutil"
"os"
+ "path"
"path/filepath"
"sort"
"sync"
@@ -15,8 +15,6 @@ import (
"github.com/go-kit/log/term"
"github.com/stretchr/testify/require"
- "path"
-
dbm "github.com/tendermint/tm-db"
abcicli "github.com/tendermint/tendermint/abci/client"
@@ -92,8 +90,8 @@ func newValidatorStub(privValidator types.PrivValidator, valIndex int32) *valida
func (vs *validatorStub) signVote(
voteType tmproto.SignedMsgType,
hash []byte,
- header types.PartSetHeader) (*types.Vote, error) {
-
+ header types.PartSetHeader,
+) (*types.Vote, error) {
pubKey, err := vs.PrivValidator.GetPubKey()
if err != nil {
return nil, fmt.Errorf("can't get pubkey: %w", err)
@@ -141,7 +139,8 @@ func signVotes(
voteType tmproto.SignedMsgType,
hash []byte,
header types.PartSetHeader,
- vss ...*validatorStub) []*types.Vote {
+ vss ...*validatorStub,
+) []*types.Vote {
votes := make([]*types.Vote, len(vss))
for i, vs := range vss {
votes[i] = signVote(vs, voteType, hash, header)
@@ -428,7 +427,9 @@ func newStateWithConfigAndBlockStore(
// Make State
stateDB := blockDB
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
if err := stateStore.Save(state); err != nil { // for save height 1's validators info
panic(err)
}
@@ -450,7 +451,7 @@ func newStateWithConfigAndBlockStore(
func loadPrivValidator(config *cfg.Config) *privval.FilePV {
privValidatorKeyFile := config.PrivValidatorKeyFile()
- ensureDir(filepath.Dir(privValidatorKeyFile), 0700)
+ ensureDir(filepath.Dir(privValidatorKeyFile), 0o700)
privValidatorStateFile := config.PrivValidatorStateFile()
privValidator := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
privValidator.Reset()
@@ -477,7 +478,8 @@ func randState(nValidators int) (*State, []*validatorStub) {
//-------------------------------------------------------------------------------
func ensureNoNewEvent(ch <-chan tmpubsub.Message, timeout time.Duration,
- errorMessage string) {
+ errorMessage string,
+) {
select {
case <-time.After(timeout):
break
@@ -655,7 +657,8 @@ func ensurePrevote(voteCh <-chan tmpubsub.Message, height int64, round int32) {
}
func ensureVote(voteCh <-chan tmpubsub.Message, height int64, round int32,
- voteType tmproto.SignedMsgType) {
+ voteType tmproto.SignedMsgType,
+) {
select {
case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewVote event")
@@ -711,21 +714,24 @@ func consensusLogger() log.Logger {
}
func randConsensusNet(nValidators int, testName string, tickerFunc func() TimeoutTicker,
- appFunc func() abci.Application, configOpts ...func(*cfg.Config)) ([]*State, cleanupFunc) {
+ appFunc func() abci.Application, configOpts ...func(*cfg.Config),
+) ([]*State, cleanupFunc) {
genDoc, privVals := randGenesisDoc(nValidators, false, 30)
css := make([]*State, nValidators)
logger := consensusLogger()
configRootDirs := make([]string, 0, nValidators)
for i := 0; i < nValidators; i++ {
stateDB := dbm.NewMemDB() // each state needs its own db
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
configRootDirs = append(configRootDirs, thisConfig.RootDir)
for _, opt := range configOpts {
opt(thisConfig)
}
- ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
+ ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0o700) // dir for wal
app := appFunc()
vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals})
@@ -756,11 +762,13 @@ func randConsensusNetWithPeers(
configRootDirs := make([]string, 0, nPeers)
for i := 0; i < nPeers; i++ {
stateDB := dbm.NewMemDB() // each state needs its own db
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
configRootDirs = append(configRootDirs, thisConfig.RootDir)
- ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
+ ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0o700) // dir for wal
if i == 0 {
peer0Config = thisConfig
}
@@ -768,11 +776,11 @@ func randConsensusNetWithPeers(
if i < nValidators {
privVal = privVals[i]
} else {
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
if err != nil {
panic(err)
}
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
if err != nil {
panic(err)
}
@@ -894,7 +902,7 @@ func newCounter() abci.Application {
}
func newPersistentKVStore() abci.Application {
- dir, err := ioutil.TempDir("", "persistent-kvstore")
+ dir, err := os.MkdirTemp("", "persistent-kvstore")
if err != nil {
panic(err)
}
diff --git a/consensus/invalid_test.go b/consensus/invalid_test.go
index 907693c573..a9c1a1f199 100644
--- a/consensus/invalid_test.go
+++ b/consensus/invalid_test.go
@@ -7,6 +7,7 @@ import (
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/p2p"
+ tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types"
)
@@ -94,7 +95,10 @@ func invalidDoPrevoteFunc(t *testing.T, height int64, round int32, cs *State, sw
peers := sw.Peers().List()
for _, peer := range peers {
cs.Logger.Info("Sending bad vote", "block", blockHash, "peer", peer)
- peer.Send(VoteChannel, MustEncode(&VoteMessage{precommit}))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ Message: &tmcons.Vote{Vote: precommit.ToProto()},
+ ChannelID: VoteChannel,
+ }, cs.Logger)
}
}()
}
diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go
index a0cdae1dfa..c9e461d481 100644
--- a/consensus/mempool_test.go
+++ b/consensus/mempool_test.go
@@ -113,7 +113,7 @@ func deliverTxsRange(cs *State, start, end int) {
func TestMempoolTxConcurrentWithCommit(t *testing.T) {
state, privVals := randGenesisState(1, false, 10)
blockDB := dbm.NewMemDB()
- stateStore := sm.NewStore(blockDB)
+ stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB)
err := stateStore.Save(state)
require.NoError(t, err)
@@ -138,7 +138,7 @@ func TestMempoolRmBadTx(t *testing.T) {
state, privVals := randGenesisState(1, false, 10)
app := NewCounterApplication()
blockDB := dbm.NewMemDB()
- stateStore := sm.NewStore(blockDB)
+ stateStore := sm.NewStore(blockDB, sm.StoreOptions{DiscardABCIResponses: false})
cs := newStateWithConfigAndBlockStore(config, state, privVals[0], app, blockDB)
err := stateStore.Save(state)
require.NoError(t, err)
diff --git a/consensus/msgs.go b/consensus/msgs.go
index 4de96b5f40..c63af3ea84 100644
--- a/consensus/msgs.go
+++ b/consensus/msgs.go
@@ -5,7 +5,6 @@ import (
"fmt"
"github.com/gogo/protobuf/proto"
-
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/libs/bits"
tmmath "github.com/tendermint/tendermint/libs/math"
@@ -15,173 +14,155 @@ import (
"github.com/tendermint/tendermint/types"
)
-// MsgToProto takes a consensus message type and returns the proto defined consensus message
+// MsgToProto takes a consensus message type and returns the proto defined consensus message.
+//
+// TODO: This needs to be removed, but WALToProto depends on this.
func MsgToProto(msg Message) (*tmcons.Message, error) {
if msg == nil {
return nil, errors.New("consensus: message is nil")
}
- var pb tmcons.Message
-
switch msg := msg.(type) {
case *NewRoundStepMessage:
- pb = tmcons.Message{
- Sum: &tmcons.Message_NewRoundStep{
- NewRoundStep: &tmcons.NewRoundStep{
- Height: msg.Height,
- Round: msg.Round,
- Step: uint32(msg.Step),
- SecondsSinceStartTime: msg.SecondsSinceStartTime,
- LastCommitRound: msg.LastCommitRound,
- },
- },
- }
+ m := &tmcons.NewRoundStep{
+ Height: msg.Height,
+ Round: msg.Round,
+ Step: uint32(msg.Step),
+ SecondsSinceStartTime: msg.SecondsSinceStartTime,
+ LastCommitRound: msg.LastCommitRound,
+ }
+ return m.Wrap().(*tmcons.Message), nil
+
case *NewValidBlockMessage:
pbPartSetHeader := msg.BlockPartSetHeader.ToProto()
pbBits := msg.BlockParts.ToProto()
- pb = tmcons.Message{
- Sum: &tmcons.Message_NewValidBlock{
- NewValidBlock: &tmcons.NewValidBlock{
- Height: msg.Height,
- Round: msg.Round,
- BlockPartSetHeader: pbPartSetHeader,
- BlockParts: pbBits,
- IsCommit: msg.IsCommit,
- },
- },
+ m := &tmcons.NewValidBlock{
+ Height: msg.Height,
+ Round: msg.Round,
+ BlockPartSetHeader: pbPartSetHeader,
+ BlockParts: pbBits,
+ IsCommit: msg.IsCommit,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *ProposalMessage:
pbP := msg.Proposal.ToProto()
- pb = tmcons.Message{
- Sum: &tmcons.Message_Proposal{
- Proposal: &tmcons.Proposal{
- Proposal: *pbP,
- },
- },
+ m := &tmcons.Proposal{
+ Proposal: *pbP,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *ProposalPOLMessage:
pbBits := msg.ProposalPOL.ToProto()
- pb = tmcons.Message{
- Sum: &tmcons.Message_ProposalPol{
- ProposalPol: &tmcons.ProposalPOL{
- Height: msg.Height,
- ProposalPolRound: msg.ProposalPOLRound,
- ProposalPol: *pbBits,
- },
- },
+ m := &tmcons.ProposalPOL{
+ Height: msg.Height,
+ ProposalPolRound: msg.ProposalPOLRound,
+ ProposalPol: *pbBits,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *BlockPartMessage:
parts, err := msg.Part.ToProto()
if err != nil {
return nil, fmt.Errorf("msg to proto error: %w", err)
}
- pb = tmcons.Message{
- Sum: &tmcons.Message_BlockPart{
- BlockPart: &tmcons.BlockPart{
- Height: msg.Height,
- Round: msg.Round,
- Part: *parts,
- },
- },
+ m := &tmcons.BlockPart{
+ Height: msg.Height,
+ Round: msg.Round,
+ Part: *parts,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *VoteMessage:
vote := msg.Vote.ToProto()
- pb = tmcons.Message{
- Sum: &tmcons.Message_Vote{
- Vote: &tmcons.Vote{
- Vote: vote,
- },
- },
+ m := &tmcons.Vote{
+ Vote: vote,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *HasVoteMessage:
- pb = tmcons.Message{
- Sum: &tmcons.Message_HasVote{
- HasVote: &tmcons.HasVote{
- Height: msg.Height,
- Round: msg.Round,
- Type: msg.Type,
- Index: msg.Index,
- },
- },
+ m := &tmcons.HasVote{
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
+ Index: msg.Index,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *VoteSetMaj23Message:
bi := msg.BlockID.ToProto()
- pb = tmcons.Message{
- Sum: &tmcons.Message_VoteSetMaj23{
- VoteSetMaj23: &tmcons.VoteSetMaj23{
- Height: msg.Height,
- Round: msg.Round,
- Type: msg.Type,
- BlockID: bi,
- },
- },
+ m := &tmcons.VoteSetMaj23{
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
+ BlockID: bi,
}
+ return m.Wrap().(*tmcons.Message), nil
+
case *VoteSetBitsMessage:
bi := msg.BlockID.ToProto()
bits := msg.Votes.ToProto()
- vsb := &tmcons.Message_VoteSetBits{
- VoteSetBits: &tmcons.VoteSetBits{
- Height: msg.Height,
- Round: msg.Round,
- Type: msg.Type,
- BlockID: bi,
- },
+ m := &tmcons.VoteSetBits{
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
+ BlockID: bi,
}
if bits != nil {
- vsb.VoteSetBits.Votes = *bits
+ m.Votes = *bits
}
- pb = tmcons.Message{
- Sum: vsb,
- }
+ return m.Wrap().(*tmcons.Message), nil
default:
return nil, fmt.Errorf("consensus: message not recognized: %T", msg)
}
-
- return &pb, nil
}
// MsgFromProto takes a consensus proto message and returns the native go type
-func MsgFromProto(msg *tmcons.Message) (Message, error) {
- if msg == nil {
+func MsgFromProto(p *tmcons.Message) (Message, error) {
+ if p == nil {
return nil, errors.New("consensus: nil message")
}
var pb Message
+ um, err := p.Unwrap()
+ if err != nil {
+ return nil, err
+ }
- switch msg := msg.Sum.(type) {
- case *tmcons.Message_NewRoundStep:
- rs, err := tmmath.SafeConvertUint8(int64(msg.NewRoundStep.Step))
+ switch msg := um.(type) {
+ case *tmcons.NewRoundStep:
+ rs, err := tmmath.SafeConvertUint8(int64(msg.Step))
// deny message based on possible overflow
if err != nil {
return nil, fmt.Errorf("denying message due to possible overflow: %w", err)
}
pb = &NewRoundStepMessage{
- Height: msg.NewRoundStep.Height,
- Round: msg.NewRoundStep.Round,
+ Height: msg.Height,
+ Round: msg.Round,
Step: cstypes.RoundStepType(rs),
- SecondsSinceStartTime: msg.NewRoundStep.SecondsSinceStartTime,
- LastCommitRound: msg.NewRoundStep.LastCommitRound,
+ SecondsSinceStartTime: msg.SecondsSinceStartTime,
+ LastCommitRound: msg.LastCommitRound,
}
- case *tmcons.Message_NewValidBlock:
- pbPartSetHeader, err := types.PartSetHeaderFromProto(&msg.NewValidBlock.BlockPartSetHeader)
+ case *tmcons.NewValidBlock:
+ pbPartSetHeader, err := types.PartSetHeaderFromProto(&msg.BlockPartSetHeader)
if err != nil {
return nil, fmt.Errorf("parts to proto error: %w", err)
}
pbBits := new(bits.BitArray)
- pbBits.FromProto(msg.NewValidBlock.BlockParts)
+ pbBits.FromProto(msg.BlockParts)
pb = &NewValidBlockMessage{
- Height: msg.NewValidBlock.Height,
- Round: msg.NewValidBlock.Round,
+ Height: msg.Height,
+ Round: msg.Round,
BlockPartSetHeader: *pbPartSetHeader,
BlockParts: pbBits,
- IsCommit: msg.NewValidBlock.IsCommit,
+ IsCommit: msg.IsCommit,
}
- case *tmcons.Message_Proposal:
- pbP, err := types.ProposalFromProto(&msg.Proposal.Proposal)
+ case *tmcons.Proposal:
+ pbP, err := types.ProposalFromProto(&msg.Proposal)
if err != nil {
return nil, fmt.Errorf("proposal msg to proto error: %w", err)
}
@@ -189,26 +170,26 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) {
pb = &ProposalMessage{
Proposal: pbP,
}
- case *tmcons.Message_ProposalPol:
+ case *tmcons.ProposalPOL:
pbBits := new(bits.BitArray)
- pbBits.FromProto(&msg.ProposalPol.ProposalPol)
+ pbBits.FromProto(&msg.ProposalPol)
pb = &ProposalPOLMessage{
- Height: msg.ProposalPol.Height,
- ProposalPOLRound: msg.ProposalPol.ProposalPolRound,
+ Height: msg.Height,
+ ProposalPOLRound: msg.ProposalPolRound,
ProposalPOL: pbBits,
}
- case *tmcons.Message_BlockPart:
- parts, err := types.PartFromProto(&msg.BlockPart.Part)
+ case *tmcons.BlockPart:
+ parts, err := types.PartFromProto(&msg.Part)
if err != nil {
return nil, fmt.Errorf("blockpart msg to proto error: %w", err)
}
pb = &BlockPartMessage{
- Height: msg.BlockPart.Height,
- Round: msg.BlockPart.Round,
+ Height: msg.Height,
+ Round: msg.Round,
Part: parts,
}
- case *tmcons.Message_Vote:
- vote, err := types.VoteFromProto(msg.Vote.Vote)
+ case *tmcons.Vote:
+ vote, err := types.VoteFromProto(msg.Vote)
if err != nil {
return nil, fmt.Errorf("vote msg to proto error: %w", err)
}
@@ -216,36 +197,36 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) {
pb = &VoteMessage{
Vote: vote,
}
- case *tmcons.Message_HasVote:
+ case *tmcons.HasVote:
pb = &HasVoteMessage{
- Height: msg.HasVote.Height,
- Round: msg.HasVote.Round,
- Type: msg.HasVote.Type,
- Index: msg.HasVote.Index,
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
+ Index: msg.Index,
}
- case *tmcons.Message_VoteSetMaj23:
- bi, err := types.BlockIDFromProto(&msg.VoteSetMaj23.BlockID)
+ case *tmcons.VoteSetMaj23:
+ bi, err := types.BlockIDFromProto(&msg.BlockID)
if err != nil {
return nil, fmt.Errorf("voteSetMaj23 msg to proto error: %w", err)
}
pb = &VoteSetMaj23Message{
- Height: msg.VoteSetMaj23.Height,
- Round: msg.VoteSetMaj23.Round,
- Type: msg.VoteSetMaj23.Type,
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
BlockID: *bi,
}
- case *tmcons.Message_VoteSetBits:
- bi, err := types.BlockIDFromProto(&msg.VoteSetBits.BlockID)
+ case *tmcons.VoteSetBits:
+ bi, err := types.BlockIDFromProto(&msg.BlockID)
if err != nil {
return nil, fmt.Errorf("voteSetBits msg to proto error: %w", err)
}
bits := new(bits.BitArray)
- bits.FromProto(&msg.VoteSetBits.Votes)
+ bits.FromProto(&msg.Votes)
pb = &VoteSetBitsMessage{
- Height: msg.VoteSetBits.Height,
- Round: msg.VoteSetBits.Round,
- Type: msg.VoteSetBits.Type,
+ Height: msg.Height,
+ Round: msg.Round,
+ Type: msg.Type,
BlockID: *bi,
Votes: bits,
}
@@ -262,6 +243,8 @@ func MsgFromProto(msg *tmcons.Message) (Message, error) {
// MustEncode takes the reactors msg, makes it proto and marshals it
// this mimics `MustMarshalBinaryBare` in that is panics on error
+//
+// Deprecated: Will be removed in v0.37.
func MustEncode(msg Message) []byte {
pb, err := MsgToProto(msg)
if err != nil {
diff --git a/consensus/msgs_test.go b/consensus/msgs_test.go
index b1f32e67dd..62f723b1c1 100644
--- a/consensus/msgs_test.go
+++ b/consensus/msgs_test.go
@@ -80,17 +80,15 @@ func TestMsgToProto(t *testing.T) {
Step: 1,
SecondsSinceStartTime: 1,
LastCommitRound: 2,
- }, &tmcons.Message{
- Sum: &tmcons.Message_NewRoundStep{
- NewRoundStep: &tmcons.NewRoundStep{
- Height: 2,
- Round: 1,
- Step: 1,
- SecondsSinceStartTime: 1,
- LastCommitRound: 2,
- },
- },
- }, false},
+ }, (&tmcons.NewRoundStep{
+ Height: 2,
+ Round: 1,
+ Step: 1,
+ SecondsSinceStartTime: 1,
+ LastCommitRound: 2,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful NewValidBlockMessage", &NewValidBlockMessage{
Height: 1,
@@ -98,92 +96,78 @@ func TestMsgToProto(t *testing.T) {
BlockPartSetHeader: psh,
BlockParts: bits,
IsCommit: false,
- }, &tmcons.Message{
- Sum: &tmcons.Message_NewValidBlock{
- NewValidBlock: &tmcons.NewValidBlock{
- Height: 1,
- Round: 1,
- BlockPartSetHeader: pbPsh,
- BlockParts: pbBits,
- IsCommit: false,
- },
- },
- }, false},
+ }, (&tmcons.NewValidBlock{
+ Height: 1,
+ Round: 1,
+ BlockPartSetHeader: pbPsh,
+ BlockParts: pbBits,
+ IsCommit: false,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful BlockPartMessage", &BlockPartMessage{
Height: 100,
Round: 1,
Part: &parts,
- }, &tmcons.Message{
- Sum: &tmcons.Message_BlockPart{
- BlockPart: &tmcons.BlockPart{
- Height: 100,
- Round: 1,
- Part: *pbParts,
- },
- },
- }, false},
+ }, (&tmcons.BlockPart{
+ Height: 100,
+ Round: 1,
+ Part: *pbParts,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful ProposalPOLMessage", &ProposalPOLMessage{
Height: 1,
ProposalPOLRound: 1,
ProposalPOL: bits,
- }, &tmcons.Message{
- Sum: &tmcons.Message_ProposalPol{
- ProposalPol: &tmcons.ProposalPOL{
- Height: 1,
- ProposalPolRound: 1,
- ProposalPol: *pbBits,
- },
- }}, false},
+ }, (&tmcons.ProposalPOL{
+ Height: 1,
+ ProposalPolRound: 1,
+ ProposalPol: *pbBits,
+ }).Wrap().(*tmcons.Message),
+ false},
{"successful ProposalMessage", &ProposalMessage{
Proposal: &proposal,
- }, &tmcons.Message{
- Sum: &tmcons.Message_Proposal{
- Proposal: &tmcons.Proposal{
- Proposal: *pbProposal,
- },
- },
- }, false},
+ }, (&tmcons.Proposal{
+ Proposal: *pbProposal,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful VoteMessage", &VoteMessage{
Vote: vote,
- }, &tmcons.Message{
- Sum: &tmcons.Message_Vote{
- Vote: &tmcons.Vote{
- Vote: pbVote,
- },
- },
- }, false},
+ }, (&tmcons.Vote{
+ Vote: pbVote,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful VoteSetMaj23", &VoteSetMaj23Message{
Height: 1,
Round: 1,
Type: 1,
BlockID: bi,
- }, &tmcons.Message{
- Sum: &tmcons.Message_VoteSetMaj23{
- VoteSetMaj23: &tmcons.VoteSetMaj23{
- Height: 1,
- Round: 1,
- Type: 1,
- BlockID: pbBi,
- },
- },
- }, false},
+ }, (&tmcons.VoteSetMaj23{
+ Height: 1,
+ Round: 1,
+ Type: 1,
+ BlockID: pbBi,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"successful VoteSetBits", &VoteSetBitsMessage{
Height: 1,
Round: 1,
Type: 1,
BlockID: bi,
Votes: bits,
- }, &tmcons.Message{
- Sum: &tmcons.Message_VoteSetBits{
- VoteSetBits: &tmcons.VoteSetBits{
- Height: 1,
- Round: 1,
- Type: 1,
- BlockID: pbBi,
- Votes: *pbBits,
- },
- },
- }, false},
+ }, (&tmcons.VoteSetBits{
+ Height: 1,
+ Round: 1,
+ Type: 1,
+ BlockID: pbBi,
+ Votes: *pbBits,
+ }).Wrap().(*tmcons.Message),
+
+ false},
{"failure", nil, &tmcons.Message{}, true},
}
for _, tt := range testsCases {
@@ -314,7 +298,7 @@ func TestWALMsgProto(t *testing.T) {
}
}
-// nolint:lll //ignore line length for tests
+//nolint:lll //ignore line length for tests
func TestConsMsgsVectors(t *testing.T) {
date := time.Date(2018, 8, 30, 12, 0, 0, 0, time.UTC)
psh := types.PartSetHeader{
diff --git a/consensus/reactor.go b/consensus/reactor.go
index d6b22786b0..e052f197af 100644
--- a/consensus/reactor.go
+++ b/consensus/reactor.go
@@ -8,7 +8,6 @@ import (
"time"
"github.com/gogo/protobuf/proto"
-
cstypes "github.com/tendermint/tendermint/consensus/types"
"github.com/tendermint/tendermint/libs/bits"
tmevents "github.com/tendermint/tendermint/libs/events"
@@ -148,6 +147,7 @@ func (conR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
Priority: 6,
SendQueueCapacity: 100,
RecvMessageCapacity: maxMsgSize,
+ MessageType: &tmcons.Message{},
},
{
ID: DataChannel, // maybe split between gossiping current block and catchup stuff
@@ -156,6 +156,7 @@ func (conR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 100,
RecvBufferCapacity: 50 * 4096,
RecvMessageCapacity: maxMsgSize,
+ MessageType: &tmcons.Message{},
},
{
ID: VoteChannel,
@@ -163,6 +164,7 @@ func (conR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 100,
RecvBufferCapacity: 100 * 100,
RecvMessageCapacity: maxMsgSize,
+ MessageType: &tmcons.Message{},
},
{
ID: VoteSetBitsChannel,
@@ -170,6 +172,7 @@ func (conR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
SendQueueCapacity: 2,
RecvBufferCapacity: 1024,
RecvMessageCapacity: maxMsgSize,
+ MessageType: &tmcons.Message{},
},
}
}
@@ -223,34 +226,37 @@ func (conR *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {
// Peer state updates can happen in parallel, but processing of
// proposals, block parts, and votes are ordered by the receiveRoutine
// NOTE: blocks on consensus state for proposals, block parts, and votes
-func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
+func (conR *Reactor) ReceiveEnvelope(e p2p.Envelope) {
if !conR.IsRunning() {
- conR.Logger.Debug("Receive", "src", src, "chId", chID, "bytes", msgBytes)
+ conR.Logger.Debug("Receive", "src", e.Src, "chId", e.ChannelID)
return
}
-
- msg, err := decodeMsg(msgBytes)
+ m := e.Message
+ if wm, ok := m.(p2p.Wrapper); ok {
+ m = wm.Wrap()
+ }
+ msg, err := MsgFromProto(m.(*tmcons.Message))
if err != nil {
- conR.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err)
- conR.Switch.StopPeerForError(src, err)
+ conR.Logger.Error("Error decoding message", "src", e.Src, "chId", e.ChannelID, "err", err)
+ conR.Switch.StopPeerForError(e.Src, err)
return
}
if err = msg.ValidateBasic(); err != nil {
- conR.Logger.Error("Peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
- conR.Switch.StopPeerForError(src, err)
+ conR.Logger.Error("Peer sent us invalid msg", "peer", e.Src, "msg", e.Message, "err", err)
+ conR.Switch.StopPeerForError(e.Src, err)
return
}
- conR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg)
+ conR.Logger.Debug("Receive", "src", e.Src, "chId", e.ChannelID, "msg", msg)
// Get peer states
- ps, ok := src.Get(types.PeerStateKey).(*PeerState)
+ ps, ok := e.Src.Get(types.PeerStateKey).(*PeerState)
if !ok {
- panic(fmt.Sprintf("Peer %v has no state", src))
+ panic(fmt.Sprintf("Peer %v has no state", e.Src))
}
- switch chID {
+ switch e.ChannelID {
case StateChannel:
switch msg := msg.(type) {
case *NewRoundStepMessage:
@@ -258,8 +264,8 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
initialHeight := conR.conS.state.InitialHeight
conR.conS.mtx.Unlock()
if err = msg.ValidateHeight(initialHeight); err != nil {
- conR.Logger.Error("Peer sent us invalid msg", "peer", src, "msg", msg, "err", err)
- conR.Switch.StopPeerForError(src, err)
+ conR.Logger.Error("Peer sent us invalid msg", "peer", e.Src, "msg", msg, "err", err)
+ conR.Switch.StopPeerForError(e.Src, err)
return
}
ps.ApplyNewRoundStepMessage(msg)
@@ -278,7 +284,7 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
// Peer claims to have a maj23 for some BlockID at H,R,S,
err := votes.SetPeerMaj23(msg.Round, msg.Type, ps.peer.ID(), msg.BlockID)
if err != nil {
- conR.Switch.StopPeerForError(src, err)
+ conR.Switch.StopPeerForError(e.Src, err)
return
}
// Respond with a VoteSetBitsMessage showing which votes we have.
@@ -292,13 +298,19 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
default:
panic("Bad VoteSetBitsMessage field Type. Forgot to add a check in ValidateBasic?")
}
- src.TrySend(VoteSetBitsChannel, MustEncode(&VoteSetBitsMessage{
+ eMsg := &tmcons.VoteSetBits{
Height: msg.Height,
Round: msg.Round,
Type: msg.Type,
- BlockID: msg.BlockID,
- Votes: ourVotes,
- }))
+ BlockID: msg.BlockID.ToProto(),
+ }
+ if votes := ourVotes.ToProto(); votes != nil {
+ eMsg.Votes = *votes
+ }
+ p2p.TrySendEnvelopeShim(e.Src, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: VoteSetBitsChannel,
+ Message: eMsg,
+ }, conR.Logger)
default:
conR.Logger.Error(fmt.Sprintf("Unknown message type %v", reflect.TypeOf(msg)))
}
@@ -311,13 +323,13 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
switch msg := msg.(type) {
case *ProposalMessage:
ps.SetHasProposal(msg.Proposal)
- conR.conS.peerMsgQueue <- msgInfo{msg, src.ID()}
+ conR.conS.peerMsgQueue <- msgInfo{msg, e.Src.ID()}
case *ProposalPOLMessage:
ps.ApplyProposalPOLMessage(msg)
case *BlockPartMessage:
ps.SetHasProposalBlockPart(msg.Height, msg.Round, int(msg.Part.Index))
- conR.Metrics.BlockParts.With("peer_id", string(src.ID())).Add(1)
- conR.conS.peerMsgQueue <- msgInfo{msg, src.ID()}
+ conR.Metrics.BlockParts.With("peer_id", string(e.Src.ID())).Add(1)
+ conR.conS.peerMsgQueue <- msgInfo{msg, e.Src.ID()}
default:
conR.Logger.Error(fmt.Sprintf("Unknown message type %v", reflect.TypeOf(msg)))
}
@@ -337,7 +349,7 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
ps.EnsureVoteBitArrays(height-1, lastCommitSize)
ps.SetHasVote(msg.Vote)
- cs.peerMsgQueue <- msgInfo{msg, src.ID()}
+ cs.peerMsgQueue <- msgInfo{msg, e.Src.ID()}
default:
// don't punish (leave room for soft upgrades)
@@ -376,8 +388,25 @@ func (conR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
}
default:
- conR.Logger.Error(fmt.Sprintf("Unknown chId %X", chID))
+ conR.Logger.Error(fmt.Sprintf("Unknown chId %X", e.ChannelID))
+ }
+}
+
+func (conR *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &tmcons.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
}
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+ conR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
}
// SetEventBus sets event bus.
@@ -430,29 +459,39 @@ func (conR *Reactor) unsubscribeFromBroadcastEvents() {
func (conR *Reactor) broadcastNewRoundStepMessage(rs *cstypes.RoundState) {
nrsMsg := makeRoundStepMessage(rs)
- conR.Switch.Broadcast(StateChannel, MustEncode(nrsMsg))
+ conR.Switch.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: StateChannel,
+ Message: nrsMsg,
+ })
}
func (conR *Reactor) broadcastNewValidBlockMessage(rs *cstypes.RoundState) {
- csMsg := &NewValidBlockMessage{
+ psh := rs.ProposalBlockParts.Header()
+ csMsg := &tmcons.NewValidBlock{
Height: rs.Height,
Round: rs.Round,
- BlockPartSetHeader: rs.ProposalBlockParts.Header(),
- BlockParts: rs.ProposalBlockParts.BitArray(),
+ BlockPartSetHeader: psh.ToProto(),
+ BlockParts: rs.ProposalBlockParts.BitArray().ToProto(),
IsCommit: rs.Step == cstypes.RoundStepCommit,
}
- conR.Switch.Broadcast(StateChannel, MustEncode(csMsg))
+ conR.Switch.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: StateChannel,
+ Message: csMsg,
+ })
}
// Broadcasts HasVoteMessage to peers that care.
func (conR *Reactor) broadcastHasVoteMessage(vote *types.Vote) {
- msg := &HasVoteMessage{
+ msg := &tmcons.HasVote{
Height: vote.Height,
Round: vote.Round,
Type: vote.Type,
Index: vote.ValidatorIndex,
}
- conR.Switch.Broadcast(StateChannel, MustEncode(msg))
+ conR.Switch.BroadcastEnvelope(p2p.Envelope{
+ ChannelID: StateChannel,
+ Message: msg,
+ })
/*
// TODO: Make this broadcast more selective.
for _, peer := range conR.Switch.Peers().List() {
@@ -463,7 +502,11 @@ func (conR *Reactor) broadcastHasVoteMessage(vote *types.Vote) {
prs := ps.GetRoundState()
if prs.Height == vote.Height {
// TODO: Also filter on round?
- peer.TrySend(StateChannel, struct{ ConsensusMessage }{msg})
+ e := p2p.Envelope{
+ ChannelID: StateChannel, struct{ ConsensusMessage }{msg},
+ Message: p,
+ }
+ p2p.TrySendEnvelopeShim(peer, e) //nolint: staticcheck
} else {
// Height doesn't match
// TODO: check a field, maybe CatchupCommitRound?
@@ -473,11 +516,11 @@ func (conR *Reactor) broadcastHasVoteMessage(vote *types.Vote) {
*/
}
-func makeRoundStepMessage(rs *cstypes.RoundState) (nrsMsg *NewRoundStepMessage) {
- nrsMsg = &NewRoundStepMessage{
+func makeRoundStepMessage(rs *cstypes.RoundState) (nrsMsg *tmcons.NewRoundStep) {
+ nrsMsg = &tmcons.NewRoundStep{
Height: rs.Height,
Round: rs.Round,
- Step: rs.Step,
+ Step: uint32(rs.Step),
SecondsSinceStartTime: int64(time.Since(rs.StartTime).Seconds()),
LastCommitRound: rs.LastCommit.GetRound(),
}
@@ -487,7 +530,10 @@ func makeRoundStepMessage(rs *cstypes.RoundState) (nrsMsg *NewRoundStepMessage)
func (conR *Reactor) sendNewRoundStepMessage(peer p2p.Peer) {
rs := conR.getRoundState()
nrsMsg := makeRoundStepMessage(rs)
- peer.Send(StateChannel, MustEncode(nrsMsg))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: StateChannel,
+ Message: nrsMsg,
+ }, conR.Logger)
}
func (conR *Reactor) updateRoundStateRoutine() {
@@ -526,13 +572,19 @@ OUTER_LOOP:
if rs.ProposalBlockParts.HasHeader(prs.ProposalBlockPartSetHeader) {
if index, ok := rs.ProposalBlockParts.BitArray().Sub(prs.ProposalBlockParts.Copy()).PickRandom(); ok {
part := rs.ProposalBlockParts.GetPart(index)
- msg := &BlockPartMessage{
- Height: rs.Height, // This tells peer that this part applies to us.
- Round: rs.Round, // This tells peer that this part applies to us.
- Part: part,
+ parts, err := part.ToProto()
+ if err != nil {
+ panic(err)
}
logger.Debug("Sending block part", "height", prs.Height, "round", prs.Round)
- if peer.Send(DataChannel, MustEncode(msg)) {
+ if p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.BlockPart{
+ Height: rs.Height, // This tells peer that this part applies to us.
+ Round: rs.Round, // This tells peer that this part applies to us.
+ Part: *parts,
+ },
+ }, logger) {
ps.SetHasProposalBlockPart(prs.Height, prs.Round, index)
}
continue OUTER_LOOP
@@ -578,9 +630,11 @@ OUTER_LOOP:
if rs.Proposal != nil && !prs.Proposal {
// Proposal: share the proposal metadata with peer.
{
- msg := &ProposalMessage{Proposal: rs.Proposal}
logger.Debug("Sending proposal", "height", prs.Height, "round", prs.Round)
- if peer.Send(DataChannel, MustEncode(msg)) {
+ if p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.Proposal{Proposal: *rs.Proposal.ToProto()},
+ }, logger) {
// NOTE[ZM]: A peer might have received different proposal msg so this Proposal msg will be rejected!
ps.SetHasProposal(rs.Proposal)
}
@@ -590,13 +644,15 @@ OUTER_LOOP:
// rs.Proposal was validated, so rs.Proposal.POLRound <= rs.Round,
// so we definitely have rs.Votes.Prevotes(rs.Proposal.POLRound).
if 0 <= rs.Proposal.POLRound {
- msg := &ProposalPOLMessage{
- Height: rs.Height,
- ProposalPOLRound: rs.Proposal.POLRound,
- ProposalPOL: rs.Votes.Prevotes(rs.Proposal.POLRound).BitArray(),
- }
logger.Debug("Sending POL", "height", prs.Height, "round", prs.Round)
- peer.Send(DataChannel, MustEncode(msg))
+ p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.ProposalPOL{
+ Height: rs.Height,
+ ProposalPolRound: rs.Proposal.POLRound,
+ ProposalPol: *rs.Votes.Prevotes(rs.Proposal.POLRound).BitArray().ToProto(),
+ },
+ }, logger)
}
continue OUTER_LOOP
}
@@ -633,13 +689,20 @@ func (conR *Reactor) gossipDataForCatchup(logger log.Logger, rs *cstypes.RoundSt
return
}
// Send the part
- msg := &BlockPartMessage{
- Height: prs.Height, // Not our height, so it doesn't matter.
- Round: prs.Round, // Not our height, so it doesn't matter.
- Part: part,
- }
logger.Debug("Sending block part for catchup", "round", prs.Round, "index", index)
- if peer.Send(DataChannel, MustEncode(msg)) {
+ pp, err := part.ToProto()
+ if err != nil {
+ logger.Error("Could not convert part to proto", "index", index, "error", err)
+ return
+ }
+ if p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: DataChannel,
+ Message: &tmcons.BlockPart{
+ Height: prs.Height, // Not our height, so it doesn't matter.
+ Round: prs.Round, // Not our height, so it doesn't matter.
+ Part: *pp,
+ },
+ }, logger) {
ps.SetHasProposalBlockPart(prs.Height, prs.Round, index)
} else {
logger.Debug("Sending block part for catchup failed")
@@ -798,12 +861,16 @@ OUTER_LOOP:
prs := ps.GetRoundState()
if rs.Height == prs.Height {
if maj23, ok := rs.Votes.Prevotes(prs.Round).TwoThirdsMajority(); ok {
- peer.TrySend(StateChannel, MustEncode(&VoteSetMaj23Message{
- Height: prs.Height,
- Round: prs.Round,
- Type: tmproto.PrevoteType,
- BlockID: maj23,
- }))
+
+ p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: StateChannel,
+ Message: &tmcons.VoteSetMaj23{
+ Height: prs.Height,
+ Round: prs.Round,
+ Type: tmproto.PrevoteType,
+ BlockID: maj23.ToProto(),
+ },
+ }, ps.logger)
time.Sleep(conR.conS.config.PeerQueryMaj23SleepDuration)
}
}
@@ -815,12 +882,15 @@ OUTER_LOOP:
prs := ps.GetRoundState()
if rs.Height == prs.Height {
if maj23, ok := rs.Votes.Precommits(prs.Round).TwoThirdsMajority(); ok {
- peer.TrySend(StateChannel, MustEncode(&VoteSetMaj23Message{
- Height: prs.Height,
- Round: prs.Round,
- Type: tmproto.PrecommitType,
- BlockID: maj23,
- }))
+ p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: StateChannel,
+ Message: &tmcons.VoteSetMaj23{
+ Height: prs.Height,
+ Round: prs.Round,
+ Type: tmproto.PrecommitType,
+ BlockID: maj23.ToProto(),
+ },
+ }, ps.logger)
time.Sleep(conR.conS.config.PeerQueryMaj23SleepDuration)
}
}
@@ -832,12 +902,16 @@ OUTER_LOOP:
prs := ps.GetRoundState()
if rs.Height == prs.Height && prs.ProposalPOLRound >= 0 {
if maj23, ok := rs.Votes.Prevotes(prs.ProposalPOLRound).TwoThirdsMajority(); ok {
- peer.TrySend(StateChannel, MustEncode(&VoteSetMaj23Message{
- Height: prs.Height,
- Round: prs.ProposalPOLRound,
- Type: tmproto.PrevoteType,
- BlockID: maj23,
- }))
+
+ p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: StateChannel,
+ Message: &tmcons.VoteSetMaj23{
+ Height: prs.Height,
+ Round: prs.ProposalPOLRound,
+ Type: tmproto.PrevoteType,
+ BlockID: maj23.ToProto(),
+ },
+ }, ps.logger)
time.Sleep(conR.conS.config.PeerQueryMaj23SleepDuration)
}
}
@@ -852,12 +926,15 @@ OUTER_LOOP:
if prs.CatchupCommitRound != -1 && prs.Height > 0 && prs.Height <= conR.conS.blockStore.Height() &&
prs.Height >= conR.conS.blockStore.Base() {
if commit := conR.conS.LoadCommit(prs.Height); commit != nil {
- peer.TrySend(StateChannel, MustEncode(&VoteSetMaj23Message{
- Height: prs.Height,
- Round: commit.Round,
- Type: tmproto.PrecommitType,
- BlockID: commit.BlockID,
- }))
+ p2p.TrySendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: StateChannel,
+ Message: &tmcons.VoteSetMaj23{
+ Height: prs.Height,
+ Round: commit.Round,
+ Type: tmproto.PrecommitType,
+ BlockID: commit.BlockID.ToProto(),
+ },
+ }, ps.logger)
time.Sleep(conR.conS.config.PeerQueryMaj23SleepDuration)
}
}
@@ -1071,9 +1148,13 @@ func (ps *PeerState) SetHasProposalBlockPart(height int64, round int32, index in
// Returns true if vote was sent.
func (ps *PeerState) PickSendVote(votes types.VoteSetReader) bool {
if vote, ok := ps.PickVoteToSend(votes); ok {
- msg := &VoteMessage{vote}
ps.logger.Debug("Sending vote message", "ps", ps, "vote", vote)
- if ps.peer.Send(VoteChannel, MustEncode(msg)) {
+ if p2p.SendEnvelopeShim(ps.peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: VoteChannel,
+ Message: &tmcons.Vote{
+ Vote: vote.ToProto(),
+ },
+ }, ps.logger) {
ps.SetHasVote(vote)
return true
}
@@ -1439,15 +1520,6 @@ func init() {
tmjson.RegisterType(&VoteSetBitsMessage{}, "tendermint/VoteSetBits")
}
-func decodeMsg(bz []byte) (msg Message, err error) {
- pb := &tmcons.Message{}
- if err = proto.Unmarshal(bz, pb); err != nil {
- return msg, err
- }
-
- return MsgFromProto(pb)
-}
-
//-------------------------------------
// NewRoundStepMessage is sent for every step taken in the ConsensusState.
diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go
index 5d68cd9b70..851070ba67 100644
--- a/consensus/reactor_test.go
+++ b/consensus/reactor_test.go
@@ -11,6 +11,7 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -33,6 +34,7 @@ import (
mempoolv1 "github.com/tendermint/tendermint/mempool/v1"
"github.com/tendermint/tendermint/p2p"
p2pmock "github.com/tendermint/tendermint/p2p/mock"
+ tmcons "github.com/tendermint/tendermint/proto/tendermint/consensus"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
sm "github.com/tendermint/tendermint/state"
statemocks "github.com/tendermint/tendermint/state/mocks"
@@ -138,7 +140,9 @@ func TestReactorWithEvidence(t *testing.T) {
logger := consensusLogger()
for i := 0; i < nValidators; i++ {
stateDB := dbm.NewMemDB() // each state needs its own db
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, _ := stateStore.LoadFromDBOrGenesisDoc(genDoc)
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
defer os.RemoveAll(thisConfig.RootDir)
@@ -252,7 +256,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) {
}, css)
}
-func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) {
+func TestLegacyReactorReceiveBasicIfAddPeerHasntBeenCalledYet(t *testing.T) {
N := 1
css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter)
defer cleanup()
@@ -262,13 +266,45 @@ func TestReactorReceiveDoesNotPanicIfAddPeerHasntBeenCalledYet(t *testing.T) {
var (
reactor = reactors[0]
peer = p2pmock.NewPeer(nil)
- msg = MustEncode(&HasVoteMessage{Height: 1,
- Round: 1, Index: 1, Type: tmproto.PrevoteType})
)
reactor.InitPeer(peer)
// simulate switch calling Receive before AddPeer
+ assert.NotPanics(t, func() {
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: StateChannel,
+ Src: peer,
+ Message: &tmcons.HasVote{Height: 1,
+ Round: 1, Index: 1, Type: tmproto.PrevoteType},
+ })
+ reactor.AddPeer(peer)
+ })
+}
+
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ N := 1
+ css, cleanup := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter)
+ defer cleanup()
+ reactors, _, eventBuses := startConsensusNet(t, css, N)
+ defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses)
+
+ var (
+ reactor = reactors[0]
+ peer = p2pmock.NewPeer(nil)
+ )
+
+ reactor.InitPeer(peer)
+ v := &tmcons.HasVote{
+ Height: 1,
+ Round: 1,
+ Index: 1,
+ Type: tmproto.PrevoteType,
+ }
+ w := v.Wrap()
+ msg, err := proto.Marshal(w)
+ assert.NoError(t, err)
+
assert.NotPanics(t, func() {
reactor.Receive(StateChannel, peer, msg)
reactor.AddPeer(peer)
@@ -285,15 +321,18 @@ func TestReactorReceivePanicsIfInitPeerHasntBeenCalledYet(t *testing.T) {
var (
reactor = reactors[0]
peer = p2pmock.NewPeer(nil)
- msg = MustEncode(&HasVoteMessage{Height: 1,
- Round: 1, Index: 1, Type: tmproto.PrevoteType})
)
// we should call InitPeer here
// simulate switch calling Receive before AddPeer
assert.Panics(t, func() {
- reactor.Receive(StateChannel, peer, msg)
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: StateChannel,
+ Src: peer,
+ Message: &tmcons.HasVote{Height: 1,
+ Round: 1, Index: 1, Type: tmproto.PrevoteType},
+ })
})
}
@@ -689,7 +728,7 @@ func capture() {
// Ensure basic validation of structs is functioning
func TestNewRoundStepMessageValidateBasic(t *testing.T) {
- testCases := []struct { // nolint: maligned
+ testCases := []struct {
expectErr bool
messageRound int32
messageLastCommitRound int32
@@ -728,7 +767,7 @@ func TestNewRoundStepMessageValidateBasic(t *testing.T) {
func TestNewRoundStepMessageValidateHeight(t *testing.T) {
initialHeight := int64(10)
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageLastCommitRound int32
messageHeight int64
@@ -878,7 +917,7 @@ func TestHasVoteMessageValidateBasic(t *testing.T) {
invalidSignedMsgType tmproto.SignedMsgType = 0x03
)
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageRound int32
messageIndex int32
@@ -923,7 +962,7 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) {
},
}
- testCases := []struct { // nolint: maligned
+ testCases := []struct { //nolint: maligned
expectErr bool
messageRound int32
messageHeight int64
diff --git a/consensus/replay.go b/consensus/replay.go
index 9fd59a40eb..bed2a2c4da 100644
--- a/consensus/replay.go
+++ b/consensus/replay.go
@@ -418,7 +418,7 @@ func (h *Handshaker) ReplayBlocks(
case appBlockHeight == storeBlockHeight:
// We ran Commit, but didn't save the state, so replayBlock with mock app.
- abciResponses, err := h.stateStore.LoadABCIResponses(storeBlockHeight)
+ abciResponses, err := h.stateStore.LoadLastABCIResponse(storeBlockHeight)
if err != nil {
return nil, err
}
diff --git a/consensus/replay_file.go b/consensus/replay_file.go
index 4bf7466abf..0145dfe928 100644
--- a/consensus/replay_file.go
+++ b/consensus/replay_file.go
@@ -297,7 +297,9 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo
if err != nil {
tmos.Exit(err.Error())
}
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
gdoc, err := sm.MakeGenesisDocFromFile(config.GenesisFile())
if err != nil {
tmos.Exit(err.Error())
diff --git a/consensus/replay_test.go b/consensus/replay_test.go
index c830cc8303..b037c5cfa4 100644
--- a/consensus/replay_test.go
+++ b/consensus/replay_test.go
@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -66,7 +65,8 @@ func TestMain(m *testing.M) {
// wal writer when we need to, instead of with every message.
func startNewStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Config,
- lastBlockHeight int64, blockDB dbm.DB, stateStore sm.Store) {
+ lastBlockHeight int64, blockDB dbm.DB, stateStore sm.Store,
+) {
logger := log.TestingLogger()
state, _ := stateStore.LoadFromDBOrGenesisFile(consensusReplayConfig.GenesisFile())
privValidator := loadPrivValidator(consensusReplayConfig)
@@ -79,7 +79,7 @@ func startNewStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Confi
)
cs.SetLogger(logger)
- bytes, _ := ioutil.ReadFile(cs.config.WalFile())
+ bytes, _ := os.ReadFile(cs.config.WalFile())
t.Logf("====== WAL: \n\r%X\n", bytes)
err := cs.Start()
@@ -127,14 +127,18 @@ func TestWALCrash(t *testing.T) {
initFn func(dbm.DB, *State, context.Context)
heightToStop int64
}{
- {"empty block",
+ {
+ "empty block",
func(stateDB dbm.DB, cs *State, ctx context.Context) {},
- 1},
- {"many non-empty blocks",
+ 1,
+ },
+ {
+ "many non-empty blocks",
func(stateDB dbm.DB, cs *State, ctx context.Context) {
go sendTxs(ctx, cs)
},
- 3},
+ 3,
+ },
}
for i, tc := range testCases {
@@ -147,7 +151,8 @@ func TestWALCrash(t *testing.T) {
}
func crashWALandCheckLiveness(t *testing.T, consensusReplayConfig *cfg.Config,
- initFn func(dbm.DB, *State, context.Context), heightToStop int64) {
+ initFn func(dbm.DB, *State, context.Context), heightToStop int64,
+) {
walPanicked := make(chan error)
crashingWal := &crashingWAL{panicCh: walPanicked, heightToStop: heightToStop}
@@ -160,7 +165,9 @@ LOOP:
logger := log.NewNopLogger()
blockDB := dbm.NewMemDB()
stateDB := blockDB
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, err := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile())
require.NoError(t, err)
privValidator := loadPrivValidator(consensusReplayConfig)
@@ -283,7 +290,8 @@ func (w *crashingWAL) FlushAndSync() error { return w.next.FlushAndSync() }
func (w *crashingWAL) SearchForEndHeight(
height int64,
- options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) {
+ options *WALSearchOptions,
+) (rd io.ReadCloser, found bool, err error) {
return w.next.SearchForEndHeight(height, options)
}
@@ -587,7 +595,7 @@ func TestHandshakeReplayNone(t *testing.T) {
func TestMockProxyApp(t *testing.T) {
sim.CleanupFunc() // clean the test env created in TestSimulateValidatorsChange
logger := log.TestingLogger()
- var validTxs, invalidTxs = 0, 0
+ validTxs, invalidTxs := 0, 0
txIndex := 0
assert.NotPanics(t, func() {
@@ -635,7 +643,7 @@ func TestMockProxyApp(t *testing.T) {
}
func tempWALWithData(data []byte) string {
- walFile, err := ioutil.TempFile("", "wal")
+ walFile, err := os.CreateTemp("", "wal")
if err != nil {
panic(fmt.Sprintf("failed to create temp WAL file: %v", err))
}
@@ -694,7 +702,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin
stateDB, genesisState, store = stateAndStore(config, pubKey, kvstore.ProtocolVersion)
}
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
store.chain = chain
store.commits = commits
@@ -713,7 +723,9 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin
// use a throwaway tendermint state
proxyApp := proxy.NewAppConns(clientCreator2)
stateDB1 := dbm.NewMemDB()
- stateStore := sm.NewStore(stateDB1)
+ stateStore := sm.NewStore(stateDB1, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
err := stateStore.Save(genesisState)
require.NoError(t, err)
buildAppStateFromChain(proxyApp, stateStore, genesisState, chain, nBlocks, mode)
@@ -789,7 +801,8 @@ func applyBlock(stateStore sm.Store, st sm.State, blk *types.Block, proxyApp pro
}
func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store,
- state sm.State, chain []*types.Block, nBlocks int, mode uint) {
+ state sm.State, chain []*types.Block, nBlocks int, mode uint,
+) {
// start a new app without handshake, play nBlocks blocks
if err := proxyApp.Start(); err != nil {
panic(err)
@@ -826,7 +839,6 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store,
default:
panic(fmt.Sprintf("unknown mode %v", mode))
}
-
}
func buildTMStateFromChain(
@@ -835,7 +847,8 @@ func buildTMStateFromChain(
state sm.State,
chain []*types.Block,
nBlocks int,
- mode uint) sm.State {
+ mode uint,
+) sm.State {
// run the whole chain against this client to build up the tendermint state
clientCreator := proxy.NewLocalClientCreator(
kvstore.NewPersistentKVStoreApplication(
@@ -892,7 +905,9 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) {
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
stateDB, state, store := stateAndStore(config, pubKey, appVersion)
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
genDoc, _ := sm.MakeGenesisDocFromFile(config.GenesisFile())
state.LastValidators = state.Validators.Copy()
// mode = 0 for committing all the blocks
@@ -976,8 +991,8 @@ func makeBlocks(n int, state *sm.State, privVal types.PrivValidator) []*types.Bl
}
func makeBlock(state sm.State, lastBlock *types.Block, lastBlockMeta *types.BlockMeta,
- privVal types.PrivValidator, height int64) (*types.Block, *types.PartSet) {
-
+ privVal types.PrivValidator, height int64,
+) (*types.Block, *types.PartSet) {
lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
if height > 1 {
vote, _ := types.MakeVote(
@@ -1065,8 +1080,8 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
case EndHeightMessage:
// if its not the first one, we have a full block
if thisBlockParts != nil {
- var pbb = new(tmproto.Block)
- bz, err := ioutil.ReadAll(thisBlockParts.GetReader())
+ pbb := new(tmproto.Block)
+ bz, err := io.ReadAll(thisBlockParts.GetReader())
if err != nil {
panic(err)
}
@@ -1105,11 +1120,11 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
}
}
// grab the last block too
- bz, err := ioutil.ReadAll(thisBlockParts.GetReader())
+ bz, err := io.ReadAll(thisBlockParts.GetReader())
if err != nil {
panic(err)
}
- var pbb = new(tmproto.Block)
+ pbb := new(tmproto.Block)
err = proto.Unmarshal(bz, pbb)
if err != nil {
panic(err)
@@ -1153,9 +1168,12 @@ func readPieceFromWAL(msg *TimedWALMessage) interface{} {
func stateAndStore(
config *cfg.Config,
pubKey crypto.PubKey,
- appVersion uint64) (dbm.DB, sm.State, *mockBlockStore) {
+ appVersion uint64,
+) (dbm.DB, sm.State, *mockBlockStore) {
stateDB := dbm.NewMemDB()
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile())
state.Version.Consensus.App = appVersion
store := newMockBlockStore(config, state.ConsensusParams)
@@ -1189,6 +1207,7 @@ func (bs *mockBlockStore) LoadBlock(height int64) *types.Block { return bs.chain
func (bs *mockBlockStore) LoadBlockByHash(hash []byte) *types.Block {
return bs.chain[int64(len(bs.chain))-1]
}
+
func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
block := bs.chain[height-1]
return &types.BlockMeta{
@@ -1199,9 +1218,11 @@ func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
func (bs *mockBlockStore) LoadBlockPart(height int64, index int) *types.Part { return nil }
func (bs *mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
}
+
func (bs *mockBlockStore) LoadBlockCommit(height int64) *types.Commit {
return bs.commits[height-1]
}
+
func (bs *mockBlockStore) LoadSeenCommit(height int64) *types.Commit {
return bs.commits[height-1]
}
@@ -1232,7 +1253,9 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
pubKey, err := privVal.GetPubKey()
require.NoError(t, err)
stateDB, state, store := stateAndStore(config, pubKey, 0x0)
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
oldValAddr := state.Validators.Validators[0].Address
diff --git a/consensus/state.go b/consensus/state.go
index 7f0e9c3371..6b39cab210 100644
--- a/consensus/state.go
+++ b/consensus/state.go
@@ -4,7 +4,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"os"
"runtime/debug"
"sort"
@@ -468,7 +468,6 @@ func (cs *State) AddVote(vote *types.Vote, peerID p2p.ID) (added bool, err error
// SetProposal inputs a proposal.
func (cs *State) SetProposal(proposal *types.Proposal, peerID p2p.ID) error {
-
if peerID == "" {
cs.internalMsgQueue <- msgInfo{&ProposalMessage{proposal}, ""}
} else {
@@ -481,7 +480,6 @@ func (cs *State) SetProposal(proposal *types.Proposal, peerID p2p.ID) error {
// AddProposalBlockPart inputs a part of the proposal block.
func (cs *State) AddProposalBlockPart(height int64, round int32, part *types.Part, peerID p2p.ID) error {
-
if peerID == "" {
cs.internalMsgQueue <- msgInfo{&BlockPartMessage{height, round, part}, ""}
} else {
@@ -499,7 +497,6 @@ func (cs *State) SetProposalAndBlock(
parts *types.PartSet,
peerID p2p.ID,
) error {
-
if err := cs.SetProposal(proposal, peerID); err != nil {
return err
}
@@ -821,7 +818,7 @@ func (cs *State) handleMsg(mi msgInfo) {
// We unlock here to yield to any routines that need to read the the RoundState.
// Previously, this code held the lock from the point at which the final block
- // part was recieved until the block executed against the application.
+ // part was received until the block executed against the application.
// This prevented the reactor from being able to retrieve the most updated
// version of the RoundState. The reactor needs the updated RoundState to
// gossip the now completed block.
@@ -937,7 +934,6 @@ func (cs *State) handleTimeout(ti timeoutInfo, rs cstypes.RoundState) {
default:
panic(fmt.Sprintf("invalid timeout step: %v", ti.Step))
}
-
}
func (cs *State) handleTxsAvailable() {
@@ -1181,7 +1177,6 @@ func (cs *State) isProposalComplete() bool {
}
// if this is false the proposer is lying or we haven't received the POL yet
return cs.Votes.Prevotes(cs.Proposal.POLRound).HasTwoThirdsMajority()
-
}
// Create the next block to propose and return it. Returns nil block upon error.
@@ -1898,12 +1893,12 @@ func (cs *State) addProposalBlockPart(msg *BlockPartMessage, peerID p2p.ID) (add
)
}
if added && cs.ProposalBlockParts.IsComplete() {
- bz, err := ioutil.ReadAll(cs.ProposalBlockParts.GetReader())
+ bz, err := io.ReadAll(cs.ProposalBlockParts.GetReader())
if err != nil {
return added, err
}
- var pbb = new(tmproto.Block)
+ pbb := new(tmproto.Block)
err = proto.Unmarshal(bz, pbb)
if err != nil {
return added, err
@@ -1968,7 +1963,7 @@ func (cs *State) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, error) {
// If the vote height is off, we'll just ignore it,
// But if it's a conflicting sig, add it to the cs.evpool.
// If it's otherwise invalid, punish peer.
- // nolint: gocritic
+ //nolint: gocritic
if voteErr, ok := err.(*types.ErrVoteConflictingVotes); ok {
if cs.privValidatorPubKey == nil {
return false, errPubKeyIsNotSet
@@ -2231,10 +2226,11 @@ func (cs *State) voteTime() time.Time {
now := tmtime.Now()
minVoteTime := now
// TODO: We should remove next line in case we don't vote for v in case cs.ProposalBlock == nil,
- // even if cs.LockedBlock != nil. See https://docs.tendermint.com/master/spec/.
+ // even if cs.LockedBlock != nil. See https://github.com/tendermint/tendermint/tree/v0.34.x/spec/.
timeIota := time.Duration(cs.state.ConsensusParams.Block.TimeIotaMs) * time.Millisecond
if cs.LockedBlock != nil {
- // See the BFT time spec https://docs.tendermint.com/master/spec/consensus/bft-time.html
+ // See the BFT time spec
+ // https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/bft-time.md
minVoteTime = cs.LockedBlock.Time.Add(timeIota)
} else if cs.ProposalBlock != nil {
minVoteTime = cs.ProposalBlock.Time.Add(timeIota)
diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go
index 1c449717bd..53712bf3dc 100644
--- a/consensus/wal_generator.go
+++ b/consensus/wal_generator.go
@@ -47,7 +47,9 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) {
}
blockStoreDB := db.NewMemDB()
stateDB := blockStoreDB
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, err := sm.MakeGenesisState(genDoc)
if err != nil {
return fmt.Errorf("failed to make genesis state: %w", err)
diff --git a/consensus/wal_test.go b/consensus/wal_test.go
index 4ee8136091..5a4f4098f7 100644
--- a/consensus/wal_test.go
+++ b/consensus/wal_test.go
@@ -3,7 +3,6 @@ package consensus
import (
"bytes"
"crypto/rand"
- "io/ioutil"
"os"
"path/filepath"
@@ -27,7 +26,7 @@ const (
)
func TestWALTruncate(t *testing.T) {
- walDir, err := ioutil.TempDir("", "wal")
+ walDir, err := os.MkdirTemp("", "wal")
require.NoError(t, err)
defer os.RemoveAll(walDir)
@@ -109,7 +108,7 @@ func TestWALEncoderDecoder(t *testing.T) {
}
func TestWALWrite(t *testing.T) {
- walDir, err := ioutil.TempDir("", "wal")
+ walDir, err := os.MkdirTemp("", "wal")
require.NoError(t, err)
defer os.RemoveAll(walDir)
walFile := filepath.Join(walDir, "wal")
@@ -177,7 +176,7 @@ func TestWALSearchForEndHeight(t *testing.T) {
}
func TestWALPeriodicSync(t *testing.T) {
- walDir, err := ioutil.TempDir("", "wal")
+ walDir, err := os.MkdirTemp("", "wal")
require.NoError(t, err)
defer os.RemoveAll(walDir)
@@ -269,18 +268,23 @@ func BenchmarkWalDecode512B(b *testing.B) {
func BenchmarkWalDecode10KB(b *testing.B) {
benchmarkWalDecode(b, 10*1024)
}
+
func BenchmarkWalDecode100KB(b *testing.B) {
benchmarkWalDecode(b, 100*1024)
}
+
func BenchmarkWalDecode1MB(b *testing.B) {
benchmarkWalDecode(b, 1024*1024)
}
+
func BenchmarkWalDecode10MB(b *testing.B) {
benchmarkWalDecode(b, 10*1024*1024)
}
+
func BenchmarkWalDecode100MB(b *testing.B) {
benchmarkWalDecode(b, 100*1024*1024)
}
+
func BenchmarkWalDecode1GB(b *testing.B) {
benchmarkWalDecode(b, 1024*1024*1024)
}
diff --git a/crypto/README.md b/crypto/README.md
index 20346d7155..eaedbf7f2c 100644
--- a/crypto/README.md
+++ b/crypto/README.md
@@ -12,7 +12,7 @@ For any specific algorithm, use its specific module e.g.
## Binary encoding
-For Binary encoding, please refer to the [Tendermint encoding specification](https://docs.tendermint.com/master/spec/blockchain/encoding.html).
+For Binary encoding, please refer to the [Tendermint encoding specification](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/encoding.md).
## JSON Encoding
diff --git a/crypto/armor/armor.go b/crypto/armor/armor.go
index bfc2193e93..99e2c3b3a2 100644
--- a/crypto/armor/armor.go
+++ b/crypto/armor/armor.go
@@ -3,9 +3,9 @@ package armor
import (
"bytes"
"fmt"
- "io/ioutil"
+ "io"
- "golang.org/x/crypto/openpgp/armor" // nolint: staticcheck
+ "golang.org/x/crypto/openpgp/armor" //nolint: staticcheck
)
func EncodeArmor(blockType string, headers map[string]string, data []byte) string {
@@ -31,7 +31,7 @@ func DecodeArmor(armorStr string) (blockType string, headers map[string]string,
if err != nil {
return "", nil, nil, err
}
- data, err = ioutil.ReadAll(block.Body)
+ data, err = io.ReadAll(block.Body)
if err != nil {
return "", nil, nil, err
}
diff --git a/crypto/merkle/doc.go b/crypto/merkle/doc.go
index 865c302170..fe50b34631 100644
--- a/crypto/merkle/doc.go
+++ b/crypto/merkle/doc.go
@@ -12,20 +12,19 @@ second pre-image attacks. Hence, use this library with caution.
Otherwise you might run into similar issues as, e.g., in early Bitcoin:
https://bitcointalk.org/?topic=102395
- *
- / \
- / \
- / \
- / \
- * *
- / \ / \
- / \ / \
- / \ / \
- * * * h6
- / \ / \ / \
- h0 h1 h2 h3 h4 h5
+ *
+ / \
+ / \
+ / \
+ / \
+ * *
+ / \ / \
+ / \ / \
+ / \ / \
+ * * * h6
+ / \ / \ / \
+ h0 h1 h2 h3 h4 h5
TODO(ismail): add 2nd pre-image protection or clarify further on how we use this and why this secure.
-
*/
package merkle
diff --git a/crypto/merkle/proof_value.go b/crypto/merkle/proof_value.go
index ab776216b0..842dc82018 100644
--- a/crypto/merkle/proof_value.go
+++ b/crypto/merkle/proof_value.go
@@ -85,8 +85,8 @@ func (op ValueOp) Run(args [][]byte) ([][]byte, error) {
bz := new(bytes.Buffer)
// Wrap to hash the KVPair.
- encodeByteSlice(bz, op.key) // nolint: errcheck // does not error
- encodeByteSlice(bz, vhash) // nolint: errcheck // does not error
+ encodeByteSlice(bz, op.key) //nolint: errcheck // does not error
+ encodeByteSlice(bz, vhash) //nolint: errcheck // does not error
kvhash := leafHash(bz.Bytes())
if !bytes.Equal(kvhash, op.Proof.LeafHash) {
diff --git a/crypto/merkle/tree.go b/crypto/merkle/tree.go
index 466c434824..089c2f82ee 100644
--- a/crypto/merkle/tree.go
+++ b/crypto/merkle/tree.go
@@ -47,10 +47,10 @@ func HashFromByteSlices(items [][]byte) []byte {
//
// These preliminary results suggest:
//
-// 1. The performance of the HashFromByteSlice is pretty good
-// 2. Go has low overhead for recursive functions
-// 3. The performance of the HashFromByteSlice routine is dominated
-// by the actual hashing of data
+// 1. The performance of the HashFromByteSlice is pretty good
+// 2. Go has low overhead for recursive functions
+// 3. The performance of the HashFromByteSlice routine is dominated
+// by the actual hashing of data
//
// Although this work is in no way exhaustive, point #3 suggests that
// optimization of this routine would need to take an alternative
diff --git a/crypto/secp256k1/secp256k1.go b/crypto/secp256k1/secp256k1.go
index 0fbd9ad2db..21073bea12 100644
--- a/crypto/secp256k1/secp256k1.go
+++ b/crypto/secp256k1/secp256k1.go
@@ -9,13 +9,13 @@ import (
"math/big"
secp256k1 "github.com/btcsuite/btcd/btcec"
- "golang.org/x/crypto/ripemd160" // nolint: staticcheck // necessary for Bitcoin address format
+ "golang.org/x/crypto/ripemd160" //nolint: staticcheck // necessary for Bitcoin address format
"github.com/tendermint/tendermint/crypto"
tmjson "github.com/tendermint/tendermint/libs/json"
)
-//-------------------------------------
+// -------------------------------------
const (
PrivKeyName = "tendermint/PrivKeySecp256k1"
PubKeyName = "tendermint/PubKeySecp256k1"
@@ -124,8 +124,8 @@ func GenPrivKeySecp256k1(secret []byte) PrivKey {
// used to reject malleable signatures
// see:
-// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
-// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
+// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
+// - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
// Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index 351be09644..71338fb6ff 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -1,14 +1,6 @@
module.exports = {
theme: 'cosmos',
title: 'Tendermint Core',
- // locales: {
- // "/": {
- // lang: "en-US"
- // },
- // "/ru/": {
- // lang: "ru"
- // }
- // },
base: process.env.VUEPRESS_BASE,
themeConfig: {
repo: 'tendermint/tendermint',
@@ -23,16 +15,12 @@ module.exports = {
},
versions: [
{
- "label": "v0.33",
- "key": "v0.33"
- },
- {
- "label": "v0.34",
+ "label": "v0.34 (latest)",
"key": "v0.34"
},
{
- "label": "v0.35",
- "key": "v0.35"
+ "label": "v0.33",
+ "key": "v0.33"
}
],
topbar: {
@@ -45,10 +33,8 @@ module.exports = {
title: 'Resources',
children: [
{
- // TODO(creachadair): Figure out how to make this per-branch.
- // See: https://github.com/tendermint/tendermint/issues/7908
title: 'RPC',
- path: 'https://docs.tendermint.com/v0.35/rpc/',
+ path: (process.env.VUEPRESS_BASE ? process.env.VUEPRESS_BASE : '/')+'rpc/',
static: true
},
]
@@ -59,9 +45,9 @@ module.exports = {
title: 'Help & Support',
editLink: true,
forum: {
- title: 'Tendermint Forum',
- text: 'Join the Tendermint forum to learn more',
- url: 'https://forum.cosmos.network/c/tendermint',
+ title: 'Tendermint Discussions',
+ text: 'Join the Tendermint discussions to learn more',
+ url: 'https://github.com/tendermint/tendermint/discussions',
bg: '#0B7E0B',
logo: 'tendermint'
},
@@ -72,7 +58,7 @@ module.exports = {
},
footer: {
question: {
- text: 'Chat with Tendermint developers in Discord or reach out on the Tendermint Forum to learn more.'
+ text: 'Chat with Tendermint developers in Discord or reach out on GitHub to learn more.'
},
logo: '/logo-bw.svg',
textLink: {
@@ -129,8 +115,8 @@ module.exports = {
url: 'https://medium.com/@tendermint'
},
{
- title: 'Forum',
- url: 'https://forum.cosmos.network/c/tendermint'
+ title: 'GitHub Discussions',
+ url: 'https://github.com/tendermint/tendermint/discussions'
}
]
},
diff --git a/docs/.vuepress/redirects b/docs/.vuepress/redirects
index 15bd6111b5..f17d072aa6 100644
--- a/docs/.vuepress/redirects
+++ b/docs/.vuepress/redirects
@@ -1 +1,66 @@
-/master/ /v0.35/
+/redirects/master/ /main/
+/redirects/master/spec/core/state.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/state.md
+/redirects/master/spec/core/encoding.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/encoding.md
+/redirects/master/spec/core/genesis.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/genesis.md
+/redirects/master/spec/core/data_structures.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/data_structures.md
+/redirects/master/spec/core/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/readme.md
+/redirects/master/spec/p2p/messages/pex.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/pex.md
+/redirects/master/spec/p2p/messages/mempool.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/mempool.md
+/redirects/master/spec/p2p/messages/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/README.md
+/redirects/master/spec/p2p/messages/block-sync.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/block-sync.md
+/redirects/master/spec/p2p/messages/state-sync.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/state-sync.md
+/redirects/master/spec/p2p/messages/consensus.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/consensus.md
+/redirects/master/spec/p2p/messages/evidence.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/messages/evidence.md
+/redirects/master/spec/p2p/peer.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/peer.md
+/redirects/master/spec/p2p/connection.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/connection.md
+/redirects/master/spec/p2p/config.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/config.md
+/redirects/master/spec/p2p/node.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/node.md
+/redirects/master/spec/p2p/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/readme.md
+/redirects/master/spec/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/README.md
+/redirects/master/spec/ivy-proofs/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/ivy-proofs/README.md
+/redirects/master/spec/consensus/proposer-selection.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/proposer-selection.md
+/redirects/master/spec/consensus/creating-proposal.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/creating-proposal.md
+/redirects/master/spec/consensus/proposer-based-timestamp/pbts-sysmodel_001_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/proposer-based-timestamp/pbts-sysmodel_001_draft.md
+/redirects/master/spec/consensus/proposer-based-timestamp/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/proposer-based-timestamp/README.md
+/redirects/master/spec/consensus/proposer-based-timestamp/pbts-algorithm_001_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/proposer-based-timestamp/pbts-algorithm_001_draft.md
+/redirects/master/spec/consensus/proposer-based-timestamp/pbts_001_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/proposer-based-timestamp/pbts_001_draft.md
+/redirects/master/spec/consensus/light-client/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client/README.md
+/redirects/master/spec/consensus/light-client/accountability.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client/accountability.md
+/redirects/master/spec/consensus/light-client/detection.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client/detection.md
+/redirects/master/spec/consensus/light-client/verification.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client/verification.md
+/redirects/master/spec/consensus/consensus-paper/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/consensus-paper/README.md
+/redirects/master/spec/consensus/signing.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/signing.md
+/redirects/master/spec/consensus/consensus.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/consensus.md
+/redirects/master/spec/consensus/evidence.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/evidence.md
+/redirects/master/spec/consensus/bft-time.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/bft-time.md
+/redirects/master/spec/consensus/wal.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/wal.md
+/redirects/master/spec/consensus/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/readme.md
+/redirects/master/spec/light-client/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/README.md
+/redirects/master/spec/light-client/detection/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/README.md
+/redirects/master/spec/light-client/detection/req-ibc-detection.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/req-ibc-detection.md
+/redirects/master/spec/light-client/detection/detection_001_reviewed.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/detection_001_reviewed.md
+/redirects/master/spec/light-client/detection/draft-functions.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/draft-functions.md
+/redirects/master/spec/light-client/detection/discussions.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/discussions.md
+/redirects/master/spec/light-client/detection/detection_003_reviewed.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/detection/detection_003_reviewed.md
+/redirects/master/spec/light-client/accountability/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/accountability/README.md
+/redirects/master/spec/light-client/accountability/results/001indinv-apalache-report.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/accountability/results/001indinv-apalache-report.md
+/redirects/master/spec/light-client/accountability/Synopsis.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/accountability/Synopsis.md
+/redirects/master/spec/light-client/verification/verification_003_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/verification/verification_003_draft.md
+/redirects/master/spec/light-client/verification/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/verification/README.md
+/redirects/master/spec/light-client/verification/verification_001_published.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/verification/verification_001_published.md
+/redirects/master/spec/light-client/verification/verification_002_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/verification/verification_002_draft.md
+/redirects/master/spec/light-client/supervisor/supervisor_002_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/supervisor/supervisor_002_draft.md
+/redirects/master/spec/light-client/supervisor/supervisor_001_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/supervisor/supervisor_001_draft.md
+/redirects/master/spec/light-client/attacks/isolate-attackers_001_draft.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/attacks/isolate-attackers_001_draft.md
+/redirects/master/spec/light-client/attacks/notes-on-evidence-handling.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/attacks/notes-on-evidence-handling.md
+/redirects/master/spec/light-client/attacks/isolate-attackers_002_reviewed.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/light-client/attacks/isolate-attackers_002_reviewed.md
+/redirects/master/spec/abci/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/README.md
+/redirects/master/spec/abci/client-server.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/client-server.md
+/redirects/master/spec/abci/apps.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md
+/redirects/master/spec/abci/abci.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/abci.md
+/redirects/master/spec/rpc/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/rpc/README.md
+/redirects/master/spec/blockchain/state.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/state.md
+/redirects/master/spec/blockchain/encoding.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/encoding.md
+/redirects/master/spec/blockchain/blockchain.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/blockchain.md
+/redirects/master/spec/blockchain/index.html https://github.com/tendermint/tendermint/blob/v0.34.x/spec/blockchain/readme.md
+/redirects/master/tutorials/go.html /v0.34/tutorials/go.html
diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md
index 04883e462a..a195b287f3 100644
--- a/docs/DOCS_README.md
+++ b/docs/DOCS_README.md
@@ -2,39 +2,38 @@
The documentation for Tendermint Core is hosted at:
--
+-
-built from the files in this (`/docs`) directory for
-[master](https://github.com/tendermint/tendermint/tree/master/docs) respectively.
+built from the files in this (`/docs`) directory.
## How It Works
-There is a CircleCI job listening for changes in the `/docs` directory, on both
-the `master` branch. Any updates to files in this directory
-on those branches will automatically trigger a website deployment. Under the hood,
-the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo.
+There is a [GitHub Action](../.github/workflows/docs-deployment.yml) that is
+triggered by changes in the `/docs` directory on `main` as well as the branch of
+each major supported version (e.g. `v0.34.x`). Any updates to files in this
+directory on those branches will automatically trigger a website deployment.
## README
-The [README.md](./README.md) is also the landing page for the documentation
-on the website. During the Jenkins build, the current commit is added to the bottom
-of the README.
+The [README.md](./README.md) is also the landing page for the documentation on
+the website.
## Config.js
-The [config.js](./.vuepress/config.js) generates the sidebar and Table of Contents
-on the website docs. Note the use of relative links and the omission of
-file extensions. Additional features are available to improve the look
-of the sidebar.
+The [config.js](./.vuepress/config.js) generates the sidebar and Table of
+Contents on the website docs. Note the use of relative links and the omission of
+file extensions. Additional features are available to improve the look of the
+sidebar.
## Links
-**NOTE:** Strongly consider the existing links - both within this directory
-and to the website docs - when moving or deleting files.
+**NOTE:** Strongly consider the existing links - both within this directory and
+to the website docs - when moving or deleting files.
Links to directories _MUST_ end in a `/`.
-Relative links should be used nearly everywhere, having discovered and weighed the following:
+Relative links should be used nearly everywhere, having discovered and weighed
+the following:
### Relative
@@ -65,7 +64,8 @@ Make sure you are in the `docs` directory and run the following commands:
rm -rf node_modules
```
-This command will remove old version of the visual theme and required packages. This step is optional.
+This command will remove old version of the visual theme and required packages.
+This step is optional.
```bash
npm install
@@ -79,17 +79,24 @@ npm run serve
-Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often ).
+Run `pre` and `post` hooks and start a hot-reloading web-server. See output of
+this command for the URL (it is often ).
-To build documentation as a static website run `npm run build`. You will find the website in `.vuepress/dist` directory.
+To build documentation as a static website run `npm run build`. You will find
+the website in `.vuepress/dist` directory.
## Search
-We are using [Algolia](https://www.algolia.com) to power full-text search. This uses a public API search-only key in the `config.js` as well as a [tendermint.json](https://github.com/algolia/docsearch-configs/blob/master/configs/tendermint.json) configuration file that we can update with PRs.
+We are using [Algolia](https://www.algolia.com) to power full-text search. This
+uses a public API search-only key in the `config.js` as well as a
+[tendermint.json](https://github.com/algolia/docsearch-configs/blob/master/configs/tendermint.json)
+configuration file that we can update with PRs.
## Consistency
-Because the build processes are identical (as is the information contained herein), this file should be kept in sync as
-much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md).
+Because the build processes are identical (as is the information contained
+herein), this file should be kept in sync as much as possible with its
+[counterpart in the Cosmos SDK
+repo](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md).
diff --git a/docs/README.md b/docs/README.md
index 7cd5f68d4c..5041766a09 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -14,20 +14,29 @@ of a web-server, database, and supporting libraries for blockchain applications
written in any programming language. Like a web-server serving web applications,
Tendermint serves blockchain applications.
-More formally, Tendermint Core performs Byzantine Fault Tolerant (BFT)
-State Machine Replication (SMR) for arbitrary deterministic, finite state machines.
+More formally, Tendermint Core performs Byzantine Fault Tolerant (BFT) State
+Machine Replication (SMR) for arbitrary deterministic, finite state machines.
For more background, see [What is
Tendermint?](introduction/what-is-tendermint.md).
-To get started quickly with an example application, see the [quick start guide](introduction/quick-start.md).
+To get started quickly with an example application, see the [quick start
+guide](introduction/quick-start.md).
-To learn about application development on Tendermint, see the [Application Blockchain Interface](https://github.com/tendermint/spec/tree/master/spec/abci).
+To learn about application development on Tendermint, see the [Application
+Blockchain
+Interface](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/abci).
For more details on using Tendermint, see the respective documentation for
-[Tendermint Core](tendermint-core/), [benchmarking and monitoring](tools/), and [network deployments](networks/).
+[Tendermint Core](tendermint-core/), [benchmarking and monitoring](tools/), and
+[network deployments](networks/).
-To find out about the Tendermint ecosystem you can go [here](https://github.com/tendermint/awesome#ecosystem). If you are a project that is using Tendermint you are welcome to make a PR to add your project to the list.
+To find out about the Tendermint ecosystem you can go
+[here](https://github.com/tendermint/awesome#ecosystem). If you are a project
+that is using Tendermint you are welcome to make a PR to add your project to the
+list.
## Contribute
-To contribute to the documentation, see [this file](https://github.com/tendermint/tendermint/blob/master/docs/DOCS_README.md) for details of the build process and considerations when making changes.
+To contribute to the documentation, see [this
+file](https://github.com/tendermint/tendermint/blob/main/docs/DOCS_README.md)
+for details of the build process and considerations when making changes.
diff --git a/docs/app-dev/abci-cli.md b/docs/app-dev/abci-cli.md
index 1645c4f8ca..98a1005c99 100644
--- a/docs/app-dev/abci-cli.md
+++ b/docs/app-dev/abci-cli.md
@@ -138,7 +138,7 @@ response.
The server may be generic for a particular language, and we provide a
[reference implementation in
-Golang](https://github.com/tendermint/tendermint/tree/master/abci/server). See the
+Golang](https://github.com/tendermint/tendermint/tree/v0.34.x/abci/server). See the
[list of other ABCI implementations](https://github.com/tendermint/awesome#ecosystem) for servers in
other languages.
@@ -325,7 +325,7 @@ But the ultimate flexibility comes from being able to write the
application easily in any language.
We have implemented the counter in a number of languages [see the
-example directory](https://github.com/tendermint/tendermint/tree/master/abci/example).
+example directory](https://github.com/tendermint/tendermint/tree/v0.34.x/abci/example).
To run the Node.js version, fist download & install [the Javascript ABCI server](https://github.com/tendermint/js-abci):
diff --git a/docs/app-dev/app-architecture.md b/docs/app-dev/app-architecture.md
index ec2822688c..761a9d85a1 100644
--- a/docs/app-dev/app-architecture.md
+++ b/docs/app-dev/app-architecture.md
@@ -55,6 +55,6 @@ Tendermint.
See the following for more extensive documentation:
- [Interchain Standard for the Light-Client REST API](https://github.com/cosmos/cosmos-sdk/pull/1028)
-- [Tendermint RPC Docs](https://docs.tendermint.com/master/rpc/)
+- [Tendermint RPC Docs](https://docs.tendermint.com/v0.34/rpc/)
- [Tendermint in Production](../tendermint-core/running-in-production.md)
- [ABCI spec](https://github.com/tendermint/spec/tree/95cf253b6df623066ff7cd4074a94e7a3f147c7a/spec/abci)
diff --git a/docs/app-dev/indexing-transactions.md b/docs/app-dev/indexing-transactions.md
index 0019df311b..33925ec7b6 100644
--- a/docs/app-dev/indexing-transactions.md
+++ b/docs/app-dev/indexing-transactions.md
@@ -15,7 +15,7 @@ the block itself is never stored.
Each event contains a type and a list of attributes, which are key-value pairs
denoting something about what happened during the method's execution. For more
details on `Events`, see the
-[ABCI](https://github.com/tendermint/spec/blob/master/spec/abci/abci.md#events)
+[ABCI](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/abci.md#events)
documentation.
An `Event` has a composite key associated with it. A `compositeKey` is
@@ -146,7 +146,7 @@ You can query for a paginated set of transaction by their events by calling the
curl "localhost:26657/tx_search?query=\"message.sender='cosmos1...'\"&prove=true"
```
-Check out [API docs](https://docs.tendermint.com/master/rpc/#/Info/tx_search)
+Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#/Info/tx_search)
for more information on query syntax and other options.
## Subscribing to Transactions
@@ -165,7 +165,7 @@ a query to `/subscribe` RPC endpoint.
}
```
-Check out [API docs](https://docs.tendermint.com/master/rpc/#subscribe) for more information
+Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#subscribe) for more information
on query syntax and other options.
## Querying Blocks Events
@@ -177,5 +177,5 @@ You can query for a paginated set of blocks by their events by calling the
curl "localhost:26657/block_search?query=\"block.height > 10 AND val_set.num_changed > 0\""
```
-Check out [API docs](https://docs.tendermint.com/master/rpc/#/Info/block_search)
+Check out [API docs](https://docs.tendermint.com/v0.34/rpc/#/Info/block_search)
for more information on query syntax and other options.
diff --git a/docs/introduction/what-is-tendermint.md b/docs/introduction/what-is-tendermint.md
index 9cff48a2a4..0fe02af193 100644
--- a/docs/introduction/what-is-tendermint.md
+++ b/docs/introduction/what-is-tendermint.md
@@ -120,7 +120,7 @@ consensus engine, and provides a particular application state.
## ABCI Overview
The [Application BlockChain Interface
-(ABCI)](https://github.com/tendermint/tendermint/tree/master/abci)
+(ABCI)](https://github.com/tendermint/tendermint/tree/v0.34.x/abci)
allows for Byzantine Fault Tolerant replication of applications
written in any programming language.
@@ -180,15 +180,15 @@ The application will be responsible for
- Allowing clients to query the UTXO database.
Tendermint is able to decompose the blockchain design by offering a very
-simple API (ie. the ABCI) between the application process and consensus
+simple API (i.e. the ABCI) between the application process and consensus
process.
The ABCI consists of 3 primary message types that get delivered from the
core to the application. The application replies with corresponding
response messages.
-The messages are specified here: [ABCI Message
-Types](https://github.com/tendermint/tendermint/blob/master/abci/README.md#message-types).
+The messages are specified in the [ABCI
+specification](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/abci.md).
The **DeliverTx** message is the work horse of the application. Each
transaction in the blockchain is delivered with this message. The
diff --git a/docs/networks/terraform-and-ansible.md b/docs/networks/terraform-and-ansible.md
index b11df37109..788945b680 100644
--- a/docs/networks/terraform-and-ansible.md
+++ b/docs/networks/terraform-and-ansible.md
@@ -14,7 +14,7 @@ testnets on those servers.
## Install
NOTE: see the [integration bash
-script](https://github.com/tendermint/tendermint/blob/master/networks/remote/integration.sh)
+script](https://github.com/tendermint/tendermint/blob/v0.34.x/networks/remote/integration.sh)
that can be run on a fresh DO droplet and will automatically spin up a 4
node testnet. The script more or less does everything described below.
@@ -58,7 +58,7 @@ With the droplets created and running, let's setup Ansible.
## Ansible
The playbooks in [the ansible
-directory](https://github.com/tendermint/tendermint/tree/master/networks/remote/ansible)
+directory](https://github.com/tendermint/tendermint/tree/v0.34.x/networks/remote/ansible)
run ansible roles to configure the sentry node architecture. You must
switch to this directory to run ansible
(`cd $GOPATH/src/github.com/tendermint/tendermint/networks/remote/ansible`).
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 8bbdae8cc6..37dfc40e70 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -8876,9 +8876,9 @@
}
},
"node_modules/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/mississippi": {
"version": "3.0.0",
@@ -13045,9 +13045,9 @@
}
},
"node_modules/url-parse": {
- "version": "1.5.7",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
- "integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dependencies": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@@ -21113,9 +21113,9 @@
}
},
"minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"mississippi": {
"version": "3.0.0",
@@ -24536,9 +24536,9 @@
}
},
"url-parse": {
- "version": "1.5.7",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
- "integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
diff --git a/docs/qa/README.md b/docs/qa/README.md
new file mode 100644
index 0000000000..cd1fba9a8d
--- /dev/null
+++ b/docs/qa/README.md
@@ -0,0 +1,22 @@
+---
+order: 1
+parent:
+ title: Tendermint Quality Assurance
+ description: This is a report on the process followed and results obtained when running v0.34.x on testnets
+ order: 2
+---
+
+# Tendermint Quality Assurance
+
+This directory keeps track of the process followed by the Tendermint Core team
+for Quality Assurance before cutting a release.
+This directory is to live in multiple branches. On each release branch,
+the contents of this directory reflect the status of the process
+at the time the Quality Assurance process was applied for that release.
+
+File [method](./method.md) keeps track of the process followed to obtain the results
+used to decide if a release is passing the Quality Assurance process.
+The results obtained in each release are stored in their own directory.
+The following releases have undergone the Quality Assurance process:
+
+* [v0.34.x](./v034/), which was tested just before releasing v0.34.22
diff --git a/docs/qa/method.md b/docs/qa/method.md
new file mode 100644
index 0000000000..cc4f82dfa4
--- /dev/null
+++ b/docs/qa/method.md
@@ -0,0 +1,214 @@
+---
+order: 1
+title: Method
+---
+
+# Method
+
+This document provides a detailed description of the QA process.
+It is intended to be used by engineers reproducing the experimental setup for future tests of Tendermint.
+
+The (first iteration of the) QA process as described [in the RELEASES.md document][releases]
+was applied to version v0.34.x in order to have a set of results acting as benchmarking baseline.
+This baseline is then compared with results obtained in later versions.
+
+Out of the testnet-based test cases described in [the releases document][releases] we focused on two of them:
+_200 Node Test_, and _Rotating Nodes Test_.
+
+[releases]: https://github.com/tendermint/tendermint/blob/v0.37.x/RELEASES.md#large-scale-testnets
+
+## Software Dependencies
+
+### Infrastructure Requirements to Run the Tests
+
+* An account at Digital Ocean (DO), with a high droplet limit (>202)
+* The machine to orchestrate the tests should have the following installed:
+ * A clone of the [testnet repository][testnet-repo]
+ * This repository contains all the scripts mentioned in the reminder of this section
+ * [Digital Ocean CLI][doctl]
+ * [Terraform CLI][Terraform]
+ * [Ansible CLI][Ansible]
+
+[testnet-repo]: https://github.com/interchainio/tendermint-testnet
+[Ansible]: https://docs.ansible.com/ansible/latest/index.html
+[Terraform]: https://www.terraform.io/docs
+[doctl]: https://docs.digitalocean.com/reference/doctl/how-to/install/
+
+### Requirements for Result Extraction
+
+* Matlab or Octave
+* [Prometheus][prometheus] server installed
+* blockstore DB of one of the full nodes in the testnet
+* Prometheus DB
+
+[prometheus]: https://prometheus.io/
+
+## 200 Node Testnet
+
+### Running the test
+
+This section explains how the tests were carried out for reproducibility purposes.
+
+1. [If you haven't done it before]
+ Follow steps 1-4 of the `README.md` at the top of the testnet repository to configure Terraform, and `doctl`.
+2. Copy file `testnets/testnet200.toml` onto `testnet.toml` (do NOT commit this change)
+3. Set the variable `VERSION_TAG` in the `Makefile` to the git hash that is to be tested.
+4. Follow steps 5-10 of the `README.md` to configure and start the 200 node testnet
+ * WARNING: Do NOT forget to run `make terraform-destroy` as soon as you are done with the tests (see step 9)
+5. As a sanity check, connect to the Prometheus node's web interface and check the graph for the `tendermint_consensus_height` metric.
+ All nodes should be increasing their heights.
+6. `ssh` into the `testnet-load-runner`, then copy script `script/200-node-loadscript.sh` and run it from the load runner node.
+ * Before running it, you need to edit the script to provide the IP address of a full node.
+ This node will receive all transactions from the load runner node.
+ * This script will take about 40 mins to run
+ * It is running 90-seconds-long experiments in a loop with different loads
+7. Run `make retrieve-data` to gather all relevant data from the testnet into the orchestrating machine
+8. Verify that the data was collected without errors
+ * at least one blockstore DB for a Tendermint validator
+ * the Prometheus database from the Prometheus node
+ * for extra care, you can run `zip -T` on the `prometheus.zip` file and (one of) the `blockstore.db.zip` file(s)
+9. **Run `make terraform-destroy`**
+ * Don't forget to type `yes`! Otherwise you're in trouble.
+
+### Result Extraction
+
+The method for extracting the results described here is highly manual (and exploratory) at this stage.
+The Core team should improve it at every iteration to increase the amount of automation.
+
+#### Steps
+
+1. Unzip the blockstore into a directory
+2. Extract the latency report and the raw latencies for all the experiments. Run these commands from the directory containing the blockstore
+ * `go run github.com/tendermint/tendermint/test/loadtime/cmd/report@3ec6e424d --database-type goleveldb --data-dir ./ > results/report.txt`
+ * `go run github.com/tendermint/tendermint/test/loadtime/cmd/report@3ec6e424d --database-type goleveldb --data-dir ./ --csv results/raw.csv`
+3. File `report.txt` contains an unordered list of experiments with varying concurrent connections and transaction rate
+ * Create files `report01.txt`, `report02.txt`, `report04.txt` and, for each experiment in file `report.txt`,
+ copy its related lines to the filename that matches the number of connections.
+ * Sort the experiments in `report01.txt` in ascending tx rate order. Likewise for `report02.txt` and `report04.txt`.
+4. Generate file `report_tabbed.txt` by showing the contents `report01.txt`, `report02.txt`, `report04.txt` side by side
+ * This effectively creates a table where rows are a particular tx rate and columns are a particular number of websocket connections.
+5. Extract the raw latencies from file `raw.csv` using the following bash loop. This creates a `.csv` file and a `.dat` file per experiment.
+ The format of the `.dat` files is amenable to loading them as matrices in Octave
+
+ ```bash
+ uuids=($(cat report01.txt report02.txt report04.txt | grep '^Experiment ID: ' | awk '{ print $3 }'))
+ c=1
+ for i in 01 02 04; do
+ for j in 0025 0050 0100 0200; do
+ echo $i $j $c "${uuids[$c]}"
+ filename=c${i}_r${j}
+ grep ${uuids[$c]} raw.csv > ${filename}.csv
+ cat ${filename}.csv | tr , ' ' | awk '{ print $2, $3 }' > ${filename}.dat
+ c=$(expr $c + 1)
+ done
+ done
+ ```
+
+6. Enter Octave
+7. Load all `.dat` files generated in step 5 into matrices using this Octave code snippet
+
+ ```octave
+ conns = { "01"; "02"; "04" };
+ rates = { "0025"; "0050"; "0100"; "0200" };
+ for i = 1:length(conns)
+ for j = 1:length(rates)
+ filename = strcat("c", conns{i}, "_r", rates{j}, ".dat");
+ load("-ascii", filename);
+ endfor
+ endfor
+ ```
+
+8. Set variable release to the current release undergoing QA
+
+ ```octave
+ release = "v0.34.x";
+ ```
+
+9. Generate a plot with all (or some) experiments, where the X axis is the experiment time,
+ and the y axis is the latency of transactions.
+ The following snippet plots all experiments.
+
+ ```octave
+ legends = {};
+ hold off;
+ for i = 1:length(conns)
+ for j = 1:length(rates)
+ data_name = strcat("c", conns{i}, "_r", rates{j});
+ l = strcat("c=", conns{i}, " r=", rates{j});
+ m = eval(data_name); plot((m(:,1) - min(m(:,1))) / 1e+9, m(:,2) / 1e+9, ".");
+ hold on;
+ legends(1, end+1) = l;
+ endfor
+ endfor
+ legend(legends, "location", "northeastoutside");
+ xlabel("experiment time (s)");
+ ylabel("latency (s)");
+ t = sprintf("200-node testnet - %s", release);
+ title(t);
+ ```
+
+10. Consider adjusting the axis, in case you want to compare your results to the baseline, for instance
+
+ ```octave
+ axis([0, 100, 0, 30], "tic");
+ ```
+
+11. Use Octave's GUI menu to save the plot (e.g. as `.png`)
+
+12. Repeat steps 9 and 10 to obtain as many plots as deemed necessary.
+
+13. To generate a latency vs throughput plot, using the raw CSV file generated
+ in step 2, follow the instructions for the [`latency_throughput.py`] script.
+
+[`latency_throughput.py`]: ../../scripts/qa/reporting/README.md
+
+#### Extracting Prometheus Metrics
+
+1. Stop the prometheus server if it is running as a service (e.g. a `systemd` unit).
+2. Unzip the prometheus database retrieved from the testnet, and move it to replace the
+ local prometheus database.
+3. Start the prometheus server and make sure no error logs appear at start up.
+4. Introduce the metrics you want to gather or plot.
+
+## Rotating Node Testnet
+
+### Running the test
+
+This section explains how the tests were carried out for reproducibility purposes.
+
+1. [If you haven't done it before]
+ Follow steps 1-4 of the `README.md` at the top of the testnet repository to configure Terraform, and `doctl`.
+2. Copy file `testnet_rotating.toml` onto `testnet.toml` (do NOT commit this change)
+3. Set variable `VERSION_TAG` to the git hash that is to be tested.
+4. Run `make terraform-apply EPHEMERAL_SIZE=25`
+ * WARNING: Do NOT forget to run `make terraform-destroy` as soon as you are done with the tests
+5. Follow steps 6-10 of the `README.md` to configure and start the "stable" part of the rotating node testnet
+6. As a sanity check, connect to the Prometheus node's web interface and check the graph for the `tendermint_consensus_height` metric.
+ All nodes should be increasing their heights.
+7. On a different shell,
+ * run `make runload ROTATE_CONNECTIONS=X ROTATE_TX_RATE=Y`
+ * `X` and `Y` should reflect a load below the saturation point (see, e.g.,
+ [this paragraph](./v034/README.md#finding-the-saturation-point) for further info)
+8. Run `make rotate` to start the script that creates the ephemeral nodes, and kills them when they are caught up.
+ * WARNING: If you run this command from your laptop, the laptop needs to be up and connected for full length
+ of the experiment.
+9. When the height of the chain reaches 3000, stop the `make rotate` script
+10. When the rotate script has made two iterations (i.e., all ephemeral nodes have caught up twice)
+ after height 3000 was reached, stop `make rotate`
+11. Run `make retrieve-data` to gather all relevant data from the testnet into the orchestrating machine
+12. Verify that the data was collected without errors
+ * at least one blockstore DB for a Tendermint validator
+ * the Prometheus database from the Prometheus node
+ * for extra care, you can run `zip -T` on the `prometheus.zip` file and (one of) the `blockstore.db.zip` file(s)
+13. **Run `make terraform-destroy`**
+
+Steps 8 to 10 are highly manual at the moment and will be improved in next iterations.
+
+### Result Extraction
+
+In order to obtain a latency plot, follow the instructions above for the 200 node experiment, but:
+
+* The `results.txt` file contains only one experiment
+* Therefore, no need for any `for` loops
+
+As for prometheus, the same method as for the 200 node experiment can be applied.
diff --git a/docs/qa/v034/README.md b/docs/qa/v034/README.md
new file mode 100644
index 0000000000..b07b102912
--- /dev/null
+++ b/docs/qa/v034/README.md
@@ -0,0 +1,278 @@
+---
+order: 1
+parent:
+ title: Tendermint Quality Assurance Results for v0.34.x
+ description: This is a report on the results obtained when running v0.34.x on testnets
+ order: 2
+---
+
+# v0.34.x
+
+## 200 Node Testnet
+
+### Finding the Saturation Point
+
+The first goal when examining the results of the tests is identifying the saturation point.
+The saturation point is a setup with a transaction load big enough to prevent the testnet
+from being stable: the load runner tries to produce slightly more transactions than can
+be processed by the testnet.
+
+The following table summarizes the results for v0.34.x, for the different experiments
+(extracted from file [`v034_report_tabbed.txt`](./img/v034_report_tabbed.txt)).
+
+The X axis of this table is `c`, the number of connections created by the load runner process to the target node.
+The Y axis of this table is `r`, the rate or number of transactions issued per second.
+
+| | c=1 | c=2 | c=4 |
+| :--- | ----: | ----: | ----: |
+| r=25 | 2225 | 4450 | 8900 |
+| r=50 | 4450 | 8900 | 17800 |
+| r=100 | 8900 | 17800 | 35600 |
+| r=200 | 17800 | 35600 | 38660 |
+
+The table shows the number of 1024-byte-long transactions that were produced by the load runner,
+and processed by Tendermint, during the 90 seconds of the experiment's duration.
+Each cell in the table refers to an experiment with a particular number of websocket connections (`c`)
+to a chosen validator, and the number of transactions per second that the load runner
+tries to produce (`r`). Note that the overall load that the tool attempts to generate is $c \cdot r$.
+
+We can see that the saturation point is beyond the diagonal that spans cells
+
+* `r=200,c=2`
+* `r=100,c=4`
+
+given that the total transactions should be close to the product of the rate, the number of connections,
+and the experiment time (89 seconds, since the last batch never gets sent).
+
+All experiments below the saturation diagonal (`r=200,c=4`) have in common that the total
+number of transactions processed is noticeably less than the product $c \cdot r \cdot 89$,
+which is the expected number of transactions when the system is able to deal well with the
+load.
+With `r=200,c=4`, we obtained 38660 whereas the theoretical number of transactions should
+have been $200 \cdot 4 \cdot 89 = 71200$.
+
+At this point, we chose an experiment at the limit of the saturation diagonal,
+in order to further study the performance of this release.
+**The chosen experiment is `r=200,c=2`**.
+
+This is a plot of the CPU load (average over 1 minute, as output by `top`) of the load runner for `r=200,c=2`,
+where we can see that the load stays close to 0 most of the time.
+
+![load-load-runner](./img/v034_r200c2_load-runner.png)
+
+### Examining latencies
+
+The method described [here](../method.md) allows us to plot the latencies of transactions
+for all experiments.
+
+![all-latencies](./img/v034_200node_latencies.png)
+
+As we can see, even the experiments beyond the saturation diagonal managed to keep
+transaction latency stable (i.e. not constantly increasing).
+Our interpretation for this is that contention within Tendermint was propagated,
+via the websockets, to the load runner,
+hence the load runner could not produce the target load, but a fraction of it.
+
+Further examination of the Prometheus data (see below), showed that the mempool contained many transactions
+at steady state, but did not grow much without quickly returning to this steady state. This demonstrates
+that the transactions were able to be processed by the Tendermint network at least as quickly as they
+were submitted to the mempool. Finally, the test script made sure that, at the end of an experiment, the
+mempool was empty so that all transactions submitted to the chain were processed.
+
+Finally, the number of points present in the plot appears to be much less than expected given the
+number of transactions in each experiment, particularly close to or above the saturation diagonal.
+This is a visual effect of the plot; what appear to be points in the plot are actually potentially huge
+clusters of points. To corroborate this, we have zoomed in the plot above by setting (carefully chosen)
+tiny axis intervals. The cluster shown below looks like a single point in the plot above.
+
+![all-latencies-zoomed](./img/v034_200node_latencies_zoomed.png)
+
+The plot of latencies can we used as a baseline to compare with other releases.
+
+The following plot summarizes average latencies versus overall throughputs
+across different numbers of WebSocket connections to the node into which
+transactions are being loaded.
+
+![latency-vs-throughput](./img/v034_latency_throughput.png)
+
+### Prometheus Metrics on the Chosen Experiment
+
+As mentioned [above](#finding-the-saturation-point), the chosen experiment is `r=200,c=2`.
+This section further examines key metrics for this experiment extracted from Prometheus data.
+
+#### Mempool Size
+
+The mempool size, a count of the number of transactions in the mempool, was shown to be stable and homogeneous
+at all full nodes. It did not exhibit any unconstrained growth.
+The plot below shows the evolution over time of the cumulative number of transactions inside all full nodes' mempools
+at a given time.
+The two spikes that can be observed correspond to a period where consensus instances proceeded beyond the initial round
+at some nodes.
+
+![mempool-cumulative](./img/v034_r200c2_mempool_size.png)
+
+The plot below shows evolution of the average over all full nodes, which oscillates between 1500 and 2000
+outstanding transactions.
+
+![mempool-avg](./img/v034_r200c2_mempool_size_avg.png)
+
+The peaks observed coincide with the moments when some nodes proceeded beyond the initial round of consensus (see below).
+
+#### Peers
+
+The number of peers was stable at all nodes.
+It was higher for the seed nodes (around 140) than for the rest (between 21 and 74).
+The fact that non-seed nodes reach more than 50 peers is due to #9548.
+
+![peers](./img/v034_r200c2_peers.png)
+
+#### Consensus Rounds per Height
+
+Most heights took just one round, but some nodes needed to advance to round 1 at some point.
+
+![rounds](./img/v034_r200c2_rounds.png)
+
+#### Blocks Produced per Minute, Transactions Processed per Minute
+
+The blocks produced per minute are the slope of this plot.
+
+![heights](./img/v034_r200c2_heights.png)
+
+Over a period of 2 minutes, the height goes from 530 to 569.
+This results in an average of 19.5 blocks produced per minute.
+
+The transactions processed per minute are the slope of this plot.
+
+![total-txs](./img/v034_r200c2_total-txs.png)
+
+Over a period of 2 minutes, the total goes from 64525 to 100125 transactions,
+resulting in 17800 transactions per minute. However, we can see in the plot that
+all transactions in the load are processed long before the two minutes.
+If we adjust the time window when transactions are processed (approx. 105 seconds),
+we obtain 20343 transactions per minute.
+
+#### Memory Resident Set Size
+
+Resident Set Size of all monitored processes is plotted below.
+
+![rss](./img/v034_r200c2_rss.png)
+
+The average over all processes oscillates around 1.2 GiB and does not demonstrate unconstrained growth.
+
+![rss-avg](./img/v034_r200c2_rss_avg.png)
+
+#### CPU utilization
+
+The best metric from Prometheus to gauge CPU utilization in a Unix machine is `load1`,
+as it usually appears in the
+[output of `top`](https://www.digitalocean.com/community/tutorials/load-average-in-linux).
+
+![load1](./img/v034_r200c2_load1.png)
+
+It is contained in most cases below 5, which is generally considered acceptable load.
+
+### Test Result
+
+**Result: N/A** (v0.34.x is the baseline)
+
+Date: 2022-10-14
+
+Version: 3ec6e424d6ae4c96867c2dcf8310572156068bb6
+
+## Rotating Node Testnet
+
+For this testnet, we will use a load that can safely be considered below the saturation
+point for the size of this testnet (between 13 and 38 full nodes): `c=4,r=800`.
+
+N.B.: The version of Tendermint used for these tests is affected by #9539.
+However, the reduced load that reaches the mempools is orthogonal to functionality
+we are focusing on here.
+
+### Latencies
+
+The plot of all latencies can be seen in the following plot.
+
+![rotating-all-latencies](./img/v034_rotating_latencies.png)
+
+We can observe there are some very high latencies, towards the end of the test.
+Upon suspicion that they are duplicate transactions, we examined the latencies
+raw file and discovered there are more than 100K duplicate transactions.
+
+The following plot shows the latencies file where all duplicate transactions have
+been removed, i.e., only the first occurrence of a duplicate transaction is kept.
+
+![rotating-all-latencies-uniq](./img/v034_rotating_latencies_uniq.png)
+
+This problem, existing in `v0.34.x`, will need to be addressed, perhaps in the same way
+we addressed it when running the 200 node test with high loads: increasing the `cache_size`
+configuration parameter.
+
+### Prometheus Metrics
+
+The set of metrics shown here are less than for the 200 node experiment.
+We are only interested in those for which the catch-up process (blocksync) may have an impact.
+
+#### Blocks and Transactions per minute
+
+Just as shown for the 200 node test, the blocks produced per minute are the gradient of this plot.
+
+![rotating-heights](./img/v034_rotating_heights.png)
+
+Over a period of 5229 seconds, the height goes from 2 to 3638.
+This results in an average of 41 blocks produced per minute.
+
+The following plot shows only the heights reported by ephemeral nodes
+(which are also included in the plot above). Note that the _height_ metric
+is only showed _once the node has switched to consensus_, hence the gaps
+when nodes are killed, wiped out, started from scratch, and catching up.
+
+![rotating-heights-ephe](./img/v034_rotating_heights_ephe.png)
+
+The transactions processed per minute are the gradient of this plot.
+
+![rotating-total-txs](./img/v034_rotating_total-txs.png)
+
+The small lines we see periodically close to `y=0` are the transactions that
+ephemeral nodes start processing when they are caught up.
+
+Over a period of 5229 minutes, the total goes from 0 to 387697 transactions,
+resulting in 4449 transactions per minute. We can see some abrupt changes in
+the plot's gradient. This will need to be investigated.
+
+#### Peers
+
+The plot below shows the evolution in peers throughout the experiment.
+The periodic changes observed are due to the ephemeral nodes being stopped,
+wiped out, and recreated.
+
+![rotating-peers](./img/v034_rotating_peers.png)
+
+The validators' plots are concentrated at the higher part of the graph, whereas the ephemeral nodes
+are mostly at the lower part.
+
+#### Memory Resident Set Size
+
+The average Resident Set Size (RSS) over all processes seems stable, and slightly growing toward the end.
+This might be related to the increased in transaction load observed above.
+
+![rotating-rss-avg](./img/v034_rotating_rss_avg.png)
+
+The memory taken by the validators and the ephemeral nodes (when they are up) is comparable.
+
+#### CPU utilization
+
+The plot shows metric `load1` for all nodes.
+
+![rotating-load1](./img/v034_rotating_load1.png)
+
+It is contained under 5 most of the time, which is considered normal load.
+The purple line, which follows a different pattern is the validator receiving all
+transactions, via RPC, from the load runner process.
+
+### Test Result
+
+**Result: N/A**
+
+Date: 2022-10-10
+
+Version: a28c987f5a604ff66b515dd415270063e6fb069d
diff --git a/docs/qa/v034/img/v034_200node_latencies.png b/docs/qa/v034/img/v034_200node_latencies.png
new file mode 100644
index 0000000000..afd1060caf
Binary files /dev/null and b/docs/qa/v034/img/v034_200node_latencies.png differ
diff --git a/docs/qa/v034/img/v034_200node_latencies_zoomed.png b/docs/qa/v034/img/v034_200node_latencies_zoomed.png
new file mode 100644
index 0000000000..1ff9364422
Binary files /dev/null and b/docs/qa/v034/img/v034_200node_latencies_zoomed.png differ
diff --git a/docs/qa/v034/img/v034_latency_throughput.png b/docs/qa/v034/img/v034_latency_throughput.png
new file mode 100644
index 0000000000..3674fe47b4
Binary files /dev/null and b/docs/qa/v034/img/v034_latency_throughput.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_heights.png b/docs/qa/v034/img/v034_r200c2_heights.png
new file mode 100644
index 0000000000..11f3bba432
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_heights.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_load-runner.png b/docs/qa/v034/img/v034_r200c2_load-runner.png
new file mode 100644
index 0000000000..70211b0d21
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_load-runner.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_load1.png b/docs/qa/v034/img/v034_r200c2_load1.png
new file mode 100644
index 0000000000..11012844dc
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_load1.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_mempool_size.png b/docs/qa/v034/img/v034_r200c2_mempool_size.png
new file mode 100644
index 0000000000..c5d690200a
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_mempool_size.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png b/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png
new file mode 100644
index 0000000000..bda399fe5d
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_peers.png b/docs/qa/v034/img/v034_r200c2_peers.png
new file mode 100644
index 0000000000..a0aea7ada3
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_peers.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_rounds.png b/docs/qa/v034/img/v034_r200c2_rounds.png
new file mode 100644
index 0000000000..215be100de
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rounds.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_rss.png b/docs/qa/v034/img/v034_r200c2_rss.png
new file mode 100644
index 0000000000..6d14dced0b
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rss.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_rss_avg.png b/docs/qa/v034/img/v034_r200c2_rss_avg.png
new file mode 100644
index 0000000000..8dec67da29
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rss_avg.png differ
diff --git a/docs/qa/v034/img/v034_r200c2_total-txs.png b/docs/qa/v034/img/v034_r200c2_total-txs.png
new file mode 100644
index 0000000000..177d5f1c31
Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_total-txs.png differ
diff --git a/docs/qa/v034/img/v034_report_tabbed.txt b/docs/qa/v034/img/v034_report_tabbed.txt
new file mode 100644
index 0000000000..2514954743
--- /dev/null
+++ b/docs/qa/v034/img/v034_report_tabbed.txt
@@ -0,0 +1,52 @@
+Experiment ID: 3d5cf4ef-1a1a-4b46-aa2d-da5643d2e81e │Experiment ID: 80e472ec-13a1-4772-a827-3b0c907fb51d │Experiment ID: 07aca6cf-c5a4-4696-988f-e3270fc6333b
+ │ │
+ Connections: 1 │ Connections: 2 │ Connections: 4
+ Rate: 25 │ Rate: 25 │ Rate: 25
+ Size: 1024 │ Size: 1024 │ Size: 1024
+ │ │
+ Total Valid Tx: 2225 │ Total Valid Tx: 4450 │ Total Valid Tx: 8900
+ Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0
+ Minimum Latency: 599.404362ms │ Minimum Latency: 448.145181ms │ Minimum Latency: 412.485729ms
+ Maximum Latency: 3.539686885s │ Maximum Latency: 3.237392049s │ Maximum Latency: 12.026665368s
+ Average Latency: 1.441485349s │ Average Latency: 1.441267946s │ Average Latency: 2.150192457s
+ Standard Deviation: 541.049869ms │ Standard Deviation: 525.040007ms │ Standard Deviation: 2.233852478s
+ │ │
+Experiment ID: 953dc544-dd40-40e8-8712-20c34c3ce45e │Experiment ID: d31fc258-16e7-45cd-9dc8-13ab87bc0b0a │Experiment ID: 15d90a7e-b941-42f4-b411-2f15f857739e
+ │ │
+ Connections: 1 │ Connections: 2 │ Connections: 4
+ Rate: 50 │ Rate: 50 │ Rate: 50
+ Size: 1024 │ Size: 1024 │ Size: 1024
+ │ │
+ Total Valid Tx: 4450 │ Total Valid Tx: 8900 │ Total Valid Tx: 17800
+ Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0
+ Minimum Latency: 482.046942ms │ Minimum Latency: 435.458913ms │ Minimum Latency: 510.746448ms
+ Maximum Latency: 3.761483455s │ Maximum Latency: 7.175583584s │ Maximum Latency: 6.551497882s
+ Average Latency: 1.450408183s │ Average Latency: 1.681673116s │ Average Latency: 1.738083875s
+ Standard Deviation: 587.560056ms │ Standard Deviation: 1.147902047s │ Standard Deviation: 943.46522ms
+ │ │
+Experiment ID: 9a0b9980-9ce6-4db5-a80a-65ca70294b87 │Experiment ID: df8fa4f4-80af-4ded-8a28-356d15018b43 │Experiment ID: d0e41c2c-89c0-4f38-8e34-ca07adae593a
+ │ │
+ Connections: 1 │ Connections: 2 │ Connections: 4
+ Rate: 100 │ Rate: 100 │ Rate: 100
+ Size: 1024 │ Size: 1024 │ Size: 1024
+ │ │
+ Total Valid Tx: 8900 │ Total Valid Tx: 17800 │ Total Valid Tx: 35600
+ Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0
+ Minimum Latency: 477.417219ms │ Minimum Latency: 564.29247ms │ Minimum Latency: 840.71089ms
+ Maximum Latency: 6.63744785s │ Maximum Latency: 6.988553219s │ Maximum Latency: 9.555312398s
+ Average Latency: 1.561216103s │ Average Latency: 1.76419063s │ Average Latency: 3.200941683s
+ Standard Deviation: 1.011333552s │ Standard Deviation: 1.068459423s │ Standard Deviation: 1.732346601s
+ │ │
+Experiment ID: 493df3ee-4a36-4bce-80f8-6d65da66beda │Experiment ID: 13060525-f04f-46f6-8ade-286684b2fe50 │Experiment ID: 1777cbd2-8c96-42e4-9ec7-9b21f2225e4d
+ │ │
+ Connections: 1 │ Connections: 2 │ Connections: 4
+ Rate: 200 │ Rate: 200 │ Rate: 200
+ Size: 1024 │ Size: 1024 │ Size: 1024
+ │ │
+ Total Valid Tx: 17800 │ Total Valid Tx: 35600 │ Total Valid Tx: 38660
+ Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0
+ Minimum Latency: 493.705261ms │ Minimum Latency: 955.090573ms │ Minimum Latency: 1.9485821s
+ Maximum Latency: 7.440921872s │ Maximum Latency: 10.086673491s │ Maximum Latency: 17.73103976s
+ Average Latency: 1.875510582s │ Average Latency: 3.438130099s │ Average Latency: 8.143862237s
+ Standard Deviation: 1.304336995s │ Standard Deviation: 1.966391574s │ Standard Deviation: 3.943140002s
+
diff --git a/docs/qa/v034/img/v034_rotating_heights.png b/docs/qa/v034/img/v034_rotating_heights.png
new file mode 100644
index 0000000000..47913c282f
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_heights.png differ
diff --git a/docs/qa/v034/img/v034_rotating_heights_ephe.png b/docs/qa/v034/img/v034_rotating_heights_ephe.png
new file mode 100644
index 0000000000..981b93d6c4
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_heights_ephe.png differ
diff --git a/docs/qa/v034/img/v034_rotating_latencies.png b/docs/qa/v034/img/v034_rotating_latencies.png
new file mode 100644
index 0000000000..f0a54ed5b6
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_latencies.png differ
diff --git a/docs/qa/v034/img/v034_rotating_latencies_uniq.png b/docs/qa/v034/img/v034_rotating_latencies_uniq.png
new file mode 100644
index 0000000000..e5d694a16e
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_latencies_uniq.png differ
diff --git a/docs/qa/v034/img/v034_rotating_load1.png b/docs/qa/v034/img/v034_rotating_load1.png
new file mode 100644
index 0000000000..e9c385b85e
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_load1.png differ
diff --git a/docs/qa/v034/img/v034_rotating_peers.png b/docs/qa/v034/img/v034_rotating_peers.png
new file mode 100644
index 0000000000..ab5c8732d3
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_peers.png differ
diff --git a/docs/qa/v034/img/v034_rotating_rss_avg.png b/docs/qa/v034/img/v034_rotating_rss_avg.png
new file mode 100644
index 0000000000..9a4167320c
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_rss_avg.png differ
diff --git a/docs/qa/v034/img/v034_rotating_total-txs.png b/docs/qa/v034/img/v034_rotating_total-txs.png
new file mode 100644
index 0000000000..1ce5f47e9b
Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_total-txs.png differ
diff --git a/docs/tendermint-core/how-to-read-logs.md b/docs/tendermint-core/how-to-read-logs.md
index 933cce5403..e13e14ba90 100644
--- a/docs/tendermint-core/how-to-read-logs.md
+++ b/docs/tendermint-core/how-to-read-logs.md
@@ -67,7 +67,7 @@ Next follows a standard block creation cycle, where we enter a new
round, propose a block, receive more than 2/3 of prevotes, then
precommits and finally have a chance to commit a block. For details,
please refer to [Byzantine Consensus
-Algorithm](https://github.com/tendermint/spec/blob/master/spec/consensus/consensus.md).
+Algorithm](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/consensus.md).
```sh
I[10-04|13:54:30.393] enterNewRound(91/0). Current: 91/0/RoundStepNewHeight module=consensus
diff --git a/docs/tendermint-core/metrics.md b/docs/tendermint-core/metrics.md
index d6c2bd82dc..245b32cdcb 100644
--- a/docs/tendermint-core/metrics.md
+++ b/docs/tendermint-core/metrics.md
@@ -18,38 +18,40 @@ Listen address can be changed in the config file (see
The following metrics are available:
-| **Name** | **Type** | **Tags** | **Description** |
-| -------------------------------------- | --------- | ------------- | ---------------------------------------------------------------------- |
-| consensus_height | Gauge | | Height of the chain |
-| consensus_validators | Gauge | | Number of validators |
-| consensus_validators_power | Gauge | | Total voting power of all validators |
-| consensus_validator_power | Gauge | | Voting power of the node if in the validator set |
-| consensus_validator_last_signed_height | Gauge | | Last height the node signed a block, if the node is a validator |
-| consensus_validator_missed_blocks | Gauge | | Total amount of blocks missed for the node, if the node is a validator |
-| consensus_missing_validators | Gauge | | Number of validators who did not sign |
-| consensus_missing_validators_power | Gauge | | Total voting power of the missing validators |
-| consensus_byzantine_validators | Gauge | | Number of validators who tried to double sign |
-| consensus_byzantine_validators_power | Gauge | | Total voting power of the byzantine validators |
-| consensus_block_interval_seconds | Histogram | | Time between this and last block (Block.Header.Time) in seconds |
-| consensus_rounds | Gauge | | Number of rounds |
-| consensus_num_txs | Gauge | | Number of transactions |
-| consensus_total_txs | Gauge | | Total number of transactions committed |
-| consensus_block_parts | counter | peer_id | number of blockparts transmitted by peer |
-| consensus_latest_block_height | gauge | | /status sync_info number |
-| consensus_fast_syncing | gauge | | either 0 (not fast syncing) or 1 (syncing) |
-| consensus_state_syncing | gauge | | either 0 (not state syncing) or 1 (syncing) |
-| consensus_block_size_bytes | Gauge | | Block size in bytes |
-| p2p_peers | Gauge | | Number of peers node's connected to |
-| p2p_peer_receive_bytes_total | counter | peer_id, chID | number of bytes per channel received from a given peer |
-| p2p_peer_send_bytes_total | counter | peer_id, chID | number of bytes per channel sent to a given peer |
-| p2p_peer_pending_send_bytes | gauge | peer_id | number of pending bytes to be sent to a given peer |
-| p2p_num_txs | gauge | peer_id | number of transactions submitted by each peer_id |
-| p2p_pending_send_bytes | gauge | peer_id | amount of data pending to be sent to peer |
-| mempool_size | Gauge | | Number of uncommitted transactions |
-| mempool_tx_size_bytes | histogram | | transaction sizes in bytes |
-| mempool_failed_txs | counter | | number of failed transactions |
-| mempool_recheck_times | counter | | number of transactions rechecked in the mempool |
-| state_block_processing_time | histogram | | time between BeginBlock and EndBlock in ms |
+| **Name** | **Type** | **Tags** | **Description** |
+|------------------------------------------|-----------|-------------------|------------------------------------------------------------------------|
+| `consensus_height` | Gauge | | Height of the chain |
+| `consensus_validators` | Gauge | | Number of validators |
+| `consensus_validators_power` | Gauge | | Total voting power of all validators |
+| `consensus_validator_power` | Gauge | | Voting power of the node if in the validator set |
+| `consensus_validator_last_signed_height` | Gauge | | Last height the node signed a block, if the node is a validator |
+| `consensus_validator_missed_blocks` | Gauge | | Total amount of blocks missed for the node, if the node is a validator |
+| `consensus_missing_validators` | Gauge | | Number of validators who did not sign |
+| `consensus_missing_validators_power` | Gauge | | Total voting power of the missing validators |
+| `consensus_byzantine_validators` | Gauge | | Number of validators who tried to double sign |
+| `consensus_byzantine_validators_power` | Gauge | | Total voting power of the byzantine validators |
+| `consensus_block_interval_seconds` | Histogram | | Time between this and last block (Block.Header.Time) in seconds |
+| `consensus_rounds` | Gauge | | Number of rounds |
+| `consensus_num_txs` | Gauge | | Number of transactions |
+| `consensus_total_txs` | Gauge | | Total number of transactions committed |
+| `consensus_block_parts` | Counter | `peer_id` | Number of blockparts transmitted by peer |
+| `consensus_latest_block_height` | Gauge | | /status sync\_info number |
+| `consensus_fast_syncing` | Gauge | | Either 0 (not fast syncing) or 1 (syncing) |
+| `consensus_state_syncing` | Gauge | | Either 0 (not state syncing) or 1 (syncing) |
+| `consensus_block_size_bytes` | Gauge | | Block size in bytes |
+| `p2p_message_send_bytes_total` | Counter | `message_type` | Number of bytes sent to all peers per message type |
+| `p2p_message_receive_bytes_total` | Counter | `message_type` | Number of bytes received from all peers per message type |
+| `p2p_peers` | Gauge | | Number of peers node's connected to |
+| `p2p_peer_receive_bytes_total` | Counter | `peer_id`, `chID` | Number of bytes per channel received from a given peer |
+| `p2p_peer_send_bytes_total` | Counter | `peer_id`, `chID` | Number of bytes per channel sent to a given peer |
+| `p2p_peer_pending_send_bytes` | Gauge | `peer_id` | Number of pending bytes to be sent to a given peer |
+| `p2p_num_txs` | Gauge | `peer_id` | Number of transactions submitted by each peer\_id |
+| `p2p_pending_send_bytes` | Gauge | `peer_id` | Amount of data pending to be sent to peer |
+| `mempool_size` | Gauge | | Number of uncommitted transactions |
+| `mempool_tx_size_bytes` | Histogram | | Transaction sizes in bytes |
+| `mempool_failed_txs` | Counter | | Number of failed transactions |
+| `mempool_recheck_times` | Counter | | Number of transactions rechecked in the mempool |
+| `state_block_processing_time` | Histogram | | Time between BeginBlock and EndBlock in ms |
## Useful queries
diff --git a/docs/tendermint-core/rpc.md b/docs/tendermint-core/rpc.md
index 56c2491c05..300078359a 100644
--- a/docs/tendermint-core/rpc.md
+++ b/docs/tendermint-core/rpc.md
@@ -6,6 +6,6 @@ order: 9
The RPC documentation is hosted here:
-- [https://docs.tendermint.com/master/rpc/](https://docs.tendermint.com/master/rpc/)
+- [https://docs.tendermint.com/v0.34/rpc/](https://docs.tendermint.com/v0.34/rpc/)
To update the documentation, edit the relevant `godoc` comments in the [rpc/core directory](https://github.com/tendermint/tendermint/blob/v0.34.x/rpc/core).
diff --git a/docs/tendermint-core/running-in-production.md b/docs/tendermint-core/running-in-production.md
index 41f40641e1..06c0d82c45 100644
--- a/docs/tendermint-core/running-in-production.md
+++ b/docs/tendermint-core/running-in-production.md
@@ -95,7 +95,7 @@ mechanisms.
### RPC
Endpoints returning multiple entries are limited by default to return 30
-elements (100 max). See the [RPC Documentation](https://docs.tendermint.com/master/rpc/)
+elements (100 max). See the [RPC Documentation](https://docs.tendermint.com/v0.34/rpc/)
for more information.
Rate-limiting and authentication are another key aspects to help protect
diff --git a/docs/tendermint-core/subscription.md b/docs/tendermint-core/subscription.md
index 067d0bf51b..d8723bdec3 100644
--- a/docs/tendermint-core/subscription.md
+++ b/docs/tendermint-core/subscription.md
@@ -31,7 +31,7 @@ method via Websocket along with a valid query.
}
```
-Check out [API docs](https://docs.tendermint.com/master/rpc/) for
+Check out [API docs](https://docs.tendermint.com/v0.34/rpc/) for
more information on query syntax and other options.
You can also use tags, given you had included them into DeliverTx
@@ -43,7 +43,7 @@ transactions](./indexing-transactions.md) for details.
When validator set changes, ValidatorSetUpdates event is published. The
event carries a list of pubkey/power pairs. The list is the same
Tendermint receives from ABCI application (see [EndBlock
-section](https://github.com/tendermint/spec/blob/master/spec/abci/abci.md#endblock) in
+section](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/abci.md#endblock) in
the ABCI spec).
Response:
diff --git a/docs/tendermint-core/using-tendermint.md b/docs/tendermint-core/using-tendermint.md
index 602b0a6a5b..4df4801417 100644
--- a/docs/tendermint-core/using-tendermint.md
+++ b/docs/tendermint-core/using-tendermint.md
@@ -39,7 +39,7 @@ tendermint testnet --help
The `genesis.json` file in `$TMHOME/config/` defines the initial
TendermintCore state upon genesis of the blockchain ([see
-definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.go)).
+definition](https://github.com/tendermint/tendermint/blob/v0.34.x/types/genesis.go)).
#### Fields
@@ -49,7 +49,7 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
chain IDs, you will have a bad time. The ChainID must be less than 50 symbols.
- `initial_height`: Height at which Tendermint should begin at. If a blockchain is conducting a network upgrade,
starting from the stopped height brings uniqueness to previous heights.
-- `consensus_params` [spec](https://github.com/tendermint/spec/blob/master/spec/core/state.md#consensusparams)
+- `consensus_params` [spec](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/core/data_structures.md#consensusparams)
- `block`
- `max_bytes`: Max block size, in bytes.
- `max_gas`: Max gas per block.
@@ -183,7 +183,7 @@ endpoints. Some take no arguments (like `/status`), while others specify
the argument name and use `_` as a placeholder.
-> TIP: Find the RPC Documentation [here](https://docs.tendermint.com/master/rpc/)
+> TIP: Find the RPC Documentation [here](https://docs.tendermint.com/v0.34/rpc/)
### Formatting
diff --git a/docs/tutorials/go-built-in.md b/docs/tutorials/go-built-in.md
index a5b1d61af2..60c444476f 100644
--- a/docs/tutorials/go-built-in.md
+++ b/docs/tutorials/go-built-in.md
@@ -84,7 +84,7 @@ Hello, Tendermint Core
Tendermint Core communicates with the application through the Application
BlockChain Interface (ABCI). All message types are defined in the [protobuf
-file](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/abci/types.proto).
+file](https://github.com/tendermint/tendermint/blob/v0.34.x/proto/tendermint/abci/types.proto).
This allows Tendermint Core to run applications written in any programming
language.
@@ -218,7 +218,7 @@ etc.) by Tendermint Core.
Valid transactions will eventually be committed given they are not too big and
have enough gas. To learn more about gas, check out ["the
-specification"](https://docs.tendermint.com/master/spec/abci/apps.html#gas).
+specification"](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#gas).
For the underlying key-value store we'll use
[badger](https://github.com/dgraph-io/badger), which is an embeddable,
@@ -337,7 +337,7 @@ func (app *KVStoreApplication) Query(reqQuery abcitypes.RequestQuery) (resQuery
```
The complete specification can be found
-[here](https://docs.tendermint.com/master/spec/abci/).
+[here](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/abci/).
## 1.4 Starting an application and a Tendermint Core instance in the same process
@@ -610,7 +610,7 @@ go build
To create a default configuration, nodeKey and private validator files, let's
execute `tendermint init`. But before we do that, we will need to install
Tendermint Core. Please refer to [the official
-guide](https://docs.tendermint.com/master/introduction/install.html). If you're
+guide](https://docs.tendermint.com/v0.34/introduction/install.html). If you're
installing from source, don't forget to checkout the latest release (`git checkout vX.Y.Z`).
```bash
@@ -680,4 +680,4 @@ $ curl -s 'localhost:26657/abci_query?data="tendermint"'
I hope everything went smoothly and your first, but hopefully not the last,
Tendermint Core application is up and running. If not, please [open an issue on
Github](https://github.com/tendermint/tendermint/issues/new/choose). To dig
-deeper, read [the docs](https://docs.tendermint.com/master/).
+deeper, read [the docs](https://docs.tendermint.com/v0.34/).
diff --git a/docs/tutorials/go.md b/docs/tutorials/go.md
index 28a015b995..64a7b57104 100644
--- a/docs/tutorials/go.md
+++ b/docs/tutorials/go.md
@@ -87,7 +87,7 @@ Hello, Tendermint Core
Tendermint Core communicates with the application through the Application
BlockChain Interface (ABCI). All message types are defined in the [protobuf
-file](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/abci/types.proto).
+file](https://github.com/tendermint/tendermint/blob/v0.34.x/proto/tendermint/abci/types.proto).
This allows Tendermint Core to run applications written in any programming
language.
@@ -221,7 +221,7 @@ etc.) by Tendermint Core.
Valid transactions will eventually be committed given they are not too big and
have enough gas. To learn more about gas, check out ["the
-specification"](https://docs.tendermint.com/master/spec/abci/apps.html#gas).
+specification"](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#gas).
For the underlying key-value store we'll use
[badger](https://github.com/dgraph-io/badger), which is an embeddable,
@@ -340,7 +340,7 @@ func (app *KVStoreApplication) Query(reqQuery abcitypes.RequestQuery) (resQuery
```
The complete specification can be found
-[here](https://docs.tendermint.com/master/spec/abci/).
+[here](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/abci/).
## 1.4 Starting an application and a Tendermint Core instances
@@ -468,7 +468,7 @@ go build
To create a default configuration, nodeKey and private validator files, let's
execute `tendermint init`. But before we do that, we will need to install
Tendermint Core. Please refer to [the official
-guide](https://docs.tendermint.com/master/introduction/install.html). If you're
+guide](https://docs.tendermint.com/v0.34/introduction/install.html). If you're
installing from source, don't forget to checkout the latest release (`git checkout vX.Y.Z`).
```bash
@@ -482,7 +482,7 @@ I[2019-07-16|18:20:36.482] Generated genesis file module=m
Feel free to explore the generated files, which can be found at
`/tmp/example/config` directory. Documentation on the config can be found
-[here](https://docs.tendermint.com/master/tendermint-core/configuration.html).
+[here](https://docs.tendermint.com/v0.34/tendermint-core/configuration.html).
We are ready to start our application:
@@ -565,4 +565,4 @@ curl -s 'localhost:26657/abci_query?data="tendermint"'
I hope everything went smoothly and your first, but hopefully not the last,
Tendermint Core application is up and running. If not, please [open an issue on
Github](https://github.com/tendermint/tendermint/issues/new/choose). To dig
-deeper, read [the docs](https://docs.tendermint.com/master/).
+deeper, read [the docs](https://docs.tendermint.com/v0.34/).
diff --git a/docs/tutorials/java.md b/docs/tutorials/java.md
index dbd005957b..526d3a2c68 100644
--- a/docs/tutorials/java.md
+++ b/docs/tutorials/java.md
@@ -115,7 +115,7 @@ Hello world.
Tendermint Core communicates with the application through the Application
BlockChain Interface (ABCI). All message types are defined in the [protobuf
-file](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/abci/types.proto).
+file](https://github.com/tendermint/tendermint/blob/v0.34.x/proto/tendermint/abci/types.proto).
This allows Tendermint Core to run applications written in any programming
language.
@@ -323,7 +323,7 @@ etc.) by Tendermint Core.
Valid transactions will eventually be committed given they are not too big and
have enough gas. To learn more about gas, check out ["the
-specification"](https://docs.tendermint.com/master/spec/abci/apps.html#gas).
+specification"](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#gas).
For the underlying key-value store we'll use
[JetBrains Xodus](https://github.com/JetBrains/xodus), which is a transactional schema-less embedded high-performance database written in Java.
@@ -467,7 +467,7 @@ public void query(RequestQuery req, StreamObserver responseObserv
```
The complete specification can be found
-[here](https://docs.tendermint.com/master/spec/abci/).
+[here](https://github.com/tendermint/tendermint/tree/v0.34.x/spec/abci/).
## 1.4 Starting an application and a Tendermint Core instances
@@ -559,7 +559,7 @@ I[2019-07-16|18:20:36.482] Generated genesis file module=m
Feel free to explore the generated files, which can be found at
`/tmp/example/config` directory. Documentation on the config can be found
-[here](https://docs.tendermint.com/master/tendermint-core/configuration.html).
+[here](https://docs.tendermint.com/v0.34/tendermint-core/configuration.html).
We are ready to start our application:
@@ -625,6 +625,6 @@ $ curl -s 'localhost:26657/abci_query?data="tendermint"'
I hope everything went smoothly and your first, but hopefully not the last,
Tendermint Core application is up and running. If not, please [open an issue on
Github](https://github.com/tendermint/tendermint/issues/new/choose). To dig
-deeper, read [the docs](https://docs.tendermint.com/master/).
+deeper, read [the docs](https://docs.tendermint.com/v0.34/).
The full source code of this example project can be found [here](https://github.com/climber73/tendermint-abci-grpc-java).
diff --git a/docs/tutorials/kotlin.md b/docs/tutorials/kotlin.md
index 50f846e68a..c311e9d71e 100644
--- a/docs/tutorials/kotlin.md
+++ b/docs/tutorials/kotlin.md
@@ -115,7 +115,7 @@ Hello world.
Tendermint Core communicates with the application through the Application
BlockChain Interface (ABCI). All message types are defined in the [protobuf
-file](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/abci/types.proto).
+file](https://github.com/tendermint/tendermint/blob/v0.34.x/proto/tendermint/abci/types.proto).
This allows Tendermint Core to run applications written in any programming
language.
@@ -314,7 +314,7 @@ etc.) by Tendermint Core.
Valid transactions will eventually be committed given they are not too big and
have enough gas. To learn more about gas, check out ["the
-specification"](https://docs.tendermint.com/master/spec/abci/apps.html#gas).
+specification"](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/abci/apps.md#gas).
For the underlying key-value store we'll use
[JetBrains Xodus](https://github.com/JetBrains/xodus), which is a transactional schema-less embedded high-performance database written in Java.
@@ -446,7 +446,7 @@ override fun query(req: RequestQuery, responseObserver: StreamObserver 0 {
evR.Logger.Debug("Gossiping evidence to peer", "ev", ev, "peer", peer)
- msgBytes, err := encodeMsg(evis)
+ evp, err := evidenceListToProto(evis)
if err != nil {
panic(err)
}
- success := peer.Send(EvidenceChannel, msgBytes)
+
+ success := p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: EvidenceChannel,
+ Message: evp,
+ }, evR.Logger)
if !success {
time.Sleep(peerRetryMessageIntervalMS * time.Millisecond)
continue
@@ -210,7 +229,7 @@ type PeerState interface {
// encodemsg takes a array of evidence
// returns the byte encoding of the List Message
-func encodeMsg(evis []types.Evidence) ([]byte, error) {
+func evidenceListToProto(evis []types.Evidence) (*tmproto.EvidenceList, error) {
evi := make([]tmproto.Evidence, len(evis))
for i := 0; i < len(evis); i++ {
ev, err := types.EvidenceToProto(evis[i])
@@ -222,19 +241,13 @@ func encodeMsg(evis []types.Evidence) ([]byte, error) {
epl := tmproto.EvidenceList{
Evidence: evi,
}
-
- return epl.Marshal()
+ return &epl, nil
}
-// decodemsg takes an array of bytes
-// returns an array of evidence
-func decodeMsg(bz []byte) (evis []types.Evidence, err error) {
- lm := tmproto.EvidenceList{}
- if err := lm.Unmarshal(bz); err != nil {
- return nil, err
- }
+func evidenceListFromProto(m proto.Message) ([]types.Evidence, error) {
+ lm := m.(*tmproto.EvidenceList)
- evis = make([]types.Evidence, len(lm.Evidence))
+ evis := make([]types.Evidence, len(lm.Evidence))
for i := 0; i < len(lm.Evidence); i++ {
ev, err := types.EvidenceFromProto(&lm.Evidence[i])
if err != nil {
diff --git a/evidence/reactor_test.go b/evidence/reactor_test.go
index c0a22be26e..8dbd58dcbf 100644
--- a/evidence/reactor_test.go
+++ b/evidence/reactor_test.go
@@ -9,6 +9,7 @@ import (
"github.com/fortytw2/leaktest"
"github.com/go-kit/log/term"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -207,7 +208,10 @@ func TestReactorBroadcastEvidenceMemoryLeak(t *testing.T) {
// i.e. broadcastEvidenceRoutine finishes when peer is stopped
defer leaktest.CheckTimeout(t, 10*time.Second)()
- p.On("Send", evidence.EvidenceChannel, mock.AnythingOfType("[]uint8")).Return(false)
+ p.On("SendEnvelope", mock.MatchedBy(func(i interface{}) bool {
+ e, ok := i.(p2p.Envelope)
+ return ok && e.ChannelID == evidence.EvidenceChannel
+ })).Return(false)
quitChan := make(<-chan struct{})
p.On("Quit").Return(quitChan)
ps := peerState{2}
@@ -366,8 +370,35 @@ func exampleVote(t byte) *types.Vote {
ValidatorIndex: 56789,
}
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config := cfg.TestConfig()
+ N := 1
+
+ stateDBs := make([]sm.Store, N)
+ val := types.NewMockPV()
+ stateDBs[0] = initializeValidatorState(val, 1)
+
+ reactors, _ := makeAndConnectReactorsAndPools(config, stateDBs)
+
+ var (
+ reactor = reactors[0]
+ peer = &p2pmocks.Peer{}
+ )
+ quitChan := make(<-chan struct{})
+ peer.On("Quit").Return(quitChan)
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ e := &tmproto.EvidenceList{}
+ msg, err := proto.Marshal(e)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(evidence.EvidenceChannel, peer, msg)
+ })
+}
-// nolint:lll //ignore line length for tests
+//nolint:lll //ignore line length for tests
func TestEvidenceVectors(t *testing.T) {
val := &types.Validator{
diff --git a/evidence/services.go b/evidence/services.go
index 274433cbe0..5c4d2e953e 100644
--- a/evidence/services.go
+++ b/evidence/services.go
@@ -4,7 +4,7 @@ import (
"github.com/tendermint/tendermint/types"
)
-//go:generate mockery --case underscore --name BlockStore
+//go:generate ../scripts/mockery_generate.sh BlockStore
type BlockStore interface {
LoadBlockMeta(height int64) *types.BlockMeta
diff --git a/evidence/verify.go b/evidence/verify.go
index f3eba53581..c20cb0a2de 100644
--- a/evidence/verify.go
+++ b/evidence/verify.go
@@ -102,13 +102,14 @@ func (evpool *Pool) verify(evidence types.Evidence) error {
// VerifyLightClientAttack verifies LightClientAttackEvidence against the state of the full node. This involves
// the following checks:
-// - the common header from the full node has at least 1/3 voting power which is also present in
-// the conflicting header's commit
-// - 2/3+ of the conflicting validator set correctly signed the conflicting block
-// - the nodes trusted header at the same height as the conflicting header has a different hash
+// - the common header from the full node has at least 1/3 voting power which is also present in
+// the conflicting header's commit
+// - 2/3+ of the conflicting validator set correctly signed the conflicting block
+// - the nodes trusted header at the same height as the conflicting header has a different hash
//
// CONTRACT: must run ValidateBasic() on the evidence before verifying
-// must check that the evidence has not expired (i.e. is outside the maximum age threshold)
+//
+// must check that the evidence has not expired (i.e. is outside the maximum age threshold)
func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, trustedHeader *types.SignedHeader,
commonVals *types.ValidatorSet, now time.Time, trustPeriod time.Duration) error {
// In the case of lunatic attack there will be a different commonHeader height. Therefore the node perform a single
@@ -154,10 +155,10 @@ func VerifyLightClientAttack(e *types.LightClientAttackEvidence, commonHeader, t
// VerifyDuplicateVote verifies DuplicateVoteEvidence against the state of full node. This involves the
// following checks:
-// - the validator is in the validator set at the height of the evidence
-// - the height, round, type and validator address of the votes must be the same
-// - the block ID's must be different
-// - The signatures must both be valid
+// - the validator is in the validator set at the height of the evidence
+// - the height, round, type and validator address of the votes must be the same
+// - the block ID's must be different
+// - The signatures must both be valid
func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error {
_, val := valSet.GetByAddress(e.VoteA.ValidatorAddress)
if val == nil {
diff --git a/go.mod b/go.mod
index 77eb291913..2001d6107d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,21 +1,23 @@
module github.com/tendermint/tendermint
-go 1.17
+go 1.18
require (
- github.com/BurntSushi/toml v1.2.0
+ github.com/BurntSushi/toml v1.2.1
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d
- github.com/Workiva/go-datastructures v1.0.52
- github.com/adlio/schema v1.1.13
- github.com/btcsuite/btcd v0.21.0-beta
- github.com/btcsuite/btcutil v1.0.2
+ github.com/Workiva/go-datastructures v1.0.53
+ github.com/adlio/schema v1.3.3
+ github.com/btcsuite/btcd v0.22.1
+ github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
+ github.com/bufbuild/buf v1.9.0
github.com/celestiaorg/nmt v0.11.0
github.com/fortytw2/leaktest v1.3.0
github.com/go-kit/kit v0.12.0
github.com/go-kit/log v0.2.1
github.com/go-logfmt/logfmt v0.5.1
- github.com/gogo/protobuf v1.3.2
+ github.com/gofrs/uuid v4.3.0+incompatible
github.com/golang/protobuf v1.5.2
+ github.com/golangci/golangci-lint v1.50.1
github.com/google/orderedcode v0.0.1
github.com/gorilla/websocket v1.5.0
github.com/gtank/merlin v0.1.1
@@ -25,43 +27,48 @@ require (
github.com/ory/dockertest v3.3.5+incompatible
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.12.2
- github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
+ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/rs/cors v1.8.2
- github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa
+ github.com/sasha-s/go-deadlock v0.3.1
github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa
- github.com/spf13/cobra v1.5.0
- github.com/spf13/viper v1.12.0
+ github.com/spf13/cobra v1.6.0
+ github.com/spf13/viper v1.13.0
github.com/stretchr/testify v1.8.0
+ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
+)
+
+require (
+ github.com/google/uuid v1.3.0
github.com/tendermint/tm-db v0.6.6
- golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e
- golang.org/x/net v0.0.0-20220617184016-355a448f1bc9
- google.golang.org/grpc v1.48.0
+ golang.org/x/crypto v0.1.0
+ golang.org/x/net v0.1.0
+ google.golang.org/grpc v1.50.1
)
+require github.com/vektra/mockery/v2 v2.14.0
+
require (
- github.com/bufbuild/buf v1.4.0
- github.com/creachadair/taskgroup v0.3.2
- github.com/golangci/golangci-lint v1.47.2
- github.com/prometheus/common v0.34.0 // indirect
- github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
- github.com/vektra/mockery/v2 v2.14.0
- google.golang.org/protobuf v1.28.0
+ github.com/gogo/protobuf v1.3.2
+ github.com/informalsystems/tm-load-test v1.0.0
+ gonum.org/v1/gonum v0.12.0
+ google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8
)
require (
4d63.com/gochecknoglobals v0.1.0 // indirect
+ github.com/Abirdcfly/dupword v0.0.7 // indirect
github.com/Antonboom/errname v0.1.7 // indirect
github.com/Antonboom/nilnil v0.1.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/DataDog/zstd v1.4.1 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
- github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.0 // indirect
+ github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
- github.com/Microsoft/go-winio v0.5.0 // indirect
+ github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
- github.com/OpenPeeDeeP/depguard v1.1.0 // indirect
+ github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
- github.com/alingse/asasalint v0.0.10 // indirect
+ github.com/alingse/asasalint v0.0.11 // indirect
github.com/ashanbrown/forbidigo v1.3.0 // indirect
github.com/ashanbrown/makezero v1.1.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -70,38 +77,46 @@ require (
github.com/bombsimon/wsl/v3 v3.3.0 // indirect
github.com/breml/bidichk v0.2.3 // indirect
github.com/breml/errchkjson v0.3.0 // indirect
+ github.com/bufbuild/connect-go v1.0.0 // indirect
+ github.com/bufbuild/protocompile v0.1.0 // indirect
github.com/butuzov/ireturn v0.1.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/charithe/durationcheck v0.0.9 // indirect
- github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 // indirect
- github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect
+ github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect
+ github.com/containerd/containerd v1.6.8 // indirect
+ github.com/containerd/continuity v0.3.0 // indirect
+ github.com/containerd/typeurl v1.0.2 // indirect
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
- github.com/daixiang0/gci v0.4.3 // indirect
+ github.com/creachadair/taskgroup v0.3.2
+ github.com/curioswitch/go-reassign v0.2.0 // indirect
+ github.com/daixiang0/gci v0.8.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/denis-tingaikin/go-header v0.4.3 // indirect
github.com/dgraph-io/badger/v2 v2.2007.2 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
+ github.com/docker/distribution v2.8.1+incompatible // indirect
+ github.com/docker/docker v20.10.19+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
- github.com/docker/go-units v0.4.0 // indirect
+ github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/esimonov/ifshort v1.0.4 // indirect
github.com/ettle/strcase v0.1.1 // indirect
- github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c // indirect
- github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
- github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/firefart/nonamedreturns v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fzipp/gocyclo v0.6.0 // indirect
- github.com/go-critic/go-critic v0.6.3 // indirect
+ github.com/go-chi/chi/v5 v5.0.7 // indirect
+ github.com/go-critic/go-critic v0.6.5 // indirect
+ github.com/go-logr/logr v1.2.3 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-toolsmith/astcast v1.0.0 // indirect
- github.com/go-toolsmith/astcopy v1.0.0 // indirect
- github.com/go-toolsmith/astequal v1.0.1 // indirect
+ github.com/go-toolsmith/astcopy v1.0.2 // indirect
+ github.com/go-toolsmith/astequal v1.0.3 // indirect
github.com/go-toolsmith/astfmt v1.0.0 // indirect
github.com/go-toolsmith/astp v1.0.0 // indirect
github.com/go-toolsmith/strparse v1.0.0 // indirect
@@ -109,43 +124,42 @@ require (
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gofrs/flock v0.8.1 // indirect
- github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/snappy v0.0.3 // indirect
+ github.com/golang/snappy v0.0.4 // indirect
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect
- github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect
+ github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect
github.com/golangci/misspell v0.3.5 // indirect
- github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 // indirect
+ github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
github.com/google/btree v1.0.0 // indirect
- github.com/google/go-cmp v0.5.8 // indirect
+ github.com/google/go-cmp v0.5.9 // indirect
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect
github.com/gostaticanalysis/nilerr v0.1.1 // indirect
+ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect
github.com/gtank/ristretto255 v0.1.2 // indirect
- github.com/hashicorp/errwrap v1.0.0 // indirect
+ github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
- github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect
github.com/jgautheron/goconst v1.5.1 // indirect
- github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f // indirect
- github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753 // indirect
github.com/jingyugao/rowserrcheck v1.1.1 // indirect
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/julz/importas v0.1.0 // indirect
- github.com/kisielk/errcheck v1.6.1 // indirect
+ github.com/kisielk/errcheck v1.6.2 // indirect
github.com/kisielk/gotool v1.0.0 // indirect
- github.com/klauspost/compress v1.15.6 // indirect
+ github.com/kkHAIKE/contextcheck v1.1.3 // indirect
+ github.com/klauspost/compress v1.15.11 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/kulti/thelper v0.6.3 // indirect
github.com/kunwardeep/paralleltest v1.0.6 // indirect
@@ -155,50 +169,58 @@ require (
github.com/leonklingele/grouper v1.1.0 // indirect
github.com/lufeee/execinquery v1.2.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
+ github.com/maratori/testableexamples v1.0.0 // indirect
github.com/maratori/testpackage v1.1.0 // indirect
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect
- github.com/mattn/go-colorable v0.1.12 // indirect
- github.com/mattn/go-isatty v0.0.14 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/mbilski/exhaustivestruct v1.2.0 // indirect
- github.com/mgechev/revive v1.2.1 // indirect
- github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect
+ github.com/mgechev/revive v1.2.4 // indirect
+ github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/moby/buildkit v0.10.4 // indirect
+ github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/moricho/tparallel v0.2.1 // indirect
+ github.com/morikuni/aec v1.0.0 // indirect
github.com/nakabonne/nestif v0.3.1 // indirect
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
- github.com/nishanths/exhaustive v0.8.1 // indirect
+ github.com/nishanths/exhaustive v0.8.3 // indirect
github.com/nishanths/predeclared v0.2.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
- github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
- github.com/opencontainers/image-spec v1.0.1 // indirect
- github.com/opencontainers/runc v1.0.2 // indirect
+ github.com/opencontainers/go-digest v1.0.0 // indirect
+ github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
+ github.com/opencontainers/runc v1.1.3 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
- github.com/pelletier/go-toml/v2 v2.0.2 // indirect
+ github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/profile v1.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/polyfloyd/go-errorlint v1.0.0 // indirect
+ github.com/polyfloyd/go-errorlint v1.0.5 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
- github.com/prometheus/procfs v0.7.3 // indirect
- github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a // indirect
- github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect
+ github.com/prometheus/common v0.32.1 // indirect
+ github.com/prometheus/procfs v0.8.0 // indirect
+ github.com/quasilyte/go-ruleguard v0.3.18 // indirect
+ github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
github.com/rs/zerolog v1.27.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/ryancurrah/gomodguard v1.2.3 // indirect
+ github.com/ryancurrah/gomodguard v1.2.4 // indirect
github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect
github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect
- github.com/securego/gosec/v2 v2.12.0 // indirect
+ github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
+ github.com/sashamelentyev/usestdlibvars v1.20.0 // indirect
+ github.com/satori/go.uuid v1.2.0 // indirect
+ github.com/securego/gosec/v2 v2.13.1 // indirect
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect
- github.com/sirupsen/logrus v1.8.1 // indirect
+ github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sivchari/containedctx v1.0.2 // indirect
- github.com/sivchari/nosnakecase v1.5.0 // indirect
+ github.com/sivchari/nosnakecase v1.7.0 // indirect
github.com/sivchari/tenv v1.7.0 // indirect
github.com/sonatard/noctx v0.0.1 // indirect
github.com/sourcegraph/go-diff v0.6.1 // indirect
@@ -209,39 +231,43 @@ require (
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect
github.com/stretchr/objx v0.4.0 // indirect
- github.com/subosito/gotenv v1.4.0 // indirect
- github.com/sylvia7788/contextcheck v1.0.4 // indirect
+ github.com/subosito/gotenv v1.4.1 // indirect
github.com/tdakkota/asciicheck v0.1.1 // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
github.com/tetafro/godot v1.4.11 // indirect
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect
- github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect
- github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect
+ github.com/timonwong/loggercheck v0.9.3 // indirect
+ github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect
+ github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/ultraware/funlen v0.0.3 // indirect
github.com/ultraware/whitespace v0.0.5 // indirect
github.com/uudashr/gocognit v1.0.6 // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.2.0 // indirect
- gitlab.com/bosi/decorder v0.2.2 // indirect
+ gitlab.com/bosi/decorder v0.2.3 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
go.opencensus.io v0.23.0 // indirect
- go.uber.org/atomic v1.9.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3 // indirect
+ go.opentelemetry.io/otel v1.11.0 // indirect
+ go.opentelemetry.io/otel/metric v0.32.3 // indirect
+ go.opentelemetry.io/otel/trace v1.11.0 // indirect
+ go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
- go.uber.org/zap v1.21.0 // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
- golang.org/x/sys v0.0.0-20220702020025-31831981b65f // indirect
- golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 // indirect
- golang.org/x/text v0.3.7 // indirect
- golang.org/x/tools v0.1.12-0.20220628192153-7743d1d949f1 // indirect
- google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
- gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
- gopkg.in/ini.v1 v1.66.6 // indirect
+ go.uber.org/zap v1.23.0 // indirect
+ golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
+ golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect
+ golang.org/x/mod v0.6.0 // indirect
+ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0 // indirect
+ golang.org/x/sys v0.1.0 // indirect
+ golang.org/x/term v0.1.0 // indirect
+ golang.org/x/text v0.4.0 // indirect
+ golang.org/x/tools v0.2.0 // indirect
+ google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- honnef.co/go/tools v0.3.2 // indirect
- mvdan.cc/gofumpt v0.3.1 // indirect
+ honnef.co/go/tools v0.3.3 // indirect
+ mvdan.cc/gofumpt v0.4.0 // indirect
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect
diff --git a/go.sum b/go.sum
index f3b821ac2a..cfcf0c706f 100644
--- a/go.sum
+++ b/go.sum
@@ -1,6 +1,6 @@
4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0=
4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
-bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M=
+bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
@@ -15,7 +15,6 @@ cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
@@ -24,44 +23,30 @@ cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPT
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.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
-cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
-cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
+cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
-cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
-cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
-cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
-cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
+cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w=
-cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
-contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q=
+github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk=
github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako=
github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU=
github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q=
@@ -70,46 +55,44 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
-github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg=
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d/go.mod h1:URdX5+vg25ts3aCh8H5IFZybJYKWhJHYMTnf+ULtoC4=
+github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM=
github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
-github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.0 h1:V9xVvhKbLt7unNEGAruK1xXglyc668Pq3Xx0MNTNqpo=
-github.com/GaijinEntertainment/go-exhaustruct/v2 v2.2.0/go.mod h1:n/vLeA7V+QY84iYAGwMkkUUp9ooeuftMEvaDrSVch+Q=
+github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts=
+github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0=
github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
-github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
+github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
+github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
-github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o=
-github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
+github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA=
+github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc=
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/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.52 h1:PLSK6pwn8mYdaoaCZEMsXBpBotr4HHn9abU0yMQt0NI=
github.com/Workiva/go-datastructures v1.0.52/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA=
-github.com/adlio/schema v1.1.13 h1:LeNMVg5Z1FX+Qgz8tJUijBLRdcpbFUElz+d1489On98=
+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/adlio/schema v1.1.13/go.mod h1:L5Z7tw+7lRK1Fnpi/LT/ooCP1elkXn0krMWBQHUhEDE=
+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=
@@ -120,40 +103,39 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw=
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
-github.com/alingse/asasalint v0.0.10 h1:qqGPDTV0ff0tWHN/nnIlSdjlU/EwRPaUY4SfpE1rnms=
-github.com/alingse/asasalint v0.0.10/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
-github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
-github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
+github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw=
+github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
-github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
+github.com/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.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
-github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc=
github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s=
github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI=
-github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
-github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
+github.com/aws/aws-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.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
+github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
-github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
+github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A=
github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
@@ -165,12 +147,16 @@ github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc
github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw=
github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
-github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M=
github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
+github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA=
+github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c=
+github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y=
+github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
-github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
+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/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=
@@ -178,20 +164,24 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
-github.com/bufbuild/buf v1.4.0 h1:GqE3a8CMmcFvWPzuY3Mahf9Kf3S9XgZ/ORpfYFzO+90=
-github.com/bufbuild/buf v1.4.0/go.mod h1:mwHG7klTHnX+rM/ym8LXGl7vYpVmnwT96xWoRB4H5QI=
+github.com/bufbuild/buf v1.9.0 h1:8a60qapVuRj6crerWR0rny4UUV/MhZSL5gagJuBxmx8=
+github.com/bufbuild/buf v1.9.0/go.mod h1:1Q+rMHiMVcfgScEF/GOldxmu4o9TrQ2sQQh58K6MscE=
+github.com/bufbuild/connect-go v1.0.0 h1:htSflKUT8y1jxhoPhPYTZMrsY3ipUXjjrbcZR5O2cVo=
+github.com/bufbuild/connect-go v1.0.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I=
+github.com/bufbuild/protocompile v0.1.0 h1:HjgJBI85hY/qmW5tw/66sNDZ7z0UDdVSi/5r40WHw4s=
+github.com/bufbuild/protocompile v0.1.0/go.mod h1:ix/MMMdsT3fzxfw91dvbfzKW3fRRnuPCP47kpAm5m/4=
github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY=
github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc=
+github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/casbin/casbin/v2 v2.37.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
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.11.0 h1:iqTaNwnVzM3njBmPklpHzb3A4Xy/JKahoclRPbAzxNc=
github.com/celestiaorg/nmt v0.11.0/go.mod h1:NN3W8EEoospv8EHCw50DDNWwPLpJkFHoEFiqCEcNCH4=
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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -199,16 +189,19 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk=
github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
-github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4 h1:tFXjAxje9thrTF4h57Ckik+scJjTWdwAtZqZPtOT48M=
-github.com/chavacava/garif v0.0.0-20220316182200-5cad0b5181d4/go.mod h1:W8EnPSQ8Nv4fUjc/v1/8tHFqhuOJXnRub0dTfuAQktU=
+github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI=
+github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
+github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
+github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
+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/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=
@@ -217,40 +210,51 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
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/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
-github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw=
+github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
+github.com/containerd/containerd v1.6.8 h1:h4dOFDwzHmqFEP754PgfgTeVXFnLiRc6kiqC7tplDJs=
+github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0=
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
+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/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
+github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
-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.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/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/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
+github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ=
+github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo=
+github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
-github.com/daixiang0/gci v0.4.3 h1:wf7x0xRjQqTlA2dzHTI0A/xPyp7VcBatBG9nwGatwbQ=
-github.com/daixiang0/gci v0.4.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c=
-github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/daixiang0/gci v0.8.1 h1:T4xpSC+hmsi4CSyuYfIJdMZAr9o7xZmHpQVygMghGZ4=
+github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -258,6 +262,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU=
github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c=
+github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA=
github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLIegjaI3k=
github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE=
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA=
@@ -265,10 +270,17 @@ github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KP
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
+github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
+github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64=
+github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
-github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@@ -276,6 +288,7 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m
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/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=
@@ -284,24 +297,19 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
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.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
-github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
-github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA=
github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0=
github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw=
github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
-github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
-github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
+github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
+github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/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/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
+github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
-github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
@@ -312,28 +320,28 @@ github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIg
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/goblin v0.0.0-20210519012713-85d372ac71e2/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
-github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
-github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
-github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-critic/go-critic v0.6.3 h1:abibh5XYBTASawfTQ0rA7dVtQT+6KzpGqb/J+DxRDaw=
-github.com/go-critic/go-critic v0.6.3/go.mod h1:c6b3ZP1MQ7o6lPR7Rv3lEf7pYQUmAcx8ABHgdZCQt/k=
+github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
+github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo=
+github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY=
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.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -345,19 +353,23 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
-github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
-github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
-github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8=
-github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
+github.com/go-toolsmith/astcopy v1.0.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0=
+github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y=
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
-github.com/go-toolsmith/astequal v1.0.1 h1:JbSszi42Jiqu36Gnf363HWS9MTEAz67vTQLponh3Moc=
-github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw=
+github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
+github.com/go-toolsmith/astequal v1.0.3 h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o=
+github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k=
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg=
@@ -374,20 +386,24 @@ github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
-github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
-github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.3.0+incompatible h1:CaSVZxm5B+7o45rtab4jC2G37WGYX1zQfuU2i6DSvnc=
+github.com/gofrs/uuid v4.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
-github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
-github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
+github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/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=
@@ -401,8 +417,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
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/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
-github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -423,33 +437,32 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo=
github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ=
-github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks=
-github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
-github.com/golangci/golangci-lint v1.47.2 h1:qvMDVv49Hrx3PSEXZ0bD/yhwSbhsOihQjFYCKieegIw=
-github.com/golangci/golangci-lint v1.47.2/go.mod h1:lpS2pjBZtRyXewUcOY7yUL3K4KfpoWz072yRN8AuhHg=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY=
+github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs=
+github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY=
+github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo=
github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
-github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2 h1:SgM7GDZTxtTTQPU84heOxy34iG5Du7F2jcoZnvp+fXI=
-github.com/golangci/revgrep v0.0.0-20210930125155-c22e5001d4f2/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=
+github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ=
+github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
-github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -462,16 +475,14 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
-github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
-github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/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/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=
@@ -480,49 +491,35 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
-github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
-github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
-github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U=
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
-github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
+github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
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.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+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/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
-github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk=
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
@@ -535,34 +532,35 @@ github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3
github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY=
-github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI=
github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
-github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
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.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/gtank/merlin v0.1.1-0.20191105220539-8318aed1a79f/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
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.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
-github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
-github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
-github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
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/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
-github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
@@ -571,56 +569,51 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
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-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
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-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1/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.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/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/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
-github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
-github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
-github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
-github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
-github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
+github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo=
-github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
+github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
+github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/informalsystems/tm-load-test v1.0.0 h1:e1IeUw8701HWCMuOM1vLM/XcpH2Lrb88GNWdFAPDmmA=
+github.com/informalsystems/tm-load-test v1.0.0/go.mod h1:WVaSKaQdfZK3v0C74EMzn7//+3aeCZF8wkIKBz2/M74=
github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a h1:d4+I1YEKVmWZrgkt6jpXBnLgV2ZjO0YxEtLDdfIZfH4=
github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
-github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
-github.com/jhump/gopoet v0.1.0/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
-github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
-github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f h1:BNuUg9k2EiJmlMwjoef3e8vZLHplbVw6DrjGFjLL+Yo=
-github.com/jhump/protocompile v0.0.0-20220216033700-d705409f108f/go.mod h1:qr2b5kx4HbFS7/g4uYO5qv9ei8303JMsC7ESbYiqr2Q=
-github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
-github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=
-github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753 h1:uFlcJKZPLQd7rmOY/RrvBuUaYmAFnlFHKLivhO6cOy8=
-github.com/jhump/protoreflect v1.12.1-0.20220417024638-438db461d753/go.mod h1:JytZfP5d0r8pVNLZvai7U/MCuTWITgrI4tTg7puQFKI=
+github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM=
github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48=
@@ -632,12 +625,11 @@ github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U
github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
-github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
-github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.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.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -645,31 +637,27 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY=
github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
-github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
-github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/errcheck v1.6.1 h1:cErYo+J4SmEjdXZrVXGwLJCE2sB06s23LpkcyWNrT+s=
-github.com/kisielk/errcheck v1.6.1/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
+github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c=
+github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw=
+github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
-github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY=
-github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
+github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
+github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
@@ -677,7 +665,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
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=
@@ -686,7 +673,6 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs=
github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g=
github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes=
-github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M=
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA=
@@ -695,23 +681,25 @@ github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKi
github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88=
github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg=
github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY=
-github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM=
github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8=
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
+github.com/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/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM=
github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM=
-github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
-github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
+github.com/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.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI=
+github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q=
github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc=
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA=
@@ -723,157 +711,170 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
github.com/mattn/go-colorable v0.1.6/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.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
+github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo=
github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
-github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
-github.com/mgechev/revive v1.2.1 h1:GjFml7ZsoR0IrQ2E2YIvWFNS5GPDV7xNwvA5GM1HZC4=
-github.com/mgechev/revive v1.2.1/go.mod h1:+Ro3wqY4vakcYNtkBWdZC7dBg1xSB6sp054wWwmeFm0=
+github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI=
+github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
-github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
-github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
-github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
-github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
-github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
+github.com/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.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
-github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/go-homedir v1.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-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/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.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4=
+github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
+github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
+github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
+github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
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/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4=
github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=
-github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=
-github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
-github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=
github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U=
github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
+github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
+github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q=
github.com/nats-io/jwt/v2 v2.0.3/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
+github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats-server/v2 v2.5.0/go.mod h1:Kj86UtrXAL6LwYRA6H4RqzkHhK0Vcv2ZnKD5WbQ1t3g=
+github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
github.com/nats-io/nats.go v1.12.1/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
+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/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo=
-github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg=
-github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
+github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM=
+github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg=
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/oklog/ulid/v2 v2.0.2/go.mod h1:mtBL0Qe/0HAx6/a4Z30qxVIAL1eQDweXq5lxOEiwQ68=
+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.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
-github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
+github.com/onsi/ginkgo v1.16.2 h1:HFB2fbVIlhIfCfOW81bZFbiC/RvnpXSdhbF2/DJr134=
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
-github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
-github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
-github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
-github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
-github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
-github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
-github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
+github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
-github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
-github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
+github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
-github.com/opencontainers/runc v1.0.2 h1:opHZMaswlyxz1OuGpBE53Dwe4/xF7EZTY0A2L/FpCOg=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
+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/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
+github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
+github.com/opentracing-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.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+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/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
+github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
+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/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
-github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
+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 v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
-github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw=
-github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
+github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
+github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
+github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/performancecopilot/speed/v4 v4.0.0/go.mod h1:qxrSyuDGrTOWfV+uKRFhfxw6h/4HXRGUiZiufxo49BM=
-github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
+github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
-github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -883,101 +884,110 @@ github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
-github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/polyfloyd/go-errorlint v1.0.0 h1:pDrQG0lrh68e602Wfp68BlUTRFoHn8PZYAjLgt2LFsM=
-github.com/polyfloyd/go-errorlint v1.0.0/go.mod h1:KZy4xxPJyy88/gldCe5OdW6OQRtNO3EZE7hXzmnebgA=
+github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY=
+github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
-github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.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.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
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 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+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.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+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.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
-github.com/prometheus/common v0.34.0 h1:RBmGO9d/FVjqHT0yUGQwBJhkwKV+wPCn7KGpvfab0uE=
-github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE=
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.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
+github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
-github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
+github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
+github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=
-github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a h1:sWFavxtIctGrVs5SYZ5Ml1CvrDAs8Kf5kx2PI3C41dA=
-github.com/quasilyte/go-ruleguard v0.3.16-0.20220213074421-6aa060fab41a/go.mod h1:VMX+OnnSw4LicdiEGtRSD/1X8kW7GuEscjYNr4cOIT4=
+github.com/quasilyte/go-ruleguard v0.3.18 h1:sd+abO1PEI9fkYennwzHn9kl3nqP6M5vE7FiOzZ+5CE=
+github.com/quasilyte/go-ruleguard v0.3.18/go.mod h1:lOIzcYlgxrQ2sGJ735EHXmf/e9MJ516j16K/Ifcttvs=
github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
-github.com/quasilyte/go-ruleguard/dsl v0.3.16/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
-github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8=
-github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM=
+github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f h1:6Gtn2i04RD0gVyYf2/IUMTIs+qYleBt4zxDqkLTcu4U=
+github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY=
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs=
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5/go.mod h1:+u151txRmLpwxBmpYn9z3d1sdJdjRPQpsXuYeY9jNls=
-github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96/go.mod h1:90HvCY7+oHHUKkbeMCiHt1WuFR2/hPJ9QrljDG+v6ls=
-github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e/go.mod h1:80FQABjoFzZ2M5uEa6FUaJYEmqU2UOKojlFVak1UAwI=
+github.com/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/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
-github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs=
github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U=
-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/ryancurrah/gomodguard v1.2.3 h1:ww2fsjqocGCAFamzvv/b8IsRduuHHeK2MHTcTxZTQX8=
-github.com/ryancurrah/gomodguard v1.2.3/go.mod h1:rYbA/4Tg5c54mV1sv4sQTP5WOPBcoLtnBZ7/TEhXAbg=
+github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4=
+github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M=
github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw=
github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
-github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
-github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
+github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA=
github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
-github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa h1:0U2s5loxrTy6/VgfVoLuVLFJcURKLH49ie0zSch7gh4=
github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
+github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
+github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
+github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw=
+github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
+github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw=
+github.com/sashamelentyev/usestdlibvars v1.20.0/go.mod h1:0GaP+ecfZMXShS0A94CJn6aEuPRILv8h/VuWI9n1ygg=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
-github.com/securego/gosec/v2 v2.12.0 h1:CQWdW7ATFpvLSohMVsajscfyHJ5rsGmEXmsNcsDNmAg=
-github.com/securego/gosec/v2 v2.12.0/go.mod h1:iTpT+eKTw59bSgklBHlSnH5O2tNygHMDxfvMubA4i7I=
-github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
+github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM=
+github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
-github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -986,12 +996,13 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
+github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI=
github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw=
-github.com/sivchari/nosnakecase v1.5.0 h1:ZBvAu1H3uteN0KQ0IsLpIFOwYgPEhKLyv2ahrVkub6M=
-github.com/sivchari/nosnakecase v1.5.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
+github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8=
+github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY=
github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE=
github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -1008,20 +1019,20 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
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.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
-github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
-github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
-github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
-github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
+github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
+github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI=
+github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
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=
@@ -1030,21 +1041,25 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
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.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
-github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
-github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
+github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
+github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
+github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0=
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc=
github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I=
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/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/streadway/handy v0.0.0-20200128134331-0f66f006fb2e/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 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1053,23 +1068,21 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
-github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
-github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs=
-github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
-github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
-github.com/sylvia7788/contextcheck v1.0.4 h1:MsiVqROAdr0efZc/fOCt0c235qm9XJqHtWwM+2h2B04=
-github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ=
+github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
+github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
+github.com/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/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A=
github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
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/tendermint v0.34.14/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0=
+github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw=
github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM=
github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI=
github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA=
@@ -1080,17 +1093,18 @@ github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw=
github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro=
github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
-github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
-github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
+github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI=
+github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw=
+github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
-github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M=
-github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg=
-github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
-github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s=
-github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA=
+github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA=
github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
@@ -1100,54 +1114,40 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y=
github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
-github.com/valyala/quicktemplate v1.7.0/go.mod h1:sqKJnoaOF88V07vkO+9FL8fb9uZg/VPSJnLYn+LmLk8=
-github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vektra/mockery/v2 v2.14.0 h1:KZ1p5Hrn8tiY+LErRMr14HHle6khxo+JKOXLBW/yfqs=
github.com/vektra/mockery/v2 v2.14.0/go.mod h1:bnD1T8tExSgPD1ripLkDbr60JA9VtQeu12P3wgLZd7M=
-github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
+github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o=
github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA=
-github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
-github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
-github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
-gitlab.com/NebulousLabs/errors v0.0.0-20171229012116-7ead97ef90b8/go.mod h1:ZkMZ0dpQyWwlENaeZVBiQRjhMEZvk6VTXquzl3FOFP8=
-gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40/go.mod h1:rOnSnoRyxMI3fe/7KIbVcsHRGxe30OONv8dEgo+vCfA=
-gitlab.com/bosi/decorder v0.2.2 h1:LRfb3lP6mZWjUzpMOCLTVjcnl/SqZWBWmKNqQvMocQs=
-gitlab.com/bosi/decorder v0.2.2/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0=
+gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
-go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
+go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
-go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
+go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
-go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
-go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
-go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
-go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
-go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU=
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
-go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY=
-go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=
+go.opencensus.io v0.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=
@@ -1156,19 +1156,26 @@ 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 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3 h1:syAz40OyelLZo42+3U68Phisvrx4qh+4wpdZw7eUUdY=
+go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.3/go.mod h1:Dts42MGkzZne2yCru741+bFiTMWkIj/LLRizad7b9tw=
+go.opentelemetry.io/otel v1.11.0 h1:kfToEGMDq6TrVrJ9Vht84Y8y9enykSZzDDZglV0kIEk=
+go.opentelemetry.io/otel v1.11.0/go.mod h1:H2KtuEphyMvlhZ+F7tg9GRhAOe60moNx61Ex+WmiKkk=
+go.opentelemetry.io/otel/metric v0.32.3 h1:dMpnJYk2KULXr0j8ph6N7+IcuiIQXlPXD4kix9t7L9c=
+go.opentelemetry.io/otel/metric v0.32.3/go.mod h1:pgiGmKohxHyTPHGOff+vrtIH39/R9fiO/WoenUQ3kcc=
+go.opentelemetry.io/otel/trace v1.11.0 h1:20U/Vj42SX+mASlXLmSGBg6jpI1jQtv682lZtTAOVFI=
+go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U=
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/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
+go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
+go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
-go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
-go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
@@ -1178,37 +1185,33 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
-go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8=
-go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
+go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY=
+go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
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-20200323165209-0ec3e9974c59/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-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
-golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/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=
@@ -1222,11 +1225,11 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5 h1:FR+oGxGfbQu1d+jglI3rCkjAjUnhRSZcUxr+DqlDLNo=
-golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
-golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
+golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
+golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk=
+golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
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=
@@ -1253,24 +1256,27 @@ 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.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
+golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1278,7 +1284,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1286,7 +1291,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -1305,25 +1309,16 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
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-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
-golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220617184016-355a448f1bc9 h1:Yqz/iviulwKwAREEeUd3nbBFn0XuyJqkoft2IlrvOhc=
-golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
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=
@@ -1335,20 +1330,13 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
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-20210402161424-2e8d93401602/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-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
+golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1356,9 +1344,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
-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 h1:cu5kTvlzcw1Q5S9f5ip1/cpiB4nXvw1XYzFPGgzLUOY=
+golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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=
@@ -1366,6 +1354,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
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=
@@ -1382,7 +1371,6 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1392,6 +1380,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-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-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1404,7 +1393,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1418,9 +1406,9 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1437,49 +1425,34 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-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-20210616045830-e2b7044e8c71/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-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-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/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-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220406163625-3f8b81556e12/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/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-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220702020025-31831981b65f h1:xdsejrW/0Wf2diT5CPp3XmKUNbr7Xvw8kYilQ+6qjRY=
golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM=
-golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
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=
@@ -1488,22 +1461,23 @@ 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 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
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-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/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-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190228203856-589c23e65e65/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -1517,25 +1491,26 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@@ -1551,7 +1526,6 @@ golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWc
golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -1560,9 +1534,6 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
@@ -1573,8 +1544,8 @@ golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82u
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
+golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -1588,33 +1559,29 @@ golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0t
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
-golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
-golang.org/x/tools v0.1.12-0.20220628192153-7743d1d949f1 h1:NHLFZ56qCjD+0hYY3kE5Wl40Z7q4Gn9Ln/7YU0lsGko=
-golang.org/x/tools v0.1.12-0.20220628192153-7743d1d949f1/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
+golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
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=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
+gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o=
+gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY=
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.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
@@ -1632,44 +1599,25 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
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.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
-google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
-google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
-google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
-google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
-google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
-google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
-google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
-google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
-google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
-google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko=
+google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
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.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
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-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
@@ -1690,8 +1638,6 @@ google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -1707,60 +1653,25 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D
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-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-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
-google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
-google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
-google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
-google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
-google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad h1:kqrS+lhvaMHCxul6sKQvKJ8nAAhlVItmZV822hYFH/U=
-google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
-google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a h1:GH6UPn3ixhWcKDhpnEC55S75cerLPdpp3hrhfKYjZgw=
+google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
+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.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.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
-google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
@@ -1772,21 +1683,12 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
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.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
-google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
-google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
-google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
+google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
+google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
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=
@@ -1799,27 +1701,24 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
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.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 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk=
+google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
-gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
-gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
-gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/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=
@@ -1830,18 +1729,19 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
+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=
@@ -1849,10 +1749,10 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
-honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
-mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=
-mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE=
+honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
+honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
+mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM=
+mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
@@ -1865,3 +1765,4 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
diff --git a/libs/autofile/autofile_test.go b/libs/autofile/autofile_test.go
index 3e3814d5e9..ff6056fc56 100644
--- a/libs/autofile/autofile_test.go
+++ b/libs/autofile/autofile_test.go
@@ -1,7 +1,6 @@
package autofile
import (
- "io/ioutil"
"os"
"path/filepath"
"syscall"
@@ -24,7 +23,7 @@ func TestSIGHUP(t *testing.T) {
})
// First, create a temporary directory and move into it
- dir, err := ioutil.TempDir("", "sighup_test")
+ dir, err := os.MkdirTemp("", "sighup_test")
require.NoError(t, err)
t.Cleanup(func() {
os.RemoveAll(dir)
@@ -49,7 +48,7 @@ func TestSIGHUP(t *testing.T) {
require.NoError(t, err)
// Move into a different temporary directory
- otherDir, err := ioutil.TempDir("", "sighup_test_other")
+ otherDir, err := os.MkdirTemp("", "sighup_test_other")
require.NoError(t, err)
defer os.RemoveAll(otherDir)
err = os.Chdir(otherDir)
@@ -79,7 +78,7 @@ func TestSIGHUP(t *testing.T) {
}
// The current directory should be empty
- files, err := ioutil.ReadDir(".")
+ files, err := os.ReadDir(".")
require.NoError(t, err)
assert.Empty(t, files)
}
@@ -87,7 +86,7 @@ func TestSIGHUP(t *testing.T) {
// // Manually modify file permissions, close, and reopen using autofile:
// // We expect the file permissions to be changed back to the intended perms.
// func TestOpenAutoFilePerms(t *testing.T) {
-// file, err := ioutil.TempFile("", "permission_test")
+// file, err := os.CreateTemp("", "permission_test")
// require.NoError(t, err)
// err = file.Close()
// require.NoError(t, err)
@@ -113,7 +112,7 @@ func TestSIGHUP(t *testing.T) {
func TestAutoFileSize(t *testing.T) {
// First, create an AutoFile writing to a tempfile dir
- f, err := ioutil.TempFile("", "sighup_test")
+ f, err := os.CreateTemp("", "sighup_test")
require.NoError(t, err)
err = f.Close()
require.NoError(t, err)
diff --git a/libs/autofile/group_test.go b/libs/autofile/group_test.go
index 0981923eb4..a57c59b606 100644
--- a/libs/autofile/group_test.go
+++ b/libs/autofile/group_test.go
@@ -2,7 +2,6 @@ package autofile
import (
"io"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -17,7 +16,7 @@ import (
func createTestGroupWithHeadSizeLimit(t *testing.T, headSizeLimit int64) *Group {
testID := tmrand.Str(12)
testDir := "_test_" + testID
- err := tmos.EnsureDir(testDir, 0700)
+ err := tmos.EnsureDir(testDir, 0o700)
require.NoError(t, err, "Error creating dir")
headPath := testDir + "/myfile"
@@ -122,7 +121,7 @@ func TestRotateFile(t *testing.T) {
}
}()
- dir, err := ioutil.TempDir("", "rotate_test")
+ dir, err := os.MkdirTemp("", "rotate_test")
require.NoError(t, err)
defer os.RemoveAll(dir)
err = os.Chdir(dir)
@@ -151,21 +150,21 @@ func TestRotateFile(t *testing.T) {
require.NoError(t, err)
// Read g.Head.Path+"000"
- body1, err := ioutil.ReadFile(g.Head.Path + ".000")
+ body1, err := os.ReadFile(g.Head.Path + ".000")
assert.NoError(t, err, "Failed to read first rolled file")
if string(body1) != "Line 1\nLine 2\nLine 3\n" {
t.Errorf("got unexpected contents: [%v]", string(body1))
}
// Read g.Head.Path
- body2, err := ioutil.ReadFile(g.Head.Path)
+ body2, err := os.ReadFile(g.Head.Path)
assert.NoError(t, err, "Failed to read first rolled file")
if string(body2) != "Line 4\nLine 5\nLine 6\n" {
t.Errorf("got unexpected contents: [%v]", string(body2))
}
// Make sure there are no files in the current, temporary directory
- files, err := ioutil.ReadDir(".")
+ files, err := os.ReadDir(".")
require.NoError(t, err)
assert.Empty(t, files)
diff --git a/libs/cli/flags/log_level.go b/libs/cli/flags/log_level.go
index d96ad3f47c..706305300e 100644
--- a/libs/cli/flags/log_level.go
+++ b/libs/cli/flags/log_level.go
@@ -17,7 +17,8 @@ const (
// all other modules).
//
// Example:
-// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info")
+//
+// ParseLogLevel("consensus:debug,mempool:debug,*:error", log.NewTMLogger(os.Stdout), "info")
func ParseLogLevel(lvl string, logger log.Logger, defaultLogLevelValue string) (log.Logger, error) {
if lvl == "" {
return nil, errors.New("empty log level")
diff --git a/libs/cli/helper.go b/libs/cli/helper.go
index 4b87bd60be..fb90bb0bb5 100644
--- a/libs/cli/helper.go
+++ b/libs/cli/helper.go
@@ -4,7 +4,6 @@ import (
"bytes"
"fmt"
"io"
- "io/ioutil"
"os"
"path/filepath"
@@ -19,7 +18,7 @@ func WriteConfigVals(dir string, vals map[string]string) error {
data += fmt.Sprintf("%s = \"%s\"\n", k, v)
}
cfile := filepath.Join(dir, "config.toml")
- return ioutil.WriteFile(cfile, []byte(data), 0600)
+ return os.WriteFile(cfile, []byte(data), 0o600)
}
// RunWithArgs executes the given command with the specified command line args
diff --git a/libs/cli/setup_test.go b/libs/cli/setup_test.go
index 0cb3223446..87539278c6 100644
--- a/libs/cli/setup_test.go
+++ b/libs/cli/setup_test.go
@@ -2,7 +2,7 @@ package cli
import (
"fmt"
- "io/ioutil"
+ "os"
"strconv"
"strings"
"testing"
@@ -27,8 +27,11 @@ func TestSetupEnv(t *testing.T) {
{nil, map[string]string{"DEMO_FOOBAR": "good"}, "good"},
{nil, map[string]string{"DEMOFOOBAR": "silly"}, "silly"},
// and that cli overrides env...
- {[]string{"--foobar", "important"},
- map[string]string{"DEMO_FOOBAR": "ignored"}, "important"},
+ {
+ []string{"--foobar", "important"},
+ map[string]string{"DEMO_FOOBAR": "ignored"},
+ "important",
+ },
}
for idx, tc := range cases {
@@ -55,7 +58,7 @@ func TestSetupEnv(t *testing.T) {
}
func tempDir() string {
- cdir, err := ioutil.TempDir("", "test-cli")
+ cdir, err := os.MkdirTemp("", "test-cli")
if err != nil {
panic(err)
}
diff --git a/libs/clist/clist.go b/libs/clist/clist.go
index 5579b1d0f2..2e4171b1c7 100644
--- a/libs/clist/clist.go
+++ b/libs/clist/clist.go
@@ -24,7 +24,6 @@ import (
const MaxLength = int(^uint(0) >> 1)
/*
-
CElement is an element of a linked-list
Traversal from a CElement is goroutine-safe.
@@ -41,7 +40,6 @@ the for-loop. Use sync.Cond when you need serial access to the
"condition". In our case our condition is if `next != nil || removed`,
and there's no reason to serialize that condition for goroutines
waiting on NextWait() (since it's just a read operation).
-
*/
type CElement struct {
mtx tmsync.RWMutex
diff --git a/libs/clist/clist_test.go b/libs/clist/clist_test.go
index d10a1e5ae9..7b10478fd9 100644
--- a/libs/clist/clist_test.go
+++ b/libs/clist/clist_test.go
@@ -68,6 +68,7 @@ func TestSmall(t *testing.T) {
// This test is quite hacky because it relies on SetFinalizer
// which isn't guaranteed to run at all.
+
//nolint:unused,deadcode
func _TestGCFifo(t *testing.T) {
if runtime.GOARCH != "amd64" {
@@ -117,6 +118,7 @@ func _TestGCFifo(t *testing.T) {
// This test is quite hacky because it relies on SetFinalizer
// which isn't guaranteed to run at all.
+//
//nolint:unused,deadcode
func _TestGCRandom(t *testing.T) {
if runtime.GOARCH != "amd64" {
diff --git a/libs/flowrate/flowrate.go b/libs/flowrate/flowrate.go
index c7ba932821..fdc168d18d 100644
--- a/libs/flowrate/flowrate.go
+++ b/libs/flowrate/flowrate.go
@@ -39,10 +39,10 @@ type Monitor struct {
// weight of each sample in the exponential moving average (EMA) calculation.
// The exact formulas are:
//
-// sampleTime = currentTime - prevSampleTime
-// sampleRate = byteCount / sampleTime
-// weight = 1 - exp(-sampleTime/windowSize)
-// newRate = weight*sampleRate + (1-weight)*oldRate
+// sampleTime = currentTime - prevSampleTime
+// sampleRate = byteCount / sampleTime
+// weight = 1 - exp(-sampleTime/windowSize)
+// newRate = weight*sampleRate + (1-weight)*oldRate
//
// The default values for sampleRate and windowSize (if <= 0) are 100ms and 1s,
// respectively.
diff --git a/libs/json/doc.go b/libs/json/doc.go
index d5ef4047f3..1b92c0db62 100644
--- a/libs/json/doc.go
+++ b/libs/json/doc.go
@@ -13,12 +13,12 @@
// compatibility with e.g. Javascript (which uses 64-bit floats for numbers, having 53-bit
// precision):
//
-// int32(32) // Output: 32
-// uint32(32) // Output: 32
-// int64(64) // Output: "64"
-// uint64(64) // Output: "64"
-// int(64) // Output: "64"
-// uint(64) // Output: "64"
+// int32(32) // Output: 32
+// uint32(32) // Output: 32
+// int64(64) // Output: "64"
+// uint64(64) // Output: "64"
+// int(64) // Output: "64"
+// uint(64) // Output: "64"
//
// Encoding of other scalars follows encoding/json:
//
@@ -50,7 +50,7 @@
// Times are encoded as encoding/json, in RFC3339Nano format, but requiring UTC time zone (with zero
// times emitted as "0001-01-01T00:00:00Z" as with encoding/json):
//
-// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
+// time.Date(2020, 6, 8, 16, 21, 28, 123, time.FixedZone("UTC+2", 2*60*60))
// // Output: "2020-06-08T14:21:28.000000123Z"
// time.Time{} // Output: "0001-01-01T00:00:00Z"
// (*time.Time)(nil) // Output: null
@@ -95,5 +95,4 @@
//
// Struct{Car: &Car{Wheels: 4}, Vehicle: &Car{Wheels: 4}}
// // Output: {"Car": {"Wheels: 4"}, "Vehicle": {"type":"vehicle/car","value":{"Wheels":4}}}
-//
package json
diff --git a/libs/log/filter.go b/libs/log/filter.go
index e39a85dcbf..4b7ed981cd 100644
--- a/libs/log/filter.go
+++ b/libs/log/filter.go
@@ -69,18 +69,19 @@ func (l *filter) Error(msg string, keyvals ...interface{}) {
// Allow*With methods, it is used as the logger's level.
//
// Examples:
-// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
-// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
//
-// logger = log.NewFilter(logger, log.AllowError(),
-// log.AllowInfoWith("module", "crypto"),
-// log.AllowNoneWith("user", "Sam"))
-// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
+// logger = log.NewFilter(logger, log.AllowError(), log.AllowInfoWith("module", "crypto"))
+// logger.With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto"
//
-// logger = log.NewFilter(logger,
-// log.AllowError(),
-// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
-// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
+// logger = log.NewFilter(logger, log.AllowError(),
+// log.AllowInfoWith("module", "crypto"),
+// log.AllowNoneWith("user", "Sam"))
+// logger.With("module", "crypto", "user", "Sam").Info("Hello") # returns nil
+//
+// logger = log.NewFilter(logger,
+// log.AllowError(),
+// log.AllowInfoWith("module", "crypto"), log.AllowNoneWith("user", "Sam"))
+// logger.With("user", "Sam").With("module", "crypto").Info("Hello") # produces "I... Hello module=crypto user=Sam"
func (l *filter) With(keyvals ...interface{}) Logger {
keyInAllowedKeyvals := false
diff --git a/libs/log/logger.go b/libs/log/logger.go
index 9b1a65d42a..34aca8af5d 100644
--- a/libs/log/logger.go
+++ b/libs/log/logger.go
@@ -22,9 +22,9 @@ type Logger interface {
//
// If w implements the following interface, so does the returned writer.
//
-// interface {
-// Fd() uintptr
-// }
+// interface {
+// Fd() uintptr
+// }
func NewSyncWriter(w io.Writer) io.Writer {
return kitlog.NewSyncWriter(w)
}
diff --git a/libs/log/tm_logger_test.go b/libs/log/tm_logger_test.go
index cbe29d9942..8427febf18 100644
--- a/libs/log/tm_logger_test.go
+++ b/libs/log/tm_logger_test.go
@@ -2,7 +2,7 @@ package log_test
import (
"bytes"
- "io/ioutil"
+ "io"
"strings"
"testing"
@@ -90,11 +90,11 @@ func TestError(t *testing.T) {
}
func BenchmarkTMLoggerSimple(b *testing.B) {
- benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), baseInfoMessage)
+ benchmarkRunner(b, log.NewTMLogger(io.Discard), baseInfoMessage)
}
func BenchmarkTMLoggerContextual(b *testing.B) {
- benchmarkRunner(b, log.NewTMLogger(ioutil.Discard), withInfoMessage)
+ benchmarkRunner(b, log.NewTMLogger(io.Discard), withInfoMessage)
}
func benchmarkRunner(b *testing.B, logger log.Logger, f func(log.Logger)) {
diff --git a/libs/log/tmfmt_logger.go b/libs/log/tmfmt_logger.go
index 391ae478a4..492c1c12ea 100644
--- a/libs/log/tmfmt_logger.go
+++ b/libs/log/tmfmt_logger.go
@@ -65,7 +65,7 @@ func (l tmfmtLogger) Log(keyvals ...interface{}) error {
switch keyvals[i] {
case kitlevel.Key():
excludeIndexes = append(excludeIndexes, i)
- switch keyvals[i+1].(type) { // nolint:gocritic
+ switch keyvals[i+1].(type) { //nolint:gocritic
case string:
lvl = keyvals[i+1].(string)
case kitlevel.Value:
diff --git a/libs/log/tmfmt_logger_test.go b/libs/log/tmfmt_logger_test.go
index 4b82455f13..9642d03646 100644
--- a/libs/log/tmfmt_logger_test.go
+++ b/libs/log/tmfmt_logger_test.go
@@ -3,7 +3,7 @@ package log_test
import (
"bytes"
"errors"
- "io/ioutil"
+ "io"
"math"
"regexp"
"testing"
@@ -62,16 +62,16 @@ func TestTMFmtLogger(t *testing.T) {
}
func BenchmarkTMFmtLoggerSimple(b *testing.B) {
- benchmarkRunnerKitlog(b, log.NewTMFmtLogger(ioutil.Discard), baseMessage)
+ benchmarkRunnerKitlog(b, log.NewTMFmtLogger(io.Discard), baseMessage)
}
func BenchmarkTMFmtLoggerContextual(b *testing.B) {
- benchmarkRunnerKitlog(b, log.NewTMFmtLogger(ioutil.Discard), withMessage)
+ benchmarkRunnerKitlog(b, log.NewTMFmtLogger(io.Discard), withMessage)
}
func TestTMFmtLoggerConcurrency(t *testing.T) {
t.Parallel()
- testConcurrency(t, log.NewTMFmtLogger(ioutil.Discard), 10000)
+ testConcurrency(t, log.NewTMFmtLogger(io.Discard), 10000)
}
func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Logger)) {
@@ -83,7 +83,7 @@ func benchmarkRunnerKitlog(b *testing.B, logger kitlog.Logger, f func(kitlog.Log
}
}
-//nolint: errcheck // ignore errors
+//nolint:errcheck // ignore errors
var (
baseMessage = func(logger kitlog.Logger) { logger.Log("foo_key", "foo_value") }
withMessage = func(logger kitlog.Logger) { kitlog.With(logger, "a", "b").Log("d", "f") }
diff --git a/libs/os/os.go b/libs/os/os.go
index a24e1ba7ff..16aa3e68bb 100644
--- a/libs/os/os.go
+++ b/libs/os/os.go
@@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"io"
- "io/ioutil"
"os"
"os/signal"
"syscall"
@@ -62,11 +61,11 @@ func FileExists(filePath string) bool {
}
func ReadFile(filePath string) ([]byte, error) {
- return ioutil.ReadFile(filePath)
+ return os.ReadFile(filePath)
}
func MustReadFile(filePath string) []byte {
- fileBytes, err := ioutil.ReadFile(filePath)
+ fileBytes, err := os.ReadFile(filePath)
if err != nil {
Exit(fmt.Sprintf("MustReadFile failed: %v", err))
return nil
@@ -75,7 +74,7 @@ func MustReadFile(filePath string) []byte {
}
func WriteFile(filePath string, contents []byte, mode os.FileMode) error {
- return ioutil.WriteFile(filePath, contents, mode)
+ return os.WriteFile(filePath, contents, mode)
}
func MustWriteFile(filePath string, contents []byte, mode os.FileMode) {
diff --git a/libs/os/os_test.go b/libs/os/os_test.go
index 88bf1412c3..7c43476e88 100644
--- a/libs/os/os_test.go
+++ b/libs/os/os_test.go
@@ -3,7 +3,6 @@ package os
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -12,7 +11,7 @@ import (
)
func TestCopyFile(t *testing.T) {
- tmpfile, err := ioutil.TempFile("", "example")
+ tmpfile, err := os.CreateTemp("", "example")
if err != nil {
t.Fatal(err)
}
@@ -29,7 +28,7 @@ func TestCopyFile(t *testing.T) {
if _, err := os.Stat(copyfile); os.IsNotExist(err) {
t.Fatal("copy should exist")
}
- data, err := ioutil.ReadFile(copyfile)
+ data, err := os.ReadFile(copyfile)
if err != nil {
t.Fatal(err)
}
@@ -40,35 +39,35 @@ func TestCopyFile(t *testing.T) {
}
func TestEnsureDir(t *testing.T) {
- tmp, err := ioutil.TempDir("", "ensure-dir")
+ tmp, err := os.MkdirTemp("", "ensure-dir")
require.NoError(t, err)
defer os.RemoveAll(tmp)
// Should be possible to create a new directory.
- err = EnsureDir(filepath.Join(tmp, "dir"), 0755)
+ err = EnsureDir(filepath.Join(tmp, "dir"), 0o755)
require.NoError(t, err)
require.DirExists(t, filepath.Join(tmp, "dir"))
// Should succeed on existing directory.
- err = EnsureDir(filepath.Join(tmp, "dir"), 0755)
+ err = EnsureDir(filepath.Join(tmp, "dir"), 0o755)
require.NoError(t, err)
// Should fail on file.
- err = ioutil.WriteFile(filepath.Join(tmp, "file"), []byte{}, 0644)
+ err = os.WriteFile(filepath.Join(tmp, "file"), []byte{}, 0o644)
require.NoError(t, err)
- err = EnsureDir(filepath.Join(tmp, "file"), 0755)
+ err = EnsureDir(filepath.Join(tmp, "file"), 0o755)
require.Error(t, err)
// Should allow symlink to dir.
err = os.Symlink(filepath.Join(tmp, "dir"), filepath.Join(tmp, "linkdir"))
require.NoError(t, err)
- err = EnsureDir(filepath.Join(tmp, "linkdir"), 0755)
+ err = EnsureDir(filepath.Join(tmp, "linkdir"), 0o755)
require.NoError(t, err)
// Should error on symlink to file.
err = os.Symlink(filepath.Join(tmp, "file"), filepath.Join(tmp, "linkfile"))
require.NoError(t, err)
- err = EnsureDir(filepath.Join(tmp, "linkfile"), 0755)
+ err = EnsureDir(filepath.Join(tmp, "linkfile"), 0o755)
require.Error(t, err)
}
@@ -76,7 +75,7 @@ func TestEnsureDir(t *testing.T) {
// the origin is positively a non-directory and that it is ready for copying.
// See https://github.com/tendermint/tendermint/issues/6427
func TestTrickedTruncation(t *testing.T) {
- tmpDir, err := ioutil.TempDir(os.TempDir(), "pwn_truncate")
+ tmpDir, err := os.MkdirTemp(os.TempDir(), "pwn_truncate")
if err != nil {
t.Fatal(err)
}
@@ -84,12 +83,12 @@ func TestTrickedTruncation(t *testing.T) {
originalWALPath := filepath.Join(tmpDir, "wal")
originalWALContent := []byte("I AM BECOME DEATH, DESTROYER OF ALL WORLDS!")
- if err := ioutil.WriteFile(originalWALPath, originalWALContent, 0755); err != nil {
+ if err := os.WriteFile(originalWALPath, originalWALContent, 0o755); err != nil {
t.Fatal(err)
}
// 1. Sanity check.
- readWAL, err := ioutil.ReadFile(originalWALPath)
+ readWAL, err := os.ReadFile(originalWALPath)
if err != nil {
t.Fatal(err)
}
@@ -104,7 +103,7 @@ func TestTrickedTruncation(t *testing.T) {
}
// 3. Check the WAL's content
- reReadWAL, err := ioutil.ReadFile(originalWALPath)
+ reReadWAL, err := os.ReadFile(originalWALPath)
if err != nil {
t.Fatal(err)
}
diff --git a/libs/pubsub/pubsub.go b/libs/pubsub/pubsub.go
index 914a080de9..321e775c88 100644
--- a/libs/pubsub/pubsub.go
+++ b/libs/pubsub/pubsub.go
@@ -12,26 +12,25 @@
//
// Example:
//
-// q, err := query.New("account.name='John'")
-// if err != nil {
-// return err
-// }
-// ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
-// defer cancel()
-// subscription, err := pubsub.Subscribe(ctx, "johns-transactions", q)
-// if err != nil {
-// return err
-// }
-//
-// for {
-// select {
-// case msg <- subscription.Out():
-// // handle msg.Data() and msg.Events()
-// case <-subscription.Cancelled():
-// return subscription.Err()
-// }
-// }
+// q, err := query.New("account.name='John'")
+// if err != nil {
+// return err
+// }
+// ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
+// defer cancel()
+// subscription, err := pubsub.Subscribe(ctx, "johns-transactions", q)
+// if err != nil {
+// return err
+// }
//
+// for {
+// select {
+// case msg <- subscription.Out():
+// // handle msg.Data() and msg.Events()
+// case <-subscription.Cancelled():
+// return subscription.Err()
+// }
+// }
package pubsub
import (
diff --git a/libs/pubsub/query/query.go b/libs/pubsub/query/query.go
index cf6903ccfc..35023d5650 100644
--- a/libs/pubsub/query/query.go
+++ b/libs/pubsub/query/query.go
@@ -1,6 +1,6 @@
// Package query provides a parser for a custom query format:
//
-// abci.invoice.number=22 AND abci.invoice.owner=Ivan
+// abci.invoice.number=22 AND abci.invoice.owner=Ivan
//
// See query.peg for the grammar, which is a https://en.wikipedia.org/wiki/Parsing_expression_grammar.
// More: https://github.com/PhilippeSigaud/Pegged/wiki/PEG-Basics
diff --git a/libs/pubsub/query/query.peg.go b/libs/pubsub/query/query.peg.go
index 98f8f4ed1e..27a708f67a 100644
--- a/libs/pubsub/query/query.peg.go
+++ b/libs/pubsub/query/query.peg.go
@@ -1,4 +1,3 @@
-//nolint
package query
import (
diff --git a/libs/pubsub/subscription.go b/libs/pubsub/subscription.go
index 8f90e177ac..eca2c5dfb9 100644
--- a/libs/pubsub/subscription.go
+++ b/libs/pubsub/subscription.go
@@ -43,7 +43,6 @@ func (s *Subscription) Out() <-chan Message {
return s.out
}
-// nolint: misspell
// Cancelled returns a channel that's closed when the subscription is
// terminated and supposed to be used in a select statement.
func (s *Subscription) Cancelled() <-chan struct{} {
@@ -54,7 +53,8 @@ func (s *Subscription) Cancelled() <-chan struct{} {
// If the channel is closed, Err returns a non-nil error explaining why:
// - ErrUnsubscribed if the subscriber choose to unsubscribe,
// - ErrOutOfCapacity if the subscriber is not pulling messages fast enough
-// and the channel returned by Out became full,
+// and the channel returned by Out became full,
+//
// After Err returns a non-nil error, successive calls to Err return the same
// error.
func (s *Subscription) Err() error {
diff --git a/libs/rand/random.go b/libs/rand/random.go
index 41d04a4406..e86581d8b2 100644
--- a/libs/rand/random.go
+++ b/libs/rand/random.go
@@ -48,7 +48,7 @@ func (r *Rand) init() {
}
func (r *Rand) reset(seed int64) {
- r.rand = mrand.New(mrand.NewSource(seed)) // nolint:gosec // G404: Use of weak random number generator
+ r.rand = mrand.New(mrand.NewSource(seed)) //nolint:gosec,nolintlint // G404: Use of weak random number generator
}
//----------------------------------------
diff --git a/libs/tempfile/tempfile_test.go b/libs/tempfile/tempfile_test.go
index 9d07f806bd..ccff9f42e0 100644
--- a/libs/tempfile/tempfile_test.go
+++ b/libs/tempfile/tempfile_test.go
@@ -5,7 +5,6 @@ package tempfile
import (
"bytes"
"fmt"
- "io/ioutil"
"os"
testing "testing"
@@ -18,16 +17,16 @@ func TestWriteFileAtomic(t *testing.T) {
var (
data = []byte(tmrand.Str(tmrand.Intn(2048)))
old = tmrand.Bytes(tmrand.Intn(2048))
- perm os.FileMode = 0600
+ perm os.FileMode = 0o600
)
- f, err := ioutil.TempFile("/tmp", "write-atomic-test-")
+ f, err := os.CreateTemp("/tmp", "write-atomic-test-")
if err != nil {
t.Fatal(err)
}
defer os.Remove(f.Name())
- if err = ioutil.WriteFile(f.Name(), old, 0600); err != nil {
+ if err = os.WriteFile(f.Name(), old, 0o600); err != nil {
t.Fatal(err)
}
@@ -35,7 +34,7 @@ func TestWriteFileAtomic(t *testing.T) {
t.Fatal(err)
}
- rData, err := ioutil.ReadFile(f.Name())
+ rData, err := os.ReadFile(f.Name())
if err != nil {
t.Fatal(err)
}
@@ -69,7 +68,7 @@ func TestWriteFileAtomicDuplicateFile(t *testing.T) {
firstFileRand := randWriteFileSuffix()
atomicWriteFileRand = defaultSeed
fname := "/tmp/" + atomicWriteFilePrefix + firstFileRand
- f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777)
+ f, err := os.OpenFile(fname, atomicWriteFileFlag, 0o777)
defer os.Remove(fname)
// Defer here, in case there is a panic in WriteFileAtomic.
defer os.Remove(fileToWrite)
@@ -77,14 +76,14 @@ func TestWriteFileAtomicDuplicateFile(t *testing.T) {
require.NoError(t, err)
_, err = f.WriteString(testString)
require.NoError(t, err)
- err = WriteFileAtomic(fileToWrite, []byte(expectedString), 0777)
+ err = WriteFileAtomic(fileToWrite, []byte(expectedString), 0o777)
require.NoError(t, err)
// Check that the first atomic file was untouched
- firstAtomicFileBytes, err := ioutil.ReadFile(fname)
+ firstAtomicFileBytes, err := os.ReadFile(fname)
require.NoError(t, err, "Error reading first atomic file")
require.Equal(t, []byte(testString), firstAtomicFileBytes, "First atomic file was overwritten")
// Check that the resultant file is correct
- resultantFileBytes, err := ioutil.ReadFile(fileToWrite)
+ resultantFileBytes, err := os.ReadFile(fileToWrite)
require.NoError(t, err, "Error reading resultant file")
require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes")
@@ -113,7 +112,7 @@ func TestWriteFileAtomicManyDuplicates(t *testing.T) {
for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ {
fileRand := randWriteFileSuffix()
fname := "/tmp/" + atomicWriteFilePrefix + fileRand
- f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777)
+ f, err := os.OpenFile(fname, atomicWriteFileFlag, 0o777)
require.Nil(t, err)
_, err = f.WriteString(fmt.Sprintf(testString, i))
require.NoError(t, err)
@@ -124,21 +123,21 @@ func TestWriteFileAtomicManyDuplicates(t *testing.T) {
// Defer here, in case there is a panic in WriteFileAtomic.
defer os.Remove(fileToWrite)
- err := WriteFileAtomic(fileToWrite, []byte(expectedString), 0777)
+ err := WriteFileAtomic(fileToWrite, []byte(expectedString), 0o777)
require.NoError(t, err)
// Check that all intermittent atomic file were untouched
atomicWriteFileRand = defaultSeed
for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ {
fileRand := randWriteFileSuffix()
fname := "/tmp/" + atomicWriteFilePrefix + fileRand
- firstAtomicFileBytes, err := ioutil.ReadFile(fname)
+ firstAtomicFileBytes, err := os.ReadFile(fname)
require.Nil(t, err, "Error reading first atomic file")
require.Equal(t, []byte(fmt.Sprintf(testString, i)), firstAtomicFileBytes,
"atomic write file %d was overwritten", i)
}
// Check that the resultant file is correct
- resultantFileBytes, err := ioutil.ReadFile(fileToWrite)
+ resultantFileBytes, err := os.ReadFile(fileToWrite)
require.Nil(t, err, "Error reading resultant file")
require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes")
}
diff --git a/light/client.go b/light/client.go
index 51330c77c9..8a0500cbfe 100644
--- a/light/client.go
+++ b/light/client.go
@@ -284,16 +284,16 @@ func (c *Client) restoreTrustedLightBlock() error {
// if options.Height:
//
-// 1) ahead of trustedLightBlock.Height => fetch light blocks (same height as
+// 1. ahead of trustedLightBlock.Height => fetch light blocks (same height as
// trustedLightBlock) from primary provider and check it's hash matches the
// trustedLightBlock's hash (if not, remove trustedLightBlock and all the light blocks
// before)
//
-// 2) equals trustedLightBlock.Height => check options.Hash matches the
+// 2. equals trustedLightBlock.Height => check options.Hash matches the
// trustedLightBlock's hash (if not, remove trustedLightBlock and all the light blocks
// before)
//
-// 3) behind trustedLightBlock.Height => remove all the light blocks between
+// 3. behind trustedLightBlock.Height => remove all the light blocks between
// options.Height and trustedLightBlock.Height, update trustedLightBlock, then
// check options.Hash matches the trustedLightBlock's hash (if not, remove
// trustedLightBlock and all the light blocks before)
@@ -395,10 +395,10 @@ func (c *Client) initializeWithTrustOptions(ctx context.Context, options TrustOp
// TrustedLightBlock returns a trusted light block at the given height (0 - the latest).
//
// It returns an error if:
-// - there are some issues with the trusted store, although that should not
-// happen normally;
-// - negative height is passed;
-// - header has not been verified yet and is therefore not in the store
+// - there are some issues with the trusted store, although that should not
+// happen normally;
+// - negative height is passed;
+// - header has not been verified yet and is therefore not in the store
//
// Safe for concurrent use by multiple goroutines.
func (c *Client) TrustedLightBlock(height int64) (*types.LightBlock, error) {
@@ -506,12 +506,13 @@ func (c *Client) VerifyLightBlockAtHeight(ctx context.Context, height int64, now
// headers are not adjacent, verifySkipping is performed and necessary (not all)
// intermediate headers will be requested. See the specification for details.
// Intermediate headers are not saved to database.
-// https://github.com/tendermint/spec/blob/master/spec/consensus/light-client.md
+// https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client.md
//
// If the header, which is older than the currently trusted header, is
// requested and the light client does not have it, VerifyHeader will perform:
-// a) verifySkipping verification if nearest trusted header is found & not expired
-// b) backwards verification in all other cases
+//
+// a) verifySkipping verification if nearest trusted header is found & not expired
+// b) backwards verification in all other cases
//
// It returns ErrOldHeaderExpired if the latest trusted header expired.
//
@@ -980,12 +981,12 @@ func (c *Client) backwards(
// lightBlockFromPrimary retrieves the lightBlock from the primary provider
// at the specified height. This method also handles provider behavior as follows:
//
-// 1. If the provider does not respond or does not have the block, it tries again
-// with a different provider
-// 2. If all providers return the same error, the light client forwards the error to
-// where the initial request came from
-// 3. If the provider provides an invalid light block, is deemed unreliable or returns
-// any other error, the primary is permanently dropped and is replaced by a witness.
+// 1. If the provider does not respond or does not have the block, it tries again
+// with a different provider
+// 2. If all providers return the same error, the light client forwards the error to
+// where the initial request came from
+// 3. If the provider provides an invalid light block, is deemed unreliable or returns
+// any other error, the primary is permanently dropped and is replaced by a witness.
func (c *Client) lightBlockFromPrimary(ctx context.Context, height int64) (*types.LightBlock, error) {
c.providerMutex.Lock()
l, err := c.primary.LightBlock(ctx, height)
diff --git a/light/detector.go b/light/detector.go
index 881242135c..1fd21f41eb 100644
--- a/light/detector.go
+++ b/light/detector.go
@@ -109,7 +109,9 @@ func (c *Client) detectDivergence(ctx context.Context, primaryTrace []*types.Lig
//
// 1: errConflictingHeaders -> there may have been an attack on this light client
// 2: errBadWitness -> the witness has either not responded, doesn't have the header or has given us an invalid one
-// Note: In the case of an invalid header we remove the witness
+//
+// Note: In the case of an invalid header we remove the witness
+//
// 3: nil -> the hashes of the two headers match
func (c *Client) compareNewHeaderWithWitness(ctx context.Context, errc chan error, h *types.SignedHeader,
witness provider.Provider, witnessIndex int) {
@@ -275,16 +277,16 @@ func (c *Client) handleConflictingHeaders(
// it has received from another and preforms verifySkipping at the heights of each of the intermediate
// headers in the trace until it reaches the divergentHeader. 1 of 2 things can happen.
//
-// 1. The light client verifies a header that is different to the intermediate header in the trace. This
-// is the bifurcation point and the light client can create evidence from it
-// 2. The source stops responding, doesn't have the block or sends an invalid header in which case we
-// return the error and remove the witness
+// 1. The light client verifies a header that is different to the intermediate header in the trace. This
+// is the bifurcation point and the light client can create evidence from it
+// 2. The source stops responding, doesn't have the block or sends an invalid header in which case we
+// return the error and remove the witness
//
// CONTRACT:
-// 1. Trace can not be empty len(trace) > 0
-// 2. The last block in the trace can not be of a lower height than the target block
-// trace[len(trace)-1].Height >= targetBlock.Height
-// 3. The
+// 1. Trace can not be empty len(trace) > 0
+// 2. The last block in the trace can not be of a lower height than the target block
+// trace[len(trace)-1].Height >= targetBlock.Height
+// 3. The
func (c *Client) examineConflictingHeaderAgainstTrace(
ctx context.Context,
trace []*types.LightBlock,
diff --git a/light/doc.go b/light/doc.go
index 700bbeb6cf..2fa6fa72ba 100644
--- a/light/doc.go
+++ b/light/doc.go
@@ -63,38 +63,38 @@ This package provides three major things:
Example usage:
- db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
- if err != nil {
- // handle error
- }
-
- c, err := NewHTTPClient(
- chainID,
- TrustOptions{
- Period: 504 * time.Hour, // 21 days
- Height: 100,
- Hash: header.Hash(),
- },
- "http://localhost:26657",
- []string{"http://witness1:26657"},
- dbs.New(db, ""),
- )
- if err != nil {
- // handle error
- }
-
- h, err := c.TrustedHeader(100)
- if err != nil {
- // handle error
- }
- fmt.Println("header", h)
+ db, err := dbm.NewGoLevelDB("light-client-db", dbDir)
+ if err != nil {
+ // handle error
+ }
+
+ c, err := NewHTTPClient(
+ chainID,
+ TrustOptions{
+ Period: 504 * time.Hour, // 21 days
+ Height: 100,
+ Hash: header.Hash(),
+ },
+ "http://localhost:26657",
+ []string{"http://witness1:26657"},
+ dbs.New(db, ""),
+ )
+ if err != nil {
+ // handle error
+ }
+
+ h, err := c.TrustedHeader(100)
+ if err != nil {
+ // handle error
+ }
+ fmt.Println("header", h)
Check out other examples in example_test.go
## 2. Pure functions to verify a new header (see verifier.go)
Verify function verifies a new header against some trusted header. See
-https://github.com/tendermint/spec/blob/master/spec/consensus/light-client/verification.md
+https://github.com/tendermint/tendermint/blob/v0.34.x/spec/consensus/light-client/verification.md
for details.
There are two methods of verification: sequential and bisection
@@ -118,10 +118,10 @@ as a wrapper, which verifies all the headers, using a light client connected to
some other node.
See
-https://docs.tendermint.com/master/tendermint-core/light-client-protocol.html
+https://docs.tendermint.com/v0.34/tendermint-core/light-client-protocol.html
for usage example.
Or see
-https://github.com/tendermint/spec/tree/master/spec/consensus/light-client
+https://github.com/tendermint/tendermint/tree/v0.34.x/spec/consensus/light-client
for the full spec
*/
package light
diff --git a/light/example_test.go b/light/example_test.go
index b599778b86..f49b34a5de 100644
--- a/light/example_test.go
+++ b/light/example_test.go
@@ -3,7 +3,6 @@ package light_test
import (
"context"
"fmt"
- "io/ioutil"
stdlog "log"
"os"
"testing"
@@ -25,7 +24,7 @@ func ExampleClient_Update() {
// give Tendermint time to generate some blocks
time.Sleep(5 * time.Second)
- dbDir, err := ioutil.TempDir("", "light-client-example")
+ dbDir, err := os.MkdirTemp("", "light-client-example")
if err != nil {
stdlog.Fatal(err)
}
@@ -93,7 +92,7 @@ func ExampleClient_VerifyLightBlockAtHeight() {
// give Tendermint time to generate some blocks
time.Sleep(5 * time.Second)
- dbDir, err := ioutil.TempDir("", "light-client-example")
+ dbDir, err := os.MkdirTemp("", "light-client-example")
if err != nil {
stdlog.Fatal(err)
}
diff --git a/light/provider/http/http.go b/light/provider/http/http.go
index 665fcbe707..f529cae484 100644
--- a/light/provider/http/http.go
+++ b/light/provider/http/http.go
@@ -216,6 +216,6 @@ func validateHeight(height int64) (*int64, error) {
// exponential backoff (with jitter)
// 0.5s -> 2s -> 4.5s -> 8s -> 12.5 with 1s variation
func backoffTimeout(attempt uint16) time.Duration {
- // nolint:gosec // G404: Use of weak random number generator
+ //nolint:gosec // G404: Use of weak random number generator
return time.Duration(500*attempt*attempt)*time.Millisecond + time.Duration(rand.Intn(1000))*time.Millisecond
}
diff --git a/light/proxy/routes.go b/light/proxy/routes.go
index 7aacbed10b..169d026f26 100644
--- a/light/proxy/routes.go
+++ b/light/proxy/routes.go
@@ -21,21 +21,21 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
"health": rpcserver.NewRPCFunc(makeHealthFunc(c), ""),
"status": rpcserver.NewRPCFunc(makeStatusFunc(c), ""),
"net_info": rpcserver.NewRPCFunc(makeNetInfoFunc(c), ""),
- "blockchain": rpcserver.NewRPCFunc(makeBlockchainInfoFunc(c), "minHeight,maxHeight"),
- "genesis": rpcserver.NewRPCFunc(makeGenesisFunc(c), ""),
- "genesis_chunked": rpcserver.NewRPCFunc(makeGenesisChunkedFunc(c), ""),
- "block": rpcserver.NewRPCFunc(makeBlockFunc(c), "height"),
- "block_by_hash": rpcserver.NewRPCFunc(makeBlockByHashFunc(c), "hash"),
- "block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height"),
- "commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height"),
+ "blockchain": rpcserver.NewRPCFunc(makeBlockchainInfoFunc(c), "minHeight,maxHeight", rpcserver.Cacheable()),
+ "genesis": rpcserver.NewRPCFunc(makeGenesisFunc(c), "", rpcserver.Cacheable()),
+ "genesis_chunked": rpcserver.NewRPCFunc(makeGenesisChunkedFunc(c), "", rpcserver.Cacheable()),
+ "block": rpcserver.NewRPCFunc(makeBlockFunc(c), "height", rpcserver.Cacheable("height")),
+ "block_by_hash": rpcserver.NewRPCFunc(makeBlockByHashFunc(c), "hash", rpcserver.Cacheable()),
+ "block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height", rpcserver.Cacheable("height")),
+ "commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height", rpcserver.Cacheable("height")),
"data_commitment": rpcserver.NewRPCFunc(makeDataCommitmentFunc(c), "beginBlock,endBlock"),
- "tx": rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove"),
+ "tx": rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove", rpcserver.Cacheable()),
"tx_search": rpcserver.NewRPCFunc(makeTxSearchFunc(c), "query,prove,page,per_page,order_by"),
"block_search": rpcserver.NewRPCFunc(makeBlockSearchFunc(c), "query,page,per_page,order_by"),
- "validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height,page,per_page"),
+ "validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height,page,per_page", rpcserver.Cacheable("height")),
"dump_consensus_state": rpcserver.NewRPCFunc(makeDumpConsensusStateFunc(c), ""),
"consensus_state": rpcserver.NewRPCFunc(makeConsensusStateFunc(c), ""),
- "consensus_params": rpcserver.NewRPCFunc(makeConsensusParamsFunc(c), "height"),
+ "consensus_params": rpcserver.NewRPCFunc(makeConsensusParamsFunc(c), "height", rpcserver.Cacheable("height")),
"unconfirmed_txs": rpcserver.NewRPCFunc(makeUnconfirmedTxsFunc(c), "limit"),
"num_unconfirmed_txs": rpcserver.NewRPCFunc(makeNumUnconfirmedTxsFunc(c), ""),
@@ -46,7 +46,7 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
// abci API
"abci_query": rpcserver.NewRPCFunc(makeABCIQueryFunc(c), "path,data,height,prove"),
- "abci_info": rpcserver.NewRPCFunc(makeABCIInfoFunc(c), ""),
+ "abci_info": rpcserver.NewRPCFunc(makeABCIInfoFunc(c), "", rpcserver.Cacheable()),
// evidence API
"broadcast_evidence": rpcserver.NewRPCFunc(makeBroadcastEvidenceFunc(c), "evidence"),
@@ -63,7 +63,7 @@ func makeHealthFunc(c *lrpc.Client) rpcHealthFunc {
type rpcStatusFunc func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error)
-// nolint: interfacer
+//nolint:interfacer
func makeStatusFunc(c *lrpc.Client) rpcStatusFunc {
return func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) {
return c.Status(ctx.Context())
@@ -276,8 +276,8 @@ type rpcABCIQueryFunc func(ctx *rpctypes.Context, path string,
func makeABCIQueryFunc(c *lrpc.Client) rpcABCIQueryFunc {
return func(ctx *rpctypes.Context, path string, data bytes.HexBytes,
- height int64, prove bool) (*ctypes.ResultABCIQuery, error) {
-
+ height int64, prove bool,
+ ) (*ctypes.ResultABCIQuery, error) {
return c.ABCIQueryWithOptions(ctx.Context(), path, data, rpcclient.ABCIQueryOptions{
Height: height,
Prove: prove,
@@ -295,7 +295,7 @@ func makeABCIInfoFunc(c *lrpc.Client) rpcABCIInfoFunc {
type rpcBroadcastEvidenceFunc func(ctx *rpctypes.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error)
-// nolint: interfacer
+//nolint:interfacer
func makeBroadcastEvidenceFunc(c *lrpc.Client) rpcBroadcastEvidenceFunc {
return func(ctx *rpctypes.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
return c.BroadcastEvidence(ctx.Context(), ev)
diff --git a/light/rpc/client.go b/light/rpc/client.go
index a4ee6b3fcc..2ebcff8c5e 100644
--- a/light/rpc/client.go
+++ b/light/rpc/client.go
@@ -27,7 +27,8 @@ var errNegOrZeroHeight = errors.New("negative or zero height")
type KeyPathFunc func(path string, key []byte) (merkle.KeyPath, error)
// LightClient is an interface that contains functionality needed by Client from the light client.
-//go:generate mockery --case underscore --name LightClient
+//
+//go:generate ../../scripts/mockery_generate.sh LightClient
type LightClient interface {
ChainID() string
Update(ctx context.Context, now time.Time) (*types.LightBlock, error)
diff --git a/light/rpc/mocks/light_client.go b/light/rpc/mocks/light_client.go
index 9dfdcd001d..fabf73b01e 100644
--- a/light/rpc/mocks/light_client.go
+++ b/light/rpc/mocks/light_client.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
diff --git a/light/verifier.go b/light/verifier.go
index 0b0a4926b1..2ec02e8773 100644
--- a/light/verifier.go
+++ b/light/verifier.go
@@ -19,13 +19,13 @@ var (
// VerifyNonAdjacent verifies non-adjacent untrustedHeader against
// trustedHeader. It ensures that:
//
-// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
-// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
-// c) trustLevel ([1/3, 1]) of trustedHeaderVals (or trustedHeaderNextVals)
-// signed correctly (if not, ErrNewValSetCantBeTrusted is returned)
-// d) more than 2/3 of untrustedVals have signed h2
-// (otherwise, ErrInvalidHeader is returned)
-// e) headers are non-adjacent.
+// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
+// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
+// c) trustLevel ([1/3, 1]) of trustedHeaderVals (or trustedHeaderNextVals)
+// signed correctly (if not, ErrNewValSetCantBeTrusted is returned)
+// d) more than 2/3 of untrustedVals have signed h2
+// (otherwise, ErrInvalidHeader is returned)
+// e) headers are non-adjacent.
//
// maxClockDrift defines how much untrustedHeader.Time can drift into the
// future.
@@ -81,12 +81,12 @@ func VerifyNonAdjacent(
// VerifyAdjacent verifies directly adjacent untrustedHeader against
// trustedHeader. It ensures that:
//
-// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
-// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
-// c) untrustedHeader.ValidatorsHash equals trustedHeader.NextValidatorsHash
-// d) more than 2/3 of new validators (untrustedVals) have signed h2
-// (otherwise, ErrInvalidHeader is returned)
-// e) headers are adjacent.
+// a) trustedHeader can still be trusted (if not, ErrOldHeaderExpired is returned)
+// b) untrustedHeader is valid (if not, ErrInvalidHeader is returned)
+// c) untrustedHeader.ValidatorsHash equals trustedHeader.NextValidatorsHash
+// d) more than 2/3 of new validators (untrustedVals) have signed h2
+// (otherwise, ErrInvalidHeader is returned)
+// e) headers are adjacent.
//
// maxClockDrift defines how much untrustedHeader.Time can drift into the
// future.
@@ -212,12 +212,12 @@ func HeaderExpired(h *types.SignedHeader, trustingPeriod time.Duration, now time
// VerifyBackwards verifies an untrusted header with a height one less than
// that of an adjacent trusted header. It ensures that:
//
-// a) untrusted header is valid
-// b) untrusted header has a time before the trusted header
-// c) that the LastBlockID hash of the trusted header is the same as the hash
-// of the trusted header
+// a) untrusted header is valid
+// b) untrusted header has a time before the trusted header
+// c) that the LastBlockID hash of the trusted header is the same as the hash
+// of the trusted header
//
-// For any of these cases ErrInvalidHeader is returned.
+// For any of these cases ErrInvalidHeader is returned.
func VerifyBackwards(untrustedHeader, trustedHeader *types.Header) error {
if err := untrustedHeader.ValidateBasic(); err != nil {
return ErrInvalidHeader{err}
diff --git a/mempool/v0/reactor.go b/mempool/v0/reactor.go
index 3fc8506418..52ed185142 100644
--- a/mempool/v0/reactor.go
+++ b/mempool/v0/reactor.go
@@ -5,6 +5,8 @@ import (
"fmt"
"time"
+ "github.com/gogo/protobuf/proto"
+
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/clist"
"github.com/tendermint/tendermint/libs/log"
@@ -134,6 +136,7 @@ func (memR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
ID: mempool.MempoolChannel,
Priority: 5,
RecvMessageCapacity: batchMsg.Size(),
+ MessageType: &protomem.Message{},
},
}
}
@@ -154,32 +157,56 @@ func (memR *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {
// Receive implements Reactor.
// It adds any received transactions to the mempool.
-func (memR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
- msg, err := memR.decodeMsg(msgBytes)
- if err != nil {
- memR.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err)
- memR.Switch.StopPeerForError(src, err)
- return
- }
- memR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg)
-
- txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(src)}
- if src != nil {
- txInfo.SenderP2PID = src.ID()
- }
+func (memR *Reactor) ReceiveEnvelope(e p2p.Envelope) {
+ memR.Logger.Debug("Receive", "src", e.Src, "chId", e.ChannelID, "msg", e.Message)
+ switch msg := e.Message.(type) {
+ case *protomem.Txs:
+ protoTxs := msg.GetTxs()
+ if len(protoTxs) == 0 {
+ memR.Logger.Error("received empty txs from peer", "src", e.Src)
+ return
+ }
+ txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(e.Src)}
+ if e.Src != nil {
+ txInfo.SenderP2PID = e.Src.ID()
+ }
- for _, tx := range msg.Txs {
- err = memR.mempool.CheckTx(tx, nil, txInfo)
- if errors.Is(err, mempool.ErrTxInCache) {
- memR.Logger.Debug("Tx already exists in cache", "tx", tx.String())
- } else if err != nil {
- memR.Logger.Info("Could not check tx", "tx", tx.String(), "err", err)
+ var err error
+ for _, tx := range protoTxs {
+ ntx := types.Tx(tx)
+ err = memR.mempool.CheckTx(ntx, nil, txInfo)
+ if errors.Is(err, mempool.ErrTxInCache) {
+ memR.Logger.Debug("Tx already exists in cache", "tx", ntx.String())
+ } else if err != nil {
+ memR.Logger.Info("Could not check tx", "tx", ntx.String(), "err", err)
+ }
}
+ default:
+ memR.Logger.Error("unknown message type", "src", e.Src, "chId", e.ChannelID, "msg", e.Message)
+ memR.Switch.StopPeerForError(e.Src, fmt.Errorf("mempool cannot handle message of type: %T", e.Message))
+ return
}
// broadcasting happens from go routines per peer
}
+func (memR *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &protomem.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+ memR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
+}
+
// PeerState describes the state of a peer.
type PeerState interface {
GetHeight() int64
@@ -234,18 +261,10 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) {
// https://github.com/tendermint/tendermint/issues/5796
if _, ok := memTx.senders.Load(peerID); !ok {
- msg := protomem.Message{
- Sum: &protomem.Message_Txs{
- Txs: &protomem.Txs{Txs: [][]byte{memTx.tx}},
- },
- }
-
- bz, err := msg.Marshal()
- if err != nil {
- panic(err)
- }
-
- success := peer.Send(mempool.MempoolChannel, bz)
+ success := p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: mempool.MempoolChannel,
+ Message: &protomem.Txs{Txs: [][]byte{memTx.tx}},
+ }, memR.Logger)
if !success {
time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond)
continue
@@ -264,35 +283,6 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) {
}
}
-func (memR *Reactor) decodeMsg(bz []byte) (TxsMessage, error) {
- msg := protomem.Message{}
- err := msg.Unmarshal(bz)
- if err != nil {
- return TxsMessage{}, err
- }
-
- var message TxsMessage
-
- if i, ok := msg.Sum.(*protomem.Message_Txs); ok {
- txs := i.Txs.GetTxs()
-
- if len(txs) == 0 {
- return message, errors.New("empty TxsMessage")
- }
-
- decoded := make([]types.Tx, len(txs))
- for j, tx := range txs {
- decoded[j] = types.Tx(tx)
- }
-
- message = TxsMessage{
- Txs: decoded,
- }
- return message, nil
- }
- return message, fmt.Errorf("msg type: %T is not supported", msg)
-}
-
// TxsMessage is a Message containing transactions.
type TxsMessage struct {
Txs []types.Tx
diff --git a/mempool/v0/reactor_test.go b/mempool/v0/reactor_test.go
index 4250836549..c629b0aeb2 100644
--- a/mempool/v0/reactor_test.go
+++ b/mempool/v0/reactor_test.go
@@ -10,6 +10,7 @@ import (
"github.com/fortytw2/leaktest"
"github.com/go-kit/log/term"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -264,6 +265,10 @@ func TestMempoolIDsPanicsIfNodeRequestsOvermaxActiveIDs(t *testing.T) {
})
}
+// TODO: This test tests that we don't panic and are able to generate new
+// PeerIDs for each peer we add. It seems as though we should be able to test
+// this in a much more direct way.
+// https://github.com/tendermint/tendermint/issues/9639
func TestDontExhaustMaxActiveIDs(t *testing.T) {
config := cfg.TestConfig()
const N = 1
@@ -279,11 +284,41 @@ func TestDontExhaustMaxActiveIDs(t *testing.T) {
for i := 0; i < mempool.MaxActiveIDs+1; i++ {
peer := mock.NewPeer(nil)
- reactor.Receive(mempool.MempoolChannel, peer, []byte{0x1, 0x2, 0x3})
+ reactor.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: mempool.MempoolChannel,
+ Src: peer,
+ Message: &memproto.Message{}, // This uses the wrong message type on purpose to stop the peer as in an error state in the reactor.
+ },
+ )
reactor.AddPeer(peer)
}
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config := cfg.TestConfig()
+ const N = 1
+ reactors := makeAndConnectReactors(config, N)
+ var (
+ reactor = reactors[0]
+ peer = mock.NewPeer(nil)
+ )
+ defer func() {
+ err := reactor.Stop()
+ assert.NoError(t, err)
+ }()
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ m := &memproto.Txs{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(mempool.MempoolChannel, peer, msg)
+ })
+}
+
// mempoolLogger is a TestingLogger which uses a different
// color for each validator ("validator" key must exist).
func mempoolLogger() log.Logger {
diff --git a/mempool/v1/mempool.go b/mempool/v1/mempool.go
index 0deee0fbba..20db6d2947 100644
--- a/mempool/v1/mempool.go
+++ b/mempool/v1/mempool.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/creachadair/taskgroup"
+
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/clist"
diff --git a/mempool/v1/mempool_bench_test.go b/mempool/v1/mempool_bench_test.go
index bad8ec8ab9..a26501275d 100644
--- a/mempool/v1/mempool_bench_test.go
+++ b/mempool/v1/mempool_bench_test.go
@@ -7,6 +7,7 @@ import (
"time"
"github.com/stretchr/testify/require"
+
"github.com/tendermint/tendermint/mempool"
)
diff --git a/mempool/v1/reactor.go b/mempool/v1/reactor.go
index 4da51bab8f..00fe65e797 100644
--- a/mempool/v1/reactor.go
+++ b/mempool/v1/reactor.go
@@ -5,6 +5,8 @@ import (
"fmt"
"time"
+ "github.com/gogo/protobuf/proto"
+
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/clist"
"github.com/tendermint/tendermint/libs/log"
@@ -133,6 +135,7 @@ func (memR *Reactor) GetChannels() []*p2p.ChannelDescriptor {
ID: mempool.MempoolChannel,
Priority: 5,
RecvMessageCapacity: batchMsg.Size(),
+ MessageType: &protomem.Message{},
},
}
}
@@ -153,28 +156,54 @@ func (memR *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {
// Receive implements Reactor.
// It adds any received transactions to the mempool.
-func (memR *Reactor) Receive(chID byte, src p2p.Peer, msgBytes []byte) {
- msg, err := memR.decodeMsg(msgBytes)
- if err != nil {
- memR.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err)
- memR.Switch.StopPeerForError(src, err)
+func (memR *Reactor) ReceiveEnvelope(e p2p.Envelope) {
+ memR.Logger.Debug("Receive", "src", e.Src, "chId", e.ChannelID, "msg", e.Message)
+ switch msg := e.Message.(type) {
+ case *protomem.Txs:
+ protoTxs := msg.GetTxs()
+ if len(protoTxs) == 0 {
+ memR.Logger.Error("received tmpty txs from peer", "src", e.Src)
+ return
+ }
+ txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(e.Src)}
+ if e.Src != nil {
+ txInfo.SenderP2PID = e.Src.ID()
+ }
+
+ var err error
+ for _, tx := range protoTxs {
+ ntx := types.Tx(tx)
+ err = memR.mempool.CheckTx(ntx, nil, txInfo)
+ if errors.Is(err, mempool.ErrTxInCache) {
+ memR.Logger.Debug("Tx already exists in cache", "tx", ntx.String())
+ } else if err != nil {
+ memR.Logger.Info("Could not check tx", "tx", ntx.String(), "err", err)
+ }
+ }
+ default:
+ memR.Logger.Error("unknown message type", "src", e.Src, "chId", e.ChannelID, "msg", e.Message)
+ memR.Switch.StopPeerForError(e.Src, fmt.Errorf("mempool cannot handle message of type: %T", e.Message))
return
}
- memR.Logger.Debug("Receive", "src", src, "chId", chID, "msg", msg)
- txInfo := mempool.TxInfo{SenderID: memR.ids.GetForPeer(src)}
- if src != nil {
- txInfo.SenderP2PID = src.ID()
+ // broadcasting happens from go routines per peer
+}
+
+func (memR *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &protomem.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
}
- for _, tx := range msg.Txs {
- err = memR.mempool.CheckTx(tx, nil, txInfo)
- if err == mempool.ErrTxInCache {
- memR.Logger.Debug("Tx already exists in cache", "tx", tx.String())
- } else if err != nil {
- memR.Logger.Info("Could not check tx", "tx", tx.String(), "err", err)
- }
+ uw, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
}
- // broadcasting happens from go routines per peer
+ memR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: uw,
+ })
}
// PeerState describes the state of a peer.
@@ -233,18 +262,10 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) {
// NOTE: Transaction batching was disabled due to
// https://github.com/tendermint/tendermint/issues/5796
if !memTx.HasPeer(peerID) {
- msg := protomem.Message{
- Sum: &protomem.Message_Txs{
- Txs: &protomem.Txs{Txs: [][]byte{memTx.tx}},
- },
- }
-
- bz, err := msg.Marshal()
- if err != nil {
- panic(err)
- }
-
- success := peer.Send(mempool.MempoolChannel, bz)
+ success := p2p.SendEnvelopeShim(peer, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: mempool.MempoolChannel,
+ Message: &protomem.Txs{Txs: [][]byte{memTx.tx}},
+ }, memR.Logger)
if !success {
time.Sleep(mempool.PeerCatchupSleepIntervalMS * time.Millisecond)
continue
@@ -268,37 +289,6 @@ func (memR *Reactor) broadcastTxRoutine(peer p2p.Peer) {
//-----------------------------------------------------------------------------
// Messages
-func (memR *Reactor) decodeMsg(bz []byte) (TxsMessage, error) {
- msg := protomem.Message{}
- err := msg.Unmarshal(bz)
- if err != nil {
- return TxsMessage{}, err
- }
-
- var message TxsMessage
-
- if i, ok := msg.Sum.(*protomem.Message_Txs); ok {
- txs := i.Txs.GetTxs()
-
- if len(txs) == 0 {
- return message, errors.New("empty TxsMessage")
- }
-
- decoded := make([]types.Tx, len(txs))
- for j, tx := range txs {
- decoded[j] = types.Tx(tx)
- }
-
- message = TxsMessage{
- Txs: decoded,
- }
- return message, nil
- }
- return message, fmt.Errorf("msg type: %T is not supported", msg)
-}
-
-//-------------------------------------
-
// TxsMessage is a Message containing transactions.
type TxsMessage struct {
Txs []types.Tx
diff --git a/mempool/v1/reactor_test.go b/mempool/v1/reactor_test.go
index a911220164..74f9f469ff 100644
--- a/mempool/v1/reactor_test.go
+++ b/mempool/v1/reactor_test.go
@@ -8,10 +8,12 @@ import (
"time"
"github.com/go-kit/log/term"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/abci/example/kvstore"
+ "github.com/tendermint/tendermint/p2p/mock"
cfg "github.com/tendermint/tendermint/config"
@@ -93,6 +95,35 @@ func TestMempoolVectors(t *testing.T) {
}
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ config := cfg.TestConfig()
+ // if there were more than two reactors, the order of transactions could not be
+ // asserted in waitForTxsOnReactors (due to transactions gossiping). If we
+ // replace Connect2Switches (full mesh) with a func, which connects first
+ // reactor to others and nothing else, this test should also pass with >2 reactors.
+ const N = 1
+ reactors := makeAndConnectReactors(config, N)
+ var (
+ reactor = reactors[0]
+ peer = mock.NewPeer(nil)
+ )
+ defer func() {
+ err := reactor.Stop()
+ assert.NoError(t, err)
+ }()
+
+ reactor.InitPeer(peer)
+ reactor.AddPeer(peer)
+ m := &memproto.Txs{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ reactor.Receive(mempool.MempoolChannel, peer, msg)
+ })
+}
+
func makeAndConnectReactors(config *cfg.Config, n int) []*Reactor {
reactors := make([]*Reactor, n)
logger := mempoolLogger()
diff --git a/networks/local/README.md b/networks/local/README.md
index dcb31ae713..de7057ee79 100644
--- a/networks/local/README.md
+++ b/networks/local/README.md
@@ -1,3 +1,3 @@
# Local Cluster with Docker Compose
-See the [docs](https://docs.tendermint.com/master/networks/docker-compose.html).
+See the [docs](https://docs.tendermint.com/v0.34/networks/docker-compose.html).
diff --git a/networks/remote/README.md b/networks/remote/README.md
index 8f2e047363..f5d0685a3e 100644
--- a/networks/remote/README.md
+++ b/networks/remote/README.md
@@ -1,3 +1,3 @@
# Remote Cluster with Terraform and Ansible
-See the [docs](https://docs.tendermint.com/master/networks/terraform-and-ansible.html).
+See the [docs](https://docs.tendermint.com/v0.34/networks/terraform-and-ansible.html).
diff --git a/node/doc.go b/node/doc.go
index 08f3fa2586..3a145c573a 100644
--- a/node/doc.go
+++ b/node/doc.go
@@ -6,35 +6,34 @@ Adding new p2p.Reactor(s)
To add a new p2p.Reactor, use the CustomReactors option:
- node, err := NewNode(
- config,
- privVal,
- nodeKey,
- clientCreator,
- genesisDocProvider,
- dbProvider,
- metricsProvider,
- logger,
- CustomReactors(map[string]p2p.Reactor{"CUSTOM": customReactor}),
- )
+ node, err := NewNode(
+ config,
+ privVal,
+ nodeKey,
+ clientCreator,
+ genesisDocProvider,
+ dbProvider,
+ metricsProvider,
+ logger,
+ CustomReactors(map[string]p2p.Reactor{"CUSTOM": customReactor}),
+ )
Replacing existing p2p.Reactor(s)
To replace the built-in p2p.Reactor, use the CustomReactors option:
- node, err := NewNode(
- config,
- privVal,
- nodeKey,
- clientCreator,
- genesisDocProvider,
- dbProvider,
- metricsProvider,
- logger,
- CustomReactors(map[string]p2p.Reactor{"BLOCKCHAIN": customBlockchainReactor}),
- )
+ node, err := NewNode(
+ config,
+ privVal,
+ nodeKey,
+ clientCreator,
+ genesisDocProvider,
+ dbProvider,
+ metricsProvider,
+ logger,
+ CustomReactors(map[string]p2p.Reactor{"BLOCKCHAIN": customBlockchainReactor}),
+ )
The list of existing reactors can be found in CustomReactors documentation.
-
*/
package node
diff --git a/node/node.go b/node/node.go
index 22d1471cac..eb0b77e427 100644
--- a/node/node.go
+++ b/node/node.go
@@ -53,7 +53,7 @@ import (
tmtime "github.com/tendermint/tendermint/types/time"
"github.com/tendermint/tendermint/version"
- _ "net/http/pprof" // nolint: gosec // securely exposed on separate, optional port
+ _ "net/http/pprof" //nolint: gosec // securely exposed on separate, optional port
_ "github.com/lib/pq" // provide the psql db driver
)
@@ -69,6 +69,8 @@ type DBContext struct {
// DBProvider takes a DBContext and returns an instantiated DB.
type DBProvider func(*DBContext) (dbm.DB, error)
+const readHeaderTimeout = 10 * time.Second
+
// DefaultDBProvider returns a database using the DBBackend and DBDir
// specified in the ctx.Config.
func DefaultDBProvider(ctx *DBContext) (dbm.DB, error) {
@@ -144,12 +146,12 @@ type fastSyncReactor interface {
// WARNING: using any name from the below list of the existing reactors will
// result in replacing it with the custom one.
//
-// - MEMPOOL
-// - BLOCKCHAIN
-// - CONSENSUS
-// - EVIDENCE
-// - PEX
-// - STATESYNC
+// - MEMPOOL
+// - BLOCKCHAIN
+// - CONSENSUS
+// - EVIDENCE
+// - PEX
+// - STATESYNC
func CustomReactors(reactors map[string]p2p.Reactor) Option {
return func(n *Node) {
for name, reactor := range reactors {
@@ -271,7 +273,6 @@ func createAndStartIndexerService(
eventBus *types.EventBus,
logger log.Logger,
) (*txindex.IndexerService, txindex.TxIndexer, indexer.BlockIndexer, error) {
-
var (
txIndexer txindex.TxIndexer
blockIndexer indexer.BlockIndexer
@@ -303,7 +304,7 @@ func createAndStartIndexerService(
blockIndexer = &blockidxnull.BlockerIndexer{}
}
- indexerService := txindex.NewIndexerService(txIndexer, blockIndexer, eventBus)
+ indexerService := txindex.NewIndexerService(txIndexer, blockIndexer, eventBus, false)
indexerService.SetLogger(logger.With("module", "txindex"))
if err := indexerService.Start(); err != nil {
@@ -320,8 +321,8 @@ func doHandshake(
genDoc *types.GenesisDoc,
eventBus types.BlockEventPublisher,
proxyApp proxy.AppConns,
- consensusLogger log.Logger) error {
-
+ consensusLogger log.Logger,
+) error {
handshaker := cs.NewHandshaker(stateStore, state, blockStore, genDoc)
handshaker.SetLogger(consensusLogger)
handshaker.SetEventBus(eventBus)
@@ -371,7 +372,6 @@ func createMempoolAndMempoolReactor(
memplMetrics *mempl.Metrics,
logger log.Logger,
) (mempl.Mempool, p2p.Reactor) {
-
switch config.Mempool.Version {
case cfg.MempoolV1:
mp := mempoolv1.NewTxMempool(
@@ -422,14 +422,16 @@ func createMempoolAndMempoolReactor(
}
func createEvidenceReactor(config *cfg.Config, dbProvider DBProvider,
- stateDB dbm.DB, blockStore *store.BlockStore, logger log.Logger) (*evidence.Reactor, *evidence.Pool, error) {
-
+ stateDB dbm.DB, blockStore *store.BlockStore, logger log.Logger,
+) (*evidence.Reactor, *evidence.Pool, error) {
evidenceDB, err := dbProvider(&DBContext{"evidence", config})
if err != nil {
return nil, nil, err
}
evidenceLogger := logger.With("module", "evidence")
- evidencePool, err := evidence.NewPool(evidenceDB, sm.NewStore(stateDB), blockStore)
+ evidencePool, err := evidence.NewPool(evidenceDB, sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: config.Storage.DiscardABCIResponses,
+ }), blockStore)
if err != nil {
return nil, nil, err
}
@@ -443,8 +445,8 @@ func createBlockchainReactor(config *cfg.Config,
blockExec *sm.BlockExecutor,
blockStore *store.BlockStore,
fastSync bool,
- logger log.Logger) (bcReactor p2p.Reactor, err error) {
-
+ logger log.Logger,
+) (bcReactor p2p.Reactor, err error) {
switch config.FastSync.Version {
case "v0":
bcReactor = bcv0.NewBlockchainReactor(state.Copy(), blockExec, blockStore, fastSync)
@@ -470,8 +472,8 @@ func createConsensusReactor(config *cfg.Config,
csMetrics *cs.Metrics,
waitSync bool,
eventBus *types.EventBus,
- consensusLogger log.Logger) (*cs.Reactor, *cs.State) {
-
+ consensusLogger log.Logger,
+) (*cs.Reactor, *cs.State) {
consensusState := cs.NewState(
config.Consensus,
state.Copy(),
@@ -573,8 +575,8 @@ func createSwitch(config *cfg.Config,
evidenceReactor *evidence.Reactor,
nodeInfo p2p.NodeInfo,
nodeKey *p2p.NodeKey,
- p2pLogger log.Logger) *p2p.Switch {
-
+ p2pLogger log.Logger,
+) *p2p.Switch {
sw := p2p.NewSwitch(
config.P2P,
transport,
@@ -596,8 +598,8 @@ func createSwitch(config *cfg.Config,
}
func createAddrBookAndSetOnSwitch(config *cfg.Config, sw *p2p.Switch,
- p2pLogger log.Logger, nodeKey *p2p.NodeKey) (pex.AddrBook, error) {
-
+ p2pLogger log.Logger, nodeKey *p2p.NodeKey,
+) (pex.AddrBook, error) {
addrBook := pex.NewAddrBook(config.P2P.AddrBookFile(), config.P2P.AddrBookStrict)
addrBook.SetLogger(p2pLogger.With("book", config.P2P.AddrBookFile()))
@@ -623,8 +625,8 @@ func createAddrBookAndSetOnSwitch(config *cfg.Config, sw *p2p.Switch,
}
func createPEXReactorAndAddToSwitch(addrBook pex.AddrBook, config *cfg.Config,
- sw *p2p.Switch, logger log.Logger) *pex.Reactor {
-
+ sw *p2p.Switch, logger log.Logger,
+) *pex.Reactor {
// TODO persistent peers ? so we can have their DNS addrs saved
pexReactor := pex.NewReactor(addrBook,
&pex.ReactorConfig{
@@ -646,7 +648,8 @@ func createPEXReactorAndAddToSwitch(addrBook pex.AddrBook, config *cfg.Config,
// startStateSync starts an asynchronous state sync process, then switches to fast sync mode.
func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reactor,
stateProvider statesync.StateProvider, config *cfg.StateSyncConfig, fastSync bool,
- stateStore sm.Store, blockStore *store.BlockStore, state sm.State) error {
+ stateStore sm.Store, blockStore *store.BlockStore, state sm.State,
+) error {
ssR.Logger.Info("Starting state sync")
if stateProvider == nil {
@@ -708,14 +711,16 @@ func NewNode(config *cfg.Config,
dbProvider DBProvider,
metricsProvider MetricsProvider,
logger log.Logger,
- options ...Option) (*Node, error) {
-
+ options ...Option,
+) (*Node, error) {
blockStore, stateDB, err := initDBs(config, dbProvider)
if err != nil {
return nil, err
}
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: config.Storage.DiscardABCIResponses,
+ })
state, genDoc, err := LoadStateFromDBOrGenesisDocProvider(stateDB, genesisDocProvider)
if err != nil {
@@ -889,6 +894,7 @@ func NewNode(config *cfg.Config,
if config.RPC.PprofListenAddress != "" {
go func() {
logger.Info("Starting pprof server", "laddr", config.RPC.PprofListenAddress)
+ //nolint:gosec,nolintlint // G114: Use of net/http serve function that has no support for setting timeouts
logger.Error("pprof server error", "err", http.ListenAndServe(config.RPC.PprofListenAddress, nil))
}()
}
@@ -1203,7 +1209,6 @@ func (n *Node) startRPC() ([]net.Listener, error) {
}
return listeners, nil
-
}
// startPrometheusServer starts a Prometheus HTTP server, listening for metrics
@@ -1217,6 +1222,7 @@ func (n *Node) startPrometheusServer(addr string) *http.Server {
promhttp.HandlerOpts{MaxRequestsInFlight: n.config.Instrumentation.MaxOpenConnections},
),
),
+ ReadHeaderTimeout: readHeaderTimeout,
}
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
@@ -1375,9 +1381,7 @@ func makeNodeInfo(
//------------------------------------------------------------------------------
-var (
- genesisDocKey = []byte("genesisDoc")
-)
+var genesisDocKey = []byte("genesisDoc")
// LoadStateFromDBOrGenesisDocProvider attempts to load the state from the
// database, or creates one using the given genesisDocProvider. On success this also
@@ -1399,7 +1403,9 @@ func LoadStateFromDBOrGenesisDocProvider(
return sm.State{}, nil, err
}
}
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
state, err := stateStore.LoadFromDBOrGenesisDoc(genDoc)
if err != nil {
return sm.State{}, nil, err
diff --git a/node/node_test.go b/node/node_test.go
index 8a4a44dc7a..953870a811 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -235,7 +235,9 @@ func TestCreateProposalBlock(t *testing.T) {
var height int64 = 1
state, stateDB, privVals := state(1, height)
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
maxBytes := 16384
var partSize uint32 = 256
maxEvidenceBytes := int64(maxBytes / 2)
@@ -340,7 +342,9 @@ func TestMaxProposalBlockSize(t *testing.T) {
var height int64 = 1
state, stateDB, _ := state(1, height)
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
var maxBytes int64 = 16384
var partSize uint32 = 256
state.ConsensusParams.Block.MaxBytes = maxBytes
@@ -464,7 +468,9 @@ func state(nVals int, height int64) (sm.State, dbm.DB, []types.PrivValidator) {
// save validators to db for 2 heights
stateDB := dbm.NewMemDB()
- stateStore := sm.NewStore(stateDB)
+ stateStore := sm.NewStore(stateDB, sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
if err := stateStore.Save(s); err != nil {
panic(err)
}
diff --git a/p2p/README.md b/p2p/README.md
index 9ba7303fa1..549f1da938 100644
--- a/p2p/README.md
+++ b/p2p/README.md
@@ -4,8 +4,8 @@ The p2p package provides an abstraction around peer-to-peer communication.
Docs:
-- [Connection](https://docs.tendermint.com/master/spec/p2p/connection.html) for details on how connections and multiplexing work
-- [Peer](https://docs.tendermint.com/master/spec/p2p/node.html) for details on peer ID, handshakes, and peer exchange
-- [Node](https://docs.tendermint.com/master/spec/p2p/node.html) for details about different types of nodes and how they should work
-- [Pex](https://docs.tendermint.com/master/spec/reactors/pex/pex.html) for details on peer discovery and exchange
-- [Config](https://docs.tendermint.com/master/spec/p2p/config.html) for details on some config option
+- [Connection](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/connection.md) for details on how connections and multiplexing work
+- [Peer](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/node.md) for details on peer ID, handshakes, and peer exchange
+- [Node](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/node.md) for details about different types of nodes and how they should work
+- [Pex](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/reactors/pex/pex.md) for details on peer discovery and exchange
+- [Config](https://github.com/tendermint/tendermint/blob/v0.34.x/spec/p2p/config.md) for details on some config option
diff --git a/p2p/base_reactor.go b/p2p/base_reactor.go
index 86b0d980a0..87e145fb20 100644
--- a/p2p/base_reactor.go
+++ b/p2p/base_reactor.go
@@ -44,9 +44,25 @@ type Reactor interface {
// copying.
//
// CONTRACT: msgBytes are not nil.
+ //
+ // Only one of Receive or ReceiveEnvelope are called per message. If ReceiveEnvelope
+ // is implemented, it will be used, otherwise the switch will fallback to
+ // using Receive.
+ // Deprecated: Reactors looking to receive data from a peer should implement ReceiveEnvelope.
+ // Receive will be deprecated in favor of ReceiveEnvelope in v0.37.
Receive(chID byte, peer Peer, msgBytes []byte)
}
+type EnvelopeReceiver interface {
+ // ReceiveEnvelope is called by the switch when an envelope is received from any connected
+ // peer on any of the channels registered by the reactor.
+ //
+ // Only one of Receive or ReceiveEnvelope are called per message. If ReceiveEnvelope
+ // is implemented, it will be used, otherwise the switch will fallback to
+ // using Receive. Receive will be replaced by ReceiveEnvelope in a future version
+ ReceiveEnvelope(Envelope)
+}
+
//--------------------------------------
type BaseReactor struct {
@@ -67,5 +83,6 @@ func (br *BaseReactor) SetSwitch(sw *Switch) {
func (*BaseReactor) GetChannels() []*conn.ChannelDescriptor { return nil }
func (*BaseReactor) AddPeer(peer Peer) {}
func (*BaseReactor) RemovePeer(peer Peer, reason interface{}) {}
+func (*BaseReactor) ReceiveEnvelope(e Envelope) {}
func (*BaseReactor) Receive(chID byte, peer Peer, msgBytes []byte) {}
func (*BaseReactor) InitPeer(peer Peer) Peer { return peer }
diff --git a/p2p/conn/conn_notgo110.go b/p2p/conn/conn_notgo110.go
index 21dffad2c2..96f9a2a7ea 100644
--- a/p2p/conn/conn_notgo110.go
+++ b/p2p/conn/conn_notgo110.go
@@ -10,9 +10,13 @@ import (
// Only Go1.10 has a proper net.Conn implementation that
// has the SetDeadline method implemented as per
-// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
+//
+// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
+//
// lest we run into problems like
-// https://github.com/tendermint/tendermint/issues/851
+//
+// https://github.com/tendermint/tendermint/issues/851
+//
// so for go versions < Go1.10 use our custom net.Conn creator
// that doesn't return an `Unimplemented error` for net.Conn.
// Before https://github.com/tendermint/tendermint/commit/49faa79bdce5663894b3febbf4955fb1d172df04
diff --git a/p2p/conn/connection.go b/p2p/conn/connection.go
index 44ff838939..187f579222 100644
--- a/p2p/conn/connection.go
+++ b/p2p/conn/connection.go
@@ -62,6 +62,7 @@ The byte id and the relative priorities of each `Channel` are configured upon
initialization of the connection.
There are two methods for sending messages:
+
func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {}
@@ -723,6 +724,7 @@ type ChannelDescriptor struct {
SendQueueCapacity int
RecvBufferCapacity int
RecvMessageCapacity int
+ MessageType proto.Message
}
func (chDesc ChannelDescriptor) FillDefaults() (filled ChannelDescriptor) {
diff --git a/p2p/conn/connection_test.go b/p2p/conn/connection_test.go
index c41a46c48e..f59df3dc8b 100644
--- a/p2p/conn/connection_test.go
+++ b/p2p/conn/connection_test.go
@@ -51,7 +51,7 @@ func TestMConnectionSendFlushStop(t *testing.T) {
clientConn := createTestMConnection(client)
err := clientConn.Start()
require.Nil(t, err)
- defer clientConn.Stop() // nolint:errcheck // ignore for tests
+ defer clientConn.Stop() //nolint:errcheck // ignore for tests
msg := []byte("abc")
assert.True(t, clientConn.Send(0x01, msg))
@@ -89,7 +89,7 @@ func TestMConnectionSend(t *testing.T) {
mconn := createTestMConnection(client)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
msg := []byte("Ant-Man")
assert.True(t, mconn.Send(0x01, msg))
@@ -128,12 +128,12 @@ func TestMConnectionReceive(t *testing.T) {
mconn1 := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn1.Start()
require.Nil(t, err)
- defer mconn1.Stop() // nolint:errcheck // ignore for tests
+ defer mconn1.Stop() //nolint:errcheck // ignore for tests
mconn2 := createTestMConnection(server)
err = mconn2.Start()
require.Nil(t, err)
- defer mconn2.Stop() // nolint:errcheck // ignore for tests
+ defer mconn2.Stop() //nolint:errcheck // ignore for tests
msg := []byte("Cyclops")
assert.True(t, mconn2.Send(0x01, msg))
@@ -156,7 +156,7 @@ func TestMConnectionStatus(t *testing.T) {
mconn := createTestMConnection(client)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
status := mconn.Status()
assert.NotNil(t, status)
@@ -179,7 +179,7 @@ func TestMConnectionPongTimeoutResultsInError(t *testing.T) {
mconn := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
serverGotPing := make(chan struct{})
go func() {
@@ -218,7 +218,7 @@ func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) {
mconn := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
// sending 3 pongs in a row (abuse)
protoWriter := protoio.NewDelimitedWriter(server)
@@ -273,7 +273,7 @@ func TestMConnectionMultiplePings(t *testing.T) {
mconn := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
// sending 3 pings in a row (abuse)
// see https://github.com/tendermint/tendermint/issues/1190
@@ -322,7 +322,7 @@ func TestMConnectionPingPongs(t *testing.T) {
mconn := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
serverGotPing := make(chan struct{})
go func() {
@@ -380,7 +380,7 @@ func TestMConnectionStopsAndReturnsError(t *testing.T) {
mconn := createMConnectionWithCallbacks(client, onReceive, onError)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
if err := client.Close(); err != nil {
t.Error(err)
@@ -492,8 +492,8 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) {
chOnRcv := make(chan struct{})
mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
- defer mconnClient.Stop() // nolint:errcheck // ignore for tests
- defer mconnServer.Stop() // nolint:errcheck // ignore for tests
+ defer mconnClient.Stop() //nolint:errcheck // ignore for tests
+ defer mconnServer.Stop() //nolint:errcheck // ignore for tests
mconnServer.onReceive = func(chID byte, msgBytes []byte) {
chOnRcv <- struct{}{}
@@ -528,8 +528,8 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) {
func TestMConnectionReadErrorUnknownMsgType(t *testing.T) {
chOnErr := make(chan struct{})
mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
- defer mconnClient.Stop() // nolint:errcheck // ignore for tests
- defer mconnServer.Stop() // nolint:errcheck // ignore for tests
+ defer mconnClient.Stop() //nolint:errcheck // ignore for tests
+ defer mconnServer.Stop() //nolint:errcheck // ignore for tests
// send msg with unknown msg type
_, err := protoio.NewDelimitedWriter(mconnClient.conn).WriteMsg(&types.Header{ChainID: "x"})
@@ -545,7 +545,7 @@ func TestMConnectionTrySend(t *testing.T) {
mconn := createTestMConnection(client)
err := mconn.Start()
require.Nil(t, err)
- defer mconn.Stop() // nolint:errcheck // ignore for tests
+ defer mconn.Stop() //nolint:errcheck // ignore for tests
msg := []byte("Semicolon-Woman")
resultCh := make(chan string, 2)
@@ -564,7 +564,7 @@ func TestMConnectionTrySend(t *testing.T) {
assert.Equal(t, "TrySend", <-resultCh)
}
-// nolint:lll //ignore line length for tests
+//nolint:lll //ignore line length for tests
func TestConnVectors(t *testing.T) {
testCases := []struct {
diff --git a/p2p/errors.go b/p2p/errors.go
index 3650a7a0a8..4fc915292f 100644
--- a/p2p/errors.go
+++ b/p2p/errors.go
@@ -145,6 +145,13 @@ func (e ErrTransportClosed) Error() string {
return "transport has been closed"
}
+// ErrPeerRemoval is raised when attempting to remove a peer results in an error.
+type ErrPeerRemoval struct{}
+
+func (e ErrPeerRemoval) Error() string {
+ return "peer removal failed"
+}
+
//-------------------------------------------------------------------
type ErrNetAddressNoID struct {
diff --git a/p2p/fuzz.go b/p2p/fuzz.go
index 0ada85ecc0..e41e989bb9 100644
--- a/p2p/fuzz.go
+++ b/p2p/fuzz.go
@@ -103,7 +103,7 @@ func (fc *FuzzedConnection) SetWriteDeadline(t time.Time) error {
func (fc *FuzzedConnection) randomDuration() time.Duration {
maxDelayMillis := int(fc.config.MaxDelay.Nanoseconds() / 1000)
- return time.Millisecond * time.Duration(tmrand.Int()%maxDelayMillis) // nolint: gas
+ return time.Millisecond * time.Duration(tmrand.Int()%maxDelayMillis) //nolint: gas
}
// implements the fuzz (delay, kill conn)
diff --git a/p2p/key.go b/p2p/key.go
index f0f3dfd030..b99ad62630 100644
--- a/p2p/key.go
+++ b/p2p/key.go
@@ -4,7 +4,7 @@ import (
"bytes"
"encoding/hex"
"fmt"
- "io/ioutil"
+ "os"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
@@ -70,7 +70,7 @@ func LoadOrGenNodeKey(filePath string) (*NodeKey, error) {
// LoadNodeKey loads NodeKey located in filePath.
func LoadNodeKey(filePath string) (*NodeKey, error) {
- jsonBytes, err := ioutil.ReadFile(filePath)
+ jsonBytes, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
@@ -88,7 +88,7 @@ func (nodeKey *NodeKey) SaveAs(filePath string) error {
if err != nil {
return err
}
- err = ioutil.WriteFile(filePath, jsonBytes, 0600)
+ err = os.WriteFile(filePath, jsonBytes, 0o600)
if err != nil {
return err
}
diff --git a/p2p/metrics.go b/p2p/metrics.go
index 675dd9c7c7..7c80658e5d 100644
--- a/p2p/metrics.go
+++ b/p2p/metrics.go
@@ -1,6 +1,11 @@
package p2p
import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "sync"
+
"github.com/go-kit/kit/metrics"
"github.com/go-kit/kit/metrics/discard"
"github.com/go-kit/kit/metrics/prometheus"
@@ -13,6 +18,13 @@ const (
MetricsSubsystem = "p2p"
)
+var (
+ // valueToLabelRegexp is used to find the golang package name and type name
+ // so that the name can be turned into a prometheus label where the characters
+ // in the label do not include prometheus special characters such as '*' and '.'.
+ valueToLabelRegexp = regexp.MustCompile(`\*?(\w+)\.(.*)`)
+)
+
// Metrics contains metrics exposed by this package.
type Metrics struct {
// Number of peers.
@@ -25,6 +37,10 @@ type Metrics struct {
PeerPendingSendBytes metrics.Gauge
// Number of transactions submitted by each peer.
NumTxs metrics.Gauge
+ // Number of bytes of each message type received.
+ MessageReceiveBytesTotal metrics.Counter
+ // Number of bytes of each message type sent.
+ MessageSendBytesTotal metrics.Counter
}
// PrometheusMetrics returns Metrics build using Prometheus client library.
@@ -58,7 +74,7 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
Namespace: namespace,
Subsystem: MetricsSubsystem,
Name: "peer_pending_send_bytes",
- Help: "Number of pending bytes to be sent to a given peer.",
+ Help: "Pending bytes to be sent to a given peer.",
}, append(labels, "peer_id")).With(labelsAndValues...),
NumTxs: prometheus.NewGaugeFrom(stdprometheus.GaugeOpts{
Namespace: namespace,
@@ -66,16 +82,64 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics {
Name: "num_txs",
Help: "Number of transactions submitted by each peer.",
}, append(labels, "peer_id")).With(labelsAndValues...),
+ MessageReceiveBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
+ Namespace: namespace,
+ Subsystem: MetricsSubsystem,
+ Name: "message_receive_bytes_total",
+ Help: "Number of bytes of each message type received.",
+ }, append(labels, "message_type")).With(labelsAndValues...),
+ MessageSendBytesTotal: prometheus.NewCounterFrom(stdprometheus.CounterOpts{
+ Namespace: namespace,
+ Subsystem: MetricsSubsystem,
+ Name: "message_send_bytes_total",
+ Help: "Number of bytes of each message type sent.",
+ }, append(labels, "message_type")).With(labelsAndValues...),
}
}
-// NopMetrics returns no-op Metrics.
func NopMetrics() *Metrics {
return &Metrics{
- Peers: discard.NewGauge(),
- PeerReceiveBytesTotal: discard.NewCounter(),
- PeerSendBytesTotal: discard.NewCounter(),
- PeerPendingSendBytes: discard.NewGauge(),
- NumTxs: discard.NewGauge(),
+ Peers: discard.NewGauge(),
+ PeerReceiveBytesTotal: discard.NewCounter(),
+ PeerSendBytesTotal: discard.NewCounter(),
+ PeerPendingSendBytes: discard.NewGauge(),
+ NumTxs: discard.NewGauge(),
+ MessageReceiveBytesTotal: discard.NewCounter(),
+ MessageSendBytesTotal: discard.NewCounter(),
+ }
+}
+
+type metricsLabelCache struct {
+ mtx *sync.RWMutex
+ messageLabelNames map[reflect.Type]string
+}
+
+// ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang
+// type that is passed in.
+// This method uses a map on the Metrics struct so that each label name only needs
+// to be produced once to prevent expensive string operations.
+func (m *metricsLabelCache) ValueToMetricLabel(i interface{}) string {
+ t := reflect.TypeOf(i)
+ m.mtx.RLock()
+
+ if s, ok := m.messageLabelNames[t]; ok {
+ m.mtx.RUnlock()
+ return s
+ }
+ m.mtx.RUnlock()
+
+ s := t.String()
+ ss := valueToLabelRegexp.FindStringSubmatch(s)
+ l := fmt.Sprintf("%s_%s", ss[1], ss[2])
+ m.mtx.Lock()
+ defer m.mtx.Unlock()
+ m.messageLabelNames[t] = l
+ return l
+}
+
+func newMetricsLabelCache() *metricsLabelCache {
+ return &metricsLabelCache{
+ mtx: &sync.RWMutex{},
+ messageLabelNames: map[reflect.Type]string{},
}
}
diff --git a/p2p/mock/peer.go b/p2p/mock/peer.go
index 59f6e0f4aa..31ce856237 100644
--- a/p2p/mock/peer.go
+++ b/p2p/mock/peer.go
@@ -42,9 +42,11 @@ func NewPeer(ip net.IP) *Peer {
return mp
}
-func (mp *Peer) FlushStop() { mp.Stop() } //nolint:errcheck //ignore error
-func (mp *Peer) TrySend(chID byte, msgBytes []byte) bool { return true }
-func (mp *Peer) Send(chID byte, msgBytes []byte) bool { return true }
+func (mp *Peer) FlushStop() { mp.Stop() } //nolint:errcheck //ignore error
+func (mp *Peer) TrySendEnvelope(e p2p.Envelope) bool { return true }
+func (mp *Peer) SendEnvelope(e p2p.Envelope) bool { return true }
+func (mp *Peer) TrySend(_ byte, _ []byte) bool { return true }
+func (mp *Peer) Send(_ byte, _ []byte) bool { return true }
func (mp *Peer) NodeInfo() p2p.NodeInfo {
return p2p.DefaultNodeInfo{
DefaultNodeID: mp.addr.ID,
@@ -68,3 +70,5 @@ func (mp *Peer) RemoteIP() net.IP { return mp.ip }
func (mp *Peer) SocketAddr() *p2p.NetAddress { return mp.addr }
func (mp *Peer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.ip, Port: 8800} }
func (mp *Peer) CloseConn() error { return nil }
+func (mp *Peer) SetRemovalFailed() {}
+func (mp *Peer) GetRemovalFailed() bool { return false }
diff --git a/p2p/mock/reactor.go b/p2p/mock/reactor.go
index 0389a7d190..8443ac8f11 100644
--- a/p2p/mock/reactor.go
+++ b/p2p/mock/reactor.go
@@ -22,4 +22,5 @@ func NewReactor() *Reactor {
func (r *Reactor) GetChannels() []*conn.ChannelDescriptor { return r.Channels }
func (r *Reactor) AddPeer(peer p2p.Peer) {}
func (r *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {}
+func (r *Reactor) ReceiveEnvelope(e p2p.Envelope) {}
func (r *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {}
diff --git a/p2p/mocks/peer.go b/p2p/mocks/peer.go
index 94ec169f97..92f0106e16 100644
--- a/p2p/mocks/peer.go
+++ b/p2p/mocks/peer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
@@ -53,6 +53,20 @@ func (_m *Peer) Get(_a0 string) interface{} {
return r0
}
+// GetRemovalFailed provides a mock function with given fields:
+func (_m *Peer) GetRemovalFailed() bool {
+ ret := _m.Called()
+
+ var r0 bool
+ if rf, ok := ret.Get(0).(func() bool); ok {
+ r0 = rf()
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ return r0
+}
+
// ID provides a mock function with given fields:
func (_m *Peer) ID() p2p.ID {
ret := _m.Called()
@@ -109,6 +123,34 @@ func (_m *Peer) IsRunning() bool {
return r0
}
+// SendEnvelope provides a mock function with given fields: _a0
+func (_m *Peer) SendEnvelope(_a0 p2p.Envelope) bool {
+ ret := _m.Called(_a0)
+
+ var r0 bool
+ if rf, ok := ret.Get(0).(func(p2p.Envelope) bool); ok {
+ r0 = rf(_a0)
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ return r0
+}
+
+// TrySendEnvelope provides a mock function with given fields: _a0
+func (_m *Peer) TrySendEnvelope(_a0 p2p.Envelope) bool {
+ ret := _m.Called(_a0)
+
+ var r0 bool
+ if rf, ok := ret.Get(0).(func(p2p.Envelope) bool); ok {
+ r0 = rf(_a0)
+ } else {
+ r0 = ret.Get(0).(bool)
+ }
+
+ return r0
+}
+
// NodeInfo provides a mock function with given fields:
func (_m *Peer) NodeInfo() p2p.NodeInfo {
ret := _m.Called()
@@ -244,6 +286,11 @@ func (_m *Peer) SetLogger(_a0 log.Logger) {
_m.Called(_a0)
}
+// SetRemovalFailed provides a mock function with given fields:
+func (_m *Peer) SetRemovalFailed() {
+ _m.Called()
+}
+
// SocketAddr provides a mock function with given fields:
func (_m *Peer) SocketAddr() *p2p.NetAddress {
ret := _m.Called()
diff --git a/p2p/node_info_test.go b/p2p/node_info_test.go
index 1bceb4a101..9c317f8a16 100644
--- a/p2p/node_info_test.go
+++ b/p2p/node_info_test.go
@@ -33,7 +33,7 @@ func TestNodeInfoValidate(t *testing.T) {
}{
{
"Too Many Channels",
- func(ni *DefaultNodeInfo) { ni.Channels = append(channels, byte(maxNumChannels)) }, // nolint: gocritic
+ func(ni *DefaultNodeInfo) { ni.Channels = append(channels, byte(maxNumChannels)) }, //nolint: gocritic
true,
},
{"Duplicate Channel", func(ni *DefaultNodeInfo) { ni.Channels = dupChannels }, true},
diff --git a/p2p/peer.go b/p2p/peer.go
index 21ebac6782..36b58f0e4f 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -3,8 +3,11 @@ package p2p
import (
"fmt"
"net"
+ "reflect"
"time"
+ "github.com/gogo/protobuf/proto"
+
"github.com/tendermint/tendermint/libs/cmap"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/service"
@@ -12,7 +15,7 @@ import (
tmconn "github.com/tendermint/tendermint/p2p/conn"
)
-//go:generate mockery --case underscore --name Peer
+//go:generate ../scripts/mockery_generate.sh Peer
const metricsTickerDuration = 10 * time.Second
@@ -34,11 +37,68 @@ type Peer interface {
Status() tmconn.ConnectionStatus
SocketAddr() *NetAddress // actual address of the socket
+ // Deprecated: entities looking to act as peers should implement SendEnvelope instead.
+ // Send will be removed in v0.37.
Send(byte, []byte) bool
+
+ // Deprecated: entities looking to act as peers should implement TrySendEnvelope instead.
+ // TrySend will be removed in v0.37.
TrySend(byte, []byte) bool
Set(string, interface{})
Get(string) interface{}
+
+ SetRemovalFailed()
+ GetRemovalFailed() bool
+}
+
+type EnvelopeSender interface {
+ SendEnvelope(Envelope) bool
+ TrySendEnvelope(Envelope) bool
+}
+
+// EnvelopeSendShim implements a shim to allow the legacy peer type that
+// does not implement SendEnvelope to be used in places where envelopes are
+// being sent. If the peer implements the *Envelope methods, then they are used,
+// otherwise, the message is marshaled and dispatched to the legacy *Send.
+//
+// Deprecated: Will be removed in v0.37.
+func SendEnvelopeShim(p Peer, e Envelope, lg log.Logger) bool {
+ if es, ok := p.(EnvelopeSender); ok {
+ return es.SendEnvelope(e)
+ }
+ msg := e.Message
+ if w, ok := msg.(Wrapper); ok {
+ msg = w.Wrap()
+ }
+ msgBytes, err := proto.Marshal(msg)
+ if err != nil {
+ lg.Error("marshaling message to send", "error", err)
+ return false
+ }
+ return p.Send(e.ChannelID, msgBytes)
+}
+
+// EnvelopeTrySendShim implements a shim to allow the legacy peer type that
+// does not implement TrySendEnvelope to be used in places where envelopes are
+// being sent. If the peer implements the *Envelope methods, then they are used,
+// otherwise, the message is marshaled and dispatched to the legacy *Send.
+//
+// Deprecated: Will be removed in v0.37.
+func TrySendEnvelopeShim(p Peer, e Envelope, lg log.Logger) bool {
+ if es, ok := p.(EnvelopeSender); ok {
+ return es.SendEnvelope(e)
+ }
+ msg := e.Message
+ if w, ok := msg.(Wrapper); ok {
+ msg = w.Wrap()
+ }
+ msgBytes, err := proto.Marshal(msg)
+ if err != nil {
+ lg.Error("marshaling message to send", "error", err)
+ return false
+ }
+ return p.TrySend(e.ChannelID, msgBytes)
}
//----------------------------------------------------------
@@ -117,6 +177,10 @@ type peer struct {
metrics *Metrics
metricsTicker *time.Ticker
+ mlc *metricsLabelCache
+
+ // When removal of a peer fails, we set this flag
+ removalAttemptFailed bool
}
type PeerOption func(*peer)
@@ -126,8 +190,10 @@ func newPeer(
mConfig tmconn.MConnConfig,
nodeInfo NodeInfo,
reactorsByCh map[byte]Reactor,
+ msgTypeByChID map[byte]proto.Message,
chDescs []*tmconn.ChannelDescriptor,
onPeerError func(Peer, interface{}),
+ mlc *metricsLabelCache,
options ...PeerOption,
) *peer {
p := &peer{
@@ -137,12 +203,14 @@ func newPeer(
Data: cmap.NewCMap(),
metricsTicker: time.NewTicker(metricsTickerDuration),
metrics: NopMetrics(),
+ mlc: mlc,
}
p.mconn = createMConnection(
pc.conn,
p,
reactorsByCh,
+ msgTypeByChID,
chDescs,
onPeerError,
mConfig,
@@ -188,7 +256,7 @@ func (p *peer) OnStart() error {
}
// FlushStop mimics OnStop but additionally ensures that all successful
-// .Send() calls will get flushed before closing the connection.
+// SendEnvelope() calls will get flushed before closing the connection.
// NOTE: it is not safe to call this method more than once.
func (p *peer) FlushStop() {
p.metricsTicker.Stop()
@@ -241,12 +309,39 @@ func (p *peer) Status() tmconn.ConnectionStatus {
return p.mconn.Status()
}
+// SendEnvelope sends the message in the envelope on the channel specified by the
+// envelope. Returns false if the connection times out trying to place the message
+// onto its internal queue.
+// Using SendEnvelope allows for tracking the message bytes sent and received by message type
+// as a metric which Send cannot support.
+func (p *peer) SendEnvelope(e Envelope) bool {
+ if !p.IsRunning() {
+ return false
+ } else if !p.hasChannel(e.ChannelID) {
+ return false
+ }
+ msg := e.Message
+ metricLabelValue := p.mlc.ValueToMetricLabel(msg)
+ if w, ok := msg.(Wrapper); ok {
+ msg = w.Wrap()
+ }
+ msgBytes, err := proto.Marshal(msg)
+ if err != nil {
+ p.Logger.Error("marshaling message to send", "error", err)
+ return false
+ }
+ res := p.Send(e.ChannelID, msgBytes)
+ if res {
+ p.metrics.MessageSendBytesTotal.With("message_type", metricLabelValue).Add(float64(len(msgBytes)))
+ }
+ return res
+}
+
// Send msg bytes to the channel identified by chID byte. Returns false if the
// send queue is full after timeout, specified by MConnection.
+// SendEnvelope replaces Send which will be deprecated in a future release.
func (p *peer) Send(chID byte, msgBytes []byte) bool {
if !p.IsRunning() {
- // see Switch#Broadcast, where we fetch the list of peers and loop over
- // them - while we're looping, one peer may be removed and stopped.
return false
} else if !p.hasChannel(chID) {
return false
@@ -262,8 +357,38 @@ func (p *peer) Send(chID byte, msgBytes []byte) bool {
return res
}
+// TrySendEnvelope attempts to sends the message in the envelope on the channel specified by the
+// envelope. Returns false immediately if the connection's internal queue is full
+// Using TrySendEnvelope allows for tracking the message bytes sent and received by message type
+// as a metric which TrySend cannot support.
+func (p *peer) TrySendEnvelope(e Envelope) bool {
+ if !p.IsRunning() {
+ // see Switch#Broadcast, where we fetch the list of peers and loop over
+ // them - while we're looping, one peer may be removed and stopped.
+ return false
+ } else if !p.hasChannel(e.ChannelID) {
+ return false
+ }
+ msg := e.Message
+ metricLabelValue := p.mlc.ValueToMetricLabel(msg)
+ if w, ok := msg.(Wrapper); ok {
+ msg = w.Wrap()
+ }
+ msgBytes, err := proto.Marshal(msg)
+ if err != nil {
+ p.Logger.Error("marshaling message to send", "error", err)
+ return false
+ }
+ res := p.TrySend(e.ChannelID, msgBytes)
+ if res {
+ p.metrics.MessageSendBytesTotal.With("message_type", metricLabelValue).Add(float64(len(msgBytes)))
+ }
+ return res
+}
+
// TrySend msg bytes to the channel identified by chID byte. Immediately returns
// false if the send queue is full.
+// TrySendEnvelope replaces TrySend which will be deprecated in a future release.
func (p *peer) TrySend(chID byte, msgBytes []byte) bool {
if !p.IsRunning() {
return false
@@ -316,6 +441,14 @@ func (p *peer) CloseConn() error {
return p.peerConn.conn.Close()
}
+func (p *peer) SetRemovalFailed() {
+ p.removalAttemptFailed = true
+}
+
+func (p *peer) GetRemovalFailed() bool {
+ return p.removalAttemptFailed
+}
+
//---------------------------------------------------
// methods only used for testing
// TODO: can we remove these?
@@ -370,6 +503,7 @@ func createMConnection(
conn net.Conn,
p *peer,
reactorsByCh map[byte]Reactor,
+ msgTypeByChID map[byte]proto.Message,
chDescs []*tmconn.ChannelDescriptor,
onPeerError func(Peer, interface{}),
config tmconn.MConnConfig,
@@ -382,12 +516,33 @@ func createMConnection(
// which does onPeerError.
panic(fmt.Sprintf("Unknown channel %X", chID))
}
+ mt := msgTypeByChID[chID]
+ msg := proto.Clone(mt)
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(fmt.Errorf("unmarshaling message: %s into type: %s", err, reflect.TypeOf(mt)))
+ }
labels := []string{
"peer_id", string(p.ID()),
"chID", fmt.Sprintf("%#x", chID),
}
+ if w, ok := msg.(Unwrapper); ok {
+ msg, err = w.Unwrap()
+ if err != nil {
+ panic(fmt.Errorf("unwrapping message: %s", err))
+ }
+ }
p.metrics.PeerReceiveBytesTotal.With(labels...).Add(float64(len(msgBytes)))
- reactor.Receive(chID, p, msgBytes)
+ p.metrics.MessageReceiveBytesTotal.With("message_type", p.mlc.ValueToMetricLabel(msg)).Add(float64(len(msgBytes)))
+ if nr, ok := reactor.(EnvelopeReceiver); ok {
+ nr.ReceiveEnvelope(Envelope{
+ ChannelID: chID,
+ Src: p,
+ Message: msg,
+ })
+ } else {
+ reactor.Receive(chID, p, msgBytes)
+ }
}
onError := func(r interface{}) {
diff --git a/p2p/peer_set.go b/p2p/peer_set.go
index 38dff7a9fb..30bcc4d32f 100644
--- a/p2p/peer_set.go
+++ b/p2p/peer_set.go
@@ -47,6 +47,9 @@ func (ps *PeerSet) Add(peer Peer) error {
if ps.lookup[peer.ID()] != nil {
return ErrSwitchDuplicatePeerID{peer.ID()}
}
+ if peer.GetRemovalFailed() {
+ return ErrPeerRemoval{}
+ }
index := len(ps.list)
// Appending is safe even with other goroutines
@@ -107,6 +110,12 @@ func (ps *PeerSet) Remove(peer Peer) bool {
item := ps.lookup[peer.ID()]
if item == nil {
+ // Removing the peer has failed so we set a flag to mark that a removal was attempted.
+ // This can happen when the peer add routine from the switch is running in
+ // parallel to the receive routine of MConn.
+ // There is an error within MConn but the switch has not actually added the peer to the peer set yet.
+ // Setting this flag will prevent a peer from being added to a node's peer set afterwards.
+ peer.SetRemovalFailed()
return false
}
diff --git a/p2p/peer_set_test.go b/p2p/peer_set_test.go
index b61b43f10a..6501dd77a5 100644
--- a/p2p/peer_set_test.go
+++ b/p2p/peer_set_test.go
@@ -18,20 +18,24 @@ type mockPeer struct {
id ID
}
-func (mp *mockPeer) FlushStop() { mp.Stop() } //nolint:errcheck // ignore error
-func (mp *mockPeer) TrySend(chID byte, msgBytes []byte) bool { return true }
-func (mp *mockPeer) Send(chID byte, msgBytes []byte) bool { return true }
-func (mp *mockPeer) NodeInfo() NodeInfo { return DefaultNodeInfo{} }
-func (mp *mockPeer) Status() ConnectionStatus { return ConnectionStatus{} }
-func (mp *mockPeer) ID() ID { return mp.id }
-func (mp *mockPeer) IsOutbound() bool { return false }
-func (mp *mockPeer) IsPersistent() bool { return true }
-func (mp *mockPeer) Get(s string) interface{} { return s }
-func (mp *mockPeer) Set(string, interface{}) {}
-func (mp *mockPeer) RemoteIP() net.IP { return mp.ip }
-func (mp *mockPeer) SocketAddr() *NetAddress { return nil }
-func (mp *mockPeer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.ip, Port: 8800} }
-func (mp *mockPeer) CloseConn() error { return nil }
+func (mp *mockPeer) FlushStop() { mp.Stop() } //nolint:errcheck // ignore error
+func (mp *mockPeer) TrySendEnvelope(e Envelope) bool { return true }
+func (mp *mockPeer) SendEnvelope(e Envelope) bool { return true }
+func (mp *mockPeer) TrySend(_ byte, _ []byte) bool { return true }
+func (mp *mockPeer) Send(_ byte, _ []byte) bool { return true }
+func (mp *mockPeer) NodeInfo() NodeInfo { return DefaultNodeInfo{} }
+func (mp *mockPeer) Status() ConnectionStatus { return ConnectionStatus{} }
+func (mp *mockPeer) ID() ID { return mp.id }
+func (mp *mockPeer) IsOutbound() bool { return false }
+func (mp *mockPeer) IsPersistent() bool { return true }
+func (mp *mockPeer) Get(s string) interface{} { return s }
+func (mp *mockPeer) Set(string, interface{}) {}
+func (mp *mockPeer) RemoteIP() net.IP { return mp.ip }
+func (mp *mockPeer) SocketAddr() *NetAddress { return nil }
+func (mp *mockPeer) RemoteAddr() net.Addr { return &net.TCPAddr{IP: mp.ip, Port: 8800} }
+func (mp *mockPeer) CloseConn() error { return nil }
+func (mp *mockPeer) SetRemovalFailed() {}
+func (mp *mockPeer) GetRemovalFailed() bool { return false }
// Returns a mock peer
func newMockPeer(ip net.IP) *mockPeer {
diff --git a/p2p/peer_test.go b/p2p/peer_test.go
index f8808f14d4..f021267cf5 100644
--- a/p2p/peer_test.go
+++ b/p2p/peer_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -14,6 +15,7 @@ import (
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/libs/log"
+ "github.com/tendermint/tendermint/proto/tendermint/p2p"
"github.com/tendermint/tendermint/config"
tmconn "github.com/tendermint/tendermint/p2p/conn"
@@ -70,7 +72,7 @@ func TestPeerSend(t *testing.T) {
})
assert.True(p.CanSend(testCh))
- assert.True(p.Send(testCh, []byte("Asylum")))
+ assert.True(SendEnvelopeShim(p, Envelope{ChannelID: testCh, Message: &p2p.Message{}}, p.Logger))
}
func createOutboundPeerAndPerformHandshake(
@@ -82,6 +84,9 @@ func createOutboundPeerAndPerformHandshake(
{ID: testCh, Priority: 1},
}
reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)}
+ msgTypeByChID := map[byte]proto.Message{
+ testCh: &p2p.Message{},
+ }
pk := ed25519.GenPrivKey()
pc, err := testOutboundPeerConn(addr, config, false, pk)
if err != nil {
@@ -94,7 +99,7 @@ func createOutboundPeerAndPerformHandshake(
return nil, err
}
- p := newPeer(pc, mConfig, peerNodeInfo, reactorsByCh, chDescs, func(p Peer, r interface{}) {})
+ p := newPeer(pc, mConfig, peerNodeInfo, reactorsByCh, msgTypeByChID, chDescs, func(p Peer, r interface{}) {}, newMetricsLabelCache())
p.SetLogger(log.TestingLogger().With("peer", addr))
return p, nil
}
diff --git a/p2p/pex/addrbook_test.go b/p2p/pex/addrbook_test.go
index ad41d55626..14ba0e2219 100644
--- a/p2p/pex/addrbook_test.go
+++ b/p2p/pex/addrbook_test.go
@@ -3,7 +3,6 @@ package pex
import (
"encoding/hex"
"fmt"
- "io/ioutil"
"math"
"net"
"os"
@@ -718,7 +717,7 @@ func assertMOldAndNNewAddrsInSelection(t *testing.T, m, n int, addrs []*p2p.NetA
}
func createTempFileName(prefix string) string {
- f, err := ioutil.TempFile("", prefix)
+ f, err := os.CreateTemp("", prefix)
if err != nil {
panic(err)
}
diff --git a/p2p/pex/known_address.go b/p2p/pex/known_address.go
index e98a9e97e0..33763c084c 100644
--- a/p2p/pex/known_address.go
+++ b/p2p/pex/known_address.go
@@ -94,17 +94,16 @@ func (ka *knownAddress) removeBucketRef(bucketIdx int) int {
}
/*
- An address is bad if the address in question is a New address, has not been tried in the last
- minute, and meets one of the following criteria:
+An address is bad if the address in question is a New address, has not been tried in the last
+minute, and meets one of the following criteria:
- 1) It claims to be from the future
- 2) It hasn't been seen in over a week
- 3) It has failed at least three times and never succeeded
- 4) It has failed ten times in the last week
-
- All addresses that meet these criteria are assumed to be worthless and not
- worth keeping hold of.
+1) It claims to be from the future
+2) It hasn't been seen in over a week
+3) It has failed at least three times and never succeeded
+4) It has failed ten times in the last week
+All addresses that meet these criteria are assumed to be worthless and not
+worth keeping hold of.
*/
func (ka *knownAddress) isBad() bool {
// Is Old --> good
diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go
index a13e3170e0..bcc8c4cce8 100644
--- a/p2p/pex/pex_reactor.go
+++ b/p2p/pex/pex_reactor.go
@@ -184,6 +184,7 @@ func (r *Reactor) GetChannels() []*conn.ChannelDescriptor {
Priority: 1,
SendQueueCapacity: 10,
RecvMessageCapacity: maxMsgSize,
+ MessageType: &tmp2p.Message{},
},
}
}
@@ -236,16 +237,10 @@ func (r *Reactor) logErrAddrBook(err error) {
}
// Receive implements Reactor by handling incoming PEX messages.
-func (r *Reactor) Receive(chID byte, src Peer, msgBytes []byte) {
- msg, err := decodeMsg(msgBytes)
- if err != nil {
- r.Logger.Error("Error decoding message", "src", src, "chId", chID, "err", err)
- r.Switch.StopPeerForError(src, err)
- return
- }
- r.Logger.Debug("Received message", "src", src, "chId", chID, "msg", msg)
+func (r *Reactor) ReceiveEnvelope(e p2p.Envelope) {
+ r.Logger.Debug("Received message", "src", e.Src, "chId", e.ChannelID, "msg", e.Message)
- switch msg := msg.(type) {
+ switch msg := e.Message.(type) {
case *tmp2p.PexRequest:
// NOTE: this is a prime candidate for amplification attacks,
@@ -255,8 +250,8 @@ func (r *Reactor) Receive(chID byte, src Peer, msgBytes []byte) {
// If we're a seed and this is an inbound peer,
// respond once and disconnect.
- if r.config.SeedMode && !src.IsOutbound() {
- id := string(src.ID())
+ if r.config.SeedMode && !e.Src.IsOutbound() {
+ id := string(e.Src.ID())
v := r.lastReceivedRequests.Get(id)
if v != nil {
// FlushStop/StopPeer are already
@@ -266,36 +261,36 @@ func (r *Reactor) Receive(chID byte, src Peer, msgBytes []byte) {
r.lastReceivedRequests.Set(id, time.Now())
// Send addrs and disconnect
- r.SendAddrs(src, r.book.GetSelectionWithBias(biasToSelectNewPeers))
+ r.SendAddrs(e.Src, r.book.GetSelectionWithBias(biasToSelectNewPeers))
go func() {
// In a go-routine so it doesn't block .Receive.
- src.FlushStop()
- r.Switch.StopPeerGracefully(src)
+ e.Src.FlushStop()
+ r.Switch.StopPeerGracefully(e.Src)
}()
} else {
// Check we're not receiving requests too frequently.
- if err := r.receiveRequest(src); err != nil {
- r.Switch.StopPeerForError(src, err)
- r.book.MarkBad(src.SocketAddr(), defaultBanTime)
+ if err := r.receiveRequest(e.Src); err != nil {
+ r.Switch.StopPeerForError(e.Src, err)
+ r.book.MarkBad(e.Src.SocketAddr(), defaultBanTime)
return
}
- r.SendAddrs(src, r.book.GetSelection())
+ r.SendAddrs(e.Src, r.book.GetSelection())
}
case *tmp2p.PexAddrs:
// If we asked for addresses, add them to the book
addrs, err := p2p.NetAddressesFromProto(msg.Addrs)
if err != nil {
- r.Switch.StopPeerForError(src, err)
- r.book.MarkBad(src.SocketAddr(), defaultBanTime)
+ r.Switch.StopPeerForError(e.Src, err)
+ r.book.MarkBad(e.Src.SocketAddr(), defaultBanTime)
return
}
- err = r.ReceiveAddrs(addrs, src)
+ err = r.ReceiveAddrs(addrs, e.Src)
if err != nil {
- r.Switch.StopPeerForError(src, err)
+ r.Switch.StopPeerForError(e.Src, err)
if err == ErrUnsolicitedList {
- r.book.MarkBad(src.SocketAddr(), defaultBanTime)
+ r.book.MarkBad(e.Src.SocketAddr(), defaultBanTime)
}
return
}
@@ -305,6 +300,23 @@ func (r *Reactor) Receive(chID byte, src Peer, msgBytes []byte) {
}
}
+func (r *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {
+ msg := &tmp2p.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ um, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+ r.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: um,
+ })
+}
+
// enforces a minimum amount of time between requests
func (r *Reactor) receiveRequest(src Peer) error {
id := string(src.ID())
@@ -348,7 +360,10 @@ func (r *Reactor) RequestAddrs(p Peer) {
}
r.Logger.Debug("Request addrs", "from", p)
r.requestsSent.Set(id, struct{}{})
- p.Send(PexChannel, mustEncode(&tmp2p.PexRequest{}))
+ p2p.SendEnvelopeShim(p, p2p.Envelope{ //nolint: staticcheck
+ ChannelID: PexChannel,
+ Message: &tmp2p.PexRequest{},
+ }, r.Logger)
}
// ReceiveAddrs adds the given addrs to the addrbook if theres an open
@@ -406,7 +421,11 @@ func (r *Reactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error {
// SendAddrs sends addrs to the peer.
func (r *Reactor) SendAddrs(p Peer, netAddrs []*p2p.NetAddress) {
- p.Send(PexChannel, mustEncode(&tmp2p.PexAddrs{Addrs: p2p.NetAddressesToProto(netAddrs)}))
+ e := p2p.Envelope{
+ ChannelID: PexChannel,
+ Message: &tmp2p.PexAddrs{Addrs: p2p.NetAddressesToProto(netAddrs)},
+ }
+ p2p.SendEnvelopeShim(p, e, r.Logger) //nolint: staticcheck
}
// SetEnsurePeersPeriod sets period to ensure peers connected.
@@ -763,43 +782,3 @@ func markAddrInBookBasedOnErr(addr *p2p.NetAddress, book AddrBook, err error) {
book.MarkAttempt(addr)
}
}
-
-//-----------------------------------------------------------------------------
-// Messages
-
-// mustEncode proto encodes a tmp2p.Message
-func mustEncode(pb proto.Message) []byte {
- msg := tmp2p.Message{}
- switch pb := pb.(type) {
- case *tmp2p.PexRequest:
- msg.Sum = &tmp2p.Message_PexRequest{PexRequest: pb}
- case *tmp2p.PexAddrs:
- msg.Sum = &tmp2p.Message_PexAddrs{PexAddrs: pb}
- default:
- panic(fmt.Sprintf("Unknown message type %T", pb))
- }
-
- bz, err := msg.Marshal()
- if err != nil {
- panic(fmt.Errorf("unable to marshal %T: %w", pb, err))
- }
- return bz
-}
-
-func decodeMsg(bz []byte) (proto.Message, error) {
- pb := &tmp2p.Message{}
-
- err := pb.Unmarshal(bz)
- if err != nil {
- return nil, err
- }
-
- switch msg := pb.Sum.(type) {
- case *tmp2p.Message_PexRequest:
- return msg.PexRequest, nil
- case *tmp2p.Message_PexAddrs:
- return msg.PexAddrs, nil
- default:
- return nil, fmt.Errorf("unknown message: %T", msg)
- }
-}
diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go
index 4ed1254efb..b39587ebda 100644
--- a/p2p/pex/pex_reactor_test.go
+++ b/p2p/pex/pex_reactor_test.go
@@ -3,7 +3,6 @@ package pex
import (
"encoding/hex"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"testing"
@@ -20,9 +19,7 @@ import (
tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p"
)
-var (
- cfg *config.P2PConfig
-)
+var cfg *config.P2PConfig
func init() {
cfg = config.DefaultP2PConfig()
@@ -59,21 +56,21 @@ func TestPEXReactorAddRemovePeer(t *testing.T) {
}
// --- FAIL: TestPEXReactorRunning (11.10s)
-// pex_reactor_test.go:411: expected all switches to be connected to at
-// least one peer (switches: 0 => {outbound: 1, inbound: 0}, 1 =>
-// {outbound: 0, inbound: 1}, 2 => {outbound: 0, inbound: 0}, )
+//
+// pex_reactor_test.go:411: expected all switches to be connected to at
+// least one peer (switches: 0 => {outbound: 1, inbound: 0}, 1 =>
+// {outbound: 0, inbound: 1}, 2 => {outbound: 0, inbound: 0}, )
//
// EXPLANATION: peers are getting rejected because in switch#addPeer we check
// if any peer (who we already connected to) has the same IP. Even though local
// peers have different IP addresses, they all have the same underlying remote
// IP: 127.0.0.1.
-//
func TestPEXReactorRunning(t *testing.T) {
N := 3
switches := make([]*p2p.Switch, N)
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
@@ -132,12 +129,11 @@ func TestPEXReactorReceive(t *testing.T) {
r.RequestAddrs(peer)
size := book.Size()
- msg := mustEncode(&tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}})
- r.Receive(PexChannel, peer, msg)
+ msg := &tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}}
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: msg})
assert.Equal(t, size+1, book.Size())
- msg = mustEncode(&tmp2p.PexRequest{})
- r.Receive(PexChannel, peer, msg) // should not panic.
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: &tmp2p.PexRequest{}})
}
func TestPEXReactorRequestMessageAbuse(t *testing.T) {
@@ -156,20 +152,19 @@ func TestPEXReactorRequestMessageAbuse(t *testing.T) {
require.True(t, book.HasAddress(peerAddr))
id := string(peer.ID())
- msg := mustEncode(&tmp2p.PexRequest{})
// first time creates the entry
- r.Receive(PexChannel, peer, msg)
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: &tmp2p.PexRequest{}})
assert.True(t, r.lastReceivedRequests.Has(id))
assert.True(t, sw.Peers().Has(peer.ID()))
// next time sets the last time value
- r.Receive(PexChannel, peer, msg)
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: &tmp2p.PexRequest{}})
assert.True(t, r.lastReceivedRequests.Has(id))
assert.True(t, sw.Peers().Has(peer.ID()))
// third time is too many too soon - peer is removed
- r.Receive(PexChannel, peer, msg)
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: &tmp2p.PexRequest{}})
assert.False(t, r.lastReceivedRequests.Has(id))
assert.False(t, sw.Peers().Has(peer.ID()))
assert.True(t, book.IsBanned(peerAddr))
@@ -193,29 +188,29 @@ func TestPEXReactorAddrsMessageAbuse(t *testing.T) {
assert.True(t, r.requestsSent.Has(id))
assert.True(t, sw.Peers().Has(peer.ID()))
- msg := mustEncode(&tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}})
+ msg := &tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}}
// receive some addrs. should clear the request
- r.Receive(PexChannel, peer, msg)
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: msg})
assert.False(t, r.requestsSent.Has(id))
assert.True(t, sw.Peers().Has(peer.ID()))
// receiving more unsolicited addrs causes a disconnect and ban
- r.Receive(PexChannel, peer, msg)
+ r.ReceiveEnvelope(p2p.Envelope{ChannelID: PexChannel, Src: peer, Message: msg})
assert.False(t, sw.Peers().Has(peer.ID()))
assert.True(t, book.IsBanned(peer.SocketAddr()))
}
func TestCheckSeeds(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
// 1. test creating peer with no seeds works
peerSwitch := testCreateDefaultPeer(dir, 0)
require.Nil(t, peerSwitch.Start())
- peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ peerSwitch.Stop() //nolint:errcheck // ignore for tests
// 2. create seed
seed := testCreateSeed(dir, 1, []*p2p.NetAddress{}, []*p2p.NetAddress{})
@@ -223,43 +218,47 @@ func TestCheckSeeds(t *testing.T) {
// 3. test create peer with online seed works
peerSwitch = testCreatePeerWithSeed(dir, 2, seed)
require.Nil(t, peerSwitch.Start())
- peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ peerSwitch.Stop() //nolint:errcheck // ignore for tests
// 4. test create peer with all seeds having unresolvable DNS fails
badPeerConfig := &ReactorConfig{
- Seeds: []string{"ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
- "d824b13cb5d40fa1d8a614e089357c7eff31b670@anotherbad.network.addr:26657"},
+ Seeds: []string{
+ "ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
+ "d824b13cb5d40fa1d8a614e089357c7eff31b670@anotherbad.network.addr:26657",
+ },
}
peerSwitch = testCreatePeerWithConfig(dir, 2, badPeerConfig)
require.Error(t, peerSwitch.Start())
- peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ peerSwitch.Stop() //nolint:errcheck // ignore for tests
// 5. test create peer with one good seed address succeeds
badPeerConfig = &ReactorConfig{
- Seeds: []string{"ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
+ Seeds: []string{
+ "ed3dfd27bfc4af18f67a49862f04cc100696e84d@bad.network.addr:26657",
"d824b13cb5d40fa1d8a614e089357c7eff31b670@anotherbad.network.addr:26657",
- seed.NetAddress().String()},
+ seed.NetAddress().String(),
+ },
}
peerSwitch = testCreatePeerWithConfig(dir, 2, badPeerConfig)
require.Nil(t, peerSwitch.Start())
- peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ peerSwitch.Stop() //nolint:errcheck // ignore for tests
}
func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
// 1. create seed
seed := testCreateSeed(dir, 0, []*p2p.NetAddress{}, []*p2p.NetAddress{})
require.Nil(t, seed.Start())
- defer seed.Stop() // nolint:errcheck // ignore for tests
+ defer seed.Stop() //nolint:errcheck // ignore for tests
// 2. create usual peer with only seed configured.
peer := testCreatePeerWithSeed(dir, 1, seed)
require.Nil(t, peer.Start())
- defer peer.Stop() // nolint:errcheck // ignore for tests
+ defer peer.Stop() //nolint:errcheck // ignore for tests
// 3. check that the peer connects to seed immediately
assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1)
@@ -267,25 +266,25 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) {
func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
// 1. create peer
peerSwitch := testCreateDefaultPeer(dir, 1)
require.Nil(t, peerSwitch.Start())
- defer peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ defer peerSwitch.Stop() //nolint:errcheck // ignore for tests
// 2. Create seed which knows about the peer
peerAddr := peerSwitch.NetAddress()
seed := testCreateSeed(dir, 2, []*p2p.NetAddress{peerAddr}, []*p2p.NetAddress{peerAddr})
require.Nil(t, seed.Start())
- defer seed.Stop() // nolint:errcheck // ignore for tests
+ defer seed.Stop() //nolint:errcheck // ignore for tests
// 3. create another peer with only seed configured.
secondPeer := testCreatePeerWithSeed(dir, 3, seed)
require.Nil(t, secondPeer.Start())
- defer secondPeer.Stop() // nolint:errcheck // ignore for tests
+ defer secondPeer.Stop() //nolint:errcheck // ignore for tests
// 4. check that the second peer connects to seed immediately
assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 3*time.Second, 1)
@@ -296,7 +295,7 @@ func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) {
func TestPEXReactorSeedMode(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
@@ -308,13 +307,13 @@ func TestPEXReactorSeedMode(t *testing.T) {
sw.SetAddrBook(book)
err = sw.Start()
require.NoError(t, err)
- defer sw.Stop() // nolint:errcheck // ignore for tests
+ defer sw.Stop() //nolint:errcheck // ignore for tests
assert.Zero(t, sw.Peers().Size())
peerSwitch := testCreateDefaultPeer(dir, 1)
require.NoError(t, peerSwitch.Start())
- defer peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ defer peerSwitch.Stop() //nolint:errcheck // ignore for tests
// 1. Test crawlPeers dials the peer
pexR.crawlPeers([]*p2p.NetAddress{peerSwitch.NetAddress()})
@@ -335,7 +334,7 @@ func TestPEXReactorSeedMode(t *testing.T) {
func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
@@ -347,13 +346,13 @@ func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) {
sw.SetAddrBook(book)
err = sw.Start()
require.NoError(t, err)
- defer sw.Stop() // nolint:errcheck // ignore for tests
+ defer sw.Stop() //nolint:errcheck // ignore for tests
assert.Zero(t, sw.Peers().Size())
peerSwitch := testCreateDefaultPeer(dir, 1)
require.NoError(t, peerSwitch.Start())
- defer peerSwitch.Stop() // nolint:errcheck // ignore for tests
+ defer peerSwitch.Stop() //nolint:errcheck // ignore for tests
err = sw.AddPersistentPeers([]string{peerSwitch.NetAddress().String()})
require.NoError(t, err)
@@ -373,7 +372,7 @@ func TestPEXReactorDoesNotDisconnectFromPersistentPeerInSeedMode(t *testing.T) {
func TestPEXReactorDialsPeerUpToMaxAttemptsInSeedMode(t *testing.T) {
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
@@ -409,7 +408,7 @@ func TestPEXReactorSeedModeFlushStop(t *testing.T) {
switches := make([]*p2p.Switch, N)
// directory to store address books
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir)
@@ -487,14 +486,34 @@ func TestPEXReactorDoesNotAddPrivatePeersToAddrBook(t *testing.T) {
pexR.RequestAddrs(peer)
size := book.Size()
- msg := mustEncode(&tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}})
- pexR.Receive(PexChannel, peer, msg)
+ msg := &tmp2p.PexAddrs{Addrs: []tmp2p.NetAddress{peer.SocketAddr().ToProto()}}
+ pexR.ReceiveEnvelope(p2p.Envelope{
+ ChannelID: PexChannel,
+ Src: peer,
+ Message: msg,
+ })
assert.Equal(t, size, book.Size())
pexR.AddPeer(peer)
assert.Equal(t, size, book.Size())
}
+func TestLegacyReactorReceiveBasic(t *testing.T) {
+ pexR, _ := createReactor(&ReactorConfig{})
+ peer := p2p.CreateRandomPeer(false)
+
+ pexR.InitPeer(peer)
+ pexR.AddPeer(peer)
+ m := &tmp2p.PexAddrs{}
+ wm := m.Wrap()
+ msg, err := proto.Marshal(wm)
+ assert.NoError(t, err)
+
+ assert.NotPanics(t, func() {
+ pexR.Receive(PexChannel, peer, msg)
+ })
+}
+
func TestPEXReactorDialPeer(t *testing.T) {
pexR, book := createReactor(&ReactorConfig{})
defer teardownReactor(book)
@@ -619,7 +638,7 @@ func testCreateSeed(dir string, id int, knownAddrs, srcAddrs []*p2p.NetAddress)
book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false)
book.SetLogger(log.TestingLogger())
for j := 0; j < len(knownAddrs); j++ {
- book.AddAddress(knownAddrs[j], srcAddrs[j]) // nolint:errcheck // ignore for tests
+ book.AddAddress(knownAddrs[j], srcAddrs[j]) //nolint:errcheck // ignore for tests
book.MarkGood(knownAddrs[j].ID)
}
sw.SetAddrBook(book)
@@ -646,7 +665,7 @@ func testCreatePeerWithSeed(dir string, id int, seed *p2p.Switch) *p2p.Switch {
func createReactor(conf *ReactorConfig) (r *Reactor, book AddrBook) {
// directory to store address book
- dir, err := ioutil.TempDir("", "pex_reactor")
+ dir, err := os.MkdirTemp("", "pex_reactor")
if err != nil {
panic(err)
}
@@ -677,7 +696,6 @@ func createSwitchAndAddReactors(reactors ...p2p.Reactor) *p2p.Switch {
}
func TestPexVectors(t *testing.T) {
-
addr := tmp2p.NetAddress{
ID: "1",
IP: "127.0.0.1",
@@ -696,7 +714,9 @@ func TestPexVectors(t *testing.T) {
for _, tc := range testCases {
tc := tc
- bz := mustEncode(tc.msg)
+ w := tc.msg.(p2p.Wrapper).Wrap()
+ bz, err := proto.Marshal(w)
+ require.NoError(t, err)
require.Equal(t, tc.expBytes, hex.EncodeToString(bz), tc.testName)
}
diff --git a/p2p/switch.go b/p2p/switch.go
index fa87cbccd7..9a298c72a0 100644
--- a/p2p/switch.go
+++ b/p2p/switch.go
@@ -6,9 +6,9 @@ import (
"sync"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/cmap"
- "github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/libs/service"
"github.com/tendermint/tendermint/p2p/conn"
@@ -69,16 +69,17 @@ type PeerFilterFunc func(IPeerSet, Peer) error
type Switch struct {
service.BaseService
- config *config.P2PConfig
- reactors map[string]Reactor
- chDescs []*conn.ChannelDescriptor
- reactorsByCh map[byte]Reactor
- peers *PeerSet
- dialing *cmap.CMap
- reconnecting *cmap.CMap
- nodeInfo NodeInfo // our node info
- nodeKey *NodeKey // our node privkey
- addrBook AddrBook
+ config *config.P2PConfig
+ reactors map[string]Reactor
+ chDescs []*conn.ChannelDescriptor
+ reactorsByCh map[byte]Reactor
+ msgTypeByChID map[byte]proto.Message
+ peers *PeerSet
+ dialing *cmap.CMap
+ reconnecting *cmap.CMap
+ nodeInfo NodeInfo // our node info
+ nodeKey *NodeKey // our node privkey
+ addrBook AddrBook
// peers addresses with whom we'll maintain constant connection
persistentPeersAddrs []*NetAddress
unconditionalPeerIDs map[ID]struct{}
@@ -91,6 +92,7 @@ type Switch struct {
rng *rand.Rand // seed for randomizing dial times and orders
metrics *Metrics
+ mlc *metricsLabelCache
}
// NetAddress returns the address the switch is listening on.
@@ -108,11 +110,13 @@ func NewSwitch(
transport Transport,
options ...SwitchOption,
) *Switch {
+
sw := &Switch{
config: cfg,
reactors: make(map[string]Reactor),
chDescs: make([]*conn.ChannelDescriptor, 0),
reactorsByCh: make(map[byte]Reactor),
+ msgTypeByChID: make(map[byte]proto.Message),
peers: NewPeerSet(),
dialing: cmap.NewCMap(),
reconnecting: cmap.NewCMap(),
@@ -121,6 +125,7 @@ func NewSwitch(
filterTimeout: defaultFilterTimeout,
persistentPeersAddrs: make([]*NetAddress, 0),
unconditionalPeerIDs: make(map[ID]struct{}),
+ mlc: newMetricsLabelCache(),
}
// Ensure we have a completely undeterministic PRNG.
@@ -164,6 +169,7 @@ func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor {
}
sw.chDescs = append(sw.chDescs, chDesc)
sw.reactorsByCh[chID] = reactor
+ sw.msgTypeByChID[chID] = chDesc.MessageType
}
sw.reactors[name] = reactor
reactor.SetSwitch(sw)
@@ -182,6 +188,7 @@ func (sw *Switch) RemoveReactor(name string, reactor Reactor) {
}
}
delete(sw.reactorsByCh, chDesc.ID)
+ delete(sw.msgTypeByChID, chDesc.ID)
}
delete(sw.reactors, name)
reactor.SetSwitch(nil)
@@ -255,14 +262,49 @@ func (sw *Switch) OnStop() {
//---------------------------------------------------------------------
// Peers
+// BroadcastEnvelope runs a go routine for each attempted send, which will block trying
+// to send for defaultSendTimeoutSeconds. Returns a channel which receives
+// success values for each attempted send (false if times out). Channel will be
+// closed once msg bytes are sent to all peers (or time out).
+// BroadcastEnvelope sends to the peers using the SendEnvelope method.
+//
+// NOTE: BroadcastEnvelope uses goroutines, so order of broadcast may not be preserved.
+func (sw *Switch) BroadcastEnvelope(e Envelope) chan bool {
+ sw.Logger.Debug("Broadcast", "channel", e.ChannelID)
+
+ peers := sw.peers.List()
+ var wg sync.WaitGroup
+ wg.Add(len(peers))
+ successChan := make(chan bool, len(peers))
+
+ for _, peer := range peers {
+ go func(p Peer) {
+ defer wg.Done()
+ success := SendEnvelopeShim(p, e, sw.Logger)
+ successChan <- success
+ }(peer)
+ }
+
+ go func() {
+ wg.Wait()
+ close(successChan)
+ }()
+
+ return successChan
+}
+
// Broadcast runs a go routine for each attempted send, which will block trying
// to send for defaultSendTimeoutSeconds. Returns a channel which receives
// success values for each attempted send (false if times out). Channel will be
// closed once msg bytes are sent to all peers (or time out).
+// Broadcast sends to the peers using the Send method.
//
// NOTE: Broadcast uses goroutines, so order of broadcast may not be preserved.
+//
+// Deprecated: code looking to broadcast data to all peers should use BroadcastEnvelope.
+// Broadcast will be removed in 0.37.
func (sw *Switch) Broadcast(chID byte, msgBytes []byte) chan bool {
- sw.Logger.Debug("Broadcast", "channel", chID, "msgBytes", log.NewLazySprintf("%X", msgBytes))
+ sw.Logger.Debug("Broadcast", "channel", chID)
peers := sw.peers.List()
var wg sync.WaitGroup
@@ -370,6 +412,10 @@ func (sw *Switch) stopAndRemovePeer(peer Peer, reason interface{}) {
// https://github.com/tendermint/tendermint/issues/3338
if sw.peers.Remove(peer) {
sw.metrics.Peers.Add(float64(-1))
+ } else {
+ // Removal of the peer has failed. The function above sets a flag within the peer to mark this.
+ // We keep this message here as information to the developer.
+ sw.Logger.Debug("error on peer removal", ",", "peer", peer.ID())
}
}
@@ -379,8 +425,8 @@ func (sw *Switch) stopAndRemovePeer(peer Peer, reason interface{}) {
// to the PEX/Addrbook to find the peer with the addr again
// NOTE: this will keep trying even if the handshake or auth fails.
// TODO: be more explicit with error types so we only retry on certain failures
-// - ie. if we're getting ErrDuplicatePeer we can stop
-// because the addrbook got us the peer back already
+// - ie. if we're getting ErrDuplicatePeer we can stop
+// because the addrbook got us the peer back already
func (sw *Switch) reconnectToPeer(addr *NetAddress) {
if sw.reconnecting.Has(string(addr.ID)) {
return
@@ -619,11 +665,13 @@ func (sw *Switch) IsPeerPersistent(na *NetAddress) bool {
func (sw *Switch) acceptRoutine() {
for {
p, err := sw.transport.Accept(peerConfig{
- chDescs: sw.chDescs,
- onPeerError: sw.StopPeerForError,
- reactorsByCh: sw.reactorsByCh,
- metrics: sw.metrics,
- isPersistent: sw.IsPeerPersistent,
+ chDescs: sw.chDescs,
+ onPeerError: sw.StopPeerForError,
+ reactorsByCh: sw.reactorsByCh,
+ msgTypeByChID: sw.msgTypeByChID,
+ metrics: sw.metrics,
+ mlc: sw.mlc,
+ isPersistent: sw.IsPeerPersistent,
})
if err != nil {
switch err := err.(type) {
@@ -722,11 +770,13 @@ func (sw *Switch) addOutboundPeerWithConfig(
}
p, err := sw.transport.Dial(*addr, peerConfig{
- chDescs: sw.chDescs,
- onPeerError: sw.StopPeerForError,
- isPersistent: sw.IsPeerPersistent,
- reactorsByCh: sw.reactorsByCh,
- metrics: sw.metrics,
+ chDescs: sw.chDescs,
+ onPeerError: sw.StopPeerForError,
+ isPersistent: sw.IsPeerPersistent,
+ reactorsByCh: sw.reactorsByCh,
+ msgTypeByChID: sw.msgTypeByChID,
+ metrics: sw.metrics,
+ mlc: sw.mlc,
})
if err != nil {
if e, ok := err.(ErrRejected); ok {
@@ -824,6 +874,12 @@ func (sw *Switch) addPeer(p Peer) error {
// so that if Receive errors, we will find the peer and remove it.
// Add should not err since we already checked peers.Has().
if err := sw.peers.Add(p); err != nil {
+ switch err.(type) {
+ case ErrPeerRemoval:
+ sw.Logger.Error("Error starting peer ",
+ " err ", "Peer has already errored and removal was attempted.",
+ "peer", p.ID())
+ }
return err
}
sw.metrics.Peers.Add(float64(1))
diff --git a/p2p/switch_test.go b/p2p/switch_test.go
index 36420d333c..5695d03dd6 100644
--- a/p2p/switch_test.go
+++ b/p2p/switch_test.go
@@ -4,7 +4,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"net"
"net/http"
"net/http/httptest"
@@ -14,6 +14,7 @@ import (
"testing"
"time"
+ "github.com/gogo/protobuf/proto"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -23,11 +24,10 @@ import (
"github.com/tendermint/tendermint/libs/log"
tmsync "github.com/tendermint/tendermint/libs/sync"
"github.com/tendermint/tendermint/p2p/conn"
+ p2pproto "github.com/tendermint/tendermint/proto/tendermint/p2p"
)
-var (
- cfg *config.P2PConfig
-)
+var cfg *config.P2PConfig
func init() {
cfg = config.DefaultP2PConfig()
@@ -36,9 +36,8 @@ func init() {
}
type PeerMessage struct {
- PeerID ID
- Bytes []byte
- Counter int
+ Contents proto.Message
+ Counter int
}
type TestReactor struct {
@@ -70,16 +69,34 @@ func (tr *TestReactor) AddPeer(peer Peer) {}
func (tr *TestReactor) RemovePeer(peer Peer, reason interface{}) {}
-func (tr *TestReactor) Receive(chID byte, peer Peer, msgBytes []byte) {
+func (tr *TestReactor) ReceiveEnvelope(e Envelope) {
if tr.logMessages {
tr.mtx.Lock()
defer tr.mtx.Unlock()
- // fmt.Printf("Received: %X, %X\n", chID, msgBytes)
- tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.ID(), msgBytes, tr.msgsCounter})
+ // fmt.Printf("Received: %X, %X\n", e.ChannelID, e.Message)
+ tr.msgsReceived[e.ChannelID] = append(tr.msgsReceived[e.ChannelID], PeerMessage{Contents: e.Message, Counter: tr.msgsCounter})
tr.msgsCounter++
}
}
+func (tr *TestReactor) Receive(chID byte, peer Peer, msgBytes []byte) {
+ msg := &p2pproto.Message{}
+ err := proto.Unmarshal(msgBytes, msg)
+ if err != nil {
+ panic(err)
+ }
+ um, err := msg.Unwrap()
+ if err != nil {
+ panic(err)
+ }
+
+ tr.ReceiveEnvelope(Envelope{
+ ChannelID: chID,
+ Src: peer,
+ Message: um,
+ })
+}
+
func (tr *TestReactor) getMsgs(chID byte) []PeerMessage {
tr.mtx.Lock()
defer tr.mtx.Unlock()
@@ -99,16 +116,17 @@ func MakeSwitchPair(t testing.TB, initSwitch func(int, *Switch) *Switch) (*Switc
func initSwitchFunc(i int, sw *Switch) *Switch {
sw.SetAddrBook(&AddrBookMock{
Addrs: make(map[string]struct{}),
- OurAddrs: make(map[string]struct{})})
+ OurAddrs: make(map[string]struct{}),
+ })
// Make two reactors of two channels each
sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
- {ID: byte(0x00), Priority: 10},
- {ID: byte(0x01), Priority: 10},
+ {ID: byte(0x00), Priority: 10, MessageType: &p2pproto.Message{}},
+ {ID: byte(0x01), Priority: 10, MessageType: &p2pproto.Message{}},
}, true))
sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
- {ID: byte(0x02), Priority: 10},
- {ID: byte(0x03), Priority: 10},
+ {ID: byte(0x02), Priority: 10, MessageType: &p2pproto.Message{}},
+ {ID: byte(0x03), Priority: 10, MessageType: &p2pproto.Message{}},
}, true))
return sw
@@ -135,31 +153,47 @@ func TestSwitches(t *testing.T) {
}
// Lets send some messages
- ch0Msg := []byte("channel zero")
- ch1Msg := []byte("channel foo")
- ch2Msg := []byte("channel bar")
-
- s1.Broadcast(byte(0x00), ch0Msg)
- s1.Broadcast(byte(0x01), ch1Msg)
- s1.Broadcast(byte(0x02), ch2Msg)
-
+ ch0Msg := &p2pproto.PexAddrs{
+ Addrs: []p2pproto.NetAddress{
+ {
+ ID: "1",
+ },
+ },
+ }
+ ch1Msg := &p2pproto.PexAddrs{
+ Addrs: []p2pproto.NetAddress{
+ {
+ ID: "1",
+ },
+ },
+ }
+ ch2Msg := &p2pproto.PexAddrs{
+ Addrs: []p2pproto.NetAddress{
+ {
+ ID: "2",
+ },
+ },
+ }
+ s1.BroadcastEnvelope(Envelope{ChannelID: byte(0x00), Message: ch0Msg})
+ s1.BroadcastEnvelope(Envelope{ChannelID: byte(0x01), Message: ch1Msg})
+ s1.BroadcastEnvelope(Envelope{ChannelID: byte(0x02), Message: ch2Msg})
assertMsgReceivedWithTimeout(t,
ch0Msg,
byte(0x00),
- s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
+ s2.Reactor("foo").(*TestReactor), 200*time.Millisecond, 5*time.Second)
assertMsgReceivedWithTimeout(t,
ch1Msg,
byte(0x01),
- s2.Reactor("foo").(*TestReactor), 10*time.Millisecond, 5*time.Second)
+ s2.Reactor("foo").(*TestReactor), 200*time.Millisecond, 5*time.Second)
assertMsgReceivedWithTimeout(t,
ch2Msg,
byte(0x02),
- s2.Reactor("bar").(*TestReactor), 10*time.Millisecond, 5*time.Second)
+ s2.Reactor("bar").(*TestReactor), 200*time.Millisecond, 5*time.Second)
}
func assertMsgReceivedWithTimeout(
t *testing.T,
- msgBytes []byte,
+ msg proto.Message,
channel byte,
reactor *TestReactor,
checkPeriod,
@@ -170,9 +204,13 @@ func assertMsgReceivedWithTimeout(
select {
case <-ticker.C:
msgs := reactor.getMsgs(channel)
+ expectedBytes, err := proto.Marshal(msgs[0].Contents)
+ require.NoError(t, err)
+ gotBytes, err := proto.Marshal(msg)
+ require.NoError(t, err)
if len(msgs) > 0 {
- if !bytes.Equal(msgs[0].Bytes, msgBytes) {
- t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", msgBytes, msgs[0].Bytes)
+ if !bytes.Equal(expectedBytes, gotBytes) {
+ t.Fatalf("Unexpected message bytes. Wanted: %X, Got: %X", msg, msgs[0].Counter)
}
return
}
@@ -400,7 +438,7 @@ func TestSwitchStopPeerForError(t *testing.T) {
resp, err := http.Get(s.URL)
require.NoError(t, err)
defer resp.Body.Close()
- buf, _ := ioutil.ReadAll(resp.Body)
+ buf, _ := io.ReadAll(resp.Body)
return string(buf)
}
@@ -429,7 +467,10 @@ func TestSwitchStopPeerForError(t *testing.T) {
// send messages to the peer from sw1
p := sw1.Peers().List()[0]
- p.Send(0x1, []byte("here's a message to send"))
+ SendEnvelopeShim(p, Envelope{
+ ChannelID: 0x1,
+ Message: &p2pproto.Message{},
+ }, sw1.Logger)
// stop sw2. this should cause the p to fail,
// which results in calling StopPeerForError internally
@@ -681,9 +722,11 @@ func (et errorTransport) NetAddress() NetAddress {
func (et errorTransport) Accept(c peerConfig) (Peer, error) {
return nil, et.acceptErr
}
+
func (errorTransport) Dial(NetAddress, peerConfig) (Peer, error) {
panic("not implemented")
}
+
func (errorTransport) Cleanup(Peer) {
panic("not implemented")
}
@@ -824,7 +867,7 @@ func BenchmarkSwitchBroadcast(b *testing.B) {
// Send random message from foo channel to another
for i := 0; i < b.N; i++ {
chID := byte(i % 4)
- successChan := s1.Broadcast(chID, []byte("test data"))
+ successChan := s1.BroadcastEnvelope(Envelope{ChannelID: chID})
for s := range successChan {
if s {
numSuccess++
@@ -836,3 +879,15 @@ func BenchmarkSwitchBroadcast(b *testing.B) {
b.Logf("success: %v, failure: %v", numSuccess, numFailure)
}
+
+func TestSwitchRemovalErr(t *testing.T) {
+ sw1, sw2 := MakeSwitchPair(t, func(i int, sw *Switch) *Switch {
+ return initSwitchFunc(i, sw)
+ })
+ assert.Equal(t, len(sw1.Peers().List()), 1)
+ p := sw1.Peers().List()[0]
+
+ sw2.StopPeerForError(p, fmt.Errorf("peer should error"))
+
+ assert.Equal(t, sw2.peers.Add(p).Error(), ErrPeerRemoval{}.Error())
+}
diff --git a/p2p/test_util.go b/p2p/test_util.go
index 4e56f0193c..1d9a4883cb 100644
--- a/p2p/test_util.go
+++ b/p2p/test_util.go
@@ -149,8 +149,10 @@ func (sw *Switch) addPeerWithConnection(conn net.Conn) error {
MConnConfig(sw.config),
ni,
sw.reactorsByCh,
+ sw.msgTypeByChID,
sw.chDescs,
sw.StopPeerForError,
+ sw.mlc,
)
if err = sw.addPeer(p); err != nil {
diff --git a/p2p/transport.go b/p2p/transport.go
index 1257f38b30..416c946942 100644
--- a/p2p/transport.go
+++ b/p2p/transport.go
@@ -8,6 +8,7 @@ import (
"golang.org/x/net/netutil"
+ "github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/protoio"
"github.com/tendermint/tendermint/p2p/conn"
@@ -47,9 +48,11 @@ type peerConfig struct {
// isPersistent allows you to set a function, which, given socket address
// (for outbound peers) OR self-reported address (for inbound peers), tells
// if the peer is persistent or not.
- isPersistent func(*NetAddress) bool
- reactorsByCh map[byte]Reactor
- metrics *Metrics
+ isPersistent func(*NetAddress) bool
+ reactorsByCh map[byte]Reactor
+ msgTypeByChID map[byte]proto.Message
+ metrics *Metrics
+ mlc *metricsLabelCache
}
// Transport emits and connects to Peers. The implementation of Peer is left to
@@ -519,8 +522,10 @@ func (mt *MultiplexTransport) wrapPeer(
mt.mConfig,
ni,
cfg.reactorsByCh,
+ cfg.msgTypeByChID,
cfg.chDescs,
cfg.onPeerError,
+ cfg.mlc,
PeerMetrics(cfg.metrics),
)
diff --git a/p2p/transport_test.go b/p2p/transport_test.go
index 7638de4cb2..adaab39955 100644
--- a/p2p/transport_test.go
+++ b/p2p/transport_test.go
@@ -79,8 +79,8 @@ func TestTransportMultiplexConnFilter(t *testing.T) {
}
_, err = mt.Accept(peerConfig{})
- if err, ok := err.(ErrRejected); ok {
- if !err.IsFiltered() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsFiltered() {
t.Errorf("expected peer to be filtered, got %v", err)
}
} else {
@@ -386,8 +386,8 @@ func TestTransportMultiplexValidateNodeInfo(t *testing.T) {
}
_, err := mt.Accept(peerConfig{})
- if err, ok := err.(ErrRejected); ok {
- if !err.IsNodeInfoInvalid() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsNodeInfoInvalid() {
t.Errorf("expected NodeInfo to be invalid, got %v", err)
}
} else {
@@ -425,8 +425,8 @@ func TestTransportMultiplexRejectMissmatchID(t *testing.T) {
}
_, err := mt.Accept(peerConfig{})
- if err, ok := err.(ErrRejected); ok {
- if !err.IsAuthFailure() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsAuthFailure() {
t.Errorf("expected auth failure, got %v", err)
}
} else {
@@ -453,8 +453,8 @@ func TestTransportMultiplexDialRejectWrongID(t *testing.T) {
_, err := dialer.Dial(*addr, peerConfig{})
if err != nil {
t.Logf("connection failed: %v", err)
- if err, ok := err.(ErrRejected); ok {
- if !err.IsAuthFailure() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsAuthFailure() {
t.Errorf("expected auth failure, got %v", err)
}
} else {
@@ -490,8 +490,8 @@ func TestTransportMultiplexRejectIncompatible(t *testing.T) {
}()
_, err := mt.Accept(peerConfig{})
- if err, ok := err.(ErrRejected); ok {
- if !err.IsIncompatible() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsIncompatible() {
t.Errorf("expected to reject incompatible, got %v", err)
}
} else {
@@ -517,8 +517,8 @@ func TestTransportMultiplexRejectSelf(t *testing.T) {
}()
if err := <-errc; err != nil {
- if err, ok := err.(ErrRejected); ok {
- if !err.IsSelf() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsSelf() {
t.Errorf("expected to reject self, got: %v", err)
}
} else {
@@ -529,8 +529,8 @@ func TestTransportMultiplexRejectSelf(t *testing.T) {
}
_, err := mt.Accept(peerConfig{})
- if err, ok := err.(ErrRejected); ok {
- if !err.IsSelf() {
+ if e, ok := err.(ErrRejected); ok {
+ if !e.IsSelf() {
t.Errorf("expected to reject self, got: %v", err)
}
} else {
diff --git a/p2p/trust/metric_test.go b/p2p/trust/metric_test.go
index 65caf38a23..c3adfd5d17 100644
--- a/p2p/trust/metric_test.go
+++ b/p2p/trust/metric_test.go
@@ -72,6 +72,7 @@ func TestTrustMetricCopyNilPointer(t *testing.T) {
}
// XXX: This test fails non-deterministically
+//
//nolint:unused,deadcode
func _TestTrustMetricStopPause(t *testing.T) {
// The TestTicker will provide manual control over
diff --git a/p2p/trust/store_test.go b/p2p/trust/store_test.go
index df0f14a044..c583d58aad 100644
--- a/p2p/trust/store_test.go
+++ b/p2p/trust/store_test.go
@@ -5,7 +5,6 @@ package trust
import (
"fmt"
- "io/ioutil"
"os"
"testing"
@@ -17,7 +16,7 @@ import (
)
func TestTrustMetricStoreSaveLoad(t *testing.T) {
- dir, err := ioutil.TempDir("", "trust_test")
+ dir, err := os.MkdirTemp("", "trust_test")
require.NoError(t, err)
defer os.Remove(dir)
diff --git a/p2p/types.go b/p2p/types.go
index b11765bb51..7a741bd295 100644
--- a/p2p/types.go
+++ b/p2p/types.go
@@ -1,8 +1,40 @@
package p2p
import (
+ "github.com/gogo/protobuf/proto"
"github.com/tendermint/tendermint/p2p/conn"
+ tmp2p "github.com/tendermint/tendermint/proto/tendermint/p2p"
)
type ChannelDescriptor = conn.ChannelDescriptor
type ConnectionStatus = conn.ConnectionStatus
+
+// Envelope contains a message with sender routing info.
+type Envelope struct {
+ Src Peer // sender (empty if outbound)
+ Message proto.Message // message payload
+ ChannelID byte
+}
+
+// Unwrapper is a Protobuf message that can contain a variety of inner messages
+// (e.g. via oneof fields). If a Channel's message type implements Unwrapper, the
+// p2p layer will automatically unwrap inbound messages so that reactors do not have to do this themselves.
+type Unwrapper interface {
+ proto.Message
+
+ // Unwrap will unwrap the inner message contained in this message.
+ Unwrap() (proto.Message, error)
+}
+
+// Wrapper is a companion type to Unwrapper. It is a Protobuf message that can contain a variety of inner messages. The p2p layer will automatically wrap outbound messages so that the reactors do not have to do it themselves.
+type Wrapper interface {
+ proto.Message
+
+ // Wrap will take the underlying message and wrap it in its wrapper type.
+ Wrap() proto.Message
+}
+
+var (
+ _ Wrapper = &tmp2p.PexRequest{}
+ _ Wrapper = &tmp2p.PexAddrs{}
+)
diff --git a/p2p/upnp/upnp.go b/p2p/upnp/upnp.go
index c00530acae..0df5a24cfd 100644
--- a/p2p/upnp/upnp.go
+++ b/p2p/upnp/upnp.go
@@ -10,7 +10,7 @@ import (
"encoding/xml"
"errors"
"fmt"
- "io/ioutil"
+ "io"
"net"
"net/http"
"strconv"
@@ -202,7 +202,7 @@ func localIPv4() (net.IP, error) {
}
func getServiceURL(rootURL string) (url, urnDomain string, err error) {
- r, err := http.Get(rootURL) // nolint: gosec
+ r, err := http.Get(rootURL) //nolint: gosec
if err != nil {
return
}
@@ -299,7 +299,6 @@ type statusInfo struct {
}
func (n *upnpNAT) getExternalIPAddress() (info statusInfo, err error) {
-
message := "\r\n" +
""
@@ -312,7 +311,7 @@ func (n *upnpNAT) getExternalIPAddress() (info statusInfo, err error) {
return
}
var envelope Envelope
- data, err := ioutil.ReadAll(response.Body)
+ data, err := io.ReadAll(response.Body)
if err != nil {
return
}
@@ -350,7 +349,8 @@ func (n *upnpNAT) AddPortMapping(
externalPort,
internalPort int,
description string,
- timeout int) (mappedExternalPort int, err error) {
+ timeout int,
+) (mappedExternalPort int, err error) {
// A single concatenation would break ARM compilation.
message := "\r\n" +
"" + strconv.Itoa(externalPort)
@@ -374,7 +374,7 @@ func (n *upnpNAT) AddPortMapping(
// TODO: check response to see if the port was forwarded
// log.Println(message, response)
// JAE:
- // body, err := ioutil.ReadAll(response.Body)
+ // body, err := io.ReadAll(response.Body)
// fmt.Println(string(body), err)
mappedExternalPort = externalPort
_ = response
@@ -382,7 +382,6 @@ func (n *upnpNAT) AddPortMapping(
}
func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) {
-
message := "\r\n" +
"" + strconv.Itoa(externalPort) +
"" + protocol + "" +
diff --git a/privval/doc.go b/privval/doc.go
index 7695ffe9d0..63e1d071da 100644
--- a/privval/doc.go
+++ b/privval/doc.go
@@ -1,13 +1,12 @@
/*
-
Package privval provides different implementations of the types.PrivValidator.
-FilePV
+# FilePV
FilePV is the simplest implementation and developer default.
It uses one file for the private key and another to store state.
-SignerListenerEndpoint
+# SignerListenerEndpoint
SignerListenerEndpoint establishes a connection to an external process,
like a Key Management Server (KMS), using a socket.
@@ -15,15 +14,14 @@ SignerListenerEndpoint listens for the external KMS process to dial in.
SignerListenerEndpoint takes a listener, which determines the type of connection
(ie. encrypted over tcp, or unencrypted over unix).
-SignerDialerEndpoint
+# SignerDialerEndpoint
SignerDialerEndpoint is a simple wrapper around a net.Conn. It's used by both IPCVal and TCPVal.
-SignerClient
+# SignerClient
SignerClient handles remote validator connections that provide signing services.
In production, it's recommended to wrap it with RetrySignerClient to avoid
termination in case of temporary errors.
-
*/
package privval
diff --git a/privval/file.go b/privval/file.go
index fa33bb0ae6..9d0ddaf182 100644
--- a/privval/file.go
+++ b/privval/file.go
@@ -4,7 +4,7 @@ import (
"bytes"
"errors"
"fmt"
- "io/ioutil"
+ "os"
"time"
"github.com/gogo/protobuf/proto"
@@ -64,7 +64,7 @@ func (pvKey FilePVKey) Save() {
panic(err)
}
- if err := tempfile.WriteFileAtomic(outFile, jsonBytes, 0600); err != nil {
+ if err := tempfile.WriteFileAtomic(outFile, jsonBytes, 0o600); err != nil {
panic(err)
}
}
@@ -90,7 +90,6 @@ type FilePVLastSignState struct {
// we have already signed for this HRS, and can reuse the existing signature).
// It panics if the HRS matches the arguments, there's a SignBytes, but no Signature.
func (lss *FilePVLastSignState) CheckHRS(height int64, round int32, step int8) (bool, error) {
-
if lss.Height > height {
return false, fmt.Errorf("height regression. Got %v, last height %v", height, lss.Height)
}
@@ -133,7 +132,7 @@ func (lss *FilePVLastSignState) Save() {
if err != nil {
panic(err)
}
- err = tempfile.WriteFileAtomic(outFile, jsonBytes, 0600)
+ err = tempfile.WriteFileAtomic(outFile, jsonBytes, 0o600)
if err != nil {
panic(err)
}
@@ -188,7 +187,7 @@ func LoadFilePVEmptyState(keyFilePath, stateFilePath string) *FilePV {
// If loadState is true, we load from the stateFilePath. Otherwise, we use an empty LastSignState.
func loadFilePV(keyFilePath, stateFilePath string, loadState bool) *FilePV {
- keyJSONBytes, err := ioutil.ReadFile(keyFilePath)
+ keyJSONBytes, err := os.ReadFile(keyFilePath)
if err != nil {
tmos.Exit(err.Error())
}
@@ -206,7 +205,7 @@ func loadFilePV(keyFilePath, stateFilePath string, loadState bool) *FilePV {
pvState := FilePVLastSignState{}
if loadState {
- stateJSONBytes, err := ioutil.ReadFile(stateFilePath)
+ stateJSONBytes, err := os.ReadFile(stateFilePath)
if err != nil {
tmos.Exit(err.Error())
}
@@ -384,8 +383,8 @@ func (pv *FilePV) signProposal(chainID string, proposal *tmproto.Proposal) error
// Persist height/round/step and signature
func (pv *FilePV) saveSigned(height int64, round int32, step int8,
- signBytes []byte, sig []byte) {
-
+ signBytes []byte, sig []byte,
+) {
pv.LastSignState.Height = height
pv.LastSignState.Round = round
pv.LastSignState.Step = step
diff --git a/privval/file_test.go b/privval/file_test.go
index 69bd768745..76d06eab7c 100644
--- a/privval/file_test.go
+++ b/privval/file_test.go
@@ -3,7 +3,6 @@ package privval
import (
"encoding/base64"
"fmt"
- "io/ioutil"
"os"
"testing"
"time"
@@ -23,9 +22,9 @@ import (
func TestGenLoadValidator(t *testing.T) {
assert := assert.New(t)
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
@@ -41,9 +40,9 @@ func TestGenLoadValidator(t *testing.T) {
}
func TestResetValidator(t *testing.T) {
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
@@ -72,9 +71,9 @@ func TestResetValidator(t *testing.T) {
func TestLoadOrGenValidator(t *testing.T) {
assert := assert.New(t)
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
tempKeyFilePath := tempKeyFile.Name()
@@ -159,9 +158,9 @@ func TestUnmarshalValidatorKey(t *testing.T) {
func TestSignVote(t *testing.T) {
assert := assert.New(t)
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
@@ -169,10 +168,14 @@ func TestSignVote(t *testing.T) {
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
- block1 := types.BlockID{Hash: randbytes,
- PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}}
- block2 := types.BlockID{Hash: randbytes2,
- PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2}}
+ block1 := types.BlockID{
+ Hash: randbytes,
+ PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes},
+ }
+ block2 := types.BlockID{
+ Hash: randbytes2,
+ PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2},
+ }
height, round := int64(10), int32(1)
voteType := tmproto.PrevoteType
@@ -212,9 +215,9 @@ func TestSignVote(t *testing.T) {
func TestSignProposal(t *testing.T) {
assert := assert.New(t)
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
@@ -222,10 +225,14 @@ func TestSignProposal(t *testing.T) {
randbytes := tmrand.Bytes(tmhash.Size)
randbytes2 := tmrand.Bytes(tmhash.Size)
- block1 := types.BlockID{Hash: randbytes,
- PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes}}
- block2 := types.BlockID{Hash: randbytes2,
- PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2}}
+ block1 := types.BlockID{
+ Hash: randbytes,
+ PartSetHeader: types.PartSetHeader{Total: 5, Hash: randbytes},
+ }
+ block2 := types.BlockID{
+ Hash: randbytes2,
+ PartSetHeader: types.PartSetHeader{Total: 10, Hash: randbytes2},
+ }
height, round := int64(10), int32(1)
// sign a proposal for first time
@@ -260,9 +267,9 @@ func TestSignProposal(t *testing.T) {
}
func TestDifferByTimestamp(t *testing.T) {
- tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
+ tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
require.Nil(t, err)
- tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
+ tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
require.Nil(t, err)
privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name())
@@ -321,7 +328,8 @@ func TestDifferByTimestamp(t *testing.T) {
}
func newVote(addr types.Address, idx int32, height int64, round int32,
- typ tmproto.SignedMsgType, blockID types.BlockID) *types.Vote {
+ typ tmproto.SignedMsgType, blockID types.BlockID,
+) *types.Vote {
return &types.Vote{
ValidatorAddress: addr,
ValidatorIndex: idx,
diff --git a/privval/msgs_test.go b/privval/msgs_test.go
index bf532bd7b9..afefa0e77c 100644
--- a/privval/msgs_test.go
+++ b/privval/msgs_test.go
@@ -57,7 +57,7 @@ func exampleProposal() *types.Proposal {
}
}
-// nolint:lll // ignore line length for tests
+//nolint:lll // ignore line length for tests
func TestPrivvalVectors(t *testing.T) {
pk := ed25519.GenPrivKeyFromSecret([]byte("it's a secret")).PubKey()
ppk, err := cryptoenc.PubKeyToProto(pk)
diff --git a/privval/socket_listeners_test.go b/privval/socket_listeners_test.go
index 5e95ec10ce..08a285bdf8 100644
--- a/privval/socket_listeners_test.go
+++ b/privval/socket_listeners_test.go
@@ -1,7 +1,6 @@
package privval
import (
- "io/ioutil"
"net"
"os"
"testing"
@@ -29,7 +28,7 @@ type listenerTestCase struct {
// testUnixAddr will attempt to obtain a platform-independent temporary file
// name for a Unix socket
func testUnixAddr() (string, error) {
- f, err := ioutil.TempFile("", "tendermint-privval-test-*")
+ f, err := os.CreateTemp("", "tendermint-privval-test-*")
if err != nil {
return "", err
}
diff --git a/proto/README.md b/proto/README.md
new file mode 100644
index 0000000000..ebecd82d14
--- /dev/null
+++ b/proto/README.md
@@ -0,0 +1,23 @@
+# Protocol Buffers
+
+This sections defines the types and messages shared across implementations. The definition of the data structures are located in the [core/data_structures](../spec/core/data_structures.md) for the core data types and ABCI definitions are located in the [ABCI](../spec/abci/README.md) section.
+
+## Process of Updates
+
+The `.proto` files within this section are core to the protocol and updates must be treated as such.
+
+### Steps
+
+1. Make an issue with the proposed change.
+ - Within in the issue members from both the Tendermint-go and Tendermint-rs team will leave comments. If there is not consensus on the change an [RFC](../rfc/README.md) may be requested.
+ 1a. Submission of an RFC as a pull request should be made to facilitate further discussion.
+ 1b. Merge the RFC.
+2. Make the necessary changes to the `.proto` file(s), [core data structures](../spec/core/data_structures.md) and/or [ABCI protocol](../spec/abci/apps.md).
+3. Open issues within Tendermint-go and Tendermint-rs repos. This is used to notify the teams that a change occurred in the spec.
+ 1. Tag the issue with a spec version label. This will notify the team the changed has been made on master but has not entered a release.
+
+### Versioning
+
+The spec repo aims to be versioned. Once it has been versioned, updates to the protobuf files will live on master. After a certain amount of time, decided on by Tendermint-go and Tendermint-rs team leads, a release will be made on the spec repo. The spec may contain minor releases as well, depending on the implementation these changes may lead to a breaking change. If so, the implementation team should open an issue within the spec repo requiring a major release of the spec.
+
+If the steps above were followed each implementation should have issues tagged with a spec change label. Once all issues have been completed the team should signify their readiness for release.
diff --git a/proto/tendermint/blockchain/message.go b/proto/tendermint/blockchain/message.go
new file mode 100644
index 0000000000..1d11e41764
--- /dev/null
+++ b/proto/tendermint/blockchain/message.go
@@ -0,0 +1,73 @@
+package blockchain
+
+import (
+ "fmt"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/tendermint/tendermint/p2p"
+)
+
+var _ p2p.Wrapper = &StatusRequest{}
+var _ p2p.Wrapper = &StatusResponse{}
+var _ p2p.Wrapper = &NoBlockResponse{}
+var _ p2p.Wrapper = &BlockResponse{}
+var _ p2p.Wrapper = &BlockRequest{}
+
+const (
+ BlockResponseMessagePrefixSize = 4
+ BlockResponseMessageFieldKeySize = 1
+)
+
+func (m *BlockRequest) Wrap() proto.Message {
+ bm := &Message{}
+ bm.Sum = &Message_BlockRequest{BlockRequest: m}
+ return bm
+}
+
+func (m *BlockResponse) Wrap() proto.Message {
+ bm := &Message{}
+ bm.Sum = &Message_BlockResponse{BlockResponse: m}
+ return bm
+}
+
+func (m *NoBlockResponse) Wrap() proto.Message {
+ bm := &Message{}
+ bm.Sum = &Message_NoBlockResponse{NoBlockResponse: m}
+ return bm
+}
+
+func (m *StatusRequest) Wrap() proto.Message {
+ bm := &Message{}
+ bm.Sum = &Message_StatusRequest{StatusRequest: m}
+ return bm
+}
+
+func (m *StatusResponse) Wrap() proto.Message {
+ bm := &Message{}
+ bm.Sum = &Message_StatusResponse{StatusResponse: m}
+ return bm
+}
+
+// Unwrap implements the p2p Wrapper interface and unwraps a wrapped blockchain
+// message.
+func (m *Message) Unwrap() (proto.Message, error) {
+ switch msg := m.Sum.(type) {
+ case *Message_BlockRequest:
+ return m.GetBlockRequest(), nil
+
+ case *Message_BlockResponse:
+ return m.GetBlockResponse(), nil
+
+ case *Message_NoBlockResponse:
+ return m.GetNoBlockResponse(), nil
+
+ case *Message_StatusRequest:
+ return m.GetStatusRequest(), nil
+
+ case *Message_StatusResponse:
+ return m.GetStatusResponse(), nil
+
+ default:
+ return nil, fmt.Errorf("unknown message: %T", msg)
+ }
+}
diff --git a/proto/tendermint/consensus/message.go b/proto/tendermint/consensus/message.go
new file mode 100644
index 0000000000..51ac3b48f5
--- /dev/null
+++ b/proto/tendermint/consensus/message.go
@@ -0,0 +1,109 @@
+package consensus
+
+import (
+ "fmt"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/tendermint/tendermint/p2p"
+)
+
+var _ p2p.Wrapper = &VoteSetBits{}
+var _ p2p.Wrapper = &VoteSetMaj23{}
+var _ p2p.Wrapper = &Vote{}
+var _ p2p.Wrapper = &ProposalPOL{}
+var _ p2p.Wrapper = &Proposal{}
+var _ p2p.Wrapper = &NewValidBlock{}
+var _ p2p.Wrapper = &NewRoundStep{}
+var _ p2p.Wrapper = &HasVote{}
+var _ p2p.Wrapper = &BlockPart{}
+
+func (m *VoteSetBits) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_VoteSetBits{VoteSetBits: m}
+ return cm
+
+}
+
+func (m *VoteSetMaj23) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_VoteSetMaj23{VoteSetMaj23: m}
+ return cm
+}
+
+func (m *HasVote) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_HasVote{HasVote: m}
+ return cm
+}
+
+func (m *Vote) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_Vote{Vote: m}
+ return cm
+}
+
+func (m *BlockPart) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_BlockPart{BlockPart: m}
+ return cm
+}
+
+func (m *ProposalPOL) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_ProposalPol{ProposalPol: m}
+ return cm
+}
+
+func (m *Proposal) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_Proposal{Proposal: m}
+ return cm
+}
+
+func (m *NewValidBlock) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_NewValidBlock{NewValidBlock: m}
+ return cm
+}
+
+func (m *NewRoundStep) Wrap() proto.Message {
+ cm := &Message{}
+ cm.Sum = &Message_NewRoundStep{NewRoundStep: m}
+ return cm
+}
+
+// Unwrap implements the p2p Wrapper interface and unwraps a wrapped consensus
+// proto message.
+func (m *Message) Unwrap() (proto.Message, error) {
+ switch msg := m.Sum.(type) {
+ case *Message_NewRoundStep:
+ return m.GetNewRoundStep(), nil
+
+ case *Message_NewValidBlock:
+ return m.GetNewValidBlock(), nil
+
+ case *Message_Proposal:
+ return m.GetProposal(), nil
+
+ case *Message_ProposalPol:
+ return m.GetProposalPol(), nil
+
+ case *Message_BlockPart:
+ return m.GetBlockPart(), nil
+
+ case *Message_Vote:
+ return m.GetVote(), nil
+
+ case *Message_HasVote:
+ return m.GetHasVote(), nil
+
+ case *Message_VoteSetMaj23:
+ return m.GetVoteSetMaj23(), nil
+
+ case *Message_VoteSetBits:
+ return m.GetVoteSetBits(), nil
+
+ default:
+ return nil, fmt.Errorf("unknown message: %T", msg)
+ }
+}
diff --git a/proto/tendermint/mempool/message.go b/proto/tendermint/mempool/message.go
new file mode 100644
index 0000000000..e2e6c42a7d
--- /dev/null
+++ b/proto/tendermint/mempool/message.go
@@ -0,0 +1,30 @@
+package mempool
+
+import (
+ "fmt"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/tendermint/tendermint/p2p"
+)
+
+var _ p2p.Wrapper = &Txs{}
+var _ p2p.Unwrapper = &Message{}
+
+// Wrap implements the p2p Wrapper interface and wraps a mempool message.
+func (m *Txs) Wrap() proto.Message {
+ mm := &Message{}
+ mm.Sum = &Message_Txs{Txs: m}
+ return mm
+}
+
+// Unwrap implements the p2p Wrapper interface and unwraps a wrapped mempool
+// message.
+func (m *Message) Unwrap() (proto.Message, error) {
+ switch msg := m.Sum.(type) {
+ case *Message_Txs:
+ return m.GetTxs(), nil
+
+ default:
+ return nil, fmt.Errorf("unknown message: %T", msg)
+ }
+}
diff --git a/proto/tendermint/p2p/pex.go b/proto/tendermint/p2p/pex.go
new file mode 100644
index 0000000000..0fc2e2b108
--- /dev/null
+++ b/proto/tendermint/p2p/pex.go
@@ -0,0 +1,32 @@
+package p2p
+
+import (
+ "fmt"
+
+ "github.com/gogo/protobuf/proto"
+)
+
+func (m *PexAddrs) Wrap() proto.Message {
+ pm := &Message{}
+ pm.Sum = &Message_PexAddrs{PexAddrs: m}
+ return pm
+}
+
+func (m *PexRequest) Wrap() proto.Message {
+ pm := &Message{}
+ pm.Sum = &Message_PexRequest{PexRequest: m}
+ return pm
+}
+
+// Unwrap implements the p2p Wrapper interface and unwraps a wrapped PEX
+// message.
+func (m *Message) Unwrap() (proto.Message, error) {
+ switch msg := m.Sum.(type) {
+ case *Message_PexRequest:
+ return msg.PexRequest, nil
+ case *Message_PexAddrs:
+ return msg.PexAddrs, nil
+ default:
+ return nil, fmt.Errorf("unknown pex message: %T", msg)
+ }
+}
diff --git a/proto/tendermint/state/types.pb.go b/proto/tendermint/state/types.pb.go
index 85f38cada4..6b57ca1ae8 100644
--- a/proto/tendermint/state/types.pb.go
+++ b/proto/tendermint/state/types.pb.go
@@ -199,6 +199,58 @@ func (m *ConsensusParamsInfo) GetLastHeightChanged() int64 {
return 0
}
+type ABCIResponsesInfo struct {
+ AbciResponses *ABCIResponses `protobuf:"bytes,1,opt,name=abci_responses,json=abciResponses,proto3" json:"abci_responses,omitempty"`
+ Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"`
+}
+
+func (m *ABCIResponsesInfo) Reset() { *m = ABCIResponsesInfo{} }
+func (m *ABCIResponsesInfo) String() string { return proto.CompactTextString(m) }
+func (*ABCIResponsesInfo) ProtoMessage() {}
+func (*ABCIResponsesInfo) Descriptor() ([]byte, []int) {
+ return fileDescriptor_ccfacf933f22bf93, []int{3}
+}
+func (m *ABCIResponsesInfo) XXX_Unmarshal(b []byte) error {
+ return m.Unmarshal(b)
+}
+func (m *ABCIResponsesInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ if deterministic {
+ return xxx_messageInfo_ABCIResponsesInfo.Marshal(b, m, deterministic)
+ } else {
+ b = b[:cap(b)]
+ n, err := m.MarshalToSizedBuffer(b)
+ if err != nil {
+ return nil, err
+ }
+ return b[:n], nil
+ }
+}
+func (m *ABCIResponsesInfo) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_ABCIResponsesInfo.Merge(m, src)
+}
+func (m *ABCIResponsesInfo) XXX_Size() int {
+ return m.Size()
+}
+func (m *ABCIResponsesInfo) XXX_DiscardUnknown() {
+ xxx_messageInfo_ABCIResponsesInfo.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_ABCIResponsesInfo proto.InternalMessageInfo
+
+func (m *ABCIResponsesInfo) GetAbciResponses() *ABCIResponses {
+ if m != nil {
+ return m.AbciResponses
+ }
+ return nil
+}
+
+func (m *ABCIResponsesInfo) GetHeight() int64 {
+ if m != nil {
+ return m.Height
+ }
+ return 0
+}
+
type Version struct {
Consensus version.Consensus `protobuf:"bytes,1,opt,name=consensus,proto3" json:"consensus"`
Software string `protobuf:"bytes,2,opt,name=software,proto3" json:"software,omitempty"`
@@ -208,7 +260,7 @@ func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) {
- return fileDescriptor_ccfacf933f22bf93, []int{3}
+ return fileDescriptor_ccfacf933f22bf93, []int{4}
}
func (m *Version) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -284,7 +336,7 @@ func (m *State) Reset() { *m = State{} }
func (m *State) String() string { return proto.CompactTextString(m) }
func (*State) ProtoMessage() {}
func (*State) Descriptor() ([]byte, []int) {
- return fileDescriptor_ccfacf933f22bf93, []int{4}
+ return fileDescriptor_ccfacf933f22bf93, []int{5}
}
func (m *State) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -415,6 +467,7 @@ func init() {
proto.RegisterType((*ABCIResponses)(nil), "tendermint.state.ABCIResponses")
proto.RegisterType((*ValidatorsInfo)(nil), "tendermint.state.ValidatorsInfo")
proto.RegisterType((*ConsensusParamsInfo)(nil), "tendermint.state.ConsensusParamsInfo")
+ proto.RegisterType((*ABCIResponsesInfo)(nil), "tendermint.state.ABCIResponsesInfo")
proto.RegisterType((*Version)(nil), "tendermint.state.Version")
proto.RegisterType((*State)(nil), "tendermint.state.State")
}
@@ -422,55 +475,58 @@ func init() {
func init() { proto.RegisterFile("tendermint/state/types.proto", fileDescriptor_ccfacf933f22bf93) }
var fileDescriptor_ccfacf933f22bf93 = []byte{
- // 763 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcf, 0x6f, 0xd3, 0x30,
- 0x14, 0x6e, 0xe8, 0xb6, 0xb6, 0xce, 0xda, 0x0e, 0x8f, 0x43, 0xd6, 0xb1, 0xb4, 0x2b, 0x3f, 0x34,
- 0x71, 0x48, 0xa5, 0x71, 0x40, 0x5c, 0x26, 0x2d, 0x2d, 0x62, 0x95, 0x26, 0x04, 0xd9, 0xb4, 0x03,
- 0x97, 0xc8, 0x6d, 0xbc, 0x24, 0xa2, 0x4d, 0xa2, 0xd8, 0x2d, 0xe3, 0x0f, 0xe0, 0xbe, 0x2b, 0xff,
- 0xd1, 0x8e, 0x3b, 0x22, 0x0e, 0x03, 0xba, 0x7f, 0x04, 0xd9, 0xce, 0x0f, 0xb7, 0x65, 0xd2, 0x10,
- 0x37, 0xfb, 0x7d, 0xdf, 0xfb, 0xfc, 0xf9, 0xf9, 0x3d, 0x19, 0x3c, 0xa6, 0x38, 0x70, 0x70, 0x3c,
- 0xf6, 0x03, 0xda, 0x21, 0x14, 0x51, 0xdc, 0xa1, 0x5f, 0x22, 0x4c, 0x8c, 0x28, 0x0e, 0x69, 0x08,
- 0x37, 0x72, 0xd4, 0xe0, 0x68, 0xe3, 0x91, 0x1b, 0xba, 0x21, 0x07, 0x3b, 0x6c, 0x25, 0x78, 0x8d,
- 0x6d, 0x49, 0x05, 0x0d, 0x86, 0xbe, 0x2c, 0xd2, 0x90, 0x8f, 0xe0, 0xf1, 0x39, 0xb4, 0xb5, 0x84,
- 0x4e, 0xd1, 0xc8, 0x77, 0x10, 0x0d, 0xe3, 0x84, 0xb1, 0xb3, 0xc4, 0x88, 0x50, 0x8c, 0xc6, 0xa9,
- 0x80, 0x2e, 0xc1, 0x53, 0x1c, 0x13, 0x3f, 0x0c, 0xe6, 0x0e, 0x68, 0xba, 0x61, 0xe8, 0x8e, 0x70,
- 0x87, 0xef, 0x06, 0x93, 0xf3, 0x0e, 0xf5, 0xc7, 0x98, 0x50, 0x34, 0x8e, 0x04, 0xa1, 0xfd, 0x43,
- 0x01, 0xd5, 0x43, 0xb3, 0xdb, 0xb7, 0x30, 0x89, 0xc2, 0x80, 0x60, 0x02, 0xbb, 0x40, 0x75, 0xf0,
- 0xc8, 0x9f, 0xe2, 0xd8, 0xa6, 0x17, 0x44, 0x53, 0x5a, 0xc5, 0x3d, 0x75, 0xbf, 0x6d, 0x48, 0xc5,
- 0x60, 0x97, 0x34, 0xd2, 0x84, 0x9e, 0xe0, 0x9e, 0x5e, 0x58, 0xc0, 0x49, 0x97, 0x04, 0x1e, 0x80,
- 0x0a, 0x0e, 0x1c, 0x7b, 0x30, 0x0a, 0x87, 0x9f, 0xb4, 0x07, 0x2d, 0x65, 0x4f, 0xdd, 0xdf, 0xbd,
- 0x53, 0xe2, 0x4d, 0xe0, 0x98, 0x8c, 0x68, 0x95, 0x71, 0xb2, 0x82, 0x3d, 0xa0, 0x0e, 0xb0, 0xeb,
- 0x07, 0x89, 0x42, 0x91, 0x2b, 0x3c, 0xb9, 0x53, 0xc1, 0x64, 0x5c, 0xa1, 0x01, 0x06, 0xd9, 0xba,
- 0xfd, 0x55, 0x01, 0xb5, 0xb3, 0xb4, 0xa0, 0xa4, 0x1f, 0x9c, 0x87, 0xb0, 0x0b, 0xaa, 0x59, 0x89,
- 0x6d, 0x82, 0xa9, 0xa6, 0x70, 0x69, 0x5d, 0x96, 0x16, 0x05, 0xcc, 0x12, 0x4f, 0x30, 0xb5, 0xd6,
- 0xa7, 0xd2, 0x0e, 0x1a, 0x60, 0x73, 0x84, 0x08, 0xb5, 0x3d, 0xec, 0xbb, 0x1e, 0xb5, 0x87, 0x1e,
- 0x0a, 0x5c, 0xec, 0xf0, 0x7b, 0x16, 0xad, 0x87, 0x0c, 0x3a, 0xe2, 0x48, 0x57, 0x00, 0xed, 0x6f,
- 0x0a, 0xd8, 0xec, 0x32, 0x9f, 0x01, 0x99, 0x90, 0xf7, 0xfc, 0xfd, 0xb8, 0x19, 0x0b, 0x6c, 0x0c,
- 0xd3, 0xb0, 0x2d, 0xde, 0x35, 0xf1, 0xb3, 0xbb, 0xec, 0x67, 0x41, 0xc0, 0x5c, 0xb9, 0xba, 0x69,
- 0x16, 0xac, 0xfa, 0x70, 0x3e, 0xfc, 0xcf, 0xde, 0x3c, 0x50, 0x3a, 0x13, 0x8d, 0x03, 0x0f, 0x41,
- 0x25, 0x53, 0x4b, 0x7c, 0xec, 0xc8, 0x3e, 0x92, 0x06, 0xcb, 0x9d, 0x24, 0x1e, 0xf2, 0x2c, 0xd8,
- 0x00, 0x65, 0x12, 0x9e, 0xd3, 0xcf, 0x28, 0xc6, 0xfc, 0xc8, 0x8a, 0x95, 0xed, 0xdb, 0xbf, 0xd7,
- 0xc0, 0xea, 0x09, 0x9b, 0x23, 0xf8, 0x1a, 0x94, 0x12, 0xad, 0xe4, 0x98, 0x2d, 0x63, 0x71, 0xd6,
- 0x8c, 0xc4, 0x54, 0x72, 0x44, 0xca, 0x87, 0xcf, 0x41, 0x79, 0xe8, 0x21, 0x3f, 0xb0, 0x7d, 0x71,
- 0xa7, 0x8a, 0xa9, 0xce, 0x6e, 0x9a, 0xa5, 0x2e, 0x8b, 0xf5, 0x7b, 0x56, 0x89, 0x83, 0x7d, 0x07,
- 0x3e, 0x03, 0x35, 0x3f, 0xf0, 0xa9, 0x8f, 0x46, 0x49, 0x25, 0xb4, 0x1a, 0xaf, 0x40, 0x35, 0x89,
- 0x8a, 0x22, 0xc0, 0x17, 0x80, 0x97, 0x44, 0xb4, 0x59, 0xca, 0x2c, 0x72, 0x66, 0x9d, 0x01, 0xbc,
- 0x8f, 0x12, 0xae, 0x05, 0xaa, 0x12, 0xd7, 0x77, 0xb4, 0x95, 0x65, 0xef, 0xe2, 0xa9, 0x78, 0x56,
- 0xbf, 0x67, 0x6e, 0x32, 0xef, 0xb3, 0x9b, 0xa6, 0x7a, 0x9c, 0x4a, 0xf5, 0x7b, 0x96, 0x9a, 0xe9,
- 0xf6, 0x1d, 0x78, 0x0c, 0xea, 0x92, 0x26, 0x1b, 0x4e, 0x6d, 0x95, 0xab, 0x36, 0x0c, 0x31, 0xb9,
- 0x46, 0x3a, 0xb9, 0xc6, 0x69, 0x3a, 0xb9, 0x66, 0x99, 0xc9, 0x5e, 0xfe, 0x6c, 0x2a, 0x56, 0x35,
- 0xd3, 0x62, 0x28, 0x7c, 0x0b, 0xea, 0x01, 0xbe, 0xa0, 0x76, 0xd6, 0xac, 0x44, 0x5b, 0xbb, 0x57,
- 0x7b, 0xd7, 0x58, 0x5a, 0x3e, 0x29, 0xf0, 0x00, 0x00, 0x49, 0xa3, 0x74, 0x2f, 0x0d, 0x29, 0x83,
- 0x19, 0xe1, 0xd7, 0x92, 0x44, 0xca, 0xf7, 0x33, 0xc2, 0xd2, 0x24, 0x23, 0x5d, 0xa0, 0xcb, 0xdd,
- 0x9c, 0xeb, 0x65, 0x8d, 0x5d, 0xe1, 0x8f, 0xb5, 0x9d, 0x37, 0x76, 0x9e, 0x9d, 0xb4, 0xf8, 0x5f,
- 0xc7, 0x0c, 0xfc, 0xe7, 0x98, 0xbd, 0x03, 0x4f, 0xe7, 0xc6, 0x6c, 0x41, 0x3f, 0xb3, 0xa7, 0x72,
- 0x7b, 0x2d, 0x69, 0xee, 0xe6, 0x85, 0x52, 0x8f, 0x69, 0x23, 0xc6, 0x98, 0x4c, 0x46, 0x94, 0xd8,
- 0x1e, 0x22, 0x9e, 0xb6, 0xde, 0x52, 0xf6, 0xd6, 0x45, 0x23, 0x5a, 0x22, 0x7e, 0x84, 0x88, 0x07,
- 0xb7, 0x40, 0x19, 0x45, 0x91, 0xa0, 0x54, 0x39, 0xa5, 0x84, 0xa2, 0x88, 0x41, 0xe6, 0x87, 0xab,
- 0x99, 0xae, 0x5c, 0xcf, 0x74, 0xe5, 0xd7, 0x4c, 0x57, 0x2e, 0x6f, 0xf5, 0xc2, 0xf5, 0xad, 0x5e,
- 0xf8, 0x7e, 0xab, 0x17, 0x3e, 0xbe, 0x72, 0x7d, 0xea, 0x4d, 0x06, 0xc6, 0x30, 0x1c, 0x77, 0xe4,
- 0x3f, 0x25, 0x5f, 0x8a, 0x8f, 0x6d, 0xf1, 0x4b, 0x1c, 0xac, 0xf1, 0xf8, 0xcb, 0x3f, 0x01, 0x00,
- 0x00, 0xff, 0xff, 0xa5, 0x17, 0xac, 0x23, 0x2d, 0x07, 0x00, 0x00,
+ // 805 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xcd, 0x8e, 0xe3, 0x44,
+ 0x10, 0x8e, 0xc9, 0x6e, 0x7e, 0xca, 0x93, 0x64, 0xb7, 0x07, 0x21, 0x6f, 0x96, 0x75, 0xb2, 0xe1,
+ 0x47, 0x23, 0x0e, 0x8e, 0xb4, 0x1c, 0x10, 0x97, 0x95, 0xd6, 0x09, 0xb0, 0x91, 0x56, 0x08, 0x3c,
+ 0xa3, 0x39, 0x70, 0xb1, 0x3a, 0x71, 0x8f, 0x6d, 0x91, 0xd8, 0x96, 0xbb, 0x13, 0x86, 0x07, 0xe0,
+ 0x3e, 0x57, 0xde, 0x68, 0x8e, 0x73, 0x44, 0x1c, 0x06, 0xc8, 0xbc, 0x08, 0xea, 0x1f, 0xdb, 0x9d,
+ 0x84, 0x91, 0x06, 0xed, 0xad, 0x5d, 0xf5, 0xd5, 0x57, 0x5f, 0x55, 0x57, 0xb5, 0xe1, 0x63, 0x46,
+ 0x92, 0x80, 0xe4, 0xab, 0x38, 0x61, 0x63, 0xca, 0x30, 0x23, 0x63, 0xf6, 0x6b, 0x46, 0xa8, 0x93,
+ 0xe5, 0x29, 0x4b, 0xd1, 0x93, 0xca, 0xeb, 0x08, 0x6f, 0xff, 0xc3, 0x30, 0x0d, 0x53, 0xe1, 0x1c,
+ 0xf3, 0x93, 0xc4, 0xf5, 0x9f, 0x6b, 0x2c, 0x78, 0xbe, 0x88, 0x75, 0x92, 0xbe, 0x9e, 0x42, 0xd8,
+ 0x77, 0xbc, 0xc3, 0x03, 0xef, 0x06, 0x2f, 0xe3, 0x00, 0xb3, 0x34, 0x57, 0x88, 0x17, 0x07, 0x88,
+ 0x0c, 0xe7, 0x78, 0x55, 0x10, 0xd8, 0x9a, 0x7b, 0x43, 0x72, 0x1a, 0xa7, 0xc9, 0x4e, 0x82, 0x41,
+ 0x98, 0xa6, 0xe1, 0x92, 0x8c, 0xc5, 0xd7, 0x7c, 0x7d, 0x31, 0x66, 0xf1, 0x8a, 0x50, 0x86, 0x57,
+ 0x99, 0x04, 0x8c, 0xfe, 0x34, 0xa0, 0xf3, 0xc6, 0x9d, 0xcc, 0x3c, 0x42, 0xb3, 0x34, 0xa1, 0x84,
+ 0xa2, 0x09, 0x98, 0x01, 0x59, 0xc6, 0x1b, 0x92, 0xfb, 0xec, 0x92, 0x5a, 0xc6, 0xb0, 0x7e, 0x62,
+ 0xbe, 0x1a, 0x39, 0x5a, 0x33, 0x78, 0x91, 0x4e, 0x11, 0x30, 0x95, 0xd8, 0xb3, 0x4b, 0x0f, 0x82,
+ 0xe2, 0x48, 0xd1, 0x6b, 0x68, 0x93, 0x24, 0xf0, 0xe7, 0xcb, 0x74, 0xf1, 0xb3, 0xf5, 0xc1, 0xd0,
+ 0x38, 0x31, 0x5f, 0xbd, 0xbc, 0x97, 0xe2, 0x9b, 0x24, 0x70, 0x39, 0xd0, 0x6b, 0x11, 0x75, 0x42,
+ 0x53, 0x30, 0xe7, 0x24, 0x8c, 0x13, 0xc5, 0x50, 0x17, 0x0c, 0x9f, 0xdc, 0xcb, 0xe0, 0x72, 0xac,
+ 0xe4, 0x80, 0x79, 0x79, 0x1e, 0xfd, 0x66, 0x40, 0xf7, 0xbc, 0x68, 0x28, 0x9d, 0x25, 0x17, 0x29,
+ 0x9a, 0x40, 0xa7, 0x6c, 0xb1, 0x4f, 0x09, 0xb3, 0x0c, 0x41, 0x6d, 0xeb, 0xd4, 0xb2, 0x81, 0x65,
+ 0xe0, 0x29, 0x61, 0xde, 0xd1, 0x46, 0xfb, 0x42, 0x0e, 0x1c, 0x2f, 0x31, 0x65, 0x7e, 0x44, 0xe2,
+ 0x30, 0x62, 0xfe, 0x22, 0xc2, 0x49, 0x48, 0x02, 0x51, 0x67, 0xdd, 0x7b, 0xca, 0x5d, 0x6f, 0x85,
+ 0x67, 0x22, 0x1d, 0xa3, 0xdf, 0x0d, 0x38, 0x9e, 0x70, 0x9d, 0x09, 0x5d, 0xd3, 0x1f, 0xc4, 0xfd,
+ 0x09, 0x31, 0x1e, 0x3c, 0x59, 0x14, 0x66, 0x5f, 0xde, 0xab, 0xd2, 0xf3, 0xf2, 0x50, 0xcf, 0x1e,
+ 0x81, 0xfb, 0xe8, 0xfa, 0x76, 0x50, 0xf3, 0x7a, 0x8b, 0x5d, 0xf3, 0xff, 0xd6, 0x46, 0xe1, 0xe9,
+ 0xce, 0xfd, 0x0b, 0x61, 0xdf, 0x42, 0x97, 0xf7, 0xd7, 0xcf, 0x0b, 0xab, 0x92, 0x35, 0x70, 0xf6,
+ 0x77, 0xc2, 0xd9, 0x09, 0xf6, 0x3a, 0x3c, 0xac, 0x9a, 0xa5, 0x8f, 0xa0, 0x21, 0x75, 0xa8, 0xfc,
+ 0xea, 0x6b, 0x14, 0x41, 0xf3, 0x5c, 0x4e, 0x2b, 0x7a, 0x03, 0xed, 0xb2, 0x04, 0x95, 0xe5, 0x85,
+ 0x9e, 0x45, 0x4d, 0x75, 0x55, 0xbe, 0x2a, 0xbc, 0x8a, 0x42, 0x7d, 0x68, 0xd1, 0xf4, 0x82, 0xfd,
+ 0x82, 0x73, 0x22, 0xf2, 0xb4, 0xbd, 0xf2, 0x7b, 0xf4, 0x4f, 0x03, 0x1e, 0x9f, 0x72, 0xa1, 0xe8,
+ 0x6b, 0x68, 0x2a, 0x2e, 0x95, 0xe6, 0xd9, 0x61, 0x31, 0x4a, 0x94, 0x4a, 0x51, 0xe0, 0xd1, 0xe7,
+ 0xd0, 0x5a, 0x44, 0x38, 0x4e, 0xfc, 0x58, 0x36, 0xb2, 0xed, 0x9a, 0xdb, 0xdb, 0x41, 0x73, 0xc2,
+ 0x6d, 0xb3, 0xa9, 0xd7, 0x14, 0xce, 0x59, 0x80, 0x3e, 0x83, 0x6e, 0x9c, 0xc4, 0x2c, 0xc6, 0x4b,
+ 0xd5, 0x7e, 0xab, 0x2b, 0xca, 0xee, 0x28, 0xab, 0xec, 0x3c, 0xfa, 0x02, 0xc4, 0x3d, 0xc8, 0xd9,
+ 0x2e, 0x90, 0x75, 0x81, 0xec, 0x71, 0x87, 0x18, 0x5e, 0x85, 0xf5, 0xa0, 0xa3, 0x61, 0xe3, 0xc0,
+ 0x7a, 0x74, 0xa8, 0x5d, 0xce, 0x87, 0x88, 0x9a, 0x4d, 0xdd, 0x63, 0xae, 0x7d, 0x7b, 0x3b, 0x30,
+ 0xdf, 0x15, 0x54, 0xb3, 0xa9, 0x67, 0x96, 0xbc, 0xb3, 0x00, 0xbd, 0x83, 0x9e, 0xc6, 0xc9, 0x5f,
+ 0x04, 0xeb, 0xb1, 0x60, 0xed, 0x3b, 0xf2, 0xb9, 0x70, 0x8a, 0xe7, 0xc2, 0x39, 0x2b, 0x9e, 0x0b,
+ 0xb7, 0xc5, 0x69, 0xaf, 0xfe, 0x1a, 0x18, 0x5e, 0xa7, 0xe4, 0xe2, 0x5e, 0xf4, 0x1d, 0xf4, 0x12,
+ 0x72, 0xc9, 0xfc, 0x72, 0x43, 0xa8, 0xd5, 0x78, 0xd0, 0x4e, 0x75, 0x79, 0x58, 0xb5, 0x9e, 0xe8,
+ 0x35, 0x80, 0xc6, 0xd1, 0x7c, 0x10, 0x87, 0x16, 0xc1, 0x85, 0x88, 0xb2, 0x34, 0x92, 0xd6, 0xc3,
+ 0x84, 0xf0, 0x30, 0x4d, 0xc8, 0x04, 0x6c, 0x7d, 0x85, 0x2a, 0xbe, 0x72, 0x9b, 0xda, 0xe2, 0xb2,
+ 0x9e, 0x57, 0xdb, 0x54, 0x45, 0xab, 0xbd, 0xfa, 0xcf, 0xdd, 0x86, 0xf7, 0xdc, 0xed, 0xef, 0xe1,
+ 0xd3, 0x9d, 0xdd, 0xde, 0xe3, 0x2f, 0xe5, 0x99, 0x42, 0xde, 0x50, 0x5b, 0xf6, 0x5d, 0xa2, 0x42,
+ 0x63, 0x31, 0x88, 0x39, 0xa1, 0xeb, 0x25, 0xa3, 0x7e, 0x84, 0x69, 0x64, 0x1d, 0x0d, 0x8d, 0x93,
+ 0x23, 0x39, 0x88, 0x9e, 0xb4, 0xbf, 0xc5, 0x34, 0x42, 0xcf, 0xa0, 0x85, 0xb3, 0x4c, 0x42, 0x3a,
+ 0x02, 0xd2, 0xc4, 0x59, 0xc6, 0x5d, 0xee, 0x8f, 0xd7, 0x5b, 0xdb, 0xb8, 0xd9, 0xda, 0xc6, 0xdf,
+ 0x5b, 0xdb, 0xb8, 0xba, 0xb3, 0x6b, 0x37, 0x77, 0x76, 0xed, 0x8f, 0x3b, 0xbb, 0xf6, 0xd3, 0x57,
+ 0x61, 0xcc, 0xa2, 0xf5, 0xdc, 0x59, 0xa4, 0xab, 0xb1, 0xfe, 0x23, 0xab, 0x8e, 0xf2, 0x6f, 0xba,
+ 0xff, 0x1f, 0x9e, 0x37, 0x84, 0xfd, 0xcb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x1a, 0xb9,
+ 0x2e, 0xa2, 0x07, 0x00, 0x00,
}
func (m *ABCIResponses) Marshal() (dAtA []byte, err error) {
@@ -612,6 +668,46 @@ func (m *ConsensusParamsInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
+func (m *ABCIResponsesInfo) Marshal() (dAtA []byte, err error) {
+ size := m.Size()
+ dAtA = make([]byte, size)
+ n, err := m.MarshalToSizedBuffer(dAtA[:size])
+ if err != nil {
+ return nil, err
+ }
+ return dAtA[:n], nil
+}
+
+func (m *ABCIResponsesInfo) MarshalTo(dAtA []byte) (int, error) {
+ size := m.Size()
+ return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *ABCIResponsesInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+ i := len(dAtA)
+ _ = i
+ var l int
+ _ = l
+ if m.Height != 0 {
+ i = encodeVarintTypes(dAtA, i, uint64(m.Height))
+ i--
+ dAtA[i] = 0x10
+ }
+ if m.AbciResponses != nil {
+ {
+ size, err := m.AbciResponses.MarshalToSizedBuffer(dAtA[:i])
+ if err != nil {
+ return 0, err
+ }
+ i -= size
+ i = encodeVarintTypes(dAtA, i, uint64(size))
+ }
+ i--
+ dAtA[i] = 0xa
+ }
+ return len(dAtA) - i, nil
+}
+
func (m *Version) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -747,12 +843,12 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x32
}
- n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime):])
- if err10 != nil {
- return 0, err10
+ n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime):])
+ if err11 != nil {
+ return 0, err11
}
- i -= n10
- i = encodeVarintTypes(dAtA, i, uint64(n10))
+ i -= n11
+ i = encodeVarintTypes(dAtA, i, uint64(n11))
i--
dAtA[i] = 0x2a
{
@@ -854,6 +950,22 @@ func (m *ConsensusParamsInfo) Size() (n int) {
return n
}
+func (m *ABCIResponsesInfo) Size() (n int) {
+ if m == nil {
+ return 0
+ }
+ var l int
+ _ = l
+ if m.AbciResponses != nil {
+ l = m.AbciResponses.Size()
+ n += 1 + l + sovTypes(uint64(l))
+ }
+ if m.Height != 0 {
+ n += 1 + sovTypes(uint64(m.Height))
+ }
+ return n
+}
+
func (m *Version) Size() (n int) {
if m == nil {
return 0
@@ -1291,6 +1403,111 @@ func (m *ConsensusParamsInfo) Unmarshal(dAtA []byte) error {
}
return nil
}
+func (m *ABCIResponsesInfo) Unmarshal(dAtA []byte) error {
+ l := len(dAtA)
+ iNdEx := 0
+ for iNdEx < l {
+ preIndex := iNdEx
+ var wire uint64
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTypes
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ wire |= uint64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ fieldNum := int32(wire >> 3)
+ wireType := int(wire & 0x7)
+ if wireType == 4 {
+ return fmt.Errorf("proto: ABCIResponsesInfo: wiretype end group for non-group")
+ }
+ if fieldNum <= 0 {
+ return fmt.Errorf("proto: ABCIResponsesInfo: illegal tag %d (wire type %d)", fieldNum, wire)
+ }
+ switch fieldNum {
+ case 1:
+ if wireType != 2 {
+ return fmt.Errorf("proto: wrong wireType = %d for field AbciResponses", wireType)
+ }
+ var msglen int
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTypes
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ msglen |= int(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ if msglen < 0 {
+ return ErrInvalidLengthTypes
+ }
+ postIndex := iNdEx + msglen
+ if postIndex < 0 {
+ return ErrInvalidLengthTypes
+ }
+ if postIndex > l {
+ return io.ErrUnexpectedEOF
+ }
+ if m.AbciResponses == nil {
+ m.AbciResponses = &ABCIResponses{}
+ }
+ if err := m.AbciResponses.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+ return err
+ }
+ iNdEx = postIndex
+ case 2:
+ if wireType != 0 {
+ return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType)
+ }
+ m.Height = 0
+ for shift := uint(0); ; shift += 7 {
+ if shift >= 64 {
+ return ErrIntOverflowTypes
+ }
+ if iNdEx >= l {
+ return io.ErrUnexpectedEOF
+ }
+ b := dAtA[iNdEx]
+ iNdEx++
+ m.Height |= int64(b&0x7F) << shift
+ if b < 0x80 {
+ break
+ }
+ }
+ default:
+ iNdEx = preIndex
+ skippy, err := skipTypes(dAtA[iNdEx:])
+ if err != nil {
+ return err
+ }
+ if (skippy < 0) || (iNdEx+skippy) < 0 {
+ return ErrInvalidLengthTypes
+ }
+ if (iNdEx + skippy) > l {
+ return io.ErrUnexpectedEOF
+ }
+ iNdEx += skippy
+ }
+ }
+
+ if iNdEx > l {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
func (m *Version) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
diff --git a/proto/tendermint/state/types.proto b/proto/tendermint/state/types.proto
index 919da91e52..f3fdc0ef39 100644
--- a/proto/tendermint/state/types.proto
+++ b/proto/tendermint/state/types.proto
@@ -32,6 +32,11 @@ message ConsensusParamsInfo {
int64 last_height_changed = 2;
}
+message ABCIResponsesInfo {
+ ABCIResponses abci_responses = 1;
+ int64 height = 2;
+}
+
message Version {
tendermint.version.Consensus consensus = 1 [(gogoproto.nullable) = false];
string software = 2;
diff --git a/proto/tendermint/statesync/message.go b/proto/tendermint/statesync/message.go
new file mode 100644
index 0000000000..66f583674f
--- /dev/null
+++ b/proto/tendermint/statesync/message.go
@@ -0,0 +1,58 @@
+package statesync
+
+import (
+ "fmt"
+
+ "github.com/gogo/protobuf/proto"
+ "github.com/tendermint/tendermint/p2p"
+)
+
+var _ p2p.Wrapper = &ChunkRequest{}
+var _ p2p.Wrapper = &ChunkResponse{}
+var _ p2p.Wrapper = &SnapshotsRequest{}
+var _ p2p.Wrapper = &SnapshotsResponse{}
+
+func (m *SnapshotsResponse) Wrap() proto.Message {
+ sm := &Message{}
+ sm.Sum = &Message_SnapshotsResponse{SnapshotsResponse: m}
+ return sm
+}
+
+func (m *SnapshotsRequest) Wrap() proto.Message {
+ sm := &Message{}
+ sm.Sum = &Message_SnapshotsRequest{SnapshotsRequest: m}
+ return sm
+}
+
+func (m *ChunkResponse) Wrap() proto.Message {
+ sm := &Message{}
+ sm.Sum = &Message_ChunkResponse{ChunkResponse: m}
+ return sm
+}
+
+func (m *ChunkRequest) Wrap() proto.Message {
+ sm := &Message{}
+ sm.Sum = &Message_ChunkRequest{ChunkRequest: m}
+ return sm
+}
+
+// Unwrap implements the p2p Wrapper interface and unwraps a wrapped state sync
+// proto message.
+func (m *Message) Unwrap() (proto.Message, error) {
+ switch msg := m.Sum.(type) {
+ case *Message_ChunkRequest:
+ return m.GetChunkRequest(), nil
+
+ case *Message_ChunkResponse:
+ return m.GetChunkResponse(), nil
+
+ case *Message_SnapshotsRequest:
+ return m.GetSnapshotsRequest(), nil
+
+ case *Message_SnapshotsResponse:
+ return m.GetSnapshotsResponse(), nil
+
+ default:
+ return nil, fmt.Errorf("unknown message: %T", msg)
+ }
+}
diff --git a/proxy/app_conn.go b/proxy/app_conn.go
index d302b5affa..f4bb888b72 100644
--- a/proxy/app_conn.go
+++ b/proxy/app_conn.go
@@ -5,7 +5,7 @@ import (
"github.com/tendermint/tendermint/abci/types"
)
-//go:generate mockery --case underscore --name AppConnConsensus|AppConnMempool|AppConnQuery|AppConnSnapshot
+//go:generate ../scripts/mockery_generate.sh AppConnConsensus|AppConnMempool|AppConnQuery|AppConnSnapshot
//----------------------------------------------------------------------------------------
// Enforce which abci msgs can be sent on a connection at the type level
diff --git a/proxy/client.go b/proxy/client.go
index e78e827abe..68498d574c 100644
--- a/proxy/client.go
+++ b/proxy/client.go
@@ -11,6 +11,8 @@ import (
e2e "github.com/tendermint/tendermint/test/e2e/app"
)
+//go:generate ../scripts/mockery_generate.sh ClientCreator
+
// ClientCreator creates new ABCI clients.
type ClientCreator interface {
// NewABCIClient returns a new ABCI client.
diff --git a/proxy/mocks/app_conn_consensus.go b/proxy/mocks/app_conn_consensus.go
index 7803a31893..eccf74fc31 100644
--- a/proxy/mocks/app_conn_consensus.go
+++ b/proxy/mocks/app_conn_consensus.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
diff --git a/proxy/mocks/app_conn_mempool.go b/proxy/mocks/app_conn_mempool.go
index e33bc4b3ac..05e23dd433 100644
--- a/proxy/mocks/app_conn_mempool.go
+++ b/proxy/mocks/app_conn_mempool.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
diff --git a/proxy/mocks/app_conn_query.go b/proxy/mocks/app_conn_query.go
index 5cbd2dfd49..544ab765ef 100644
--- a/proxy/mocks/app_conn_query.go
+++ b/proxy/mocks/app_conn_query.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
diff --git a/proxy/mocks/app_conn_snapshot.go b/proxy/mocks/app_conn_snapshot.go
index 6f2c81bb47..e3d5cb6cda 100644
--- a/proxy/mocks/app_conn_snapshot.go
+++ b/proxy/mocks/app_conn_snapshot.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.14.0. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
diff --git a/proxy/mocks/client_creator.go b/proxy/mocks/client_creator.go
index e4b924ab52..eced0aeff6 100644
--- a/proxy/mocks/client_creator.go
+++ b/proxy/mocks/client_creator.go
@@ -1,10 +1,9 @@
-// Code generated by mockery v1.1.1. DO NOT EDIT.
+// Code generated by mockery. DO NOT EDIT.
package mocks
import (
mock "github.com/stretchr/testify/mock"
-
abcicli "github.com/tendermint/tendermint/abci/client"
)
@@ -35,3 +34,18 @@ func (_m *ClientCreator) NewABCIClient() (abcicli.Client, error) {
return r0, r1
}
+
+type mockConstructorTestingTNewClientCreator interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewClientCreator creates a new instance of ClientCreator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewClientCreator(t mockConstructorTestingTNewClientCreator) *ClientCreator {
+ mock := &ClientCreator{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
diff --git a/proxy/multi_app_conn_test.go b/proxy/multi_app_conn_test.go
index 34b0d0830e..a7e77148e1 100644
--- a/proxy/multi_app_conn_test.go
+++ b/proxy/multi_app_conn_test.go
@@ -53,7 +53,7 @@ func TestAppConns_Failure(t *testing.T) {
}()
quitCh := make(chan struct{})
- var recvQuitCh <-chan struct{} // nolint:gosimple
+ var recvQuitCh <-chan struct{} //nolint:gosimple
recvQuitCh = quitCh
clientCreatorMock := &mocks.ClientCreator{}
diff --git a/rpc/client/http/http.go b/rpc/client/http/http.go
index 9a64d97f16..a317d65e14 100644
--- a/rpc/client/http/http.go
+++ b/rpc/client/http/http.go
@@ -39,24 +39,24 @@ the example for more details.
Example:
- c, err := New("http://192.168.1.10:26657", "/websocket")
- if err != nil {
- // handle error
- }
+ c, err := New("http://192.168.1.10:26657", "/websocket")
+ if err != nil {
+ // handle error
+ }
- // call Start/Stop if you're subscribing to events
- err = c.Start()
- if err != nil {
- // handle error
- }
- defer c.Stop()
+ // call Start/Stop if you're subscribing to events
+ err = c.Start()
+ if err != nil {
+ // handle error
+ }
+ defer c.Stop()
- res, err := c.Status()
- if err != nil {
- // handle error
- }
+ res, err := c.Status()
+ if err != nil {
+ // handle error
+ }
- // handle result
+ // handle result
*/
type HTTP struct {
remote string
diff --git a/rpc/client/main_test.go b/rpc/client/main_test.go
index c97311c810..4c0534868f 100644
--- a/rpc/client/main_test.go
+++ b/rpc/client/main_test.go
@@ -1,7 +1,6 @@
package client_test
import (
- "io/ioutil"
"os"
"testing"
@@ -14,7 +13,7 @@ var node *nm.Node
func TestMain(m *testing.M) {
// start a tendermint node (and kvstore) in the background to test against
- dir, err := ioutil.TempDir("/tmp", "rpc-client-test")
+ dir, err := os.MkdirTemp("/tmp", "rpc-client-test")
if err != nil {
panic(err)
}
diff --git a/rpc/core/abci.go b/rpc/core/abci.go
index 34aad0f3de..cfd1fef26a 100644
--- a/rpc/core/abci.go
+++ b/rpc/core/abci.go
@@ -9,7 +9,7 @@ import (
)
// ABCIQuery queries the application for some information.
-// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_query
+// More: https://docs.tendermint.com/v0.34/rpc/#/ABCI/abci_query
func ABCIQuery(
ctx *rpctypes.Context,
path string,
@@ -31,7 +31,7 @@ func ABCIQuery(
}
// ABCIInfo gets some info about the application.
-// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info
+// More: https://docs.tendermint.com/v0.34/rpc/#/ABCI/abci_info
func ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) {
resInfo, err := GetEnvironment().ProxyAppQuery.InfoSync(proxy.RequestInfo)
if err != nil {
diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go
index e389d3f082..f7bc4bbaf5 100644
--- a/rpc/core/blocks.go
+++ b/rpc/core/blocks.go
@@ -18,7 +18,7 @@ import (
// BlockchainInfo gets block headers for minHeight <= height <= maxHeight.
// Block headers are returned in descending order (highest first).
-// More: https://docs.tendermint.com/master/rpc/#/Info/blockchain
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/blockchain
func BlockchainInfo(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
// maximum 20 block metas
const limit int64 = 20
@@ -81,7 +81,7 @@ func filterMinMax(base, height, min, max, limit int64) (int64, int64, error) {
// Block gets block at a given height.
// If no height is provided, it will fetch the latest block.
-// More: https://docs.tendermint.com/master/rpc/#/Info/block
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/block
func Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error) {
height, err := getHeight(GetEnvironment().BlockStore.Height(), heightPtr)
if err != nil {
@@ -97,7 +97,7 @@ func Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error)
}
// BlockByHash gets block by hash.
-// More: https://docs.tendermint.com/master/rpc/#/Info/block_by_hash
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/block_by_hash
func BlockByHash(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error) {
env := GetEnvironment()
block := env.BlockStore.LoadBlockByHash(hash)
@@ -111,7 +111,7 @@ func BlockByHash(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error
// Commit gets block commit at a given height.
// If no height is provided, it will fetch the commit for the latest block.
-// More: https://docs.tendermint.com/master/rpc/#/Info/commit
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/commit
func Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, error) {
env := GetEnvironment()
height, err := getHeight(env.BlockStore.Height(), heightPtr)
@@ -207,11 +207,12 @@ func hashDataRoots(blocks []*ctypes.ResultBlock) []byte {
// BlockResults gets ABCIResults at a given height.
// If no height is provided, it will fetch results for the latest block.
+// When DiscardABCIResponses is enabled, an error will be returned.
//
// Results are for the height of the block containing the txs.
// Thus response.results.deliver_tx[5] is the results of executing
// getBlock(h).Txs[5]
-// More: https://docs.tendermint.com/master/rpc/#/Info/block_results
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/block_results
func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockResults, error) {
env := GetEnvironment()
height, err := getHeight(env.BlockStore.Height(), heightPtr)
diff --git a/rpc/core/blocks_test.go b/rpc/core/blocks_test.go
index 19082f2cbc..9735cd3b78 100644
--- a/rpc/core/blocks_test.go
+++ b/rpc/core/blocks_test.go
@@ -85,12 +85,14 @@ func TestBlockResults(t *testing.T) {
BeginBlock: &abci.ResponseBeginBlock{},
}
- env := &Environment{}
- env.StateStore = sm.NewStore(dbm.NewMemDB())
- err := env.StateStore.SaveABCIResponses(100, results)
+ globalEnv = &Environment{}
+ globalEnv.StateStore = sm.NewStore(dbm.NewMemDB(), sm.StoreOptions{
+ DiscardABCIResponses: false,
+ })
+ err := globalEnv.StateStore.SaveABCIResponses(100, results)
require.NoError(t, err)
- env.BlockStore = mockBlockStore{height: 100}
- SetEnvironment(env)
+ globalEnv.BlockStore = mockBlockStore{height: 100}
+ SetEnvironment(globalEnv)
testCases := []struct {
height int64
diff --git a/rpc/core/consensus.go b/rpc/core/consensus.go
index 29797ac9c2..4d66d8d826 100644
--- a/rpc/core/consensus.go
+++ b/rpc/core/consensus.go
@@ -14,7 +14,7 @@ import (
// validators are sorted by their voting power - this is the canonical order
// for the validators in the set as used in computing their Merkle root.
//
-// More: https://docs.tendermint.com/master/rpc/#/Info/validators
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/validators
func Validators(ctx *rpctypes.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*ctypes.ResultValidators, error) {
// The latest validator that we know is the NextValidator of the last block.
height, err := getHeight(latestUncommittedHeight(), heightPtr)
@@ -47,7 +47,7 @@ func Validators(ctx *rpctypes.Context, heightPtr *int64, pagePtr, perPagePtr *in
// DumpConsensusState dumps consensus state.
// UNSTABLE
-// More: https://docs.tendermint.com/master/rpc/#/Info/dump_consensus_state
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/dump_consensus_state
func DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState, error) {
// Get Peer consensus states.
peers := GetEnvironment().P2PPeers.Peers().List()
@@ -80,7 +80,7 @@ func DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState
// ConsensusState returns a concise summary of the consensus state.
// UNSTABLE
-// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_state
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/consensus_state
func ConsensusState(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error) {
// Get self round state.
bz, err := GetEnvironment().ConsensusState.GetRoundStateSimpleJSON()
@@ -89,7 +89,7 @@ func ConsensusState(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error)
// ConsensusParams gets the consensus parameters at the given block height.
// If no height is provided, it will fetch the latest consensus params.
-// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_params
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/consensus_params
func ConsensusParams(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultConsensusParams, error) {
// The latest consensus params that we know is the consensus params after the
// last block.
diff --git a/rpc/core/doc.go b/rpc/core/doc.go
index 77ace4e2cf..495aed0cf8 100644
--- a/rpc/core/doc.go
+++ b/rpc/core/doc.go
@@ -2,7 +2,7 @@
Package core defines the Tendermint RPC endpoints.
Tendermint ships with its own JSONRPC library -
-https://github.com/tendermint/tendermint/tree/master/rpc/jsonrpc.
+https://github.com/tendermint/tendermint/tree/v0.34.x/rpc/jsonrpc.
## Get the list
diff --git a/rpc/core/events.go b/rpc/core/events.go
index 91c7e62a44..b457cdc8a9 100644
--- a/rpc/core/events.go
+++ b/rpc/core/events.go
@@ -19,7 +19,7 @@ const (
)
// Subscribe for events via WebSocket.
-// More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe
+// More: https://docs.tendermint.com/v0.34/rpc/#/Websocket/subscribe
func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, error) {
addr := ctx.RemoteAddr()
env := GetEnvironment()
@@ -106,7 +106,7 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er
}
// Unsubscribe from events via WebSocket.
-// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe
+// More: https://docs.tendermint.com/v0.34/rpc/#/Websocket/unsubscribe
func Unsubscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultUnsubscribe, error) {
addr := ctx.RemoteAddr()
env := GetEnvironment()
@@ -123,7 +123,7 @@ func Unsubscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultUnsubscribe
}
// UnsubscribeAll from all events via WebSocket.
-// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe_all
+// More: https://docs.tendermint.com/v0.34/rpc/#/Websocket/unsubscribe_all
func UnsubscribeAll(ctx *rpctypes.Context) (*ctypes.ResultUnsubscribe, error) {
addr := ctx.RemoteAddr()
env := GetEnvironment()
diff --git a/rpc/core/evidence.go b/rpc/core/evidence.go
index 373e7c442d..ac5b8f7a3a 100644
--- a/rpc/core/evidence.go
+++ b/rpc/core/evidence.go
@@ -10,7 +10,7 @@ import (
)
// BroadcastEvidence broadcasts evidence of the misbehavior.
-// More: https://docs.tendermint.com/master/rpc/#/Info/broadcast_evidence
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/broadcast_evidence
func BroadcastEvidence(ctx *rpctypes.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
if ev == nil {
return nil, errors.New("no evidence was provided")
diff --git a/rpc/core/health.go b/rpc/core/health.go
index 97ea56865c..1a11544a8f 100644
--- a/rpc/core/health.go
+++ b/rpc/core/health.go
@@ -7,7 +7,7 @@ import (
// Health gets node health. Returns empty result (200 OK) on success, no
// response - in case of an error.
-// More: https://docs.tendermint.com/master/rpc/#/Info/health
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/health
func Health(ctx *rpctypes.Context) (*ctypes.ResultHealth, error) {
return &ctypes.ResultHealth{}, nil
}
diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go
index 276fa4f53e..a21fb189cb 100644
--- a/rpc/core/mempool.go
+++ b/rpc/core/mempool.go
@@ -18,7 +18,7 @@ import (
// BroadcastTxAsync returns right away, with no response. Does not wait for
// CheckTx nor DeliverTx results.
-// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async
+// More: https://docs.tendermint.com/v0.34/rpc/#/Tx/broadcast_tx_async
func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
err := GetEnvironment().Mempool.CheckTx(tx, nil, mempl.TxInfo{})
@@ -30,7 +30,7 @@ func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadca
// BroadcastTxSync returns with the response from CheckTx. Does not wait for
// DeliverTx result.
-// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync
+// More: https://docs.tendermint.com/v0.34/rpc/#/Tx/broadcast_tx_sync
func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
resCh := make(chan *abci.Response, 1)
err := GetEnvironment().Mempool.CheckTx(tx, func(res *abci.Response) {
@@ -60,7 +60,7 @@ func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcas
}
// BroadcastTxCommit returns with the responses from CheckTx and DeliverTx.
-// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_commit
+// More: https://docs.tendermint.com/v0.34/rpc/#/Tx/broadcast_tx_commit
func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
subscriber := ctx.RemoteAddr()
env := GetEnvironment()
@@ -150,7 +150,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc
// UnconfirmedTxs gets unconfirmed transactions (maximum ?limit entries)
// including their number.
-// More: https://docs.tendermint.com/master/rpc/#/Info/unconfirmed_txs
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/unconfirmed_txs
func UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfirmedTxs, error) {
// reuse per_page validator
limit := validatePerPage(limitPtr)
@@ -165,7 +165,7 @@ func UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfi
}
// NumUnconfirmedTxs gets number of unconfirmed transactions.
-// More: https://docs.tendermint.com/master/rpc/#/Info/num_unconfirmed_txs
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/num_unconfirmed_txs
func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, error) {
env := GetEnvironment()
return &ctypes.ResultUnconfirmedTxs{
@@ -176,7 +176,7 @@ func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, err
// CheckTx checks the transaction without executing it. The transaction won't
// be added to the mempool either.
-// More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx
+// More: https://docs.tendermint.com/v0.34/rpc/#/Tx/check_tx
func CheckTx(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
res, err := GetEnvironment().ProxyAppMempool.CheckTxSync(abci.RequestCheckTx{Tx: tx})
if err != nil {
diff --git a/rpc/core/net.go b/rpc/core/net.go
index fd80d63877..a984407229 100644
--- a/rpc/core/net.go
+++ b/rpc/core/net.go
@@ -11,7 +11,7 @@ import (
)
// NetInfo returns network info.
-// More: https://docs.tendermint.com/master/rpc/#/Info/net_info
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/net_info
func NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) {
env := GetEnvironment()
peersList := env.P2PPeers.Peers().List()
@@ -95,7 +95,7 @@ func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent, uncondit
}
// Genesis returns genesis file.
-// More: https://docs.tendermint.com/master/rpc/#/Info/genesis
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/genesis
func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
env := GetEnvironment()
if len(env.genChunks) > 1 {
diff --git a/rpc/core/routes.go b/rpc/core/routes.go
index 4c3d2e6215..9907310f16 100644
--- a/rpc/core/routes.go
+++ b/rpc/core/routes.go
@@ -17,22 +17,22 @@ var Routes = map[string]*rpc.RPCFunc{
"health": rpc.NewRPCFunc(Health, ""),
"status": rpc.NewRPCFunc(Status, ""),
"net_info": rpc.NewRPCFunc(NetInfo, ""),
- "blockchain": rpc.NewRPCFunc(BlockchainInfo, "minHeight,maxHeight"),
- "genesis": rpc.NewRPCFunc(Genesis, ""),
- "genesis_chunked": rpc.NewRPCFunc(GenesisChunked, "chunk"),
- "block": rpc.NewRPCFunc(Block, "height"),
- "block_by_hash": rpc.NewRPCFunc(BlockByHash, "hash"),
- "block_results": rpc.NewRPCFunc(BlockResults, "height"),
- "commit": rpc.NewRPCFunc(Commit, "height"),
+ "blockchain": rpc.NewRPCFunc(BlockchainInfo, "minHeight,maxHeight", rpc.Cacheable()),
+ "genesis": rpc.NewRPCFunc(Genesis, "", rpc.Cacheable()),
+ "genesis_chunked": rpc.NewRPCFunc(GenesisChunked, "chunk", rpc.Cacheable()),
+ "block": rpc.NewRPCFunc(Block, "height", rpc.Cacheable("height")),
+ "block_by_hash": rpc.NewRPCFunc(BlockByHash, "hash", rpc.Cacheable()),
+ "block_results": rpc.NewRPCFunc(BlockResults, "height", rpc.Cacheable("height")),
+ "commit": rpc.NewRPCFunc(Commit, "height", rpc.Cacheable("height")),
"data_commitment": rpc.NewRPCFunc(DataCommitment, "beginBlock,endBlock"),
- "check_tx": rpc.NewRPCFunc(CheckTx, "tx"),
- "tx": rpc.NewRPCFunc(Tx, "hash,prove"),
+ "check_tx": rpc.NewRPCFunc(CheckTx, "tx", rpc.Cacheable()),
+ "tx": rpc.NewRPCFunc(Tx, "hash,prove", rpc.Cacheable()),
"tx_search": rpc.NewRPCFunc(TxSearch, "query,prove,page,per_page,order_by"),
"block_search": rpc.NewRPCFunc(BlockSearch, "query,page,per_page,order_by"),
- "validators": rpc.NewRPCFunc(Validators, "height,page,per_page"),
+ "validators": rpc.NewRPCFunc(Validators, "height,page,per_page", rpc.Cacheable("height")),
"dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""),
"consensus_state": rpc.NewRPCFunc(ConsensusState, ""),
- "consensus_params": rpc.NewRPCFunc(ConsensusParams, "height"),
+ "consensus_params": rpc.NewRPCFunc(ConsensusParams, "height", rpc.Cacheable("height")),
"unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxs, "limit"),
"num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxs, ""),
@@ -43,7 +43,7 @@ var Routes = map[string]*rpc.RPCFunc{
// abci API
"abci_query": rpc.NewRPCFunc(ABCIQuery, "path,data,height,prove"),
- "abci_info": rpc.NewRPCFunc(ABCIInfo, ""),
+ "abci_info": rpc.NewRPCFunc(ABCIInfo, "", rpc.Cacheable()),
// evidence API
"broadcast_evidence": rpc.NewRPCFunc(BroadcastEvidence, "evidence"),
diff --git a/rpc/core/status.go b/rpc/core/status.go
index 37a07b0238..80c7f4ec91 100644
--- a/rpc/core/status.go
+++ b/rpc/core/status.go
@@ -12,7 +12,7 @@ import (
// Status returns Tendermint status including node info, pubkey, latest block
// hash, app hash, block height and time.
-// More: https://docs.tendermint.com/master/rpc/#/Info/status
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/status
func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) {
var (
earliestBlockHeight int64
diff --git a/rpc/core/tx.go b/rpc/core/tx.go
index 9016916db2..7ffe435bbb 100644
--- a/rpc/core/tx.go
+++ b/rpc/core/tx.go
@@ -62,7 +62,7 @@ func Tx(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error
// list of transactions (maximum ?per_page entries) and the total count.
// NOTE: proveTx isn't respected but is left in the function signature to
// conform to the endpoint exposed by Tendermint
-// More: https://docs.tendermint.com/master/rpc/#/Info/tx_search
+// More: https://docs.tendermint.com/v0.34/rpc/#/Info/tx_search
func TxSearch(
ctx *rpctypes.Context,
query string,
diff --git a/rpc/jsonrpc/client/http_json_client.go b/rpc/jsonrpc/client/http_json_client.go
index fbfe073e01..8fbf9fa4ff 100644
--- a/rpc/jsonrpc/client/http_json_client.go
+++ b/rpc/jsonrpc/client/http_json_client.go
@@ -5,7 +5,7 @@ import (
"context"
"encoding/json"
"fmt"
- "io/ioutil"
+ "io"
"net"
"net/http"
"net/url"
@@ -217,7 +217,7 @@ func (c *Client) Call(
defer httpResponse.Body.Close()
- responseBytes, err := ioutil.ReadAll(httpResponse.Body)
+ responseBytes, err := io.ReadAll(httpResponse.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
@@ -265,7 +265,7 @@ func (c *Client) sendBatch(ctx context.Context, requests []*jsonRPCBufferedReque
defer httpResponse.Body.Close()
- responseBytes, err := ioutil.ReadAll(httpResponse.Body)
+ responseBytes, err := io.ReadAll(httpResponse.Body)
if err != nil {
return nil, fmt.Errorf("read response body: %w", err)
}
diff --git a/rpc/jsonrpc/client/http_json_client_test.go b/rpc/jsonrpc/client/http_json_client_test.go
index 4b82ff1eb4..03134dff58 100644
--- a/rpc/jsonrpc/client/http_json_client_test.go
+++ b/rpc/jsonrpc/client/http_json_client_test.go
@@ -1,7 +1,7 @@
package client
import (
- "io/ioutil"
+ "io"
"log"
"net/http"
"net/http/httptest"
@@ -21,7 +21,7 @@ func TestHTTPClientMakeHTTPDialer(t *testing.T) {
defer tsTLS.Close()
// This silences a TLS handshake error, caused by the dialer just immediately
// disconnecting, which we can just ignore.
- tsTLS.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+ tsTLS.Config.ErrorLog = log.New(io.Discard, "", 0)
for _, testURL := range []string{ts.URL, tsTLS.URL} {
u, err := newParsedURL(testURL)
diff --git a/rpc/jsonrpc/client/http_uri_client.go b/rpc/jsonrpc/client/http_uri_client.go
index 3f376ddb0f..e5d5a5c587 100644
--- a/rpc/jsonrpc/client/http_uri_client.go
+++ b/rpc/jsonrpc/client/http_uri_client.go
@@ -3,7 +3,7 @@ package client
import (
"context"
"fmt"
- "io/ioutil"
+ "io"
"net/http"
"strings"
@@ -52,8 +52,8 @@ func NewURI(remote string) (*URIClient, error) {
// Call issues a POST form HTTP request.
func (c *URIClient) Call(ctx context.Context, method string,
- params map[string]interface{}, result interface{}) (interface{}, error) {
-
+ params map[string]interface{}, result interface{},
+) (interface{}, error) {
values, err := argsToURLValues(params)
if err != nil {
return nil, fmt.Errorf("failed to encode params: %w", err)
@@ -76,7 +76,7 @@ func (c *URIClient) Call(ctx context.Context, method string,
}
defer resp.Body.Close()
- responseBytes, err := ioutil.ReadAll(resp.Body)
+ responseBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response body: %w", err)
}
diff --git a/rpc/jsonrpc/client/ws_client.go b/rpc/jsonrpc/client/ws_client.go
index 44bf5f0987..5a4839b045 100644
--- a/rpc/jsonrpc/client/ws_client.go
+++ b/rpc/jsonrpc/client/ws_client.go
@@ -30,7 +30,7 @@ const (
// the remote server.
//
// WSClient is safe for concurrent use by multiple goroutines.
-type WSClient struct { // nolint: maligned
+type WSClient struct { //nolint: maligned
conn *websocket.Conn
Address string // IP:PORT or /path/to/socket
@@ -89,8 +89,10 @@ func NewWS(remoteAddr, endpoint string, options ...func(*WSClient)) (*WSClient,
if err != nil {
return nil, err
}
- // default to ws protocol, unless wss is explicitly specified
- if parsedURL.Scheme != protoWSS {
+ // default to ws protocol, unless wss or https is specified
+ if parsedURL.Scheme == protoHTTPS {
+ parsedURL.Scheme = protoWSS
+ } else if parsedURL.Scheme != protoWSS {
parsedURL.Scheme = protoWS
}
@@ -265,7 +267,7 @@ func (c *WSClient) dial() error {
Proxy: http.ProxyFromEnvironment,
}
rHeader := http.Header{}
- conn, _, err := dialer.Dial(c.protocol+"://"+c.Address+c.Endpoint, rHeader) // nolint:bodyclose
+ conn, _, err := dialer.Dial(c.protocol+"://"+c.Address+c.Endpoint, rHeader) //nolint:bodyclose
if err != nil {
return err
}
diff --git a/rpc/jsonrpc/client/ws_client_test.go b/rpc/jsonrpc/client/ws_client_test.go
index 2e6403806c..b4ac8f83b9 100644
--- a/rpc/jsonrpc/client/ws_client_test.go
+++ b/rpc/jsonrpc/client/ws_client_test.go
@@ -72,7 +72,7 @@ func TestWSClientReconnectsAfterReadFailure(t *testing.T) {
defer s.Close()
c := startClient(t, "//"+s.Listener.Addr().String())
- defer c.Stop() // nolint:errcheck // ignore for tests
+ defer c.Stop() //nolint:errcheck // ignore for tests
wg.Add(1)
go callWgDoneOnResult(t, c, &wg)
@@ -104,7 +104,7 @@ func TestWSClientReconnectsAfterWriteFailure(t *testing.T) {
s := httptest.NewServer(h)
c := startClient(t, "//"+s.Listener.Addr().String())
- defer c.Stop() // nolint:errcheck // ignore for tests
+ defer c.Stop() //nolint:errcheck // ignore for tests
wg.Add(2)
go callWgDoneOnResult(t, c, &wg)
@@ -132,7 +132,7 @@ func TestWSClientReconnectFailure(t *testing.T) {
s := httptest.NewServer(h)
c := startClient(t, "//"+s.Listener.Addr().String())
- defer c.Stop() // nolint:errcheck // ignore for tests
+ defer c.Stop() //nolint:errcheck // ignore for tests
go func() {
for {
@@ -181,7 +181,7 @@ func TestNotBlockingOnStop(t *testing.T) {
timeout := 2 * time.Second
s := httptest.NewServer(&myHandler{})
c := startClient(t, "//"+s.Listener.Addr().String())
- c.Call(context.Background(), "a", make(map[string]interface{})) // nolint:errcheck // ignore for tests
+ c.Call(context.Background(), "a", make(map[string]interface{})) //nolint:errcheck // ignore for tests
// Let the readRoutine get around to blocking
time.Sleep(time.Second)
passCh := make(chan struct{})
diff --git a/rpc/jsonrpc/doc.go b/rpc/jsonrpc/doc.go
index b014fe38dd..d6dcae0db7 100644
--- a/rpc/jsonrpc/doc.go
+++ b/rpc/jsonrpc/doc.go
@@ -1,7 +1,7 @@
// HTTP RPC server supporting calls via uri params, jsonrpc over HTTP, and jsonrpc over
// websockets
//
-// Client Requests
+// # Client Requests
//
// Suppose we want to expose the rpc function `HelloWorld(name string, num int)`.
//
@@ -9,12 +9,12 @@
//
// As a GET request, it would have URI encoded parameters, and look like:
//
-// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
+// curl 'http://localhost:8008/hello_world?name="my_world"&num=5'
//
// Note the `'` around the url, which is just so bash doesn't ignore the quotes in `"my_world"`.
// This should also work:
//
-// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
+// curl http://localhost:8008/hello_world?name=\"my_world\"&num=5
//
// A GET request to `/` returns a list of available endpoints.
// For those which take arguments, the arguments will be listed in order, with `_` where the actual value should be.
@@ -23,20 +23,19 @@
//
// As a POST request, we use JSONRPC. For instance, the same request would have this as the body:
//
-// {
-// "jsonrpc": "2.0",
-// "id": "anything",
-// "method": "hello_world",
-// "params": {
-// "name": "my_world",
-// "num": 5
-// }
-// }
+// {
+// "jsonrpc": "2.0",
+// "id": "anything",
+// "method": "hello_world",
+// "params": {
+// "name": "my_world",
+// "num": 5
+// }
+// }
//
// With the above saved in file `data.json`, we can make the request with
//
-// curl --data @data.json http://localhost:8008
-//
+// curl --data @data.json http://localhost:8008
//
// WebSocket (JSONRPC)
//
@@ -44,42 +43,42 @@
// Websocket connections are available at their own endpoint, typically `/websocket`,
// though this is configurable when starting the server.
//
-// Server Definition
+// # Server Definition
//
// Define some types and routes:
//
-// type ResultStatus struct {
-// Value string
-// }
+// type ResultStatus struct {
+// Value string
+// }
//
// Define some routes
//
-// var Routes = map[string]*rpcserver.RPCFunc{
-// "status": rpcserver.NewRPCFunc(Status, "arg"),
-// }
+// var Routes = map[string]*rpcserver.RPCFunc{
+// "status": rpcserver.NewRPCFunc(Status, "arg"),
+// }
//
// An rpc function:
//
-// func Status(v string) (*ResultStatus, error) {
-// return &ResultStatus{v}, nil
-// }
+// func Status(v string) (*ResultStatus, error) {
+// return &ResultStatus{v}, nil
+// }
//
// Now start the server:
//
-// mux := http.NewServeMux()
-// rpcserver.RegisterRPCFuncs(mux, Routes)
-// wm := rpcserver.NewWebsocketManager(Routes)
-// mux.HandleFunc("/websocket", wm.WebsocketHandler)
-// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
-// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
-// if err != nil { panic(err) }
-// go rpcserver.Serve(listener, mux, logger)
+// mux := http.NewServeMux()
+// rpcserver.RegisterRPCFuncs(mux, Routes)
+// wm := rpcserver.NewWebsocketManager(Routes)
+// mux.HandleFunc("/websocket", wm.WebsocketHandler)
+// logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
+// listener, err := rpc.Listen("0.0.0.0:8080", rpcserver.Config{})
+// if err != nil { panic(err) }
+// go rpcserver.Serve(listener, mux, logger)
//
// Note that unix sockets are supported as well (eg. `/path/to/socket` instead of `0.0.0.0:8008`)
// Now see all available endpoints by sending a GET request to `0.0.0.0:8008`.
// Each route is available as a GET request, as a JSONRPCv2 POST request, and via JSONRPCv2 over websockets.
//
-// Examples
+// # Examples
//
-// - [Tendermint](https://github.com/tendermint/tendermint/blob/master/rpc/core/routes.go)
+// - [Tendermint](https://github.com/tendermint/tendermint/blob/v0.34.x/rpc/core/routes.go)
package jsonrpc
diff --git a/rpc/jsonrpc/jsonrpc_test.go b/rpc/jsonrpc/jsonrpc_test.go
index 84956bae95..c322dfcea9 100644
--- a/rpc/jsonrpc/jsonrpc_test.go
+++ b/rpc/jsonrpc/jsonrpc_test.go
@@ -7,8 +7,10 @@ import (
"encoding/json"
"fmt"
"net/http"
+ "net/url"
"os"
"os/exec"
+ "strings"
"testing"
"time"
@@ -37,9 +39,7 @@ const (
testVal = "acbd"
)
-var (
- ctx = context.Background()
-)
+var ctx = context.Background()
type ResultEcho struct {
Value string `json:"value"`
@@ -57,6 +57,10 @@ type ResultEchoDataBytes struct {
Value tmbytes.HexBytes `json:"value"`
}
+type ResultEchoWithDefault struct {
+ Value int `json:"value"`
+}
+
// Define some routes
var Routes = map[string]*server.RPCFunc{
"echo": server.NewRPCFunc(EchoResult, "arg"),
@@ -64,6 +68,7 @@ var Routes = map[string]*server.RPCFunc{
"echo_bytes": server.NewRPCFunc(EchoBytesResult, "arg"),
"echo_data_bytes": server.NewRPCFunc(EchoDataBytesResult, "arg"),
"echo_int": server.NewRPCFunc(EchoIntResult, "arg"),
+ "echo_default": server.NewRPCFunc(EchoWithDefault, "arg", server.Cacheable("arg")),
}
func EchoResult(ctx *types.Context, v string) (*ResultEcho, error) {
@@ -86,6 +91,14 @@ func EchoDataBytesResult(ctx *types.Context, v tmbytes.HexBytes) (*ResultEchoDat
return &ResultEchoDataBytes{v}, nil
}
+func EchoWithDefault(ctx *types.Context, v *int) (*ResultEchoWithDefault, error) {
+ val := -1
+ if v != nil {
+ val = *v
+ }
+ return &ResultEchoWithDefault{val}, nil
+}
+
func TestMain(m *testing.M) {
setup()
code := m.Run()
@@ -199,26 +212,47 @@ func echoDataBytesViaHTTP(cl client.Caller, bytes tmbytes.HexBytes) (tmbytes.Hex
return result.Value, nil
}
+func echoWithDefaultViaHTTP(cl client.Caller, v *int) (int, error) {
+ params := map[string]interface{}{}
+ if v != nil {
+ params["arg"] = *v
+ }
+ result := new(ResultEchoWithDefault)
+ if _, err := cl.Call(ctx, "echo_default", params, result); err != nil {
+ return 0, err
+ }
+ return result.Value, nil
+}
+
func testWithHTTPClient(t *testing.T, cl client.HTTPClient) {
val := testVal
got, err := echoViaHTTP(cl, val)
- require.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, got, val)
val2 := randBytes(t)
got2, err := echoBytesViaHTTP(cl, val2)
- require.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, got2, val2)
val3 := tmbytes.HexBytes(randBytes(t))
got3, err := echoDataBytesViaHTTP(cl, val3)
- require.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, got3, val3)
val4 := tmrand.Intn(10000)
got4, err := echoIntViaHTTP(cl, val4)
- require.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, got4, val4)
+
+ got5, err := echoWithDefaultViaHTTP(cl, nil)
+ require.NoError(t, err)
+ assert.Equal(t, got5, -1)
+
+ val6 := tmrand.Intn(10000)
+ got6, err := echoWithDefaultViaHTTP(cl, &val6)
+ require.NoError(t, err)
+ assert.Equal(t, got6, val6)
}
func echoViaWS(cl *client.WSClient, val string) (string, error) {
@@ -233,7 +267,6 @@ func echoViaWS(cl *client.WSClient, val string) (string, error) {
msg := <-cl.ResponsesCh
if msg.Error != nil {
return "", err
-
}
result := new(ResultEcho)
err = json.Unmarshal(msg.Result, result)
@@ -255,7 +288,6 @@ func echoBytesViaWS(cl *client.WSClient, bytes []byte) ([]byte, error) {
msg := <-cl.ResponsesCh
if msg.Error != nil {
return []byte{}, msg.Error
-
}
result := new(ResultEchoBytes)
err = json.Unmarshal(msg.Result, result)
@@ -399,6 +431,74 @@ func TestWSClientPingPong(t *testing.T) {
time.Sleep(6 * time.Second)
}
+func TestJSONRPCCaching(t *testing.T) {
+ httpAddr := strings.Replace(tcpAddr, "tcp://", "http://", 1)
+ cl, err := client.DefaultHTTPClient(httpAddr)
+ require.NoError(t, err)
+
+ // Not supplying the arg should result in not caching
+ params := make(map[string]interface{})
+ req, err := types.MapToRequest(types.JSONRPCIntID(1000), "echo_default", params)
+ require.NoError(t, err)
+
+ res1, err := rawJSONRPCRequest(t, cl, httpAddr, req)
+ defer func() { _ = res1.Body.Close() }()
+ require.NoError(t, err)
+ assert.Equal(t, "", res1.Header.Get("Cache-control"))
+
+ // Supplying the arg should result in caching
+ params["arg"] = tmrand.Intn(10000)
+ req, err = types.MapToRequest(types.JSONRPCIntID(1001), "echo_default", params)
+ require.NoError(t, err)
+
+ res2, err := rawJSONRPCRequest(t, cl, httpAddr, req)
+ defer func() { _ = res2.Body.Close() }()
+ require.NoError(t, err)
+ assert.Equal(t, "public, max-age=86400", res2.Header.Get("Cache-control"))
+}
+
+func rawJSONRPCRequest(t *testing.T, cl *http.Client, url string, req interface{}) (*http.Response, error) {
+ reqBytes, err := json.Marshal(req)
+ require.NoError(t, err)
+
+ reqBuf := bytes.NewBuffer(reqBytes)
+ httpReq, err := http.NewRequest(http.MethodPost, url, reqBuf)
+ require.NoError(t, err)
+
+ httpReq.Header.Set("Content-type", "application/json")
+
+ return cl.Do(httpReq)
+}
+
+func TestURICaching(t *testing.T) {
+ httpAddr := strings.Replace(tcpAddr, "tcp://", "http://", 1)
+ cl, err := client.DefaultHTTPClient(httpAddr)
+ require.NoError(t, err)
+
+ // Not supplying the arg should result in not caching
+ args := url.Values{}
+ res1, err := rawURIRequest(t, cl, httpAddr+"/echo_default", args)
+ defer func() { _ = res1.Body.Close() }()
+ require.NoError(t, err)
+ assert.Equal(t, "", res1.Header.Get("Cache-control"))
+
+ // Supplying the arg should result in caching
+ args.Set("arg", fmt.Sprintf("%d", tmrand.Intn(10000)))
+ res2, err := rawURIRequest(t, cl, httpAddr+"/echo_default", args)
+ defer func() { _ = res2.Body.Close() }()
+ require.NoError(t, err)
+ assert.Equal(t, "public, max-age=86400", res2.Header.Get("Cache-control"))
+}
+
+func rawURIRequest(t *testing.T, cl *http.Client, url string, args url.Values) (*http.Response, error) {
+ req, err := http.NewRequest(http.MethodPost, url, strings.NewReader(args.Encode()))
+ require.NoError(t, err)
+
+ req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+
+ return cl.Do(req)
+}
+
func randBytes(t *testing.T) []byte {
n := tmrand.Intn(10) + 2
buf := make([]byte, n)
diff --git a/rpc/jsonrpc/server/http_json_handler.go b/rpc/jsonrpc/server/http_json_handler.go
index 28dfcbf8a9..db162f17ab 100644
--- a/rpc/jsonrpc/server/http_json_handler.go
+++ b/rpc/jsonrpc/server/http_json_handler.go
@@ -4,7 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
- "io/ioutil"
+ "io"
"net/http"
"reflect"
"sort"
@@ -19,7 +19,7 @@ import (
// jsonrpc calls grab the given method's function info and runs reflect.Call
func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
- b, err := ioutil.ReadAll(r.Body)
+ b, err := io.ReadAll(r.Body)
if err != nil {
res := types.RPCInvalidRequestError(nil,
fmt.Errorf("error reading request body: %w", err),
@@ -55,6 +55,11 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han
requests = []types.RPCRequest{request}
}
+ // Set the default response cache to true unless
+ // 1. Any RPC request error.
+ // 2. Any RPC request doesn't allow to be cached.
+ // 3. Any RPC request has the height argument and the value is 0 (the default).
+ cache := true
for _, request := range requests {
request := request
@@ -72,11 +77,13 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han
responses,
types.RPCInvalidRequestError(request.ID, fmt.Errorf("path %s is invalid", r.URL.Path)),
)
+ cache = false
continue
}
rpcFunc, ok := funcMap[request.Method]
- if !ok || rpcFunc.ws {
+ if !ok || (rpcFunc.ws) {
responses = append(responses, types.RPCMethodNotFoundError(request.ID))
+ cache = false
continue
}
ctx := &types.Context{JSONReq: &request, HTTPReq: r}
@@ -88,11 +95,16 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han
responses,
types.RPCInvalidParamsError(request.ID, fmt.Errorf("error converting json params to arguments: %w", err)),
)
+ cache = false
continue
}
args = append(args, fnArgs...)
}
+ if cache && !rpcFunc.cacheableWithArgs(args) {
+ cache = false
+ }
+
returns := rpcFunc.f.Call(args)
result, err := unreflectResult(returns)
if err != nil {
@@ -103,7 +115,13 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han
}
if len(responses) > 0 {
- if wErr := WriteRPCResponseHTTP(w, responses...); wErr != nil {
+ var wErr error
+ if cache {
+ wErr = WriteCacheableRPCResponseHTTP(w, responses...)
+ } else {
+ wErr = WriteRPCResponseHTTP(w, responses...)
+ }
+ if wErr != nil {
logger.Error("failed to write responses", "res", responses, "err", wErr)
}
}
@@ -128,7 +146,6 @@ func mapParamsToArgs(
params map[string]json.RawMessage,
argsOffset int,
) ([]reflect.Value, error) {
-
values := make([]reflect.Value, len(rpcFunc.argNames))
for i, argName := range rpcFunc.argNames {
argType := rpcFunc.args[i+argsOffset]
@@ -153,7 +170,6 @@ func arrayParamsToArgs(
params []json.RawMessage,
argsOffset int,
) ([]reflect.Value, error) {
-
if len(rpcFunc.argNames) != len(params) {
return nil, fmt.Errorf("expected %v parameters (%v), got %v (%v)",
len(rpcFunc.argNames), rpcFunc.argNames, len(params), params)
@@ -176,8 +192,9 @@ func arrayParamsToArgs(
// array.
//
// Example:
-// rpcFunc.args = [rpctypes.Context string]
-// rpcFunc.argNames = ["arg"]
+//
+// rpcFunc.args = [rpctypes.Context string]
+// rpcFunc.argNames = ["arg"]
func jsonParamsToArgs(rpcFunc *RPCFunc, raw []byte) ([]reflect.Value, error) {
const argsOffset = 1
@@ -237,5 +254,5 @@ func writeListOfEndpoints(w http.ResponseWriter, r *http.Request, funcMap map[st
buf.WriteString("