From 17c94bb0dcb354c57f49cdcd1e62f4742752c803 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Wed, 30 Nov 2022 20:09:25 -0500 Subject: [PATCH 01/40] docs: Fix metrics name rendering (#9695) The docs theme unfortunately wraps code blocks inside tables, breaking the names and making them somewhat unreadable. This removes all the backticks from the metric names and tags. --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- docs/tendermint-core/metrics.md | 92 ++++++++++++++++----------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/docs/tendermint-core/metrics.md b/docs/tendermint-core/metrics.md index bbd14ea8213..6e28b564b56 100644 --- a/docs/tendermint-core/metrics.md +++ b/docs/tendermint-core/metrics.md @@ -18,52 +18,52 @@ Listen address can be changed in the config file (see The following metrics are available: -| **Name** | **Type** | **Tags** | **Description** | -|------------------------------------------|-----------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------| -| `abci_connection_method_timing_seconds` | Histogram | `method`, `type` | Timings for each of the ABCI methods | -| `blocksync_syncing` | Gauge | | Either 0 (not block syncing) or 1 (syncing) | -| `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_block_size_bytes` | Gauge | | Block size in bytes | -| `consensus_step_duration` | Histogram | `step` | Histogram of durations for each step in the consensus protocol | -| `consensus_round_duration` | Histogram | | Histogram of durations for all the rounds that have occurred since the process started | -| `consensus_block_gossip_parts_received` | Counter | `matches_current` | Number of block parts received by the node | -| `consensus_quorum_prevote_delay` | Gauge | | Interval in seconds between the proposal timestamp and the timestamp of the earliest prevote that achieved a quorum | -| `consensus_full_prevote_delay` | Gauge | | Interval in seconds between the proposal timestamp and the timestamp of the latest prevote in a round where all validators voted | -| `consensus_proposal_receive_count` | Counter | `status` | Total number of proposals received by the node since process start | -| `consensus_proposal_create_count` | Counter | | Total number of proposals created by the node since process start | -| `consensus_round_voting_power_percent` | Gauge | `vote_type` | A value between 0 and 1.0 representing the percentage of the total voting power per vote type received within a round | -| `consensus_late_votes` | Counter | `vote_type` | Number of votes received by the node since process start that correspond to earlier heights and rounds than this node is currently in. | -| `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 | -| `state_consensus_param_updates` | Counter | | Number of consensus parameter updates returned by the application since process start | -| `state_validator_set_updates` | Counter | | Number of validator set updates returned by the application since process start | -| `statesync_syncing` | Gauge | | Either 0 (not state syncing) or 1 (syncing) | +| **Name** | **Type** | **Tags** | **Description** | +|--------------------------------------------|-----------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| abci\_connection\_method\_timing\_seconds | Histogram | method, type | Timings for each of the ABCI methods | +| blocksync\_syncing | Gauge | | Either 0 (not block syncing) or 1 (syncing) | +| 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\_block\_size\_bytes | Gauge | | Block size in bytes | +| consensus\_step\_duration | Histogram | step | Histogram of durations for each step in the consensus protocol | +| consensus\_round\_duration | Histogram | | Histogram of durations for all the rounds that have occurred since the process started | +| consensus\_block\_gossip\_parts\_received | Counter | matches\_current | Number of block parts received by the node | +| consensus\_quorum\_prevote\_delay | Gauge | | Interval in seconds between the proposal timestamp and the timestamp of the earliest prevote that achieved a quorum | +| consensus\_full\_prevote\_delay | Gauge | | Interval in seconds between the proposal timestamp and the timestamp of the latest prevote in a round where all validators voted | +| consensus\_proposal\_receive\_count | Counter | status | Total number of proposals received by the node since process start | +| consensus\_proposal\_create\_count | Counter | | Total number of proposals created by the node since process start | +| consensus\_round\_voting\_power\_percent | Gauge | vote\_type | A value between 0 and 1.0 representing the percentage of the total voting power per vote type received within a round | +| consensus\_late\_votes | Counter | vote\_type | Number of votes received by the node since process start that correspond to earlier heights and rounds than this node is currently in. | +| 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 | +| state\_consensus\_param\_updates | Counter | | Number of consensus parameter updates returned by the application since process start | +| state\_validator\_set\_updates | Counter | | Number of validator set updates returned by the application since process start | +| statesync\_syncing | Gauge | | Either 0 (not state syncing) or 1 (syncing) | ## Useful queries From 1c0995c8095361400e1e171964bae135408ff2b9 Mon Sep 17 00:00:00 2001 From: Lasaro Camargos Date: Thu, 1 Dec 2022 08:52:18 -0300 Subject: [PATCH 02/40] Fixes reference from recalled 0.36.x to 0.37.x (#9808) --- spec/abci/abci++_app_requirements.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/abci/abci++_app_requirements.md b/spec/abci/abci++_app_requirements.md index e3f4877d914..4d2dc7011bb 100644 --- a/spec/abci/abci++_app_requirements.md +++ b/spec/abci/abci++_app_requirements.md @@ -518,7 +518,7 @@ all full nodes have the same value at a given height. #### List of Parameters -These are the current consensus parameters (as of v0.36.x): +These are the current consensus parameters (as of v0.37.x): 1. [BlockParams.MaxBytes](#blockparamsmaxbytes) 2. [BlockParams.MaxGas](#blockparamsmaxgas) From 739b92bf0151e49f3c426a5a7e38de8590f6a9a6 Mon Sep 17 00:00:00 2001 From: Sergio Mena Date: Thu, 1 Dec 2022 13:19:15 +0100 Subject: [PATCH 03/40] Fix typo in new option in e2e manifest node (#9806) The "toml" annotation of "send no load" had a typo (`send_no_laod`). This is suspected to have caused failures in e2e, however I couldn't reproduce the error locally, so not sure this will fix it. Still, the typo needs to be fixed in any case. --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- test/e2e/pkg/manifest.go | 2 +- test/e2e/runner/main.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/e2e/pkg/manifest.go b/test/e2e/pkg/manifest.go index 402f643626d..814ae61c71f 100644 --- a/test/e2e/pkg/manifest.go +++ b/test/e2e/pkg/manifest.go @@ -153,7 +153,7 @@ type ManifestNode struct { // SendNoLoad determines if the e2e test should send load to this node. // It defaults to false so unless the configured, the node will // receive load. - SendNoLoad bool `toml:"send_no_laod"` + SendNoLoad bool `toml:"send_no_load"` } // Save saves the testnet manifest to a file. diff --git a/test/e2e/runner/main.go b/test/e2e/runner/main.go index 3e9e2c66cf4..33edf64be8a 100644 --- a/test/e2e/runner/main.go +++ b/test/e2e/runner/main.go @@ -288,7 +288,7 @@ func NewCLI() *CLI { Max Block Interval over a 100 block sampling period. -Does not run any perbutations. +Does not run any perturbations. `, RunE: func(cmd *cobra.Command, args []string) error { if err := Cleanup(cli.testnet); err != nil { @@ -304,7 +304,7 @@ Does not run any perbutations. go func() { err := Load(ctx, cli.testnet) if err != nil { - logger.Error(fmt.Sprintf("Transaction load failed: %v", err.Error())) + logger.Error(fmt.Sprintf("Transaction load errored: %v", err.Error())) } chLoadResult <- err }() From ba84060b075984b21873e2176f15172a8f25068d Mon Sep 17 00:00:00 2001 From: Lasaro Camargos Date: Thu, 1 Dec 2022 11:20:37 -0300 Subject: [PATCH 04/40] Mention tx_max_bytes in the tutorials (#9809) Updates the discussion of prepareProposal in the go tutorials to mention tx_max_bytes limitation to transaction set size. --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- docs/tutorials/go-built-in.md | 3 ++- docs/tutorials/go.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/go-built-in.md b/docs/tutorials/go-built-in.md index 70b2d0892e1..3f38551cf14 100644 --- a/docs/tutorials/go-built-in.md +++ b/docs/tutorials/go-built-in.md @@ -461,7 +461,8 @@ When Tendermint Core sees that valid transactions (validated through `CheckTx`) included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. -The application is free to modify the group before returning from the call. +The application is free to modify the group before returning from the call, as long as the resulting set +does not use more bytes than `RequestPrepareProposal.max_tx_bytes' For example, the application may reorder, add, or even remove transactions from the group to improve the execution of the block once accepted. In the following code, the application simply returns the unmodified group of transactions: diff --git a/docs/tutorials/go.md b/docs/tutorials/go.md index 4a1e3bfba00..5bd65aa16ea 100644 --- a/docs/tutorials/go.md +++ b/docs/tutorials/go.md @@ -460,7 +460,8 @@ When Tendermint Core sees that valid transactions (validated through `CheckTx`) included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. -The application is free to modify the group before returning from the call. +The application is free to modify the group before returning from the call, as long as the resulting set +does not use more bytes than `RequestPrepareProposal.max_tx_bytes' For example, the application may reorder, add, or even remove transactions from the group to improve the execution of the block once accepted. In the following code, the application simply returns the unmodified group of transactions: From d09f4f503d7769c6456caa453ecea92c3cd80052 Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Thu, 1 Dec 2022 11:21:28 -0500 Subject: [PATCH 05/40] e2e: create client when sending transaction (#9814) Fixes the issue observed in an [e2e test run](https://github.com/tendermint/tendermint/actions/runs/3588927225). The issue arises when the e2e runner process cannot connect to the remote node. In the previous version of this code, the runner would simply skip the transaction if the client couldn't connect. This pull request resurrects that behavior. --- #### PR checklist - [ ] Tests written/updated, or no tests needed - [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [ ] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- test/e2e/runner/load.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/e2e/runner/load.go b/test/e2e/runner/load.go index 735af4821f0..1989886b0d8 100644 --- a/test/e2e/runner/load.go +++ b/test/e2e/runner/load.go @@ -26,6 +26,7 @@ func Load(ctx context.Context, testnet *e2e.Testnet) error { ctx, cancel := context.WithCancel(ctx) defer cancel() + logger.Info("load", "msg", log.NewLazySprintf("Starting transaction load (%v workers)...", workerPoolSize)) started := time.Now() u := [16]byte(uuid.New()) // generate run ID on startup @@ -38,11 +39,7 @@ func Load(ctx context.Context, testnet *e2e.Testnet) error { } for w := 0; w < testnet.LoadTxConnections; w++ { - cli, err := n.Client() - if err != nil { - return err - } - go loadProcess(ctx, txCh, chSuccess, cli) + go loadProcess(ctx, txCh, chSuccess, n) } } @@ -123,10 +120,18 @@ func createTxBatch(ctx context.Context, txCh chan<- types.Tx, testnet *e2e.Testn // loadProcess processes transactions by sending transactions received on the txCh // to the client. -func loadProcess(ctx context.Context, txCh <-chan types.Tx, chSuccess chan<- struct{}, client *rpchttp.HTTP) { +func loadProcess(ctx context.Context, txCh <-chan types.Tx, chSuccess chan<- struct{}, n *e2e.Node) { + var client *rpchttp.HTTP var err error s := struct{}{} for tx := range txCh { + if client == nil { + client, err = n.Client() + if err != nil { + logger.Info("non-fatal error creating node client", "error", err) + continue + } + } if _, err = client.BroadcastTxSync(ctx, tx); err != nil { continue } From 0952a99f454a9936839a461cfc5f91c12546705a Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Thu, 1 Dec 2022 12:46:22 -0500 Subject: [PATCH 06/40] ci: Better Slack failures (#9812) The primary aim of this PR is to improve the failure messages we get a little. Seeing the latest commit is often useless, and it's probably better to just get a direct link to a list of commits for that specific branch so we can see what's been committed since the previous nightly run. This PR also makes one minor improvement in the use of the now-deprecated `set-output` syntax for workflows, upgrading it to use the new approach as per https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- .github/workflows/docker.yml | 2 +- .github/workflows/e2e-nightly-34x.yml | 8 +++----- .github/workflows/e2e-nightly-37x.yml | 8 +++----- .github/workflows/e2e-nightly-main.yml | 4 ++-- .github/workflows/fuzz-nightly.yml | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index e1f38d1a631..721a2717b66 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ jobs: if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then TAGS="$TAGS,${DOCKER_IMAGE}:${VERSION}" fi - echo ::set-output name=tags::${TAGS} + echo "tags=${TAGS}" >> $GITHUB_OUTPUT - name: Set up QEMU uses: docker/setup-qemu-action@master diff --git a/.github/workflows/e2e-nightly-34x.yml b/.github/workflows/e2e-nightly-34x.yml index 944ba13ef4b..8d89a20dabd 100644 --- a/.github/workflows/e2e-nightly-34x.yml +++ b/.github/workflows/e2e-nightly-34x.yml @@ -30,8 +30,7 @@ jobs: - name: Capture git repo info id: git-info run: | - echo "::set-output name=branch::`git branch --show-current`" - echo "::set-output name=commit::`git rev-parse HEAD`" + echo "branch=`git branch --show-current`" >> $GITHUB_OUTPUT - name: Build working-directory: test/e2e @@ -49,7 +48,6 @@ jobs: outputs: git-branch: ${{ steps.git-info.outputs.branch }} - git-commit: ${{ steps.git-info.outputs.commit }} e2e-nightly-fail: needs: e2e-nightly-test @@ -63,7 +61,7 @@ jobs: SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK BRANCH: ${{ needs.e2e-nightly-test.outputs.git-branch }} RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.e2e-nightly-test.outputs.git-commit }}" + COMMITS_URL: "${{ github.server_url }}/${{ github.repository }}/commits/${{ needs.e2e-nightly-test.outputs.git-branch }}" with: payload: | { @@ -72,7 +70,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> related to the failure." + "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMITS_URL }}|latest commits> possibly related to the failure." } } ] diff --git a/.github/workflows/e2e-nightly-37x.yml b/.github/workflows/e2e-nightly-37x.yml index 769a316b23c..ebcc4a3fb7b 100644 --- a/.github/workflows/e2e-nightly-37x.yml +++ b/.github/workflows/e2e-nightly-37x.yml @@ -30,8 +30,7 @@ jobs: - name: Capture git repo info id: git-info run: | - echo "::set-output name=branch::`git branch --show-current`" - echo "::set-output name=commit::`git rev-parse HEAD`" + echo "branch=`git branch --show-current`" >> $GITHUB_OUTPUT - name: Build working-directory: test/e2e @@ -49,7 +48,6 @@ jobs: outputs: git-branch: ${{ steps.git-info.outputs.branch }} - git-commit: ${{ steps.git-info.outputs.commit }} e2e-nightly-fail: needs: e2e-nightly-test @@ -63,7 +61,7 @@ jobs: SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK BRANCH: ${{ needs.e2e-nightly-test.outputs.git-branch }} RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ needs.e2e-nightly-test.outputs.git-commit }}" + COMMITS_URL: "${{ github.server_url }}/${{ github.repository }}/commits/${{ needs.e2e-nightly-test.outputs.git-branch }}" with: payload: | { @@ -72,7 +70,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> related to the failure." + "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMITS_URL }}|latest commits> possibly related to the failure." } } ] diff --git a/.github/workflows/e2e-nightly-main.yml b/.github/workflows/e2e-nightly-main.yml index dd8b7abbb1e..7f734367d28 100644 --- a/.github/workflows/e2e-nightly-main.yml +++ b/.github/workflows/e2e-nightly-main.yml @@ -52,7 +52,7 @@ jobs: SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK BRANCH: ${{ github.ref_name }} RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - COMMIT_URL: "${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}" + COMMITS_URL: "${{ github.server_url }}/${{ github.repository }}/commits/${{ github.ref_name }}" with: payload: | { @@ -61,7 +61,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMIT_URL }}|commit> related to the failure." + "text": ":skull: Nightly E2E tests for `${{ env.BRANCH }}` failed. See the <${{ env.RUN_URL }}|run details> and the <${{ env.COMMITS_URL }}|latest commits> possibly related to the failure." } } ] diff --git a/.github/workflows/fuzz-nightly.yml b/.github/workflows/fuzz-nightly.yml index 0209501a169..e6c71db0850 100644 --- a/.github/workflows/fuzz-nightly.yml +++ b/.github/workflows/fuzz-nightly.yml @@ -64,7 +64,7 @@ jobs: - name: Set crashers count working-directory: test/fuzz - run: echo "::set-output name=count::$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')" + run: echo "count=$(find . -type d -name 'crashers' | xargs -I % sh -c 'ls % | wc -l' | awk '{total += $1} END {print total}')" >> $GITHUB_OUTPUT id: set-crashers-count outputs: From 654e5652e4ce3c521895a97909712c0a5509e8fa Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Fri, 2 Dec 2022 13:19:10 -0500 Subject: [PATCH 07/40] e2e: add defer to ensure waitgroup is finished. (#9822) * defer wait group completion * generate correct number of tx --- test/e2e/runner/load.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/e2e/runner/load.go b/test/e2e/runner/load.go index 1989886b0d8..b4478bf6dbd 100644 --- a/test/e2e/runner/load.go +++ b/test/e2e/runner/load.go @@ -92,10 +92,12 @@ func loadGenerate(ctx context.Context, txCh chan<- types.Tx, testnet *e2e.Testne // is canceled. func createTxBatch(ctx context.Context, txCh chan<- types.Tx, testnet *e2e.Testnet, id []byte) { wg := &sync.WaitGroup{} + genCh := make(chan struct{}) for i := 0; i < workerPoolSize; i++ { wg.Add(1) go func() { - for i := 0; i < testnet.LoadTxBatchSize; i++ { + defer wg.Done() + for range genCh { tx, err := payload.NewBytes(&payload.Payload{ Id: id, Size: uint64(testnet.LoadTxSizeBytes), @@ -112,9 +114,16 @@ func createTxBatch(ctx context.Context, txCh chan<- types.Tx, testnet *e2e.Testn return } } - wg.Done() }() } + for i := 0; i < testnet.LoadTxBatchSize; i++ { + select { + case genCh <- struct{}{}: + case <-ctx.Done(): + break + } + } + close(genCh) wg.Wait() } From 5ba0d131c461a469b2ad8eddf99aded18efcb3ff Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Fri, 2 Dec 2022 13:37:33 -0500 Subject: [PATCH 08/40] e2e: setup testing for multi-version (#9819) This pull requests sets up the e2e tests to be able to support multiple versions within the same test network. This is achieved through a few simple changes: * Each node takes a `version` parameter in the testnet manifest. This dictates which version of the testapp to use. If not set, the locally available version is used. * Adds a `testapp-docker.yml` workflow that publishes the testapp to docker hub so that tagged versions may be available for use in a multi-version test network. This change does not actually add a testnetwork that does multi-version testing. Since no previous versions of the testapp have been published to dockerhub, there are not old versions available to test against. We'll either need to configure this after the next minor release which will trigger a testapp to be pushed to dockerhub, or push an image from the previous version of Tendermint so that the multiversion test has an old version to pull. #### PR checklist - [ ] Tests written/updated, or no tests needed - [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [ ] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- .../{docker.yml => tendermint-docker.yml} | 0 .github/workflows/testapp-docker.yml | 60 +++++++++++++++++++ test/e2e/Makefile | 2 +- test/e2e/pkg/infra/docker/docker.go | 2 +- test/e2e/pkg/manifest.go | 7 +++ test/e2e/pkg/testnet.go | 6 ++ 6 files changed, 75 insertions(+), 2 deletions(-) rename .github/workflows/{docker.yml => tendermint-docker.yml} (100%) create mode 100644 .github/workflows/testapp-docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/tendermint-docker.yml similarity index 100% rename from .github/workflows/docker.yml rename to .github/workflows/tendermint-docker.yml diff --git a/.github/workflows/testapp-docker.yml b/.github/workflows/testapp-docker.yml new file mode 100644 index 00000000000..9e8e59a4708 --- /dev/null +++ b/.github/workflows/testapp-docker.yml @@ -0,0 +1,60 @@ +name: Testapp Docker +# Build & Push rebuilds the Testapp docker image on every push to main and creation of tags +# and pushes the image to https://hub.docker.com/r/tendermint/testapp +on: + push: + branches: + - main + tags: + - "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10 + - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" # e.g. v0.37.0-alpha.1, v0.38.0-alpha.10 + - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" # e.g. v0.37.0-beta.1, v0.38.0-beta.10 + - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" # e.g. v0.37.0-rc1, v0.38.0-rc10 + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Prepare + id: prep + run: | + DOCKER_IMAGE=tendermint/testapp + VERSION=noop + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF#refs/tags/} + elif [[ $GITHUB_REF == refs/heads/* ]]; then + VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g') + if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then + VERSION=latest + fi + fi + TAGS="${DOCKER_IMAGE}:${VERSION}" + if [[ $VERSION =~ ^v[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + TAGS="$TAGS,${DOCKER_IMAGE}:${VERSION}" + fi + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + + - name: Set up QEMU + uses: docker/setup-qemu-action@master + with: + platforms: all + + - name: Set up Docker Build + uses: docker/setup-buildx-action@v2.2.1 + + - name: Login to DockerHub + if: ${{ github.event_name != 'pull_request' }} + uses: docker/login-action@v2.1.0 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Publish to Docker Hub + uses: docker/build-push-action@v3.2.0 + with: + context: . + file: ./test/e2e/docker/Dockerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'beep_boop' }} + tags: ${{ steps.prep.outputs.tags }} diff --git a/test/e2e/Makefile b/test/e2e/Makefile index 8bafe7ca98c..7a82f82368f 100644 --- a/test/e2e/Makefile +++ b/test/e2e/Makefile @@ -1,7 +1,7 @@ all: docker generator runner docker: - docker build --tag tendermint/e2e-node -f docker/Dockerfile ../.. + docker build --tag tendermint/e2e-node --tag tendermint/e2e-node:local-version -f docker/Dockerfile ../.. # We need to build support for database backends into the app in # order to build a binary with a Tendermint node in it (for built-in diff --git a/test/e2e/pkg/infra/docker/docker.go b/test/e2e/pkg/infra/docker/docker.go index 04811aab5e1..5c118f03bdf 100644 --- a/test/e2e/pkg/infra/docker/docker.go +++ b/test/e2e/pkg/infra/docker/docker.go @@ -57,7 +57,7 @@ services: labels: e2e: true container_name: {{ .Name }} - image: tendermint/e2e-node + image: tendermint/e2e-node:{{ .Version }} {{- if eq .ABCIProtocol "builtin" }} entrypoint: /usr/bin/entrypoint-builtin {{- end }} diff --git a/test/e2e/pkg/manifest.go b/test/e2e/pkg/manifest.go index 814ae61c71f..0a9a1da5f6b 100644 --- a/test/e2e/pkg/manifest.go +++ b/test/e2e/pkg/manifest.go @@ -81,6 +81,13 @@ type ManifestNode struct { // is generated), and seed nodes run in seed mode with the PEX reactor enabled. Mode string `toml:"mode"` + // Version specifies which version of Tendermint this node is. Specifying different + // versions for different nodes allows for testing the interaction of different + // node's compatibility. Note that in order to use a node at a particular version, + // there must be a docker image of the test app tagged with this version present + // on the machine where the test is being run. + Version string `toml:"version"` + // SyncApp specifies whether this node should use a synchronized application // with an unsynchronized local client. By default this is `false`, meaning // that the node will run an unsynchronized application with a synchronized diff --git a/test/e2e/pkg/testnet.go b/test/e2e/pkg/testnet.go index 8d0d674db1f..2bd16f8c1fc 100644 --- a/test/e2e/pkg/testnet.go +++ b/test/e2e/pkg/testnet.go @@ -79,6 +79,7 @@ type Testnet struct { // Node represents a Tendermint node in a testnet. type Node struct { Name string + Version string Testnet *Testnet Mode Mode SyncApp bool // Should we use a synchronized app with an unsynchronized local client? @@ -169,8 +170,13 @@ func LoadTestnet(manifest Manifest, fname string, ifd InfrastructureData) (*Test if !ok { return nil, fmt.Errorf("information for node '%s' missing from infrastucture data", name) } + v := nodeManifest.Version + if v == "" { + v = "local-version" + } node := &Node{ Name: name, + Version: v, Testnet: testnet, PrivvalKey: keyGen.Generate(manifest.KeyType), NodeKey: keyGen.Generate("ed25519"), From c3302b0dc985f4267fc511c98d84f99daade0bdd Mon Sep 17 00:00:00 2001 From: Lasaro Camargos Date: Sun, 4 Dec 2022 08:15:49 -0300 Subject: [PATCH 09/40] fixes abci-cli console help (#9821) * adds prepare and process proposal commands to console help * comment typo fix --- abci/cmd/abci-cli/abci-cli.go | 7 +++++-- state/execution.go | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 4a42019437f..ab0d521566f 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -460,11 +460,14 @@ func cmdUnimplemented(cmd *cobra.Command, args []string) error { fmt.Println("Available commands:") fmt.Printf("%s: %s\n", echoCmd.Use, echoCmd.Short) - fmt.Printf("%s: %s\n", infoCmd.Use, infoCmd.Short) fmt.Printf("%s: %s\n", checkTxCmd.Use, checkTxCmd.Short) + fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short) fmt.Printf("%s: %s\n", deliverTxCmd.Use, deliverTxCmd.Short) + fmt.Printf("%s: %s\n", infoCmd.Use, infoCmd.Short) fmt.Printf("%s: %s\n", queryCmd.Use, queryCmd.Short) - fmt.Printf("%s: %s\n", commitCmd.Use, commitCmd.Short) + fmt.Printf("%s: %s\n", prepareProposalCmd.Use, prepareProposalCmd.Short) + fmt.Printf("%s: %s\n", processProposalCmd.Use, processProposalCmd.Short) + fmt.Println("Use \"[command] --help\" for more information about a command.") return nil diff --git a/state/execution.go b/state/execution.go index 234d81c0f3c..4ba630db741 100644 --- a/state/execution.go +++ b/state/execution.go @@ -93,7 +93,7 @@ func (blockExec *BlockExecutor) SetEventBus(eventBus types.BlockEventPublisher) // CreateProposalBlock calls state.MakeBlock with evidence from the evpool // and txs from the mempool. The max bytes must be big enough to fit the commit. -// Up to 1/10th of the block space is allcoated for maximum sized evidence. +// Up to 1/10th of the block space is allocated for maximum sized evidence. // The rest is given to txs, up to the max gas. // // Contract: application will not return more bytes than are sent over the wire. From 49502dae92047cd1fa8cf3b6b2ba348fb6de8da3 Mon Sep 17 00:00:00 2001 From: Lasaro Camargos Date: Tue, 6 Dec 2022 10:00:22 -0300 Subject: [PATCH 10/40] Rejects empty transactions in the example kvstore (#9823) * Rejects empty transactions in the example kvstore * Add code for rejected transaction; Add test for txn rejection; * Apply suggestions from code review Co-authored-by: Sergio Mena --- abci/example/code/code.go | 1 + abci/example/kvstore/kvstore.go | 4 ++++ abci/example/kvstore/kvstore_test.go | 18 ++++++++++++++++++ abci/example/kvstore/persistent_kvstore.go | 6 +++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/abci/example/code/code.go b/abci/example/code/code.go index 6d011ed9d60..660bac9875b 100644 --- a/abci/example/code/code.go +++ b/abci/example/code/code.go @@ -8,4 +8,5 @@ const ( CodeTypeUnauthorized uint32 = 3 CodeTypeUnknownError uint32 = 4 CodeTypeExecuted uint32 = 5 + CodeTypeRejected uint32 = 6 ) diff --git a/abci/example/kvstore/kvstore.go b/abci/example/kvstore/kvstore.go index 3188c94253d..cae5f79d939 100644 --- a/abci/example/kvstore/kvstore.go +++ b/abci/example/kvstore/kvstore.go @@ -122,6 +122,10 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli } func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { + if len(req.Tx) == 0 { + return types.ResponseCheckTx{Code: code.CodeTypeRejected} + } + if req.Type == types.CheckTxType_Recheck { if _, ok := app.txToRemove[string(req.Tx)]; ok { return types.ResponseCheckTx{Code: code.CodeTypeExecuted, GasWanted: 1} diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 5d91f36998b..77d6e933fb6 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -70,6 +70,24 @@ func TestKVStoreKV(t *testing.T) { testKVStore(t, kvstore, tx, key, value) } +func TestPersistentKVStoreEmptyTX(t *testing.T) { + dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO + if err != nil { + t.Fatal(err) + } + kvstore := NewPersistentKVStoreApplication(dir) + tx := []byte("") + reqCheck := types.RequestCheckTx{Tx: tx} + resCheck := kvstore.CheckTx(reqCheck) + require.Equal(t, resCheck.Code, code.CodeTypeRejected) + + txs := make([][]byte, 0, 4) + txs = append(txs, []byte("key=value"), []byte("key"), []byte(""), []byte("kee=value")) + reqPrepare := types.RequestPrepareProposal{Txs: txs, MaxTxBytes: 10 * 1024} + resPrepare := kvstore.PrepareProposal(reqPrepare) + require.Equal(t, len(reqPrepare.Txs), len(resPrepare.Txs)+1, "Empty transaction not properly removed") +} + func TestPersistentKVStoreKV(t *testing.T) { dir, err := os.MkdirTemp("/tmp", "abci-kvstore-test") // TODO if err != nil { diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index 500d4c5c97e..8aa255b75bb 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -324,11 +324,15 @@ func (app *PersistentKVStoreApplication) execPrepareTx(tx []byte) types.Response } // substPrepareTx substitutes all the transactions prefixed with 'prepare' in the -// proposal for transactions with the prefix stripped. +// proposal for transactions with the prefix stripped, while discarding invalid empty transactions. func (app *PersistentKVStoreApplication) substPrepareTx(blockData [][]byte, maxTxBytes int64) [][]byte { txs := make([][]byte, 0, len(blockData)) var totalBytes int64 for _, tx := range blockData { + if len(tx) == 0 { + continue + } + txMod := tx if isPrepareTx(tx) { txMod = bytes.Replace(tx, []byte(PreparePrefix), []byte(ReplacePrefix), 1) From ac48630fdb591a7230f6a9f4a35cb4d71d650a9b Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Tue, 6 Dec 2022 11:17:47 -0500 Subject: [PATCH 11/40] e2e: add multiversion flag to generator (#9829) * add multiversion flag to generator * clarify flag comment --- test/e2e/generator/generate.go | 10 ++++++++-- test/e2e/generator/main.go | 12 +++++++++--- test/e2e/generator/random.go | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index a0c65305faa..a898d67d8d2 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -22,7 +22,9 @@ var ( }, "validators": {"genesis", "initchain"}, } - + nodeVersions = weightedChoice{ + "": 2, + } // The following specify randomly chosen values for testnet nodes. nodeDatabases = uniformChoice{"goleveldb", "cleveldb", "rocksdb", "boltdb", "badgerdb"} ipv6 = uniformChoice{false, true} @@ -50,7 +52,10 @@ var ( ) // Generate generates random testnets using the given RNG. -func Generate(r *rand.Rand) ([]e2e.Manifest, error) { +func Generate(r *rand.Rand, multiversion string) ([]e2e.Manifest, error) { + if multiversion != "" { + nodeVersions[multiversion] = 1 + } manifests := []e2e.Manifest{} for _, opt := range combinations(testnetCombinations) { manifest, err := generateTestnet(r, opt) @@ -224,6 +229,7 @@ func generateNode( r *rand.Rand, mode e2e.Mode, syncApp bool, startAt int64, initialHeight int64, forceArchive bool, ) *e2e.ManifestNode { node := e2e.ManifestNode{ + Version: nodeVersions.Choose(r).(string), Mode: string(mode), SyncApp: syncApp, StartAt: startAt, diff --git a/test/e2e/generator/main.go b/test/e2e/generator/main.go index d5b6ab63974..16bcc1b5853 100644 --- a/test/e2e/generator/main.go +++ b/test/e2e/generator/main.go @@ -44,25 +44,31 @@ func NewCLI() *CLI { if err != nil { return err } - return cli.generate(dir, groups) + multiversion, err := cmd.Flags().GetString("multi-version") + if err != nil { + return err + } + return cli.generate(dir, groups, multiversion) }, } cli.root.PersistentFlags().StringP("dir", "d", "", "Output directory for manifests") _ = cli.root.MarkPersistentFlagRequired("dir") + cli.root.PersistentFlags().StringP("multi-version", "m", "", "Include multi-version testing."+ + "If multi-version is not specified, then only the current Tendermint version will be used in generated testnets.") cli.root.PersistentFlags().IntP("groups", "g", 0, "Number of groups") return cli } // generate generates manifests in a directory. -func (cli *CLI) generate(dir string, groups int) error { +func (cli *CLI) generate(dir string, groups int, multiversion string) error { err := os.MkdirAll(dir, 0o755) if err != nil { return err } - manifests, err := Generate(rand.New(rand.NewSource(randomSeed))) //nolint:gosec + manifests, err := Generate(rand.New(rand.NewSource(randomSeed)), multiversion) //nolint:gosec if err != nil { return err } diff --git a/test/e2e/generator/random.go b/test/e2e/generator/random.go index f21502118d7..4312eb30d70 100644 --- a/test/e2e/generator/random.go +++ b/test/e2e/generator/random.go @@ -83,3 +83,25 @@ func (usc uniformSetChoice) Choose(r *rand.Rand) []string { } return choices } + +// weightedChoice chooses a single random key from a map of keys and weights. +type weightedChoice map[interface{}]uint + +func (wc weightedChoice) Choose(r *rand.Rand) interface{} { + total := 0 + choices := make([]interface{}, 0, len(wc)) + for choice, weight := range wc { + total += int(weight) + choices = append(choices, choice) + } + + rem := r.Intn(total) + for _, choice := range choices { + rem -= int(wc[choice]) + if rem <= 0 { + return choice + } + } + + return nil +} From 3324f49fb7e7b40189726746493e83b82a61b558 Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Wed, 7 Dec 2022 12:15:55 -0500 Subject: [PATCH 12/40] inspect: resurrect the inspect command (#9655) resurrect the inspect command from #6785 Co-authored-by: Sam Kleinman Co-authored-by: Thane Thomson Co-authored-by: Callum Waters --- CHANGELOG_PENDING.md | 3 + cmd/tendermint/commands/inspect.go | 87 ++++ cmd/tendermint/main.go | 1 + config/db.go | 30 ++ consensus/replay.go | 2 +- consensus/replay_test.go | 3 +- docs/tools/debugging.md | 44 ++ go.sum | 1 + inspect/doc.go | 36 ++ inspect/inspect.go | 138 ++++++ inspect/inspect_test.go | 605 +++++++++++++++++++++++++ inspect/rpc/rpc.go | 128 ++++++ libs/pubsub/pubsub.go | 2 +- libs/pubsub/pubsub_test.go | 6 +- libs/pubsub/subscription.go | 6 +- libs/strings/string.go | 21 + light/proxy/proxy.go | 2 +- node/node.go | 36 +- node/node_test.go | 4 +- node/setup.go | 68 +-- rpc/client/local/local.go | 72 ++- rpc/client/mock/client.go | 54 ++- rpc/core/abci.go | 8 +- rpc/core/blocks.go | 49 +- rpc/core/blocks_test.go | 4 +- rpc/core/consensus.go | 29 +- rpc/core/dev.go | 2 +- rpc/core/env.go | 50 +- rpc/core/env_test.go | 6 +- rpc/core/events.go | 14 +- rpc/core/evidence.go | 7 +- rpc/core/health.go | 4 +- rpc/core/mempool.go | 28 +- rpc/core/net.go | 19 +- rpc/core/net_test.go | 6 +- rpc/core/routes.go | 94 ++-- rpc/core/status.go | 12 +- rpc/core/tx.go | 6 +- rpc/grpc/api.go | 3 +- rpc/grpc/client_server.go | 7 +- rpc/jsonrpc/jsonrpc_test.go | 4 +- rpc/jsonrpc/server/http_server.go | 6 +- rpc/jsonrpc/server/http_server_test.go | 3 +- rpc/jsonrpc/test/main.go | 2 +- rpc/test/helpers.go | 2 +- state/execution_test.go | 2 +- state/indexer/block/indexer.go | 47 ++ state/mocks/block_store.go | 14 + state/services.go | 2 + state/txindex/indexer_service.go | 79 ++-- test/e2e/node/main.go | 6 +- types/event_bus.go | 2 +- types/event_bus_test.go | 2 +- 53 files changed, 1506 insertions(+), 362 deletions(-) create mode 100644 cmd/tendermint/commands/inspect.go create mode 100644 config/db.go create mode 100644 inspect/doc.go create mode 100644 inspect/inspect.go create mode 100644 inspect/inspect_test.go create mode 100644 inspect/rpc/rpc.go create mode 100644 state/indexer/block/indexer.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 25c97aff750..945edbd599d 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -12,6 +12,8 @@ - Go API - [p2p] \#9625 Remove unused p2p/trust package (@cmwaters) + - [rpc] \#9655 Remove global environment and replace with constructor. (@williambanfield,@tychoish) + - [node] \#9655 Move DBContext and DBProvider from the node package to the config package. (@williambanfield,@tychoish) - Blockchain Protocol @@ -22,6 +24,7 @@ - [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106) - [metrics] \#9682 move state-syncing and block-syncing metrics to their respective packages (@cmwaters) labels have moved from block_syncing -> blocksync_syncing and state_syncing -> statesync_syncing + - [inspect] \#9655 Add a new `inspect` command for introspecting the state and block store of a crashed tendermint node. (@williambanfield) ### FEATURES diff --git a/cmd/tendermint/commands/inspect.go b/cmd/tendermint/commands/inspect.go new file mode 100644 index 00000000000..9e473ec0084 --- /dev/null +++ b/cmd/tendermint/commands/inspect.go @@ -0,0 +1,87 @@ +package commands + +import ( + "context" + "os" + "os/signal" + "syscall" + + "github.com/spf13/cobra" + + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/inspect" + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/state/indexer/block" + "github.com/tendermint/tendermint/store" + "github.com/tendermint/tendermint/types" +) + +// InspectCmd is the command for starting an inspect server. +var InspectCmd = &cobra.Command{ + Use: "inspect", + Short: "Run an inspect server for investigating Tendermint state", + Long: ` + inspect runs a subset of Tendermint's RPC endpoints that are useful for debugging + issues with Tendermint. + + When the Tendermint consensus engine detects inconsistent state, it will crash the + Tendermint process. Tendermint will not start up while in this inconsistent state. + The inspect command can be used to query the block and state store using Tendermint + RPC calls to debug issues of inconsistent state. + `, + + RunE: runInspect, +} + +func init() { + InspectCmd.Flags(). + String("rpc.laddr", + config.RPC.ListenAddress, "RPC listenener address. Port required") + InspectCmd.Flags(). + String("db-backend", + config.DBBackend, "database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb") + InspectCmd.Flags(). + String("db-dir", config.DBPath, "database directory") +} + +func runInspect(cmd *cobra.Command, args []string) error { + ctx, cancel := context.WithCancel(cmd.Context()) + defer cancel() + + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGTERM, syscall.SIGINT) + go func() { + <-c + cancel() + }() + + blockStoreDB, err := cfg.DefaultDBProvider(&cfg.DBContext{ID: "blockstore", Config: config}) + if err != nil { + return err + } + blockStore := store.NewBlockStore(blockStoreDB) + defer blockStore.Close() + + stateDB, err := cfg.DefaultDBProvider(&cfg.DBContext{ID: "state", Config: config}) + if err != nil { + return err + } + stateStore := state.NewStore(stateDB, state.StoreOptions{DiscardABCIResponses: false}) + defer stateStore.Close() + + genDoc, err := types.GenesisDocFromFile(config.GenesisFile()) + if err != nil { + return err + } + txIndexer, blockIndexer, err := block.IndexerFromConfig(config, cfg.DefaultDBProvider, genDoc.ChainID) + if err != nil { + return err + } + ins := inspect.New(config.RPC, blockStore, stateStore, txIndexer, blockIndexer, logger) + + logger.Info("starting inspect server") + if err := ins.Run(ctx); err != nil { + return err + } + return nil +} diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go index 59e7a1b1288..47cad15ed2a 100644 --- a/cmd/tendermint/main.go +++ b/cmd/tendermint/main.go @@ -30,6 +30,7 @@ func main() { cmd.VersionCmd, cmd.RollbackStateCmd, cmd.CompactGoLevelDBCmd, + cmd.InspectCmd, debug.DebugCmd, cli.NewCompletionCmd(rootCmd, true), ) diff --git a/config/db.go b/config/db.go new file mode 100644 index 00000000000..bbc2869446a --- /dev/null +++ b/config/db.go @@ -0,0 +1,30 @@ +package config + +import ( + "context" + + dbm "github.com/tendermint/tm-db" + + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/service" +) + +// ServiceProvider takes a config and a logger and returns a ready to go Node. +type ServiceProvider func(context.Context, *Config, log.Logger) (service.Service, error) + +// DBContext specifies config information for loading a new DB. +type DBContext struct { + ID string + Config *Config +} + +// DBProvider takes a DBContext and returns an instantiated DB. +type DBProvider func(*DBContext) (dbm.DB, error) + +// DefaultDBProvider returns a database using the DBBackend and DBDir +// specified in the Config. +func DefaultDBProvider(ctx *DBContext) (dbm.DB, error) { + dbType := dbm.BackendType(ctx.Config.DBBackend) + + return dbm.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) +} diff --git a/consensus/replay.go b/consensus/replay.go index 83569aff204..edac91425ec 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -54,7 +54,7 @@ func (cs *State) readReplayMessage(msg *TimedWALMessage, newStepSub types.Subscr if m.Height != m2.Height || m.Round != m2.Round || m.Step != m2.Step { return fmt.Errorf("roundState mismatch. Got %v; Expected %v", m2, m) } - case <-newStepSub.Cancelled(): + case <-newStepSub.Canceled(): return fmt.Errorf("failed to read off newStepSub.Out(). newStepSub was canceled") case <-ticker: return fmt.Errorf("failed to read off newStepSub.Out()") diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 44bbe09bf0d..f4c4e14e8cf 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -97,7 +97,7 @@ func startNewStateAndWaitForBlock(t *testing.T, consensusReplayConfig *cfg.Confi require.NoError(t, err) select { case <-newBlockSub.Out(): - case <-newBlockSub.Cancelled(): + case <-newBlockSub.Canceled(): t.Fatal("newBlockSub was canceled") case <-time.After(120 * time.Second): t.Fatal("Timed out waiting for new block (see trace above)") @@ -1198,6 +1198,7 @@ func (bs *mockBlockStore) PruneBlocks(height int64, state sm.State) (uint64, int } func (bs *mockBlockStore) DeleteLatestBlock() error { return nil } +func (bs *mockBlockStore) Close() error { return nil } //--------------------------------------- // Test handshake/init chain diff --git a/docs/tools/debugging.md b/docs/tools/debugging.md index 17fa0ec1174..2c9998fbea6 100644 --- a/docs/tools/debugging.md +++ b/docs/tools/debugging.md @@ -55,3 +55,47 @@ given destination directory. Each archive will contain: Note: goroutine.out and heap.out will only be written if a profile address is provided and is operational. This command is blocking and will log any error. + +## Tendermint Inspect + +Tendermint includes an `inspect` command for querying Tendermint's state store and block +store over Tendermint RPC. + +When the Tendermint consensus engine detects inconsistent state, it will crash the +entire Tendermint process. +While in this inconsistent state, a node running Tendermint's consensus engine will not start up. +The `inspect` command runs only a subset of Tendermint's RPC endpoints for querying the block store +and state store. +`inspect` allows operators to query a read-only view of the stage. +`inspect` does not run the consensus engine at all and can therefore be used to debug +processes that have crashed due to inconsistent state. + +### Running inspect + +Start up the `inspect` tool on the machine where Tendermint crashed using: +```bash +tendermint inspect --home= +``` + +`inspect` will use the data directory specified in your Tendermint configuration file. +`inspect` will also run the RPC server at the address specified in your Tendermint configuration file. + +### Using inspect + +With the `inspect` server running, you can access RPC endpoints that are critically important +for debugging. +Calling the `/status`, `/consensus_state` and `/dump_consensus_state` RPC endpoint +will return useful information about the Tendermint consensus state. + +To start the `inspect` process, run +```bash +tendermint inspect +``` + +### RPC endpoints + +The list of available RPC endpoints can be found by making a request to the RPC port. +For an `inspect` process running on `127.0.0.1:26657`, navigate your browser to +`http://127.0.0.1:26657/` to retrieve the list of enabled RPC endpoints. + +Additional information on the Tendermint RPC endpoints can be found in the [rpc documentation](https://docs.tendermint.com/master/rpc). diff --git a/go.sum b/go.sum index 142fa8d978e..d7973207e88 100644 --- a/go.sum +++ b/go.sum @@ -1361,6 +1361,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= diff --git a/inspect/doc.go b/inspect/doc.go new file mode 100644 index 00000000000..0d17771b586 --- /dev/null +++ b/inspect/doc.go @@ -0,0 +1,36 @@ +/* +Package inspect provides a tool for investigating the state of a +failed Tendermint node. + +This package provides the Inspector type. The Inspector type runs a subset of the Tendermint +RPC endpoints that are useful for debugging issues with Tendermint consensus. + +When a node running the Tendermint consensus engine detects an inconsistent consensus state, +the entire node will crash. The Tendermint consensus engine cannot run in this +inconsistent state so the node will not be able to start up again. + +The RPC endpoints provided by the Inspector type allow for a node operator to inspect +the block store and state store to better understand what may have caused the inconsistent state. + +The Inspector type's lifecycle is controlled by a context.Context + + ins := inspect.NewFromConfig(rpcConfig) + ctx, cancelFunc:= context.WithCancel(context.Background()) + + // Run blocks until the Inspector server is shut down. + go ins.Run(ctx) + ... + + // calling the cancel function will stop the running inspect server + cancelFunc() + +Inspector serves its RPC endpoints on the address configured in the RPC configuration + + rpcConfig.ListenAddress = "tcp://127.0.0.1:26657" + ins := inspect.NewFromConfig(rpcConfig) + go ins.Run(ctx) + +The list of available RPC endpoints can then be viewed by navigating to +http://127.0.0.1:26657/ in the web browser. +*/ +package inspect diff --git a/inspect/inspect.go b/inspect/inspect.go new file mode 100644 index 00000000000..71c44f7bbd3 --- /dev/null +++ b/inspect/inspect.go @@ -0,0 +1,138 @@ +package inspect + +import ( + "context" + "errors" + "net" + "os" + + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/inspect/rpc" + "github.com/tendermint/tendermint/libs/log" + tmstrings "github.com/tendermint/tendermint/libs/strings" + rpccore "github.com/tendermint/tendermint/rpc/core" + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/state/indexer" + "github.com/tendermint/tendermint/state/indexer/block" + "github.com/tendermint/tendermint/state/txindex" + "github.com/tendermint/tendermint/store" + "github.com/tendermint/tendermint/types" + + "golang.org/x/sync/errgroup" +) + +var ( + logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) +) + +// Inspector manages an RPC service that exports methods to debug a failed node. +// After a node shuts down due to a consensus failure, it will no longer start +// up its state cannot easily be inspected. An Inspector value provides a similar interface +// to the node, using the underlying Tendermint data stores, without bringing up +// any other components. A caller can query the Inspector service to inspect the +// persisted state and debug the failure. +type Inspector struct { + routes rpccore.RoutesMap + + config *config.RPCConfig + + logger log.Logger + + // References to the state store and block store are maintained to enable + // the Inspector to safely close them on shutdown. + ss state.Store + bs state.BlockStore +} + +// New returns an Inspector that serves RPC on the specified BlockStore and StateStore. +// The Inspector type does not modify the state or block stores. +// The sinks are used to enable block and transaction querying via the RPC server. +// The caller is responsible for starting and stopping the Inspector service. +// +//nolint:lll +func New(cfg *config.RPCConfig, bs state.BlockStore, ss state.Store, txidx txindex.TxIndexer, blkidx indexer.BlockIndexer, lg log.Logger) *Inspector { + routes := rpc.Routes(*cfg, ss, bs, txidx, blkidx, logger) + eb := types.NewEventBus() + eb.SetLogger(logger.With("module", "events")) + return &Inspector{ + routes: routes, + config: cfg, + logger: logger, + ss: ss, + bs: bs, + } +} + +// NewFromConfig constructs an Inspector using the values defined in the passed in config. +func NewFromConfig(cfg *config.Config) (*Inspector, error) { + bsDB, err := config.DefaultDBProvider(&config.DBContext{ID: "blockstore", Config: cfg}) + if err != nil { + return nil, err + } + bs := store.NewBlockStore(bsDB) + sDB, err := config.DefaultDBProvider(&config.DBContext{ID: "state", Config: cfg}) + if err != nil { + return nil, err + } + genDoc, err := types.GenesisDocFromFile(cfg.GenesisFile()) + if err != nil { + return nil, err + } + txidx, blkidx, err := block.IndexerFromConfig(cfg, config.DefaultDBProvider, genDoc.ChainID) + if err != nil { + return nil, err + } + lg := logger.With("module", "inspect") + ss := state.NewStore(sDB, state.StoreOptions{}) + return New(cfg.RPC, bs, ss, txidx, blkidx, lg), nil +} + +// Run starts the Inspector servers and blocks until the servers shut down. The passed +// in context is used to control the lifecycle of the servers. +func (ins *Inspector) Run(ctx context.Context) error { + defer ins.bs.Close() + defer ins.ss.Close() + + return startRPCServers(ctx, ins.config, ins.logger, ins.routes) +} + +func startRPCServers(ctx context.Context, cfg *config.RPCConfig, logger log.Logger, routes rpccore.RoutesMap) error { + g, tctx := errgroup.WithContext(ctx) + listenAddrs := tmstrings.SplitAndTrimEmpty(cfg.ListenAddress, ",", " ") + rh := rpc.Handler(cfg, routes, logger) + for _, listenerAddr := range listenAddrs { + server := rpc.Server{ + Logger: logger, + Config: cfg, + Handler: rh, + Addr: listenerAddr, + } + if cfg.IsTLSEnabled() { + keyFile := cfg.KeyFile() + certFile := cfg.CertFile() + listenerAddr := listenerAddr + g.Go(func() error { + logger.Info("RPC HTTPS server starting", "address", listenerAddr, + "certfile", certFile, "keyfile", keyFile) + err := server.ListenAndServeTLS(tctx, certFile, keyFile) + if !errors.Is(err, net.ErrClosed) { + return err + } + logger.Info("RPC HTTPS server stopped", "address", listenerAddr) + return nil + }) + } else { + listenerAddr := listenerAddr + g.Go(func() error { + logger.Info("RPC HTTP server starting", "address", listenerAddr) + err := server.ListenAndServe(tctx) + if !errors.Is(err, net.ErrClosed) { + return err + } + logger.Info("RPC HTTP server stopped", "address", listenerAddr) + return nil + }) + } + } + return g.Wait() +} diff --git a/inspect/inspect_test.go b/inspect/inspect_test.go new file mode 100644 index 00000000000..c4ad7a5e44b --- /dev/null +++ b/inspect/inspect_test.go @@ -0,0 +1,605 @@ +package inspect_test + +import ( + "context" + "fmt" + "net" + "os" + "strings" + "sync" + "testing" + "time" + + "github.com/fortytw2/leaktest" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + abcitypes "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/inspect" + "github.com/tendermint/tendermint/internal/test" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/libs/pubsub/query" + "github.com/tendermint/tendermint/proto/tendermint/state" + httpclient "github.com/tendermint/tendermint/rpc/client/http" + indexermocks "github.com/tendermint/tendermint/state/indexer/mocks" + statemocks "github.com/tendermint/tendermint/state/mocks" + txindexmocks "github.com/tendermint/tendermint/state/txindex/mocks" + "github.com/tendermint/tendermint/types" +) + +func TestInspectConstructor(t *testing.T) { + cfg := test.ResetTestRoot("test") + t.Cleanup(leaktest.Check(t)) + defer func() { _ = os.RemoveAll(cfg.RootDir) }() + t.Run("from config", func(t *testing.T) { + d, err := inspect.NewFromConfig(cfg) + require.NoError(t, err) + require.NotNil(t, d) + }) + +} + +func TestInspectRun(t *testing.T) { + cfg := test.ResetTestRoot("test") + t.Cleanup(leaktest.Check(t)) + defer func() { _ = os.RemoveAll(cfg.RootDir) }() + t.Run("from config", func(t *testing.T) { + d, err := inspect.NewFromConfig(cfg) + require.NoError(t, err) + ctx, cancel := context.WithCancel(context.Background()) + stoppedWG := &sync.WaitGroup{} + stoppedWG.Add(1) + go func() { + require.NoError(t, d.Run(ctx)) + stoppedWG.Done() + }() + cancel() + stoppedWG.Wait() + }) + +} + +func TestBlock(t *testing.T) { + testHeight := int64(1) + testBlock := new(types.Block) + testBlock.Header.Height = testHeight + testBlock.Header.LastCommitHash = []byte("test hash") + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Height").Return(testHeight) + blockStoreMock.On("Base").Return(int64(0)) + blockStoreMock.On("LoadBlockMeta", testHeight).Return(&types.BlockMeta{}) + blockStoreMock.On("LoadBlock", testHeight).Return(testBlock) + blockStoreMock.On("Close").Return(nil) + + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + resultBlock, err := cli.Block(context.Background(), &testHeight) + require.NoError(t, err) + require.Equal(t, testBlock.Height, resultBlock.Block.Height) + require.Equal(t, testBlock.LastCommitHash, resultBlock.Block.LastCommitHash) + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestTxSearch(t *testing.T) { + testHash := []byte("test") + testTx := []byte("tx") + testQuery := fmt.Sprintf("tx.hash='%s'", string(testHash)) + testTxResult := &abcitypes.TxResult{ + Height: 1, + Index: 100, + Tx: testTx, + } + + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + txIndexerMock.On("Search", mock.Anything, + mock.MatchedBy(func(q *query.Query) bool { + return testQuery == strings.ReplaceAll(q.String(), " ", "") + })). + Return([]*abcitypes.TxResult{testTxResult}, nil) + + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + + var page = 1 + resultTxSearch, err := cli.TxSearch(context.Background(), testQuery, false, &page, &page, "") + require.NoError(t, err) + require.Len(t, resultTxSearch.Txs, 1) + require.Equal(t, types.Tx(testTx), resultTxSearch.Txs[0].Tx) + + cancel() + wg.Wait() + + txIndexerMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) + blockStoreMock.AssertExpectations(t) +} +func TestTx(t *testing.T) { + testHash := []byte("test") + testTx := []byte("tx") + + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blkIdxMock := &indexermocks.BlockIndexer{} + txIndexerMock := &txindexmocks.TxIndexer{} + txIndexerMock.On("Get", testHash).Return(&abcitypes.TxResult{ + Tx: testTx, + }, nil) + + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + + res, err := cli.Tx(context.Background(), testHash, false) + require.NoError(t, err) + require.Equal(t, types.Tx(testTx), res.Tx) + + cancel() + wg.Wait() + + txIndexerMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) + blockStoreMock.AssertExpectations(t) +} +func TestConsensusParams(t *testing.T) { + testHeight := int64(1) + testMaxGas := int64(55) + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("Height").Return(testHeight) + blockStoreMock.On("Base").Return(int64(0)) + stateStoreMock.On("LoadConsensusParams", testHeight).Return(types.ConsensusParams{ + Block: types.BlockParams{ + MaxGas: testMaxGas, + }, + }, nil) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + params, err := cli.ConsensusParams(context.Background(), &testHeight) + require.NoError(t, err) + require.Equal(t, params.ConsensusParams.Block.MaxGas, testMaxGas) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestBlockResults(t *testing.T) { + testHeight := int64(1) + testGasUsed := int64(100) + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + // tmstate "github.com/tendermint/tendermint/proto/tendermint/state" + stateStoreMock.On("LoadABCIResponses", testHeight).Return(&state.ABCIResponses{ + DeliverTxs: []*abcitypes.ResponseDeliverTx{ + { + GasUsed: testGasUsed, + }, + }, + EndBlock: &abcitypes.ResponseEndBlock{}, + BeginBlock: &abcitypes.ResponseBeginBlock{}, + }, nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("Base").Return(int64(0)) + blockStoreMock.On("Height").Return(testHeight) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + res, err := cli.BlockResults(context.Background(), &testHeight) + require.NoError(t, err) + require.Equal(t, res.TxsResults[0].GasUsed, testGasUsed) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestCommit(t *testing.T) { + testHeight := int64(1) + testRound := int32(101) + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("Base").Return(int64(0)) + blockStoreMock.On("Height").Return(testHeight) + blockStoreMock.On("LoadBlockMeta", testHeight).Return(&types.BlockMeta{}, nil) + blockStoreMock.On("LoadSeenCommit", testHeight).Return(&types.Commit{ + Height: testHeight, + Round: testRound, + }, nil) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + res, err := cli.Commit(context.Background(), &testHeight) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, res.SignedHeader.Commit.Round, testRound) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestBlockByHash(t *testing.T) { + testHeight := int64(1) + testHash := []byte("test hash") + testBlock := new(types.Block) + testBlock.Header.Height = testHeight + testBlock.Header.LastCommitHash = testHash + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("LoadBlockMeta", testHeight).Return(&types.BlockMeta{ + BlockID: types.BlockID{ + Hash: testHash, + }, + Header: types.Header{ + Height: testHeight, + }, + }, nil) + blockStoreMock.On("LoadBlockByHash", testHash).Return(testBlock, nil) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + res, err := cli.BlockByHash(context.Background(), testHash) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, []byte(res.BlockID.Hash), testHash) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestBlockchain(t *testing.T) { + testHeight := int64(1) + testBlock := new(types.Block) + testBlockHash := []byte("test hash") + testBlock.Header.Height = testHeight + testBlock.Header.LastCommitHash = testBlockHash + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("Height").Return(testHeight) + blockStoreMock.On("Base").Return(int64(0)) + blockStoreMock.On("LoadBlockMeta", testHeight).Return(&types.BlockMeta{ + BlockID: types.BlockID{ + Hash: testBlockHash, + }, + }) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + res, err := cli.BlockchainInfo(context.Background(), 0, 100) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, testBlockHash, []byte(res.BlockMetas[0].BlockID.Hash)) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestValidators(t *testing.T) { + testHeight := int64(1) + testVotingPower := int64(100) + testValidators := types.ValidatorSet{ + Validators: []*types.Validator{ + { + VotingPower: testVotingPower, + }, + }, + } + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + stateStoreMock.On("LoadValidators", testHeight).Return(&testValidators, nil) + + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + blockStoreMock.On("Height").Return(testHeight) + blockStoreMock.On("Base").Return(int64(0)) + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + + testPage := 1 + testPerPage := 100 + res, err := cli.Validators(context.Background(), &testHeight, &testPage, &testPerPage) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, testVotingPower, res.Validators[0].VotingPower) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func TestBlockSearch(t *testing.T) { + testHeight := int64(1) + testBlockHash := []byte("test hash") + testQuery := "block.height = 1" + stateStoreMock := &statemocks.Store{} + stateStoreMock.On("Close").Return(nil) + + blockStoreMock := &statemocks.BlockStore{} + blockStoreMock.On("Close").Return(nil) + + txIndexerMock := &txindexmocks.TxIndexer{} + blkIdxMock := &indexermocks.BlockIndexer{} + blockStoreMock.On("LoadBlock", testHeight).Return(&types.Block{ + Header: types.Header{ + Height: testHeight, + }, + }, nil) + blockStoreMock.On("LoadBlockMeta", testHeight).Return(&types.BlockMeta{ + BlockID: types.BlockID{ + Hash: testBlockHash, + }, + }) + blkIdxMock.On("Search", mock.Anything, + mock.MatchedBy(func(q *query.Query) bool { return testQuery == q.String() })). + Return([]int64{testHeight}, nil) + rpcConfig := config.TestRPCConfig() + l := log.TestingLogger() + d := inspect.New(rpcConfig, blockStoreMock, stateStoreMock, txIndexerMock, blkIdxMock, l) + + ctx, cancel := context.WithCancel(context.Background()) + wg := &sync.WaitGroup{} + wg.Add(1) + + startedWG := &sync.WaitGroup{} + startedWG.Add(1) + go func() { + startedWG.Done() + defer wg.Done() + require.NoError(t, d.Run(ctx)) + }() + // FIXME: used to induce context switch. + // Determine more deterministic method for prompting a context switch + startedWG.Wait() + requireConnect(t, rpcConfig.ListenAddress, 20) + cli, err := httpclient.New(rpcConfig.ListenAddress, "/websocket") + require.NoError(t, err) + + testPage := 1 + testPerPage := 100 + testOrderBy := "desc" + res, err := cli.BlockSearch(context.Background(), testQuery, &testPage, &testPerPage, testOrderBy) + require.NoError(t, err) + require.NotNil(t, res) + require.Equal(t, testBlockHash, []byte(res.Blocks[0].BlockID.Hash)) + + cancel() + wg.Wait() + + blockStoreMock.AssertExpectations(t) + stateStoreMock.AssertExpectations(t) +} + +func requireConnect(t testing.TB, addr string, retries int) { + parts := strings.SplitN(addr, "://", 2) + if len(parts) != 2 { + t.Fatalf("malformed address to dial: %s", addr) + } + var err error + for i := 0; i < retries; i++ { + var conn net.Conn + conn, err = net.Dial(parts[0], parts[1]) + if err == nil { + conn.Close() + return + } + // FIXME attempt to yield and let the other goroutine continue execution. + time.Sleep(time.Microsecond * 100) + } + t.Fatalf("unable to connect to server %s after %d tries: %s", addr, retries, err) +} diff --git a/inspect/rpc/rpc.go b/inspect/rpc/rpc.go new file mode 100644 index 00000000000..0aa287511d6 --- /dev/null +++ b/inspect/rpc/rpc.go @@ -0,0 +1,128 @@ +package rpc + +import ( + "context" + "net/http" + "time" + + "github.com/rs/cors" + + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/rpc/core" + "github.com/tendermint/tendermint/rpc/jsonrpc/server" + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/state/indexer" + "github.com/tendermint/tendermint/state/txindex" +) + +// Server defines parameters for running an Inspector rpc server. +type Server struct { + Addr string // TCP address to listen on, ":http" if empty + Handler http.Handler + Logger log.Logger + Config *config.RPCConfig +} + +// Routes returns the set of routes used by the Inspector server. +func Routes(cfg config.RPCConfig, s state.Store, bs state.BlockStore, txidx txindex.TxIndexer, blkidx indexer.BlockIndexer, logger log.Logger) core.RoutesMap { //nolint: lll + env := &core.Environment{ + Config: cfg, + BlockIndexer: blkidx, + TxIndexer: txidx, + StateStore: s, + BlockStore: bs, + ConsensusReactor: waitSyncCheckerImpl{}, + Logger: logger, + } + return core.RoutesMap{ + "blockchain": server.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight"), + "consensus_params": server.NewRPCFunc(env.ConsensusParams, "height"), + "block": server.NewRPCFunc(env.Block, "height"), + "block_by_hash": server.NewRPCFunc(env.BlockByHash, "hash"), + "block_results": server.NewRPCFunc(env.BlockResults, "height"), + "commit": server.NewRPCFunc(env.Commit, "height"), + "header": server.NewRPCFunc(env.Header, "height"), + "header_by_hash": server.NewRPCFunc(env.HeaderByHash, "hash"), + "validators": server.NewRPCFunc(env.Validators, "height,page,per_page"), + "tx": server.NewRPCFunc(env.Tx, "hash,prove"), + "tx_search": server.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by"), + "block_search": server.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by"), + } +} + +// Handler returns the http.Handler configured for use with an Inspector server. Handler +// registers the routes on the http.Handler and also registers the websocket handler +// and the CORS handler if specified by the configuration options. +func Handler(rpcConfig *config.RPCConfig, routes core.RoutesMap, logger log.Logger) http.Handler { + mux := http.NewServeMux() + wmLogger := logger.With("protocol", "websocket") + wm := server.NewWebsocketManager(routes, + server.ReadLimit(rpcConfig.MaxBodyBytes)) + wm.SetLogger(wmLogger) + mux.HandleFunc("/websocket", wm.WebsocketHandler) + + server.RegisterRPCFuncs(mux, routes, logger) + var rootHandler http.Handler = mux + if rpcConfig.IsCorsEnabled() { + rootHandler = addCORSHandler(rpcConfig, mux) + } + return rootHandler +} + +func addCORSHandler(rpcConfig *config.RPCConfig, h http.Handler) http.Handler { + corsMiddleware := cors.New(cors.Options{ + AllowedOrigins: rpcConfig.CORSAllowedOrigins, + AllowedMethods: rpcConfig.CORSAllowedMethods, + AllowedHeaders: rpcConfig.CORSAllowedHeaders, + }) + h = corsMiddleware.Handler(h) + return h +} + +type waitSyncCheckerImpl struct{} + +func (waitSyncCheckerImpl) WaitSync() bool { + return false +} + +// ListenAndServe listens on the address specified in srv.Addr and handles any +// incoming requests over HTTP using the Inspector rpc handler specified on the server. +func (srv *Server) ListenAndServe(ctx context.Context) error { + listener, err := server.Listen(srv.Addr, srv.Config.MaxOpenConnections) + if err != nil { + return err + } + go func() { + <-ctx.Done() + listener.Close() + }() + return server.Serve(listener, srv.Handler, srv.Logger, serverRPCConfig(srv.Config)) +} + +// ListenAndServeTLS listens on the address specified in srv.Addr. ListenAndServeTLS handles +// incoming requests over HTTPS using the Inspector rpc handler specified on the server. +func (srv *Server) ListenAndServeTLS(ctx context.Context, certFile, keyFile string) error { + listener, err := server.Listen(srv.Addr, srv.Config.MaxOpenConnections) + if err != nil { + return err + } + go func() { + <-ctx.Done() + listener.Close() + }() + return server.ServeTLS(listener, srv.Handler, certFile, keyFile, srv.Logger, serverRPCConfig(srv.Config)) +} + +func serverRPCConfig(r *config.RPCConfig) *server.Config { + cfg := server.DefaultConfig() + cfg.MaxBodyBytes = r.MaxBodyBytes + cfg.MaxHeaderBytes = r.MaxHeaderBytes + // If necessary adjust global WriteTimeout to ensure it's greater than + // TimeoutBroadcastTxCommit. + // See https://github.com/tendermint/tendermint/issues/3435 + if cfg.WriteTimeout <= r.TimeoutBroadcastTxCommit { + cfg.WriteTimeout = r.TimeoutBroadcastTxCommit + 1*time.Second + } + return cfg +} diff --git a/libs/pubsub/pubsub.go b/libs/pubsub/pubsub.go index 321e775c882..3a1d66b3749 100644 --- a/libs/pubsub/pubsub.go +++ b/libs/pubsub/pubsub.go @@ -27,7 +27,7 @@ // select { // case msg <- subscription.Out(): // // handle msg.Data() and msg.Events() -// case <-subscription.Cancelled(): +// case <-subscription.Canceled(): // return subscription.Err() // } // } diff --git a/libs/pubsub/pubsub_test.go b/libs/pubsub/pubsub_test.go index 8edf1250847..324928b2903 100644 --- a/libs/pubsub/pubsub_test.go +++ b/libs/pubsub/pubsub_test.go @@ -431,7 +431,7 @@ func benchmarkNClients(n int, b *testing.B) { select { case <-subscription.Out(): continue - case <-subscription.Cancelled(): + case <-subscription.Canceled(): return } } @@ -472,7 +472,7 @@ func benchmarkNClientsOneQuery(n int, b *testing.B) { select { case <-subscription.Out(): continue - case <-subscription.Cancelled(): + case <-subscription.Canceled(): return } } @@ -501,7 +501,7 @@ func assertReceive(t *testing.T, expected interface{}, ch <-chan pubsub.Message, } func assertCancelled(t *testing.T, subscription *pubsub.Subscription, err error) { - _, ok := <-subscription.Cancelled() + _, ok := <-subscription.Canceled() assert.False(t, ok) assert.Equal(t, err, subscription.Err()) } diff --git a/libs/pubsub/subscription.go b/libs/pubsub/subscription.go index 141569310a4..d07abd86da7 100644 --- a/libs/pubsub/subscription.go +++ b/libs/pubsub/subscription.go @@ -43,11 +43,9 @@ func (s *Subscription) Out() <-chan Message { return s.out } -// Cancelled returns a channel that's closed when the subscription is +// Canceled returns a channel that's closed when the subscription is // terminated and supposed to be used in a select statement. -// -//nolint:misspell -func (s *Subscription) Cancelled() <-chan struct{} { +func (s *Subscription) Canceled() <-chan struct{} { return s.canceled } diff --git a/libs/strings/string.go b/libs/strings/string.go index 46675923319..37026dcc208 100644 --- a/libs/strings/string.go +++ b/libs/strings/string.go @@ -32,6 +32,27 @@ func SplitAndTrim(s, sep, cutset string) []string { return spl } +// SplitAndTrimEmpty slices s into all subslices separated by sep and returns a +// slice of the string s with all leading and trailing Unicode code points +// contained in cutset removed. If sep is empty, SplitAndTrim splits after each +// UTF-8 sequence. First part is equivalent to strings.SplitN with a count of +// -1. also filter out empty strings, only return non-empty strings. +func SplitAndTrimEmpty(s, sep, cutset string) []string { + if s == "" { + return []string{} + } + + spl := strings.Split(s, sep) + nonEmptyStrings := make([]string, 0, len(spl)) + for i := 0; i < len(spl); i++ { + element := strings.Trim(spl[i], cutset) + if element != "" { + nonEmptyStrings = append(nonEmptyStrings, element) + } + } + return nonEmptyStrings +} + // Returns true if s is a non-empty printable non-tab ascii character. func IsASCIIText(s string) bool { if len(s) == 0 { diff --git a/light/proxy/proxy.go b/light/proxy/proxy.go index 359f6a8fe4a..70dca1c1077 100644 --- a/light/proxy/proxy.go +++ b/light/proxy/proxy.go @@ -113,7 +113,7 @@ func (p *Proxy) listen() (net.Listener, *http.ServeMux, error) { } // 4) Start listening for new connections. - listener, err := rpcserver.Listen(p.Addr, p.Config) + listener, err := rpcserver.Listen(p.Addr, p.Config.MaxOpenConnections) if err != nil { return nil, mux, err } diff --git a/node/node.go b/node/node.go index ddf86e0dcff..0829db7af89 100644 --- a/node/node.go +++ b/node/node.go @@ -141,7 +141,7 @@ func NewNode(config *cfg.Config, nodeKey *p2p.NodeKey, clientCreator proxy.ClientCreator, genesisDocProvider GenesisDocProvider, - dbProvider DBProvider, + dbProvider cfg.DBProvider, metricsProvider MetricsProvider, logger log.Logger, options ...Option, @@ -503,12 +503,12 @@ func (n *Node) OnStop() { } // ConfigureRPC makes sure RPC has all the objects it needs to operate. -func (n *Node) ConfigureRPC() error { +func (n *Node) ConfigureRPC() (*rpccore.Environment, error) { pubKey, err := n.privValidator.GetPubKey() - if err != nil { - return fmt.Errorf("can't get pubkey: %w", err) + if pubKey == nil || err != nil { + return nil, fmt.Errorf("can't get pubkey: %w", err) } - rpccore.SetEnvironment(&rpccore.Environment{ + rpcCoreEnv := rpccore.Environment{ ProxyAppQuery: n.proxyApp.Query(), ProxyAppMempool: n.proxyApp.Mempool(), @@ -518,8 +518,8 @@ func (n *Node) ConfigureRPC() error { ConsensusState: n.consensusState, P2PPeers: n.sw, P2PTransport: n, + PubKey: pubKey, - PubKey: pubKey, GenDoc: n.genesisDoc, TxIndexer: n.txIndexer, BlockIndexer: n.blockIndexer, @@ -530,24 +530,24 @@ func (n *Node) ConfigureRPC() error { Logger: n.Logger.With("module", "rpc"), Config: *n.config.RPC, - }) - if err := rpccore.InitGenesisChunks(); err != nil { - return err } - - return nil + if err := rpcCoreEnv.InitGenesisChunks(); err != nil { + return nil, err + } + return &rpcCoreEnv, nil } func (n *Node) startRPC() ([]net.Listener, error) { - err := n.ConfigureRPC() + env, err := n.ConfigureRPC() if err != nil { return nil, err } listenAddrs := splitAndTrimEmpty(n.config.RPC.ListenAddress, ",", " ") + routes := env.GetRoutes() if n.config.RPC.Unsafe { - rpccore.AddUnsafeRoutes() + env.AddUnsafeRoutes(routes) } config := rpcserver.DefaultConfig() @@ -567,7 +567,7 @@ func (n *Node) startRPC() ([]net.Listener, error) { mux := http.NewServeMux() rpcLogger := n.Logger.With("module", "rpc-server") wmLogger := rpcLogger.With("protocol", "websocket") - wm := rpcserver.NewWebsocketManager(rpccore.Routes, + wm := rpcserver.NewWebsocketManager(routes, rpcserver.OnDisconnect(func(remoteAddr string) { err := n.eventBus.UnsubscribeAll(context.Background(), remoteAddr) if err != nil && err != tmpubsub.ErrSubscriptionNotFound { @@ -579,10 +579,10 @@ func (n *Node) startRPC() ([]net.Listener, error) { ) wm.SetLogger(wmLogger) mux.HandleFunc("/websocket", wm.WebsocketHandler) - rpcserver.RegisterRPCFuncs(mux, rpccore.Routes, rpcLogger) + rpcserver.RegisterRPCFuncs(mux, routes, rpcLogger) listener, err := rpcserver.Listen( listenAddr, - config, + config.MaxOpenConnections, ) if err != nil { return nil, err @@ -640,12 +640,12 @@ func (n *Node) startRPC() ([]net.Listener, error) { if config.WriteTimeout <= n.config.RPC.TimeoutBroadcastTxCommit { config.WriteTimeout = n.config.RPC.TimeoutBroadcastTxCommit + 1*time.Second } - listener, err := rpcserver.Listen(grpcListenAddr, config) + listener, err := rpcserver.Listen(grpcListenAddr, config.MaxOpenConnections) if err != nil { return nil, err } go func() { - if err := grpccore.StartGRPCServer(listener); err != nil { + if err := grpccore.StartGRPCServer(env, listener); err != nil { n.Logger.Error("Error starting gRPC server", "err", err) } }() diff --git a/node/node_test.go b/node/node_test.go index 4fdf63f3f4e..01a8e01ab95 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -53,7 +53,7 @@ func TestNodeStartStop(t *testing.T) { require.NoError(t, err) select { case <-blocksSub.Out(): - case <-blocksSub.Cancelled(): + case <-blocksSub.Canceled(): t.Fatal("blocksSub was canceled") case <-time.After(10 * time.Second): t.Fatal("timed out waiting for the node to produce a block") @@ -461,7 +461,7 @@ func TestNodeNewNodeCustomReactors(t *testing.T) { nodeKey, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), DefaultGenesisDocProviderFunc(config), - DefaultDBProvider, + cfg.DefaultDBProvider, DefaultMetricsProvider(config.Instrumentation), log.TestingLogger(), CustomReactors(map[string]p2p.Reactor{"FOO": cr, "BLOCKSYNC": customBlocksyncReactor}), diff --git a/node/setup.go b/node/setup.go index 5bada8b6f2c..d710869c7ff 100644 --- a/node/setup.go +++ b/node/setup.go @@ -7,6 +7,8 @@ import ( "fmt" "net" "strings" + + _ "net/http/pprof" //nolint: gosec // securely exposed on separate, optional port "time" dbm "github.com/tendermint/tm-db" @@ -17,6 +19,7 @@ import ( cs "github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/evidence" + "github.com/tendermint/tendermint/statesync" tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" @@ -30,13 +33,8 @@ import ( "github.com/tendermint/tendermint/proxy" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/state/indexer" - blockidxkv "github.com/tendermint/tendermint/state/indexer/block/kv" - blockidxnull "github.com/tendermint/tendermint/state/indexer/block/null" - "github.com/tendermint/tendermint/state/indexer/sink/psql" + "github.com/tendermint/tendermint/state/indexer/block" "github.com/tendermint/tendermint/state/txindex" - "github.com/tendermint/tendermint/state/txindex/kv" - "github.com/tendermint/tendermint/state/txindex/null" - "github.com/tendermint/tendermint/statesync" "github.com/tendermint/tendermint/store" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" @@ -44,24 +42,8 @@ import ( _ "github.com/lib/pq" // provide the psql db driver ) -// DBContext specifies config information for loading a new DB. -type DBContext struct { - ID string - Config *cfg.Config -} - -// 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) { - dbType := dbm.BackendType(ctx.Config.DBBackend) - return dbm.NewDB(ctx.ID, dbType, ctx.Config.DBDir()) -} - // GenesisDocProvider returns a GenesisDoc. // It allows the GenesisDoc to be pulled from sources other than the // filesystem, for instance from a distributed key-value store cluster. @@ -92,7 +74,7 @@ func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) { nodeKey, proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), DefaultGenesisDocProviderFunc(config), - DefaultDBProvider, + cfg.DefaultDBProvider, DefaultMetricsProvider(config.Instrumentation), logger, ) @@ -124,15 +106,15 @@ type blockSyncReactor interface { //------------------------------------------------------------------------------ -func initDBs(config *cfg.Config, dbProvider DBProvider) (blockStore *store.BlockStore, stateDB dbm.DB, err error) { +func initDBs(config *cfg.Config, dbProvider cfg.DBProvider) (blockStore *store.BlockStore, stateDB dbm.DB, err error) { var blockStoreDB dbm.DB - blockStoreDB, err = dbProvider(&DBContext{"blockstore", config}) + blockStoreDB, err = dbProvider(&cfg.DBContext{ID: "blockstore", Config: config}) if err != nil { return } blockStore = store.NewBlockStore(blockStoreDB) - stateDB, err = dbProvider(&DBContext{"state", config}) + stateDB, err = dbProvider(&cfg.DBContext{ID: "state", Config: config}) if err != nil { return } @@ -161,7 +143,7 @@ func createAndStartEventBus(logger log.Logger) (*types.EventBus, error) { func createAndStartIndexerService( config *cfg.Config, chainID string, - dbProvider DBProvider, + dbProvider cfg.DBProvider, eventBus *types.EventBus, logger log.Logger, ) (*txindex.IndexerService, txindex.TxIndexer, indexer.BlockIndexer, error) { @@ -169,31 +151,9 @@ func createAndStartIndexerService( txIndexer txindex.TxIndexer blockIndexer indexer.BlockIndexer ) - - switch config.TxIndex.Indexer { - case "kv": - store, err := dbProvider(&DBContext{"tx_index", config}) - if err != nil { - return nil, nil, nil, err - } - - txIndexer = kv.NewTxIndex(store) - blockIndexer = blockidxkv.New(dbm.NewPrefixDB(store, []byte("block_events"))) - - case "psql": - if config.TxIndex.PsqlConn == "" { - return nil, nil, nil, errors.New(`no psql-conn is set for the "psql" indexer`) - } - es, err := psql.NewEventSink(config.TxIndex.PsqlConn, chainID) - if err != nil { - return nil, nil, nil, fmt.Errorf("creating psql indexer: %w", err) - } - txIndexer = es.TxIndexer() - blockIndexer = es.BlockIndexer() - - default: - txIndexer = &null.TxIndex{} - blockIndexer = &blockidxnull.BlockerIndexer{} + txIndexer, blockIndexer, err := block.IndexerFromConfig(config, dbProvider, chainID) + if err != nil { + return nil, nil, nil, err } indexerService := txindex.NewIndexerService(txIndexer, blockIndexer, eventBus, false) @@ -315,10 +275,10 @@ func createMempoolAndMempoolReactor( } } -func createEvidenceReactor(config *cfg.Config, dbProvider DBProvider, +func createEvidenceReactor(config *cfg.Config, dbProvider cfg.DBProvider, stateStore sm.Store, blockStore *store.BlockStore, logger log.Logger, ) (*evidence.Reactor, *evidence.Pool, error) { - evidenceDB, err := dbProvider(&DBContext{"evidence", config}) + evidenceDB, err := dbProvider(&cfg.DBContext{ID: "evidence", Config: config}) if err != nil { return nil, nil, err } diff --git a/rpc/client/local/local.go b/rpc/client/local/local.go index ca324dee02b..31f78f6b5a7 100644 --- a/rpc/client/local/local.go +++ b/rpc/client/local/local.go @@ -41,22 +41,20 @@ type Local struct { *types.EventBus Logger log.Logger ctx *rpctypes.Context + env *core.Environment } // NewLocal configures a client that calls the Node directly. -// -// Note that given how rpc/core works with package singletons, that -// you can only have one node per process. So make sure test cases -// don't run in parallel, or try to simulate an entire network in -// one process... func New(node *nm.Node) *Local { - if err := node.ConfigureRPC(); err != nil { + env, err := node.ConfigureRPC() + if err != nil { node.Logger.Error("Error configuring RPC", "err", err) } return &Local{ EventBus: node.EventBus(), Logger: log.NewNopLogger(), ctx: &rpctypes.Context{}, + env: env, } } @@ -68,11 +66,11 @@ func (c *Local) SetLogger(l log.Logger) { } func (c *Local) Status(ctx context.Context) (*ctypes.ResultStatus, error) { - return core.Status(c.ctx) + return c.env.Status(c.ctx) } func (c *Local) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - return core.ABCIInfo(c.ctx) + return c.env.ABCIInfo(c.ctx) } func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) { @@ -84,55 +82,55 @@ func (c *Local) ABCIQueryWithOptions( path string, data bytes.HexBytes, opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - return core.ABCIQuery(c.ctx, path, data, opts.Height, opts.Prove) + return c.env.ABCIQuery(c.ctx, path, data, opts.Height, opts.Prove) } func (c *Local) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { - return core.BroadcastTxCommit(c.ctx, tx) + return c.env.BroadcastTxCommit(c.ctx, tx) } func (c *Local) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - return core.BroadcastTxAsync(c.ctx, tx) + return c.env.BroadcastTxAsync(c.ctx, tx) } func (c *Local) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - return core.BroadcastTxSync(c.ctx, tx) + return c.env.BroadcastTxSync(c.ctx, tx) } func (c *Local) UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) { - return core.UnconfirmedTxs(c.ctx, limit) + return c.env.UnconfirmedTxs(c.ctx, limit) } func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) { - return core.NumUnconfirmedTxs(c.ctx) + return c.env.NumUnconfirmedTxs(c.ctx) } func (c *Local) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { - return core.CheckTx(c.ctx, tx) + return c.env.CheckTx(c.ctx, tx) } func (c *Local) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) { - return core.NetInfo(c.ctx) + return c.env.NetInfo(c.ctx) } func (c *Local) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) { - return core.DumpConsensusState(c.ctx) + return c.env.DumpConsensusState(c.ctx) } func (c *Local) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) { - return core.ConsensusState(c.ctx) + return c.env.GetConsensusState(c.ctx) } func (c *Local) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) { - return core.ConsensusParams(c.ctx, height) + return c.env.ConsensusParams(c.ctx, height) } func (c *Local) Health(ctx context.Context) (*ctypes.ResultHealth, error) { - return core.Health(c.ctx) + return c.env.Health(c.ctx) } func (c *Local) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) { - return core.UnsafeDialSeeds(c.ctx, seeds) + return c.env.UnsafeDialSeeds(c.ctx, seeds) } func (c *Local) DialPeers( @@ -142,51 +140,51 @@ func (c *Local) DialPeers( unconditional, private bool, ) (*ctypes.ResultDialPeers, error) { - return core.UnsafeDialPeers(c.ctx, peers, persistent, unconditional, private) + return c.env.UnsafeDialPeers(c.ctx, peers, persistent, unconditional, private) } func (c *Local) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { - return core.BlockchainInfo(c.ctx, minHeight, maxHeight) + return c.env.BlockchainInfo(c.ctx, minHeight, maxHeight) } func (c *Local) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) { - return core.Genesis(c.ctx) + return c.env.Genesis(c.ctx) } func (c *Local) GenesisChunked(ctx context.Context, id uint) (*ctypes.ResultGenesisChunk, error) { - return core.GenesisChunked(c.ctx, id) + return c.env.GenesisChunked(c.ctx, id) } func (c *Local) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) { - return core.Block(c.ctx, height) + return c.env.Block(c.ctx, height) } func (c *Local) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) { - return core.BlockByHash(c.ctx, hash) + return c.env.BlockByHash(c.ctx, hash) } func (c *Local) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) { - return core.BlockResults(c.ctx, height) + return c.env.BlockResults(c.ctx, height) } func (c *Local) Header(ctx context.Context, height *int64) (*ctypes.ResultHeader, error) { - return core.Header(c.ctx, height) + return c.env.Header(c.ctx, height) } func (c *Local) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*ctypes.ResultHeader, error) { - return core.HeaderByHash(c.ctx, hash) + return c.env.HeaderByHash(c.ctx, hash) } func (c *Local) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) { - return core.Commit(c.ctx, height) + return c.env.Commit(c.ctx, height) } func (c *Local) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) { - return core.Validators(c.ctx, height, page, perPage) + return c.env.Validators(c.ctx, height, page, perPage) } func (c *Local) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) { - return core.Tx(c.ctx, hash, prove) + return c.env.Tx(c.ctx, hash, prove) } func (c *Local) TxSearch( @@ -197,7 +195,7 @@ func (c *Local) TxSearch( perPage *int, orderBy string, ) (*ctypes.ResultTxSearch, error) { - return core.TxSearch(c.ctx, query, prove, page, perPage, orderBy) + return c.env.TxSearch(c.ctx, query, prove, page, perPage, orderBy) } func (c *Local) BlockSearch( @@ -206,11 +204,11 @@ func (c *Local) BlockSearch( page, perPage *int, orderBy string, ) (*ctypes.ResultBlockSearch, error) { - return core.BlockSearch(c.ctx, query, page, perPage, orderBy) + return c.env.BlockSearch(c.ctx, query, page, perPage, orderBy) } func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) { - return core.BroadcastEvidence(c.ctx, ev) + return c.env.BroadcastEvidence(c.ctx, ev) } func (c *Local) Subscribe( @@ -262,7 +260,7 @@ func (c *Local) eventsRoutine( c.Logger.Error("wanted to publish ResultEvent, but out channel is full", "result", result, "query", result.Query) } } - case <-sub.Cancelled(): + case <-sub.Canceled(): if sub.Err() == tmpubsub.ErrUnsubscribed { return } diff --git a/rpc/client/mock/client.go b/rpc/client/mock/client.go index ec3a358cdd6..4be251ce5b9 100644 --- a/rpc/client/mock/client.go +++ b/rpc/client/mock/client.go @@ -28,10 +28,6 @@ import ( ) // Client wraps arbitrary implementations of the various interfaces. -// -// We provide a few choices to mock out each one in this package. -// Nothing hidden here, so no New function, just construct it from -// some parts, and swap them out them during the tests. type Client struct { client.ABCIClient client.SignClient @@ -41,6 +37,14 @@ type Client struct { client.EvidenceClient client.MempoolClient service.Service + + env *core.Environment +} + +func New() Client { + return Client{ + env: &core.Environment{}, + } } var _ client.Client = Client{} @@ -80,11 +84,11 @@ func (c Call) GetResponse(args interface{}) (interface{}, error) { } func (c Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { - return core.Status(&rpctypes.Context{}) + return c.env.Status(&rpctypes.Context{}) } func (c Client) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) { - return core.ABCIInfo(&rpctypes.Context{}) + return c.env.ABCIInfo(&rpctypes.Context{}) } func (c Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) { @@ -96,47 +100,47 @@ func (c Client) ABCIQueryWithOptions( path string, data bytes.HexBytes, opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) { - return core.ABCIQuery(&rpctypes.Context{}, path, data, opts.Height, opts.Prove) + return c.env.ABCIQuery(&rpctypes.Context{}, path, data, opts.Height, opts.Prove) } func (c Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { - return core.BroadcastTxCommit(&rpctypes.Context{}, tx) + return c.env.BroadcastTxCommit(&rpctypes.Context{}, tx) } func (c Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - return core.BroadcastTxAsync(&rpctypes.Context{}, tx) + return c.env.BroadcastTxAsync(&rpctypes.Context{}, tx) } func (c Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { - return core.BroadcastTxSync(&rpctypes.Context{}, tx) + return c.env.BroadcastTxSync(&rpctypes.Context{}, tx) } func (c Client) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { - return core.CheckTx(&rpctypes.Context{}, tx) + return c.env.CheckTx(&rpctypes.Context{}, tx) } func (c Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) { - return core.NetInfo(&rpctypes.Context{}) + return c.env.NetInfo(&rpctypes.Context{}) } func (c Client) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) { - return core.ConsensusState(&rpctypes.Context{}) + return c.env.GetConsensusState(&rpctypes.Context{}) } func (c Client) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) { - return core.DumpConsensusState(&rpctypes.Context{}) + return c.env.DumpConsensusState(&rpctypes.Context{}) } func (c Client) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) { - return core.ConsensusParams(&rpctypes.Context{}, height) + return c.env.ConsensusParams(&rpctypes.Context{}, height) } func (c Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) { - return core.Health(&rpctypes.Context{}) + return c.env.Health(&rpctypes.Context{}) } func (c Client) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) { - return core.UnsafeDialSeeds(&rpctypes.Context{}, seeds) + return c.env.UnsafeDialSeeds(&rpctypes.Context{}, seeds) } func (c Client) DialPeers( @@ -146,33 +150,33 @@ func (c Client) DialPeers( unconditional, private bool, ) (*ctypes.ResultDialPeers, error) { - return core.UnsafeDialPeers(&rpctypes.Context{}, peers, persistent, unconditional, private) + return c.env.UnsafeDialPeers(&rpctypes.Context{}, peers, persistent, unconditional, private) } func (c Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { - return core.BlockchainInfo(&rpctypes.Context{}, minHeight, maxHeight) + return c.env.BlockchainInfo(&rpctypes.Context{}, minHeight, maxHeight) } func (c Client) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) { - return core.Genesis(&rpctypes.Context{}) + return c.env.Genesis(&rpctypes.Context{}) } func (c Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) { - return core.Block(&rpctypes.Context{}, height) + return c.env.Block(&rpctypes.Context{}, height) } func (c Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) { - return core.BlockByHash(&rpctypes.Context{}, hash) + return c.env.BlockByHash(&rpctypes.Context{}, hash) } func (c Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) { - return core.Commit(&rpctypes.Context{}, height) + return c.env.Commit(&rpctypes.Context{}, height) } func (c Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) { - return core.Validators(&rpctypes.Context{}, height, page, perPage) + return c.env.Validators(&rpctypes.Context{}, height, page, perPage) } func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) { - return core.BroadcastEvidence(&rpctypes.Context{}, ev) + return c.env.BroadcastEvidence(&rpctypes.Context{}, ev) } diff --git a/rpc/core/abci.go b/rpc/core/abci.go index d1f7193be96..4df8cba3f96 100644 --- a/rpc/core/abci.go +++ b/rpc/core/abci.go @@ -9,8 +9,8 @@ import ( ) // ABCIQuery queries the application for some information. -// More: https://docs.tendermint.com/main/rpc/#/ABCI/abci_query -func ABCIQuery( +// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_query +func (env *Environment) ABCIQuery( ctx *rpctypes.Context, path string, data bytes.HexBytes, @@ -31,8 +31,8 @@ func ABCIQuery( } // ABCIInfo gets some info about the application. -// More: https://docs.tendermint.com/main/rpc/#/ABCI/abci_info -func ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) { +// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info +func (env *Environment) ABCIInfo(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) { resInfo, err := env.ProxyAppQuery.InfoSync(proxy.RequestInfo) if err != nil { return nil, err diff --git a/rpc/core/blocks.go b/rpc/core/blocks.go index 5d277218f6d..360e59e1222 100644 --- a/rpc/core/blocks.go +++ b/rpc/core/blocks.go @@ -15,10 +15,19 @@ import ( ) // BlockchainInfo gets block headers for minHeight <= height <= maxHeight. -// Block headers are returned in descending order (highest first). -// More: https://docs.tendermint.com/main/rpc/#/Info/blockchain -func BlockchainInfo(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { - // maximum 20 block metas +// +// If maxHeight does not yet exist, blocks up to the current height will be +// returned. If minHeight does not exist (due to pruning), earliest existing +// height will be used. +// +// At most 20 items will be returned. Block headers are returned in descending +// order (highest first). +// +// More: https://docs.tendermint.com/master/rpc/#/Info/blockchain +func (env *Environment) BlockchainInfo( + ctx *rpctypes.Context, + minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { + const limit int64 = 20 var err error minHeight, maxHeight, err = filterMinMax( @@ -79,8 +88,8 @@ func filterMinMax(base, height, min, max, limit int64) (int64, int64, error) { // Header gets block header at a given height. // If no height is provided, it will fetch the latest header. // More: https://docs.tendermint.com/master/rpc/#/Info/header -func Header(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultHeader, error) { - height, err := getHeight(env.BlockStore.Height(), heightPtr) +func (env *Environment) Header(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultHeader, error) { + height, err := env.getHeight(env.BlockStore.Height(), heightPtr) if err != nil { return nil, err } @@ -95,7 +104,7 @@ func Header(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultHeader, erro // HeaderByHash gets header by hash. // More: https://docs.tendermint.com/master/rpc/#/Info/header_by_hash -func HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*ctypes.ResultHeader, error) { +func (env *Environment) HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*ctypes.ResultHeader, error) { // N.B. The hash parameter is HexBytes so that the reflective parameter // decoding logic in the HTTP service will correctly translate from JSON. // See https://github.com/tendermint/tendermint/issues/6802 for context. @@ -110,9 +119,9 @@ func HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*ctypes.ResultHea // Block gets block at a given height. // If no height is provided, it will fetch the latest block. -// More: https://docs.tendermint.com/main/rpc/#/Info/block -func Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error) { - height, err := getHeight(env.BlockStore.Height(), heightPtr) +// More: https://docs.tendermint.com/master/rpc/#/Info/block +func (env *Environment) Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error) { + height, err := env.getHeight(env.BlockStore.Height(), heightPtr) if err != nil { return nil, err } @@ -126,8 +135,8 @@ func Block(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlock, error) } // BlockByHash gets block by hash. -// More: https://docs.tendermint.com/main/rpc/#/Info/block_by_hash -func BlockByHash(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/block_by_hash +func (env *Environment) BlockByHash(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error) { block := env.BlockStore.LoadBlockByHash(hash) if block == nil { return &ctypes.ResultBlock{BlockID: types.BlockID{}, Block: nil}, nil @@ -139,9 +148,9 @@ 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/main/rpc/#/Info/commit -func Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, error) { - height, err := getHeight(env.BlockStore.Height(), heightPtr) +// More: https://docs.tendermint.com/master/rpc/#/Info/commit +func (env *Environment) Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, error) { + height, err := env.getHeight(env.BlockStore.Height(), heightPtr) if err != nil { return nil, err } @@ -170,9 +179,9 @@ func Commit(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultCommit, erro // 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/main/rpc/#/Info/block_results -func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockResults, error) { - height, err := getHeight(env.BlockStore.Height(), heightPtr) +// More: https://docs.tendermint.com/master/rpc/#/Info/block_results +func (env *Environment) BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockResults, error) { + height, err := env.getHeight(env.BlockStore.Height(), heightPtr) if err != nil { return nil, err } @@ -194,7 +203,7 @@ func BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultBlockR // BlockSearch searches for a paginated set of blocks matching BeginBlock and // EndBlock event search criteria. -func BlockSearch( +func (env *Environment) BlockSearch( ctx *rpctypes.Context, query string, pagePtr, perPagePtr *int, @@ -230,7 +239,7 @@ func BlockSearch( // paginate results totalCount := len(results) - perPage := validatePerPage(perPagePtr) + perPage := env.validatePerPage(perPagePtr) page, err := validatePage(pagePtr, perPage, totalCount) if err != nil { diff --git a/rpc/core/blocks_test.go b/rpc/core/blocks_test.go index 71311076ce0..5ea778fbda3 100644 --- a/rpc/core/blocks_test.go +++ b/rpc/core/blocks_test.go @@ -80,7 +80,7 @@ func TestBlockResults(t *testing.T) { BeginBlock: &abci.ResponseBeginBlock{}, } - env = &Environment{} + env := &Environment{} env.StateStore = sm.NewStore(dbm.NewMemDB(), sm.StoreOptions{ DiscardABCIResponses: false, }) @@ -110,7 +110,7 @@ func TestBlockResults(t *testing.T) { } for _, tc := range testCases { - res, err := BlockResults(&rpctypes.Context{}, &tc.height) + res, err := env.BlockResults(&rpctypes.Context{}, &tc.height) if tc.wantErr { assert.Error(t, err) } else { diff --git a/rpc/core/consensus.go b/rpc/core/consensus.go index 5237ddfc6e3..f51b44f22aa 100644 --- a/rpc/core/consensus.go +++ b/rpc/core/consensus.go @@ -14,10 +14,14 @@ 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/main/rpc/#/Info/validators -func Validators(ctx *rpctypes.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*ctypes.ResultValidators, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/validators +func (env *Environment) 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) + height, err := env.getHeight(env.latestUncommittedHeight(), heightPtr) if err != nil { return nil, err } @@ -28,7 +32,7 @@ func Validators(ctx *rpctypes.Context, heightPtr *int64, pagePtr, perPagePtr *in } totalCount := len(validators.Validators) - perPage := validatePerPage(perPagePtr) + perPage := env.validatePerPage(perPagePtr) page, err := validatePage(pagePtr, perPage, totalCount) if err != nil { return nil, err @@ -47,8 +51,8 @@ func Validators(ctx *rpctypes.Context, heightPtr *int64, pagePtr, perPagePtr *in // DumpConsensusState dumps consensus state. // UNSTABLE -// More: https://docs.tendermint.com/main/rpc/#/Info/dump_consensus_state -func DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/dump_consensus_state +func (env *Environment) DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState, error) { // Get Peer consensus states. peers := env.P2PPeers.Peers().List() peerStates := make([]ctypes.PeerStateInfo, len(peers)) @@ -80,8 +84,8 @@ func DumpConsensusState(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState // ConsensusState returns a concise summary of the consensus state. // UNSTABLE -// More: https://docs.tendermint.com/main/rpc/#/Info/consensus_state -func ConsensusState(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_state +func (env *Environment) GetConsensusState(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error) { // Get self round state. bz, err := env.ConsensusState.GetRoundStateSimpleJSON() return &ctypes.ResultConsensusState{RoundState: bz}, err @@ -89,11 +93,14 @@ 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/main/rpc/#/Info/consensus_params -func ConsensusParams(ctx *rpctypes.Context, heightPtr *int64) (*ctypes.ResultConsensusParams, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_params +func (env *Environment) ConsensusParams( + ctx *rpctypes.Context, + heightPtr *int64) (*ctypes.ResultConsensusParams, error) { + // The latest consensus params that we know is the consensus params after the // last block. - height, err := getHeight(latestUncommittedHeight(), heightPtr) + height, err := env.getHeight(env.latestUncommittedHeight(), heightPtr) if err != nil { return nil, err } diff --git a/rpc/core/dev.go b/rpc/core/dev.go index b70f5f1e12d..0e365cdcc16 100644 --- a/rpc/core/dev.go +++ b/rpc/core/dev.go @@ -6,7 +6,7 @@ import ( ) // UnsafeFlushMempool removes all transactions from the mempool. -func UnsafeFlushMempool(ctx *rpctypes.Context) (*ctypes.ResultUnsafeFlushMempool, error) { +func (env *Environment) UnsafeFlushMempool(ctx *rpctypes.Context) (*ctypes.ResultUnsafeFlushMempool, error) { env.Mempool.Flush() return &ctypes.ResultUnsafeFlushMempool{}, nil } diff --git a/rpc/core/env.go b/rpc/core/env.go index e9231993769..17cf45ff285 100644 --- a/rpc/core/env.go +++ b/rpc/core/env.go @@ -6,7 +6,6 @@ import ( "time" cfg "github.com/tendermint/tendermint/config" - "github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/crypto" tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/libs/log" @@ -33,17 +32,6 @@ const ( genesisChunkSize = 16 * 1024 * 1024 // 16 ) -var ( - // set by Node - env *Environment -) - -// SetEnvironment sets up the given Environment. -// It will race if multiple Node call SetEnvironment. -func SetEnvironment(e *Environment) { - env = e -} - //---------------------------------------------- // These interfaces are used by RPC and must be thread safe @@ -69,6 +57,10 @@ type peers interface { Peers() p2p.IPeerSet } +type consensusReactor interface { + WaitSync() bool +} + // ---------------------------------------------- // Environment contains objects and interfaces used by the RPC. It is expected // to be setup once during startup. @@ -78,21 +70,21 @@ type Environment struct { ProxyAppMempool proxy.AppConnMempool // interfaces defined in types and above - StateStore sm.Store - BlockStore sm.BlockStore - EvidencePool sm.EvidencePool - ConsensusState Consensus - P2PPeers peers - P2PTransport transport + StateStore sm.Store + BlockStore sm.BlockStore + EvidencePool sm.EvidencePool + ConsensusState Consensus + ConsensusReactor consensusReactor + P2PPeers peers + P2PTransport transport // objects - PubKey crypto.PubKey - GenDoc *types.GenesisDoc // cache the genesis structure - TxIndexer txindex.TxIndexer - BlockIndexer indexer.BlockIndexer - ConsensusReactor *consensus.Reactor - EventBus *types.EventBus // thread safe - Mempool mempl.Mempool + PubKey crypto.PubKey + GenDoc *types.GenesisDoc // cache the genesis structure + TxIndexer txindex.TxIndexer + BlockIndexer indexer.BlockIndexer + EventBus *types.EventBus // thread safe + Mempool mempl.Mempool Logger log.Logger @@ -125,7 +117,7 @@ func validatePage(pagePtr *int, perPage, totalCount int) (int, error) { return page, nil } -func validatePerPage(perPagePtr *int) int { +func (env *Environment) validatePerPage(perPagePtr *int) int { if perPagePtr == nil { // no per_page parameter return defaultPerPage } @@ -141,7 +133,7 @@ func validatePerPage(perPagePtr *int) int { // InitGenesisChunks configures the environment and should be called on service // startup. -func InitGenesisChunks() error { +func (env *Environment) InitGenesisChunks() error { if env.genChunks != nil { return nil } @@ -178,7 +170,7 @@ func validateSkipCount(page, perPage int) int { } // latestHeight can be either latest committed or uncommitted (+1) height. -func getHeight(latestHeight int64, heightPtr *int64) (int64, error) { +func (env *Environment) getHeight(latestHeight int64, heightPtr *int64) (int64, error) { if heightPtr != nil { height := *heightPtr if height <= 0 { @@ -198,7 +190,7 @@ func getHeight(latestHeight int64, heightPtr *int64) (int64, error) { return latestHeight, nil } -func latestUncommittedHeight() int64 { +func (env *Environment) latestUncommittedHeight() int64 { nodeIsSyncing := env.ConsensusReactor.WaitSync() if nodeIsSyncing { return env.BlockStore.Height() diff --git a/rpc/core/env_test.go b/rpc/core/env_test.go index b44c21a4cb0..dc64db1d6ae 100644 --- a/rpc/core/env_test.go +++ b/rpc/core/env_test.go @@ -70,13 +70,13 @@ func TestPaginationPerPage(t *testing.T) { {5, maxPerPage, maxPerPage}, {5, maxPerPage + 1, maxPerPage}, } - + env := &Environment{} for _, c := range cases { - p := validatePerPage(&c.perPage) + p := env.validatePerPage(&c.perPage) assert.Equal(t, c.newPerPage, p, fmt.Sprintf("%v", c)) } // nil case - p := validatePerPage(nil) + p := env.validatePerPage(nil) assert.Equal(t, defaultPerPage, p) } diff --git a/rpc/core/events.go b/rpc/core/events.go index e8d9773631d..63ed90fa772 100644 --- a/rpc/core/events.go +++ b/rpc/core/events.go @@ -19,8 +19,8 @@ const ( ) // Subscribe for events via WebSocket. -// More: https://docs.tendermint.com/main/rpc/#/Websocket/subscribe -func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, error) { +// More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe +func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, error) { addr := ctx.RemoteAddr() if env.EventBus.NumClients() >= env.Config.MaxSubscriptionClients { @@ -76,7 +76,7 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er return } } - case <-sub.Cancelled(): + case <-sub.Canceled(): if sub.Err() != tmpubsub.ErrUnsubscribed { var reason string if sub.Err() == nil { @@ -102,8 +102,8 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er } // Unsubscribe from events via WebSocket. -// More: https://docs.tendermint.com/main/rpc/#/Websocket/unsubscribe -func Unsubscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultUnsubscribe, error) { +// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe +func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultUnsubscribe, error) { addr := ctx.RemoteAddr() env.Logger.Info("Unsubscribe from query", "remote", addr, "query", query) q, err := tmquery.New(query) @@ -118,8 +118,8 @@ func Unsubscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultUnsubscribe } // UnsubscribeAll from all events via WebSocket. -// More: https://docs.tendermint.com/main/rpc/#/Websocket/unsubscribe_all -func UnsubscribeAll(ctx *rpctypes.Context) (*ctypes.ResultUnsubscribe, error) { +// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe_all +func (env *Environment) UnsubscribeAll(ctx *rpctypes.Context) (*ctypes.ResultUnsubscribe, error) { addr := ctx.RemoteAddr() env.Logger.Info("Unsubscribe from all", "remote", addr) err := env.EventBus.UnsubscribeAll(context.Background(), addr) diff --git a/rpc/core/evidence.go b/rpc/core/evidence.go index d1b3753e7ee..0c5b5b725de 100644 --- a/rpc/core/evidence.go +++ b/rpc/core/evidence.go @@ -10,8 +10,11 @@ import ( ) // BroadcastEvidence broadcasts evidence of the misbehavior. -// More: https://docs.tendermint.com/main/rpc/#/Info/broadcast_evidence -func BroadcastEvidence(ctx *rpctypes.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) { +// More: https://docs.tendermint.com/master/rpc/#/Evidence/broadcast_evidence +func (env *Environment) 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 aaf1ceecf8f..855911d83de 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/main/rpc/#/Info/health -func Health(ctx *rpctypes.Context) (*ctypes.ResultHealth, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/health +func (env *Environment) Health(ctx *rpctypes.Context) (*ctypes.ResultHealth, error) { return &ctypes.ResultHealth{}, nil } diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 69b87dd5cbe..c0f7cd8dc06 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -18,8 +18,8 @@ import ( // BroadcastTxAsync returns right away, with no response. Does not wait for // CheckTx nor DeliverTx results. -// More: https://docs.tendermint.com/main/rpc/#/Tx/broadcast_tx_async -func BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { +// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async +func (env *Environment) BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { err := env.Mempool.CheckTx(tx, nil, mempl.TxInfo{}) if err != nil { @@ -30,8 +30,8 @@ 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/main/rpc/#/Tx/broadcast_tx_sync -func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { +// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync +func (env *Environment) BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) { resCh := make(chan *abci.Response, 1) err := env.Mempool.CheckTx(tx, func(res *abci.Response) { select { @@ -60,8 +60,8 @@ func BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcas } // BroadcastTxCommit returns with the responses from CheckTx and DeliverTx. -// More: https://docs.tendermint.com/main/rpc/#/Tx/broadcast_tx_commit -func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { +// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_commit +func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) { subscriber := ctx.RemoteAddr() if env.EventBus.NumClients() >= env.Config.MaxSubscriptionClients { @@ -121,7 +121,7 @@ func BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadc Hash: tx.Hash(), Height: deliverTxRes.Height, }, nil - case <-deliverTxSub.Cancelled(): + case <-deliverTxSub.Canceled(): var reason string if deliverTxSub.Err() == nil { reason = "Tendermint exited" @@ -149,10 +149,10 @@ 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/main/rpc/#/Info/unconfirmed_txs -func UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfirmedTxs, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/unconfirmed_txs +func (env *Environment) UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfirmedTxs, error) { // reuse per_page validator - limit := validatePerPage(limitPtr) + limit := env.validatePerPage(limitPtr) txs := env.Mempool.ReapMaxTxs(limit) return &ctypes.ResultUnconfirmedTxs{ @@ -163,8 +163,8 @@ func UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*ctypes.ResultUnconfi } // NumUnconfirmedTxs gets number of unconfirmed transactions. -// More: https://docs.tendermint.com/main/rpc/#/Info/num_unconfirmed_txs -func NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/num_unconfirmed_txs +func (env *Environment) NumUnconfirmedTxs(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, error) { return &ctypes.ResultUnconfirmedTxs{ Count: env.Mempool.Size(), Total: env.Mempool.Size(), @@ -173,8 +173,8 @@ 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/main/rpc/#/Tx/check_tx -func CheckTx(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { +// More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx +func (env *Environment) CheckTx(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) { res, err := env.ProxyAppMempool.CheckTxSync(abci.RequestCheckTx{Tx: tx}) if err != nil { return nil, err diff --git a/rpc/core/net.go b/rpc/core/net.go index 27378bfed61..688667203f4 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -11,8 +11,8 @@ import ( ) // NetInfo returns network info. -// More: https://docs.tendermint.com/main/rpc/#/Info/net_info -func NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/net_info +func (env *Environment) NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) { peersList := env.P2PPeers.Peers().List() peers := make([]ctypes.Peer, 0, len(peersList)) for _, peer := range peersList { @@ -39,7 +39,7 @@ func NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) { } // UnsafeDialSeeds dials the given seeds (comma-separated id@IP:PORT). -func UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialSeeds, error) { +func (env *Environment) UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialSeeds, error) { if len(seeds) == 0 { return &ctypes.ResultDialSeeds{}, errors.New("no seeds provided") } @@ -52,8 +52,11 @@ func UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialS // UnsafeDialPeers dials the given peers (comma-separated id@IP:PORT), // optionally making them persistent. -func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent, unconditional, private bool) ( - *ctypes.ResultDialPeers, error) { +func (env *Environment) UnsafeDialPeers( + ctx *rpctypes.Context, + peers []string, + persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) { + if len(peers) == 0 { return &ctypes.ResultDialPeers{}, errors.New("no peers provided") } @@ -92,8 +95,8 @@ func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent, uncondit } // Genesis returns genesis file. -// More: https://docs.tendermint.com/main/rpc/#/Info/genesis -func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/genesis +func (env *Environment) Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) { if len(env.genChunks) > 1 { return nil, errors.New("genesis response is large, please use the genesis_chunked API instead") } @@ -101,7 +104,7 @@ func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) { return &ctypes.ResultGenesis{Genesis: env.GenDoc}, nil } -func GenesisChunked(ctx *rpctypes.Context, chunk uint) (*ctypes.ResultGenesisChunk, error) { +func (env *Environment) GenesisChunked(ctx *rpctypes.Context, chunk uint) (*ctypes.ResultGenesisChunk, error) { if env.genChunks == nil { return nil, fmt.Errorf("service configuration error, genesis chunks are not initialized") } diff --git a/rpc/core/net_test.go b/rpc/core/net_test.go index c971776f3e8..8612e0c500b 100644 --- a/rpc/core/net_test.go +++ b/rpc/core/net_test.go @@ -23,6 +23,7 @@ func TestUnsafeDialSeeds(t *testing.T) { } }) + env := &Environment{} env.Logger = log.TestingLogger() env.P2PPeers = sw @@ -36,7 +37,7 @@ func TestUnsafeDialSeeds(t *testing.T) { } for _, tc := range testCases { - res, err := UnsafeDialSeeds(&rpctypes.Context{}, tc.seeds) + res, err := env.UnsafeDialSeeds(&rpctypes.Context{}, tc.seeds) if tc.isErr { assert.Error(t, err) } else { @@ -62,6 +63,7 @@ func TestUnsafeDialPeers(t *testing.T) { } }) + env := &Environment{} env.Logger = log.TestingLogger() env.P2PPeers = sw @@ -76,7 +78,7 @@ func TestUnsafeDialPeers(t *testing.T) { } for _, tc := range testCases { - res, err := UnsafeDialPeers(&rpctypes.Context{}, tc.peers, tc.persistence, tc.unconditional, tc.private) + res, err := env.UnsafeDialPeers(&rpctypes.Context{}, tc.peers, tc.persistence, tc.unconditional, tc.private) if tc.isErr { assert.Error(t, err) } else { diff --git a/rpc/core/routes.go b/rpc/core/routes.go index cd658889f3b..508bfa016af 100644 --- a/rpc/core/routes.go +++ b/rpc/core/routes.go @@ -6,54 +6,58 @@ import ( // TODO: better system than "unsafe" prefix +type RoutesMap map[string]*rpc.RPCFunc + // Routes is a map of available routes. -var Routes = map[string]*rpc.RPCFunc{ - // subscribe/unsubscribe are reserved for websocket events. - "subscribe": rpc.NewWSRPCFunc(Subscribe, "query"), - "unsubscribe": rpc.NewWSRPCFunc(Unsubscribe, "query"), - "unsubscribe_all": rpc.NewWSRPCFunc(UnsubscribeAll, ""), - - // info API - "health": rpc.NewRPCFunc(Health, ""), - "status": rpc.NewRPCFunc(Status, ""), - "net_info": rpc.NewRPCFunc(NetInfo, ""), - "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")), - "header": rpc.NewRPCFunc(Header, "height", rpc.Cacheable("height")), - "header_by_hash": rpc.NewRPCFunc(HeaderByHash, "hash", rpc.Cacheable()), - "check_tx": rpc.NewRPCFunc(CheckTx, "tx"), - "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", rpc.Cacheable("height")), - "dump_consensus_state": rpc.NewRPCFunc(DumpConsensusState, ""), - "consensus_state": rpc.NewRPCFunc(ConsensusState, ""), - "consensus_params": rpc.NewRPCFunc(ConsensusParams, "height", rpc.Cacheable("height")), - "unconfirmed_txs": rpc.NewRPCFunc(UnconfirmedTxs, "limit"), - "num_unconfirmed_txs": rpc.NewRPCFunc(NumUnconfirmedTxs, ""), - - // tx broadcast API - "broadcast_tx_commit": rpc.NewRPCFunc(BroadcastTxCommit, "tx"), - "broadcast_tx_sync": rpc.NewRPCFunc(BroadcastTxSync, "tx"), - "broadcast_tx_async": rpc.NewRPCFunc(BroadcastTxAsync, "tx"), - - // abci API - "abci_query": rpc.NewRPCFunc(ABCIQuery, "path,data,height,prove"), - "abci_info": rpc.NewRPCFunc(ABCIInfo, "", rpc.Cacheable()), - - // evidence API - "broadcast_evidence": rpc.NewRPCFunc(BroadcastEvidence, "evidence"), +func (env *Environment) GetRoutes() RoutesMap { + return RoutesMap{ + // subscribe/unsubscribe are reserved for websocket events. + "subscribe": rpc.NewWSRPCFunc(env.Subscribe, "query"), + "unsubscribe": rpc.NewWSRPCFunc(env.Unsubscribe, "query"), + "unsubscribe_all": rpc.NewWSRPCFunc(env.UnsubscribeAll, ""), + + // info AP + "health": rpc.NewRPCFunc(env.Health, ""), + "status": rpc.NewRPCFunc(env.Status, ""), + "net_info": rpc.NewRPCFunc(env.NetInfo, ""), + "blockchain": rpc.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight", rpc.Cacheable()), + "genesis": rpc.NewRPCFunc(env.Genesis, "", rpc.Cacheable()), + "genesis_chunked": rpc.NewRPCFunc(env.GenesisChunked, "chunk", rpc.Cacheable()), + "block": rpc.NewRPCFunc(env.Block, "height", rpc.Cacheable("height")), + "block_by_hash": rpc.NewRPCFunc(env.BlockByHash, "hash", rpc.Cacheable()), + "block_results": rpc.NewRPCFunc(env.BlockResults, "height", rpc.Cacheable("height")), + "commit": rpc.NewRPCFunc(env.Commit, "height", rpc.Cacheable("height")), + "header": rpc.NewRPCFunc(env.Header, "height", rpc.Cacheable("height")), + "header_by_hash": rpc.NewRPCFunc(env.HeaderByHash, "hash", rpc.Cacheable()), + "check_tx": rpc.NewRPCFunc(env.CheckTx, "tx"), + "tx": rpc.NewRPCFunc(env.Tx, "hash,prove", rpc.Cacheable()), + "tx_search": rpc.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by"), + "block_search": rpc.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by"), + "validators": rpc.NewRPCFunc(env.Validators, "height,page,per_page", rpc.Cacheable("height")), + "dump_consensus_state": rpc.NewRPCFunc(env.DumpConsensusState, ""), + "consensus_state": rpc.NewRPCFunc(env.GetConsensusState, ""), + "consensus_params": rpc.NewRPCFunc(env.ConsensusParams, "height", rpc.Cacheable("height")), + "unconfirmed_txs": rpc.NewRPCFunc(env.UnconfirmedTxs, "limit"), + "num_unconfirmed_txs": rpc.NewRPCFunc(env.NumUnconfirmedTxs, ""), + + // tx broadcast API + "broadcast_tx_commit": rpc.NewRPCFunc(env.BroadcastTxCommit, "tx"), + "broadcast_tx_sync": rpc.NewRPCFunc(env.BroadcastTxSync, "tx"), + "broadcast_tx_async": rpc.NewRPCFunc(env.BroadcastTxAsync, "tx"), + + // abci API + "abci_query": rpc.NewRPCFunc(env.ABCIQuery, "path,data,height,prove"), + "abci_info": rpc.NewRPCFunc(env.ABCIInfo, "", rpc.Cacheable()), + + // evidence API + "broadcast_evidence": rpc.NewRPCFunc(env.BroadcastEvidence, "evidence"), + } } // AddUnsafeRoutes adds unsafe routes. -func AddUnsafeRoutes() { +func (env *Environment) AddUnsafeRoutes(routes RoutesMap) { // control API - Routes["dial_seeds"] = rpc.NewRPCFunc(UnsafeDialSeeds, "seeds") - Routes["dial_peers"] = rpc.NewRPCFunc(UnsafeDialPeers, "peers,persistent,unconditional,private") - Routes["unsafe_flush_mempool"] = rpc.NewRPCFunc(UnsafeFlushMempool, "") + routes["dial_seeds"] = rpc.NewRPCFunc(env.UnsafeDialSeeds, "seeds") + routes["dial_peers"] = rpc.NewRPCFunc(env.UnsafeDialPeers, "peers,persistent,unconditional,private") + routes["unsafe_flush_mempool"] = rpc.NewRPCFunc(env.UnsafeFlushMempool, "") } diff --git a/rpc/core/status.go b/rpc/core/status.go index a2a70d95de4..2fd9bfe49bf 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -12,8 +12,8 @@ import ( // Status returns Tendermint status including node info, pubkey, latest block // hash, app hash, block height and time. -// More: https://docs.tendermint.com/main/rpc/#/Info/status -func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { +// More: https://docs.tendermint.com/master/rpc/#/Info/status +func (env *Environment) Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { var ( earliestBlockHeight int64 earliestBlockHash tmbytes.HexBytes @@ -47,7 +47,7 @@ func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { // Return the very last voting power, not the voting power of this validator // during the last block. var votingPower int64 - if val := validatorAtHeight(latestUncommittedHeight()); val != nil { + if val := env.validatorAtHeight(env.latestUncommittedHeight()); val != nil { votingPower = val.VotingPower } @@ -74,12 +74,12 @@ func Status(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) { return result, nil } -func validatorAtHeight(h int64) *types.Validator { - vals, err := env.StateStore.LoadValidators(h) +func (env *Environment) validatorAtHeight(h int64) *types.Validator { + valsWithH, err := env.StateStore.LoadValidators(h) if err != nil { return nil } privValAddress := env.PubKey.Address() - _, val := vals.GetByAddress(privValAddress) + _, val := valsWithH.GetByAddress(privValAddress) return val } diff --git a/rpc/core/tx.go b/rpc/core/tx.go index aa14cab1325..d7518752fad 100644 --- a/rpc/core/tx.go +++ b/rpc/core/tx.go @@ -17,7 +17,7 @@ import ( // transaction is in the mempool, invalidated, or was not sent in the first // place. // More: https://docs.tendermint.com/main/rpc/#/Info/tx -func Tx(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) { +func (env *Environment) Tx(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) { // if index is disabled, return error if _, ok := env.TxIndexer.(*null.TxIndex); ok { return nil, fmt.Errorf("transaction indexing is disabled") @@ -51,7 +51,7 @@ func Tx(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error // TxSearch allows you to query for multiple transactions results. It returns a // list of transactions (maximum ?per_page entries) and the total count. // More: https://docs.tendermint.com/main/rpc/#/Info/tx_search -func TxSearch( +func (env *Environment) TxSearch( ctx *rpctypes.Context, query string, prove bool, @@ -98,7 +98,7 @@ func TxSearch( // paginate results totalCount := len(results) - perPage := validatePerPage(perPagePtr) + perPage := env.validatePerPage(perPagePtr) page, err := validatePage(pagePtr, perPage, totalCount) if err != nil { diff --git a/rpc/grpc/api.go b/rpc/grpc/api.go index 62c6b66c172..41597dfd97c 100644 --- a/rpc/grpc/api.go +++ b/rpc/grpc/api.go @@ -9,6 +9,7 @@ import ( ) type broadcastAPI struct { + env *core.Environment } func (bapi *broadcastAPI) Ping(ctx context.Context, req *RequestPing) (*ResponsePing, error) { @@ -19,7 +20,7 @@ func (bapi *broadcastAPI) Ping(ctx context.Context, req *RequestPing) (*Response func (bapi *broadcastAPI) BroadcastTx(ctx context.Context, req *RequestBroadcastTx) (*ResponseBroadcastTx, error) { // NOTE: there's no way to get client's remote address // see https://stackoverflow.com/questions/33684570/session-and-remote-ip-address-in-grpc-go - res, err := core.BroadcastTxCommit(&rpctypes.Context{}, req.Tx) + res, err := bapi.env.BroadcastTxCommit(&rpctypes.Context{}, req.Tx) if err != nil { return nil, err } diff --git a/rpc/grpc/client_server.go b/rpc/grpc/client_server.go index 387a662134f..57380c2c5b4 100644 --- a/rpc/grpc/client_server.go +++ b/rpc/grpc/client_server.go @@ -7,6 +7,7 @@ import ( "google.golang.org/grpc" tmnet "github.com/tendermint/tendermint/libs/net" + "github.com/tendermint/tendermint/rpc/core" ) // Config is an gRPC server configuration. @@ -17,16 +18,16 @@ type Config struct { // StartGRPCServer starts a new gRPC BroadcastAPIServer using the given // net.Listener. // NOTE: This function blocks - you may want to call it in a go-routine. -func StartGRPCServer(ln net.Listener) error { +func StartGRPCServer(env *core.Environment, ln net.Listener) error { grpcServer := grpc.NewServer() - RegisterBroadcastAPIServer(grpcServer, &broadcastAPI{}) + RegisterBroadcastAPIServer(grpcServer, &broadcastAPI{env: env}) return grpcServer.Serve(ln) } // StartGRPCClient dials the gRPC server using protoAddr and returns a new // BroadcastAPIClient. func StartGRPCClient(protoAddr string) BroadcastAPIClient { - //nolint:staticcheck // SA1019 Existing use of deprecated but supported dial option. + //nolint: staticcheck // SA1019 Existing use of deprecated but supported dial option. conn, err := grpc.Dial(protoAddr, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc)) if err != nil { panic(err) diff --git a/rpc/jsonrpc/jsonrpc_test.go b/rpc/jsonrpc/jsonrpc_test.go index c322dfcea93..d6d98e5fc0c 100644 --- a/rpc/jsonrpc/jsonrpc_test.go +++ b/rpc/jsonrpc/jsonrpc_test.go @@ -138,7 +138,7 @@ func setup() { wm.SetLogger(tcpLogger) mux.HandleFunc(websocketEndpoint, wm.WebsocketHandler) config := server.DefaultConfig() - listener1, err := server.Listen(tcpAddr, config) + listener1, err := server.Listen(tcpAddr, config.MaxOpenConnections) if err != nil { panic(err) } @@ -154,7 +154,7 @@ func setup() { wm = server.NewWebsocketManager(Routes) wm.SetLogger(unixLogger) mux2.HandleFunc(websocketEndpoint, wm.WebsocketHandler) - listener2, err := server.Listen(unixAddr, config) + listener2, err := server.Listen(unixAddr, config.MaxOpenConnections) if err != nil { panic(err) } diff --git a/rpc/jsonrpc/server/http_server.go b/rpc/jsonrpc/server/http_server.go index 6dd772e3d97..526692674a2 100644 --- a/rpc/jsonrpc/server/http_server.go +++ b/rpc/jsonrpc/server/http_server.go @@ -258,7 +258,7 @@ func (h maxBytesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Listen starts a new net.Listener on the given address. // It returns an error if the address is invalid or the call to Listen() fails. -func Listen(addr string, config *Config) (listener net.Listener, err error) { +func Listen(addr string, maxOpenConnections int) (listener net.Listener, err error) { parts := strings.SplitN(addr, "://", 2) if len(parts) != 2 { return nil, fmt.Errorf( @@ -271,8 +271,8 @@ func Listen(addr string, config *Config) (listener net.Listener, err error) { if err != nil { return nil, fmt.Errorf("failed to listen on %v: %v", addr, err) } - if config.MaxOpenConnections > 0 { - listener = netutil.LimitListener(listener, config.MaxOpenConnections) + if maxOpenConnections > 0 { + listener = netutil.LimitListener(listener, maxOpenConnections) } return listener, nil diff --git a/rpc/jsonrpc/server/http_server_test.go b/rpc/jsonrpc/server/http_server_test.go index 72e87320737..6d4ab385ad4 100644 --- a/rpc/jsonrpc/server/http_server_test.go +++ b/rpc/jsonrpc/server/http_server_test.go @@ -39,8 +39,7 @@ func TestMaxOpenConnections(t *testing.T) { fmt.Fprint(w, "some body") }) config := DefaultConfig() - config.MaxOpenConnections = max - l, err := Listen("tcp://127.0.0.1:0", config) + l, err := Listen("tcp://127.0.0.1:0", max) require.NoError(t, err) defer l.Close() go Serve(l, mux, log.TestingLogger(), config) //nolint:errcheck // ignore for tests diff --git a/rpc/jsonrpc/test/main.go b/rpc/jsonrpc/test/main.go index fe3ffb76983..72583a43eb4 100644 --- a/rpc/jsonrpc/test/main.go +++ b/rpc/jsonrpc/test/main.go @@ -34,7 +34,7 @@ func main() { rpcserver.RegisterRPCFuncs(mux, routes, logger) config := rpcserver.DefaultConfig() - listener, err := rpcserver.Listen("tcp://127.0.0.1:8008", config) + listener, err := rpcserver.Listen("tcp://127.0.0.1:8008", config.MaxOpenConnections) if err != nil { tmos.Exit(err.Error()) } diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go index 1b88dec5111..14be9e22ff1 100644 --- a/rpc/test/helpers.go +++ b/rpc/test/helpers.go @@ -170,7 +170,7 @@ func NewTendermint(app abci.Application, opts *Options) *nm.Node { } node, err := nm.NewNode(config, pv, nodeKey, papp, nm.DefaultGenesisDocProviderFunc(config), - nm.DefaultDBProvider, + cfg.DefaultDBProvider, nm.DefaultMetricsProvider(config.Instrumentation), logger) if err != nil { diff --git a/state/execution_test.go b/state/execution_test.go index 8e1c69d638a..53a7c3f3171 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -549,7 +549,7 @@ func TestEndBlockValidatorUpdates(t *testing.T) { assert.Equal(t, pubkey, event.ValidatorUpdates[0].PubKey) assert.EqualValues(t, 10, event.ValidatorUpdates[0].VotingPower) } - case <-updatesSub.Cancelled(): + case <-updatesSub.Canceled(): t.Fatalf("updatesSub was canceled (reason: %v)", updatesSub.Err()) case <-time.After(1 * time.Second): t.Fatal("Did not receive EventValidatorSetUpdates within 1 sec.") diff --git a/state/indexer/block/indexer.go b/state/indexer/block/indexer.go new file mode 100644 index 00000000000..1e3b7e923f7 --- /dev/null +++ b/state/indexer/block/indexer.go @@ -0,0 +1,47 @@ +package block + +import ( + "errors" + "fmt" + + dbm "github.com/tendermint/tm-db" + + "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/state/indexer" + blockidxkv "github.com/tendermint/tendermint/state/indexer/block/kv" + blockidxnull "github.com/tendermint/tendermint/state/indexer/block/null" + "github.com/tendermint/tendermint/state/indexer/sink/psql" + "github.com/tendermint/tendermint/state/txindex" + "github.com/tendermint/tendermint/state/txindex/kv" + "github.com/tendermint/tendermint/state/txindex/null" +) + +// EventSinksFromConfig constructs a slice of indexer.EventSink using the provided +// configuration. +// +//nolint:lll +func IndexerFromConfig(cfg *config.Config, dbProvider config.DBProvider, chainID string) (txindex.TxIndexer, indexer.BlockIndexer, error) { + switch cfg.TxIndex.Indexer { + case "kv": + store, err := dbProvider(&config.DBContext{ID: "tx_index", Config: cfg}) + if err != nil { + return nil, nil, err + } + + return kv.NewTxIndex(store), blockidxkv.New(dbm.NewPrefixDB(store, []byte("block_events"))), nil + + case "psql": + conn := cfg.TxIndex.PsqlConn + if conn == "" { + return nil, nil, errors.New("the psql connection settings cannot be empty") + } + es, err := psql.NewEventSink(cfg.TxIndex.PsqlConn, chainID) + if err != nil { + return nil, nil, fmt.Errorf("creating psql indexer: %w", err) + } + return es.TxIndexer(), es.BlockIndexer(), nil + + default: + return &null.TxIndex{}, &blockidxnull.BlockerIndexer{}, nil + } +} diff --git a/state/mocks/block_store.go b/state/mocks/block_store.go index d449f67115f..ed921f4dc27 100644 --- a/state/mocks/block_store.go +++ b/state/mocks/block_store.go @@ -28,6 +28,20 @@ func (_m *BlockStore) Base() int64 { return r0 } +// Close provides a mock function with given fields: +func (_m *BlockStore) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + // DeleteLatestBlock provides a mock function with given fields: func (_m *BlockStore) DeleteLatestBlock() error { ret := _m.Called() diff --git a/state/services.go b/state/services.go index 0473b43b2f7..569242cd412 100644 --- a/state/services.go +++ b/state/services.go @@ -36,6 +36,8 @@ type BlockStore interface { LoadSeenCommit(height int64) *types.Commit DeleteLatestBlock() error + + Close() error } //----------------------------------------------------------------------------- diff --git a/state/txindex/indexer_service.go b/state/txindex/indexer_service.go index 0e8fbb9c911..7c2738382c2 100644 --- a/state/txindex/indexer_service.go +++ b/state/txindex/indexer_service.go @@ -59,54 +59,59 @@ func (is *IndexerService) OnStart() error { go func() { for { - msg := <-blockHeadersSub.Out() - eventDataHeader := msg.Data().(types.EventDataNewBlockHeader) - height := eventDataHeader.Header.Height - batch := NewBatch(eventDataHeader.NumTxs) - - for i := int64(0); i < eventDataHeader.NumTxs; i++ { - msg2 := <-txsSub.Out() - txResult := msg2.Data().(types.EventDataTx).TxResult - - if err = batch.Add(&txResult); err != nil { - is.Logger.Error( - "failed to add tx to batch", - "height", height, - "index", txResult.Index, - "err", err, - ) + select { + case <-blockHeadersSub.Canceled(): + return + case msg := <-blockHeadersSub.Out(): + + eventDataHeader := msg.Data().(types.EventDataNewBlockHeader) + height := eventDataHeader.Header.Height + batch := NewBatch(eventDataHeader.NumTxs) + + for i := int64(0); i < eventDataHeader.NumTxs; i++ { + msg2 := <-txsSub.Out() + txResult := msg2.Data().(types.EventDataTx).TxResult + + if err = batch.Add(&txResult); err != nil { + is.Logger.Error( + "failed to add tx to batch", + "height", height, + "index", txResult.Index, + "err", err, + ) + + if is.terminateOnError { + if err := is.Stop(); err != nil { + is.Logger.Error("failed to stop", "err", err) + } + return + } + } + } + if err := is.blockIdxr.Index(eventDataHeader); err != nil { + is.Logger.Error("failed to index block", "height", height, "err", err) if is.terminateOnError { if err := is.Stop(); err != nil { is.Logger.Error("failed to stop", "err", err) } return } + } else { + is.Logger.Info("indexed block exents", "height", height) } - } - if err := is.blockIdxr.Index(eventDataHeader); err != nil { - is.Logger.Error("failed to index block", "height", height, "err", err) - if is.terminateOnError { - if err := is.Stop(); err != nil { - is.Logger.Error("failed to stop", "err", err) - } - return - } - } else { - is.Logger.Info("indexed block exents", "height", height) - } - - if err = is.txIdxr.AddBatch(batch); err != nil { - is.Logger.Error("failed to index block txs", "height", height, "err", err) - if is.terminateOnError { - if err := is.Stop(); err != nil { - is.Logger.Error("failed to stop", "err", err) + if err = is.txIdxr.AddBatch(batch); err != nil { + is.Logger.Error("failed to index block txs", "height", height, "err", err) + if is.terminateOnError { + if err := is.Stop(); err != nil { + is.Logger.Error("failed to stop", "err", err) + } + return } - return + } else { + is.Logger.Debug("indexed transactions", "height", height, "num_txs", eventDataHeader.NumTxs) } - } else { - is.Logger.Debug("indexed transactions", "height", height, "num_txs", eventDataHeader.NumTxs) } } }() diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index c18878aadd2..954b4543fa6 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -141,7 +141,7 @@ func startNode(cfg *Config) error { nodeKey, cc, node.DefaultGenesisDocProviderFunc(tmcfg), - node.DefaultDBProvider, + config.DefaultDBProvider, node.DefaultMetricsProvider(tmcfg.Instrumentation), nodeLogger, ) @@ -157,8 +157,8 @@ func startLightClient(cfg *Config) error { return err } - dbContext := &node.DBContext{ID: "light", Config: tmcfg} - lightDB, err := node.DefaultDBProvider(dbContext) + dbContext := &config.DBContext{ID: "light", Config: tmcfg} + lightDB, err := config.DefaultDBProvider(dbContext) if err != nil { return err } diff --git a/types/event_bus.go b/types/event_bus.go index d51ae8e6775..3efa008e2cd 100644 --- a/types/event_bus.go +++ b/types/event_bus.go @@ -23,7 +23,7 @@ type EventBusSubscriber interface { type Subscription interface { Out() <-chan tmpubsub.Message - Cancelled() <-chan struct{} //nolint: misspell + Canceled() <-chan struct{} Err() error } diff --git a/types/event_bus_test.go b/types/event_bus_test.go index 62f57fca6f3..09461d085ee 100644 --- a/types/event_bus_test.go +++ b/types/event_bus_test.go @@ -439,7 +439,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes for { select { case <-sub.Out(): - case <-sub.Cancelled(): + case <-sub.Canceled(): return } } From 365af0651762b9e2c337669c593f730d06afbfbb Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Thu, 8 Dec 2022 10:12:15 -0500 Subject: [PATCH 13/40] workflow: correct the name for the e2e app in the workflow (#9850) --- .github/workflows/testapp-docker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/testapp-docker.yml b/.github/workflows/testapp-docker.yml index 9e8e59a4708..310e80e382f 100644 --- a/.github/workflows/testapp-docker.yml +++ b/.github/workflows/testapp-docker.yml @@ -1,6 +1,6 @@ -name: Testapp Docker -# Build & Push rebuilds the Testapp docker image on every push to main and creation of tags -# and pushes the image to https://hub.docker.com/r/tendermint/testapp +name: Docker E2E Node +# Build & Push rebuilds the e2e Testapp docker image on every push to main and creation of tags +# and pushes the image to https://hub.docker.com/r/tendermint/e2e-node on: push: branches: @@ -19,7 +19,7 @@ jobs: - name: Prepare id: prep run: | - DOCKER_IMAGE=tendermint/testapp + DOCKER_IMAGE=tendermint/e2e-node VERSION=noop if [[ $GITHUB_REF == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} From dfb6589d8c47569361e4da82a3646a8f29f3c4af Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Thu, 8 Dec 2022 15:20:02 -0500 Subject: [PATCH 14/40] rfc 27: report on bandwidth usage within Tendermint (#9706) This pull request adds a report on the major bandwidth usage within Tendermint. [Rendered](https://github.com/tendermint/tendermint/blob/wb/p2p-rfc/docs/rfc/rfc-027-p2p-message-bandwidth-report.md) #### PR checklist - [ ] Tests written/updated, or no tests needed - [ ] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [ ] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- docs/rfc/README.md | 1 + docs/rfc/images/receive-rate-all.png | Bin 0 -> 209404 bytes docs/rfc/images/send-rate-all.png | Bin 0 -> 218183 bytes docs/rfc/images/top-3-percent-receive.png | Bin 0 -> 79731 bytes docs/rfc/images/top-3-percent-send.png | Bin 0 -> 64857 bytes .../rfc-027-p2p-message-bandwidth-report.md | 287 ++++++++++++++++++ 6 files changed, 288 insertions(+) create mode 100644 docs/rfc/images/receive-rate-all.png create mode 100644 docs/rfc/images/send-rate-all.png create mode 100644 docs/rfc/images/top-3-percent-receive.png create mode 100644 docs/rfc/images/top-3-percent-send.png create mode 100644 docs/rfc/rfc-027-p2p-message-bandwidth-report.md diff --git a/docs/rfc/README.md b/docs/rfc/README.md index 83ff9551da7..bd3e2e02b01 100644 --- a/docs/rfc/README.md +++ b/docs/rfc/README.md @@ -62,5 +62,6 @@ sections. - [RFC-023: Semi-permanent Testnet](./rfc-023-semi-permanent-testnet.md) - [RFC-024: Block Structure Consolidation](./rfc-024-block-structure-consolidation.md) - [RFC-025: Application Defined Transaction Storage](./rfc-025-support-app-side-mempool.md) +- [RFC-027: P2P Message Bandwidth Report](./rfc-027-p2p-message-bandwidth-report.md) diff --git a/docs/rfc/images/receive-rate-all.png b/docs/rfc/images/receive-rate-all.png new file mode 100644 index 0000000000000000000000000000000000000000..b28a83f61c5e20e5e1322d383679c88eb643f315 GIT binary patch literal 209404 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�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
CgOSqM?yEW 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 MN-9ZIiWvv}5BAxGjQ{`u literal 0 HcmV?d00001 diff --git a/docs/rfc/images/send-rate-all.png b/docs/rfc/images/send-rate-all.png new file mode 100644 index 0000000000000000000000000000000000000000..803aca21f90396e2821a979f87b012aed22fe910 GIT binary patch literal 218183 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

9gJ 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

1_|Z2PER2buJ@ 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

Flk#Fy@I)HIj4X<{ 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 literal 0 HcmV?d00001 diff --git a/docs/rfc/images/top-3-percent-receive.png b/docs/rfc/images/top-3-percent-receive.png new file mode 100644 index 0000000000000000000000000000000000000000..39c5a2d064b67efec4ec136c97bd9349c3bdfc8e GIT binary patch literal 79731 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 literal 0 HcmV?d00001 diff --git a/docs/rfc/images/top-3-percent-send.png b/docs/rfc/images/top-3-percent-send.png new file mode 100644 index 0000000000000000000000000000000000000000..61f7f6e6a5e614b7bb0a339b8958aaf09a819268 GIT binary patch literal 64857 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 literal 0 HcmV?d00001 diff --git a/docs/rfc/rfc-027-p2p-message-bandwidth-report.md b/docs/rfc/rfc-027-p2p-message-bandwidth-report.md new file mode 100644 index 00000000000..eaa99cdef4a --- /dev/null +++ b/docs/rfc/rfc-027-p2p-message-bandwidth-report.md @@ -0,0 +1,287 @@ +# RFC 27: P2P Message Bandwidth Report + +## Changelog + +- Nov 7, 2022: initial draft (@williambanfield) +- Nov 15, 2022: draft completed (@williambanfield) + +## Abstract + +Node operators and application developers complain that Tendermint nodes consume +larges amounts of network bandwidth. This RFC catalogues the major sources of bandwidth +consumption within Tendermint and suggests modifications to Tendermint that may reduce +bandwidth consumption for nodes. + +## Background +Multiple teams running validators in production report that the validator +consumes a lot of bandwidth. They report that operators running on a network +with hundreds of validators consumes multiple terabytes of bandwidth per day. +Prometheus data collected from a validator node running on the Osmosis chain +shows that Tendermint sends and receives large amounts of data to peers. In the +nearly three hours of observation, Tendermint sent nearly 42 gigabytes and +received about 26 gigabytes, for an estimated 366 gigabytes sent daily and 208 +gigabytes received daily. While this is shy of the reported terabytes number, +operators running multiple nodes for a 'sentry' pattern could easily send and +receive a terabyte of data. + +Sending and receiving large amounts of data has a cost for node operators. Most +cloud platforms charge for network traffic egress. Google Cloud charges between +[$.05 to $.12 per gigabyte of egress traffic][gcloud-pricing], and ingress is +free. Hetzner [charges 1€ per TB used over the 10-20TB base bandwidth per +month][hetzner-pricing], which will be easily hit if multiple terabytes are +sent and received per day. Using the values collected from the validator on +Osmosis, a single node on Google cloud may cost $18 to $44 a day running on +Google cloud. On Hetzner, the estimated 18TB a month of both sending and +receiving may cost between 0 and 10 Euro a month per node. + +## Discussion + +### Overview of Major Bandwidth Usage + +To determine which components of Tendermint were consuming the most bandwidth, +I gathered prometheus metrics from the [Blockpane][blockpane] validator running +on the Osmosis network for several hours. The data reveal that three message +types account for 98% of the total bandwidth consumed. These message types are +as follows: + + +1. [consensus.BlockPart][block-part-message] +2. [mempool.Txs][mempool-txs-message] +3. [consensus.Vote][vote-message] + + +The image below of p2p data collected from the Blockpane validator illustrate +the total bandwidth consumption of these three message types. + + +#### Send: + +##### Top 3 Percent: + +![](./images/top-3-percent-send.png) + +##### Rate For All Messages: + +![](./images/send-rate-all.png) + +#### Receive: + +##### Top 3 Percent: + +![](./images/top-3-percent-receive.png) + +##### Rate For All Messages: + +![](./images/receive-rate-all.png) + +### Investigation of Message Usage + +This section discusses the usage of each of the three highest consumption messages. +#### BlockPart Transmission + +Sending `BlockPart` messages consumes the most bandwidth out of all p2p +messages types as observed in the Blockpane Osmosis validator. In the almost 3 +hour observation, the validator sent about 20 gigabytes of `BlockPart` +messages. + +A block is proposed each round of Tendermint consensus. The paper does not +define a specific way that the block is to be transmitted, just that all +participants will receive it via a gossip network. + +The Go implementation of Tendermint transmits the block in 'parts'. It +serializes the block to wire-format proto and splits this byte representation +into a set of 4 kilobyte arrays and sends these arrays to its peers, each in a +separate message. + +The logic for sending `BlockPart` messages resides in the code for the +[consensus.Reactor][gossip-data-routine]. The consensus reactor starts a new +`gossipDataRoutine` for each peer it connects to. This routine repeatedly picks +a part of the block that Tendermint believes the peer does not know about yet +and gossips it to the peer. The set of `BlockParts` that Tendermint considers +its peer as having is only updated in one of four ways: + + + 1. Our peer tells us they have entered a new round [via a `NewRoundStep` +message][new-round-step-message-send]. This message is only sent when a node +moves to a new round or height and only resets the data we collect about a +peer's blockpart state. + 1. [We receive a block part from the peer][block-part-receive]. + 1. [We send][block-part-send-1] [the peer a block part][block-part-send-2]. + 1. Our peer tells us about the parts they have block [via `NewValidBlock` +messages][new-valid-block-message-send]. This message is only sent when the +peer has a quorum of prevotes or precommits for a block. + +Each node receives block parts from all of its peers. The particular block part +to send at any given time is randomly selected from the set of parts that the +peer node is not yet known to have. Given that these are the only times that +Tendermint learns of its peers' block parts, it's very likely that a node has +an incomplete understanding of its peers' block parts and is transmitting block +parts to a peer that the peer has received from some other node. + +Multiple potential mechanisms exist to reduce the number of duplicate block +parts a node receives. One set of mechanisms relies on more frequently +communicating the set of block parts a node needs to its peers. Another +potential mechanism requires a larger overhaul to the way blocks are gossiped +in the network. + +#### Mempool Tx Transmission + +The Tendermint mempool stages transactions that are yet to be committed to the +blockchain and communicates these transactions to its peers. Each message +contains one transaction. Data collected from the Blockpane node running on +Osmosis indicates that the validator sent about 12 gigabytes of `Txs` messages +during the nearly 3 hour observation period. + +The Tendermint mempool starts a new [broadcastTxRoutine][broadcast-tx-routine] +for each peer that it is informed of. The routine sends all transactions that +the mempool is aware of to all peers with few exceptions. The only exception is +if the mempool received a transaction from a peer, then it marks it as such and +won't resend to that peer. Otherwise, it retains no information about which +transactions it already sent to a peer. In some cases it may therefore resend +transactions the peer already has. This can occur if the mempool removes a +transaction from the `CList` data structure used to store the list of +transactions while it is about to be sent and if the transaction was the tail +of the `CList` during removal. This will be more likely to occur if a large +number of transactions from the end of the list are removed during `RecheckTx`, +since multiple transactions will become the tail and then be deleted. It is +unclear at the moment how frequently this occurs on production chains. + +Beyond ensuring that transactions are rebroadcast to peers less frequently, +there is not a simple scheme to communicate fewer transactions to peers. Peers +cannot communicate what transactions they need since they do not know which +transactions exist on the network. + +#### Vote Transmission + +Tendermint votes, both prevotes and precommits, are central to Tendermint +consensus and are gossiped by all nodes to all peers during each consensus +round. Data collected from the Blockpane node running on Osmosis indicates that +about 9 gigabytes of `Vote` messages were sent during the nearly 3 hour period +of observation. Examination of the [Vote message][vote-msg] indicates that it +contains 184 bytes of data, with the proto encoding adding a few additional +bytes when transmitting. + +The Tendermint consensus reactor starts a new +[gossipVotesRoutine][gossip-votes-routine] for each peer that it connects to. +The reactor sends all votes to all peers unless it knows that the peer already +has the vote or the reactor learns that the peer is in a different round and +that thus the vote no longer applies. Tendermint learns that a peer has a vote +in one of 4 ways: + + 1. Tendermint sent the peer the vote. + 1. Tendermint received the vote from the peer. + 1. The peer [sent a `HasVote` message][apply-has-vote]. This message is broadcast +to all peers [each time validator receives a vote it hasn't seen before +corresponding to its current height and round][publish-event-vote]. + 1. The peer [sent a `VoteSetBits` message][apply-vote-set-bits]. This message is +[sent as a response to a peer that sends a `VoteSetMaj23`][vote-set-bits-send]. + +Given that Tendermint informs all peers of _each_ vote message it receives, all +nodes should be well informed of which votes their peers have. Given that the +vote messages were the third largest consumer of bandwidth in the observation +on Osmosis, it's possible that this system is not currently working correctly. +Further analysis should examine where votes may be being retransmitted. + +### Suggested Improvements to Lower Message Transmission Bandwidth + +#### Gossip Known BlockPart Data + +The `BlockPart` messages, by far, account for the majority of the data sent to +each peer. At the moment, peers do not inform the node of which block parts +they already have. This means that each block part is _very likely_ to be +transmitted many times to each node. This frivolous consumption is even worse +in networks with large blocks. + +The very simple solution to this issue is to copy the technique used in +consensus for informing peers when the node receives a vote. The consensus +reactor can be augmented with a `HasBlockPart` message that is broadcast to +each peer every time the node receives a block part. By informing each peer +every time the node receives a block part, we can drastically reduce the amount +of duplicate data sent to each node. There would be no algorithmic way of +enforcing that a peer accurately reports its block parts, so providing this +message would be a somewhat altruistic action on the part of the node. Such a +system [has been proposed in the past][i627] as well, so this is certainly not +totally new ground. + +Measuring the size of duplicately received blockparts before and after this +change would help validate this approach. + +#### Compress Transmitted Data + +Tendermint's data is sent uncompressed on the wire. The messages are not +compressed before sending and the transport performs no compression either. +Some of the information communicated by Tendermint is a poor candidate for +compression: Data such as digital signatures and hashes have high entropy and +therefore do not compress well. However, transactions may contain lots of +information that has less entropy. Compression within Tendermint may be added +at several levels. Compression may be performed at the [Tendermint 'packet' +level][must-wrap-packet] or at the [Tendermint message send +level][message-send]. + +#### Transmit Less Data During Block Gossip + +Block, vote, and mempool gossiping transmit much of same data. The mempool +reactor gossips candidate transactions to each peer. The consensus reactor, +when gossiping the votes, sends vote metadata and the digital signature of that +signs over that metadata. Finally, when a block is proposed, the proposing node +amalgamates the received votes, a set of transaction, and adds a header to +produce the block. This block is then serialized and gossiped as a list of +bytes. However, the data that the block contains, namely the votes and the +transactions were most likely _already transmitted to the nodes on the network_ +via mempool transaction gossip and consensus vote gossip. + +Therefore, block gossip can be updated to transmit a representation of the data +contained in the block that assumes the peers will already have most of this +data. Namely, the block gossip can be updated to only send 1) a list of +transaction hashes and 2) a bit array of votes selected for the block along +with the header and other required block metadata. + +This new proposed method for gossiping block data could accompany a slight +update to the mempool transaction gossip and consensus vote gossip. Since all +of the contents of each block will not be gossiped together, it's possible that +some nodes are missing a proposed transaction or the vote of a validator +indicated in the new block gossip format during block gossip. The mempool and +consensus reactors may therefore be updated to provide a `NeedTxs` and +`NeedVotes` message. Each of these messages would allow a node to request a set +of data from their peers. When a node receives one of these, it will then +transmit the Tx/Votes indicate in the associated message regardless of whether +it believes it has transmitted them to the peer before. The gossip layer will +ensure that each peer eventually receives all of the data in the block. +However, if a transaction is needed immediately by a peer so that it can verify +and execute a block during consensus, a mechanism such as the `NeedTxs` and +`NeedVotes` messages should be added to ensure it receives the messages +quickly. + +The same logic may applied for evidence transmission as well, since all nodes +should receive evidence and therefore do not need to re-transmit it in a block +part. + +A similar idea has been proposed in the past as [Compact Block +Propagation][compact-block-propagation]. + + +## References + +[blockpane]: https://www.mintscan.io/osmosis/validators/osmovaloper1z0sh4s80u99l6y9d3vfy582p8jejeeu6tcucs2 +[block-part-message]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/proto/tendermint/consensus/types.proto#L44 +[mempool-txs-message]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/proto/tendermint/mempool/types.proto#L6 +[vote-message]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/proto/tendermint/consensus/types.proto#L51 +[gossip-data-routine]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L537 +[block-part-receive]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L324 +[block-part-send-1]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L566 +[block-part-send-2]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L684. +[new-valid-block-message-send]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L268 +[new-round-step-message-send]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L266 +[broadcast-tx-routine]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/mempool/v0/reactor.go#L197 +[gossip-votes-routine]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L694 +[apply-has-vote]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L1429 +[apply-vote-set-bits]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L1445 +[publish-event-vote]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/state.go#L2083 +[vote-set-bits-send]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/consensus/reactor.go#L306 +[must-wrap-packet]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/p2p/conn/connection.go#L889-L918 +[message-send]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/p2p/peer.go#L285 +[gcloud-pricing]: https://cloud.google.com/vpc/network-pricing#vpc-pricing +[hetzner-pricing]: https://docs.hetzner.com/robot/general/traffic +[vote-msg]: https://github.com/tendermint/tendermint/blob/ff0f98892f24aac11e46aeff2b6d2c0ad816701a/proto/tendermint/types/types.pb.go#L468 +[i627]: https://github.com/tendermint/tendermint/issues/627 +[compact-block-propagation]: https://github.com/tendermint/tendermint/issues/7932 From 2f4f224faa330d9931c9c0e15560165fe5136ceb Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 9 Dec 2022 17:27:06 -0500 Subject: [PATCH 15/40] ci: Remove automatic dependabot updates for npm packages (#9854) We only use JavaScript packages in the dependencies for our docs theme, and every time I update the dependencies it breaks the rendering entirely for some unknown reason. Plus, we're going to be removing the theme anyways and replacing our docs rendering with a Jekyll-based one. Should reduce Dependabot noise a little. --- #### PR checklist - [x] Tests written/updated, or no tests needed - [x] `CHANGELOG_PENDING.md` updated, or no changelog entry needed - [x] Updated relevant documentation (`docs/`) and code comments, or no documentation updates needed --- .github/dependabot.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c823bbaae35..6dd968c201c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -30,12 +30,6 @@ updates: - T:dependencies - S:automerge - - package-ecosystem: npm - directory: "/docs" - schedule: - interval: weekly - open-pull-requests-limit: 10 - ################################### ## ## Update All Go Dependencies From 9998dff847a8b13c201a506c8a978605aa3fc4be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Dec 2022 12:58:08 +0000 Subject: [PATCH 16/40] build(deps): Bump github.com/prometheus/common from 0.37.0 to 0.38.0 (#9866) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.37.0 to 0.38.0.

Release notes

Sourced from github.com/prometheus/common's releases.

v0.38.0

  • [FEATURE] Implement Stringer on TLSVersion (#405)
  • [FEATURE] Check if TLS certificate and key file have been modified (#345)
  • [ENHANCEMENT] Add the ability to specify the maximum acceptable TLS version (#414)
  • [ENHANCEMENT] Make LoadHTTPConfigFile set directory and move from tests file (#415)
  • [ENHANCEMENT] Get Revision from debug.BuildInfo if not explicitly set (#374)
Commits
  • a33c32f Merge pull request #374 from roidelapluie/go118vcs
  • 5b6c049 go118: Get VCS info from debug.BuildInfo
  • 11bcb5b Merge pull request #415 from FUSAKLA/fus-http-config-from-file
  • 87b669d Add the ability to specify the maximum acceptable TLS version (#414)
  • d9cd6f2 feat: make LoadHTTPConfigFile set directory and move from tests file
  • bebc731 Remove ioutil after merging check client certificates (#407)
  • 8c9cb3f Update common Prometheus files (#399)
  • 1c0fa3e Check if TLS certificate and key file have been modified (#345)
  • 54e041d Implement Stringer on TLSVersion (#405)
  • c206bfc Merge pull request #404 from thaJeztah/bump_protobuf_extensions
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/prometheus/common&package-manager=go_modules&previous-version=0.37.0&new-version=0.38.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 6 +++--- go.sum | 16 +++++----------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 32e7fcca502..d02d3911efb 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pointlander/peg v1.0.1 github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_model v0.3.0 - github.com/prometheus/common v0.37.0 + github.com/prometheus/common v0.38.0 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 github.com/rs/cors v1.8.2 github.com/sasha-s/go-deadlock v0.3.1 @@ -51,6 +51,7 @@ require ( github.com/google/uuid v1.3.0 github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae github.com/vektra/mockery/v2 v2.15.0 + golang.org/x/sync v0.1.0 gonum.org/v1/gonum v0.12.0 google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 ) @@ -174,7 +175,7 @@ require ( 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.2-0.20181231171920-c182affec369 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -255,7 +256,6 @@ require ( 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.1.0 // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/term v0.2.0 // indirect golang.org/x/text v0.4.0 // indirect diff --git a/go.sum b/go.sum index d7973207e88..3709615759a 100644 --- a/go.sum +++ b/go.sum @@ -736,8 +736,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= +github.com/matttproud/golang_protobuf_extensions v1.0.2/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/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= @@ -799,7 +799,6 @@ github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV 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.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM= github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= @@ -934,8 +933,8 @@ github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.38.0 h1:VTQitp6mXTdUoCmDMugDVOJ1opi6ADftKfp/yeqTR/E= +github.com/prometheus/common v0.38.0/go.mod h1:MBXfmBQZrK5XpbCkjofnXs96LD2QQ7fEq4C0xjC/yec= 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= @@ -1331,8 +1330,6 @@ golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qx 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-20211029224645-99673261e6eb/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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= @@ -1349,7 +1346,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ 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-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= 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= @@ -1361,7 +1357,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -1458,7 +1453,6 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc 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-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1728,8 +1722,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-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/cheggaaa/pb.v1 v1.0.25/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= From de29f6e46d923bf6d2423206325af8a913874f50 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Dec 2022 13:07:40 +0000 Subject: [PATCH 17/40] build(deps): Bump github.com/bufbuild/buf from 1.9.0 to 1.10.0 (#9869) Bumps [github.com/bufbuild/buf](https://github.com/bufbuild/buf) from 1.9.0 to 1.10.0.
Release notes

Sourced from github.com/bufbuild/buf's releases.

v1.10.0

  • When using managed mode, setting enabled: false now no longer fails buf generate and instead prints a warning log and ignores managed mode options.
  • Add csharp_namespace option to managed mode, allowing except, which excludes modules from managed mode, and override, which specifies csharp_namespace values per module, overriding the default value. By default, when managed mode is enabled, csharp_namespace is set to the package name with each package sub-name capitalized.
  • Promote buf convert to stable, keep buf beta convert aliased in the beta command.
  • Add Types filter to buf generate command to specify types (message, enum, service) that should be included in the image. When specified, the resulting image will only include descriptors to describe the requested types.
Changelog

Sourced from github.com/bufbuild/buf's changelog.

[v1.10.0] - 2022-12-07

  • When using managed mode, setting enabled: false now no longer fails buf generate and instead prints a warning log and ignores managed mode options.
  • Add csharp_namespace option to managed mode, allowing except, which excludes modules from managed mode, and override, which specifies csharp_namespace values per module, overriding the default value. By default, when managed mode is enabled, csharp_namespace is set to the package name with each package sub-name capitalized.
  • Promote buf convert to stable, keep buf beta convert aliased in the beta command.
  • Add Types filter to buf generate command to specify types (message, enum, service) that should be included in the image. When specified, the resulting image will only include descriptors to describe the requested types.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/bufbuild/buf&package-manager=go_modules&previous-version=1.9.0&new-version=1.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 34 ++++++++++++++------------- go.sum | 74 ++++++++++++++++++++++++++++++++-------------------------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/go.mod b/go.mod index d02d3911efb..b85605a025c 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( ) require ( - github.com/bufbuild/buf v1.9.0 + github.com/bufbuild/buf v1.10.0 github.com/creachadair/taskgroup v0.3.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) @@ -79,14 +79,14 @@ 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/connect-go v1.1.0 // indirect github.com/bufbuild/protocompile v0.1.0 // indirect github.com/butuzov/ireturn v0.1.1 // 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-20220630083739-93517212f375 // indirect - github.com/containerd/containerd v1.6.8 // indirect + github.com/containerd/containerd v1.6.9 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect @@ -99,7 +99,7 @@ require ( 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/docker v20.10.21+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -107,6 +107,7 @@ require ( github.com/ettle/strcase v0.1.1 // indirect github.com/fatih/color v1.13.0 // indirect github.com/fatih/structtag v1.2.0 // indirect + github.com/felixge/fgprof v0.9.3 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect @@ -138,6 +139,7 @@ require ( 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.9 // indirect + github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e // 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 @@ -159,7 +161,7 @@ require ( github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.15.12 // 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 @@ -180,7 +182,7 @@ require ( github.com/mgechev/revive v1.2.4 // 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/buildkit v0.10.5 // 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 @@ -197,7 +199,7 @@ require ( 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/pkg/profile v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3 // indirect github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4 // indirect @@ -245,22 +247,22 @@ require ( github.com/yeya24/promlinter v0.2.0 // 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.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.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel/metric v0.33.0 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.23.0 // indirect - golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.6.0 // indirect + golang.org/x/mod v0.7.0 // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/term v0.2.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-20221024183307-1bc688fe9f3e // indirect + golang.org/x/tools v0.3.0 // indirect + google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // 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 diff --git a/go.sum b/go.sum index 3709615759a..7903b685d4e 100644 --- a/go.sum +++ b/go.sum @@ -23,7 +23,7 @@ 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.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= 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= @@ -172,10 +172,10 @@ 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.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/buf v1.10.0 h1:t6rV4iP1cs/sJH5SYvcLanOshLvmtvwSC+Mt+GfG05s= +github.com/bufbuild/buf v1.10.0/go.mod h1:79BrOWh8uX1a0SVSoPyeYgtP0+Y0n5J3Tt6kjTSkLoU= +github.com/bufbuild/connect-go v1.1.0 h1:AUgqqO2ePdOJSpPOep6BPYz5v2moW1Lb8sQh0EeRzQ8= +github.com/bufbuild/connect-go v1.1.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= @@ -220,8 +220,8 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z 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/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/containerd v1.6.9 h1:IN/r8DUes/B5lEGTNfIiUkfZBtIQJGx2ai703dV6lRA= +github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ= 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= @@ -284,8 +284,8 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 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/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= +github.com/docker/docker v20.10.21+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/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -325,6 +325,8 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= +github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= @@ -506,6 +508,9 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe 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-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e h1:F1LLQqQ8WoIbyoxLUY+JUZe1kuHdxThM6CPUATzE6Io= +github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -606,6 +611,7 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/hudl/fargo v1.4.0/go.mod h1:9Ai6uvFy5fQNq6VPKtg+Ceq1+eTY4nKUlR2JElEOcDo= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/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= @@ -620,7 +626,7 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= -github.com/jhump/protoreflect v1.13.1-0.20220928232736-101791cb1b4c h1:XImQJfpJLmGEEd8ll5yPVyL/aEvmgGHW4WYTyNseLOM= +github.com/jhump/protoreflect v1.14.0 h1:MBbQK392K3u8NTLbKOCIi3XdI+y+c6yt5oMq0X3xviw= 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= @@ -660,8 +666,8 @@ github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkS 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.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -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/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/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= @@ -764,8 +770,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.10.4 h1:FvC+buO8isGpUFZ1abdSLdGHZVqg9sqI4BbFL8tlzP4= -github.com/moby/buildkit v0.10.4/go.mod h1:Yajz9vt1Zw5q9Pp4pdb3TCSUXJBIroIQGQ3TTs/sLug= +github.com/moby/buildkit v0.10.5 h1:d9krS/lG3dn6N7y+R8o9PTgIixlYAaDk35f3/B4jZOw= +github.com/moby/buildkit v0.10.5/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= @@ -886,8 +892,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM= -github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= +github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= +github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -1168,16 +1174,17 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 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.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 h1:PRXhsszxTt5bbPriTjmaweWUsAnJYeWBhUMLRetUgBU= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4/go.mod h1:05eWWy6ZWzmpeImD3UowLTB3VjDMU1yxQ+ENuVWDM3c= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel/metric v0.33.0 h1:xQAyl7uGEYvrLAiV/09iTJlp1pZnQ9Wl793qbVvED1E= +go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= 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= @@ -1239,8 +1246,8 @@ 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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE= +golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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= @@ -1273,8 +1280,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -1448,6 +1455,7 @@ golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBc 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= @@ -1578,8 +1586,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.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/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= 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= @@ -1669,8 +1677,8 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+Ca/rDdKubLIU9rcJ3xfy1DC/Wd2Oo= +google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= 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= From 8895854e95b344b13bc05031f00cd2c140ed3105 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Dec 2022 13:17:12 +0000 Subject: [PATCH 18/40] build(deps): Bump golang.org/x/crypto from 0.3.0 to 0.4.0 (#9867) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.3.0 to 0.4.0.
Commits
  • eb2c406 go.mod: update golang.org/x dependencies
  • 2c47667 cryptobyte: add support for ReadASN1Integer into []byte
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/crypto&package-manager=go_modules&previous-version=0.3.0&new-version=0.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index b85605a025c..bb6b867ec48 100644 --- a/go.mod +++ b/go.mod @@ -32,8 +32,8 @@ require ( github.com/spf13/viper v1.14.0 github.com/stretchr/testify v1.8.1 github.com/tendermint/tm-db v0.6.6 - golang.org/x/crypto v0.3.0 - golang.org/x/net v0.2.0 + golang.org/x/crypto v0.4.0 + golang.org/x/net v0.3.0 google.golang.org/grpc v1.51.0 ) @@ -258,9 +258,9 @@ require ( golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/term v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect golang.org/x/tools v0.3.0 // indirect google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 7903b685d4e..53f1836a32e 100644 --- a/go.sum +++ b/go.sum @@ -1231,8 +1231,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y 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.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= +golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= 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= @@ -1338,8 +1338,8 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 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= @@ -1468,13 +1468,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.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.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= 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= @@ -1484,8 +1484,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.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= From 189d120c9fcb8b41a8327f0ee0323c58861bbdde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Dec 2022 13:04:15 +0000 Subject: [PATCH 19/40] build(deps): Bump golang.org/x/net from 0.2.0 to 0.4.0 (#9868) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.2.0 to 0.4.0.
Commits
  • 1e63c2f http2: limit canonical header cache by bytes, not entries
  • 3247b5b go.mod: update golang.org/x dependencies
  • ecf7fda http2: deflake TestTransportMaxFrameReadSize
  • 0833b63 publicsuffix: embed table data
  • ecf091a publicsuffix: update table to latest list from publicsuffix.org
  • 2f8c3d1 http2: add Transport.MaxReadFrameSize configuration setting
  • 0e478a2 http2: add SETTINGS_HEADER_TABLE_SIZE support
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/net&package-manager=go_modules&previous-version=0.2.0&new-version=0.4.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bb6b867ec48..74b8b288ad6 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/stretchr/testify v1.8.1 github.com/tendermint/tm-db v0.6.6 golang.org/x/crypto v0.4.0 - golang.org/x/net v0.3.0 + golang.org/x/net v0.4.0 google.golang.org/grpc v1.51.0 ) diff --git a/go.sum b/go.sum index 53f1836a32e..da017675c85 100644 --- a/go.sum +++ b/go.sum @@ -1338,8 +1338,8 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 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.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 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= From 1a5d5ed63b510d303f7f64671c4fcdb06da4a96a Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Thu, 15 Dec 2022 23:49:57 +0100 Subject: [PATCH 20/40] wire up logger to mempool reactor (#9885) --- node/setup.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/node/setup.go b/node/setup.go index d710869c7ff..a70894469e4 100644 --- a/node/setup.go +++ b/node/setup.go @@ -226,6 +226,7 @@ func createMempoolAndMempoolReactor( memplMetrics *mempl.Metrics, logger log.Logger, ) (mempl.Mempool, p2p.Reactor) { + logger = logger.With("module", "mempool") switch config.Mempool.Version { case cfg.MempoolV1: mp := mempoolv1.NewTxMempool( @@ -245,6 +246,7 @@ func createMempoolAndMempoolReactor( if config.Consensus.WaitForTxs() { mp.EnableTxsAvailable() } + reactor.SetLogger(logger) return mp, reactor @@ -267,6 +269,7 @@ func createMempoolAndMempoolReactor( if config.Consensus.WaitForTxs() { mp.EnableTxsAvailable() } + reactor.SetLogger(logger) return mp, reactor From 6878b38812e133b41112416bbbda70a5048dbc12 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 16 Dec 2022 10:19:02 -0500 Subject: [PATCH 21/40] abci: Adapt unsynchronized local client to replicate remote client concurrency (#9830) * Revert "abci: Add unsynchronized local client (#9660)" This reverts commit 45071d1f239febcdf1632003f1020688db921f91. Signed-off-by: Thane Thomson * proxy: Add unsync local client creator Signed-off-by: Thane Thomson * e2e: Extend tests Extend the E2E tests to randomly choose between the sync (default) and unsync (new) local client creator. Signed-off-by: Thane Thomson * abci: Remove redundant interface constraint Signed-off-by: Thane Thomson * abci: Remove irrelevant doc comment Signed-off-by: Thane Thomson * proxy: Remove backticks in doc comments Signed-off-by: Thane Thomson * e2e: Remove unnecessary gap between doc comment and struct Signed-off-by: Thane Thomson * Add pending changelog entry Signed-off-by: Thane Thomson * e2e: Expand on BuiltinProxyMode param docstring Signed-off-by: Thane Thomson * Remove builtin proxy mode config option from CI test Signed-off-by: Thane Thomson * e2e: Make builtin proxy mode option testnet-wide Signed-off-by: Thane Thomson * e2e: Embed sync/unsync notion in node protocol The approach of randomly generating the proxy mode across testnets resulted in a totally uneven ratio of sync to unsync modes for all testnets that happened to have a protocol of "builtin". This commit adapts the E2E tests to have a new ABCI protocol option: "builtin_unsync". This results in a better spread of sync/unsync choices for generated testnets. Signed-off-by: Thane Thomson * e2e: Remove unused type Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson --- CHANGELOG_PENDING.md | 3 + abci/client/unsync_local_client.go | 263 ---------------------------- proxy/client.go | 44 +++-- test/e2e/app/app.go | 2 +- test/e2e/app/sync_app.go | 111 ------------ test/e2e/generator/generate.go | 19 +- test/e2e/networks/ci.toml | 1 - test/e2e/node/config.go | 8 +- test/e2e/node/main.go | 34 ++-- test/e2e/pkg/infra/docker/docker.go | 5 +- test/e2e/pkg/manifest.go | 21 +-- test/e2e/pkg/testnet.go | 17 +- test/e2e/runner/setup.go | 7 +- 13 files changed, 79 insertions(+), 456 deletions(-) delete mode 100644 abci/client/unsync_local_client.go delete mode 100644 test/e2e/app/sync_app.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 945edbd599d..5f0e93dd067 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -28,6 +28,9 @@ ### FEATURES +- [proxy] \#9830 Introduce `NewUnsyncLocalClientCreator`, which allows local + ABCI clients to have the same concurrency model as remote clients (i.e. one + mutex per client "connection", for each of the four ABCI "connections"). - [config] \#9680 Introduce `BootstrapPeers` to the config to allow nodes to list peers to be added to the addressbook upon start up (@cmwaters) diff --git a/abci/client/unsync_local_client.go b/abci/client/unsync_local_client.go deleted file mode 100644 index 3198c172086..00000000000 --- a/abci/client/unsync_local_client.go +++ /dev/null @@ -1,263 +0,0 @@ -package abcicli - -import ( - "sync" - - types "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/service" -) - -type unsyncLocalClient struct { - service.BaseService - - types.Application - - // This mutex is exclusively used to protect the callback. - mtx sync.RWMutex - Callback -} - -var _ Client = (*unsyncLocalClient)(nil) - -// NewUnsyncLocalClient creates an unsynchronized local client, which will be -// directly calling the methods of the given app. -// -// Unlike NewLocalClient, it does not hold a mutex around the application, so -// it is up to the application to manage its synchronization properly. -func NewUnsyncLocalClient(app types.Application) Client { - cli := &unsyncLocalClient{ - Application: app, - } - cli.BaseService = *service.NewBaseService(nil, "unsyncLocalClient", cli) - return cli -} - -func (app *unsyncLocalClient) SetResponseCallback(cb Callback) { - app.mtx.Lock() - defer app.mtx.Unlock() - app.Callback = cb -} - -// TODO: change types.Application to include Error()? -func (app *unsyncLocalClient) Error() error { - return nil -} - -func (app *unsyncLocalClient) FlushAsync() *ReqRes { - // Do nothing - return newLocalReqRes(types.ToRequestFlush(), nil) -} - -func (app *unsyncLocalClient) EchoAsync(msg string) *ReqRes { - return app.callback( - types.ToRequestEcho(msg), - types.ToResponseEcho(msg), - ) -} - -func (app *unsyncLocalClient) InfoAsync(req types.RequestInfo) *ReqRes { - res := app.Application.Info(req) - return app.callback( - types.ToRequestInfo(req), - types.ToResponseInfo(res), - ) -} - -func (app *unsyncLocalClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes { - res := app.Application.DeliverTx(params) - return app.callback( - types.ToRequestDeliverTx(params), - types.ToResponseDeliverTx(res), - ) -} - -func (app *unsyncLocalClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes { - res := app.Application.CheckTx(req) - return app.callback( - types.ToRequestCheckTx(req), - types.ToResponseCheckTx(res), - ) -} - -func (app *unsyncLocalClient) QueryAsync(req types.RequestQuery) *ReqRes { - res := app.Application.Query(req) - return app.callback( - types.ToRequestQuery(req), - types.ToResponseQuery(res), - ) -} - -func (app *unsyncLocalClient) CommitAsync() *ReqRes { - res := app.Application.Commit() - return app.callback( - types.ToRequestCommit(), - types.ToResponseCommit(res), - ) -} - -func (app *unsyncLocalClient) InitChainAsync(req types.RequestInitChain) *ReqRes { - res := app.Application.InitChain(req) - return app.callback( - types.ToRequestInitChain(req), - types.ToResponseInitChain(res), - ) -} - -func (app *unsyncLocalClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { - res := app.Application.BeginBlock(req) - return app.callback( - types.ToRequestBeginBlock(req), - types.ToResponseBeginBlock(res), - ) -} - -func (app *unsyncLocalClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { - res := app.Application.EndBlock(req) - return app.callback( - types.ToRequestEndBlock(req), - types.ToResponseEndBlock(res), - ) -} - -func (app *unsyncLocalClient) ListSnapshotsAsync(req types.RequestListSnapshots) *ReqRes { - res := app.Application.ListSnapshots(req) - return app.callback( - types.ToRequestListSnapshots(req), - types.ToResponseListSnapshots(res), - ) -} - -func (app *unsyncLocalClient) OfferSnapshotAsync(req types.RequestOfferSnapshot) *ReqRes { - res := app.Application.OfferSnapshot(req) - return app.callback( - types.ToRequestOfferSnapshot(req), - types.ToResponseOfferSnapshot(res), - ) -} - -func (app *unsyncLocalClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk) *ReqRes { - res := app.Application.LoadSnapshotChunk(req) - return app.callback( - types.ToRequestLoadSnapshotChunk(req), - types.ToResponseLoadSnapshotChunk(res), - ) -} - -func (app *unsyncLocalClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk) *ReqRes { - res := app.Application.ApplySnapshotChunk(req) - return app.callback( - types.ToRequestApplySnapshotChunk(req), - types.ToResponseApplySnapshotChunk(res), - ) -} - -func (app *unsyncLocalClient) PrepareProposalAsync(req types.RequestPrepareProposal) *ReqRes { - res := app.Application.PrepareProposal(req) - return app.callback( - types.ToRequestPrepareProposal(req), - types.ToResponsePrepareProposal(res), - ) -} - -func (app *unsyncLocalClient) ProcessProposalAsync(req types.RequestProcessProposal) *ReqRes { - res := app.Application.ProcessProposal(req) - return app.callback( - types.ToRequestProcessProposal(req), - types.ToResponseProcessProposal(res), - ) -} - -//------------------------------------------------------- - -func (app *unsyncLocalClient) FlushSync() error { - return nil -} - -func (app *unsyncLocalClient) EchoSync(msg string) (*types.ResponseEcho, error) { - return &types.ResponseEcho{Message: msg}, nil -} - -func (app *unsyncLocalClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { - res := app.Application.Info(req) - return &res, nil -} - -func (app *unsyncLocalClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) { - res := app.Application.DeliverTx(req) - return &res, nil -} - -func (app *unsyncLocalClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) { - res := app.Application.CheckTx(req) - return &res, nil -} - -func (app *unsyncLocalClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { - res := app.Application.Query(req) - return &res, nil -} - -func (app *unsyncLocalClient) CommitSync() (*types.ResponseCommit, error) { - res := app.Application.Commit() - return &res, nil -} - -func (app *unsyncLocalClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { - res := app.Application.InitChain(req) - return &res, nil -} - -func (app *unsyncLocalClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { - res := app.Application.BeginBlock(req) - return &res, nil -} - -func (app *unsyncLocalClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { - res := app.Application.EndBlock(req) - return &res, nil -} - -func (app *unsyncLocalClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) { - res := app.Application.ListSnapshots(req) - return &res, nil -} - -func (app *unsyncLocalClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) { - res := app.Application.OfferSnapshot(req) - return &res, nil -} - -func (app *unsyncLocalClient) LoadSnapshotChunkSync( - req types.RequestLoadSnapshotChunk, -) (*types.ResponseLoadSnapshotChunk, error) { - res := app.Application.LoadSnapshotChunk(req) - return &res, nil -} - -func (app *unsyncLocalClient) ApplySnapshotChunkSync( - req types.RequestApplySnapshotChunk, -) (*types.ResponseApplySnapshotChunk, error) { - res := app.Application.ApplySnapshotChunk(req) - return &res, nil -} - -func (app *unsyncLocalClient) PrepareProposalSync(req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) { - res := app.Application.PrepareProposal(req) - return &res, nil -} - -func (app *unsyncLocalClient) ProcessProposalSync(req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) { - res := app.Application.ProcessProposal(req) - return &res, nil -} - -//------------------------------------------------------- - -func (app *unsyncLocalClient) callback(req *types.Request, res *types.Response) *ReqRes { - app.mtx.RLock() - defer app.mtx.RUnlock() - app.Callback(req, res) - rr := newLocalReqRes(req, res) - rr.callbackInvoked = true - return rr -} diff --git a/proxy/client.go b/proxy/client.go index 8fc9917ae7d..e4455bead6a 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -26,8 +26,12 @@ type localClientCreator struct { app types.Application } -// NewLocalClientCreator returns a ClientCreator for the given app, -// which will be running locally. +// NewLocalClientCreator returns a [ClientCreator] for the given app, which +// will be running locally. +// +// Maintains a single mutex over all new clients created with NewABCIClient. +// For a local client creator that uses a single mutex per new client, rather +// use [NewUnsyncLocalClientCreator]. func NewLocalClientCreator(app types.Application) ClientCreator { return &localClientCreator{ mtx: new(tmsync.Mutex), @@ -39,24 +43,26 @@ func (l *localClientCreator) NewABCIClient() (abcicli.Client, error) { return abcicli.NewLocalClient(l.mtx, l.app), nil } -//--------------------------------------------------------------- -// unsynchronized local proxy on an in-proc app (no mutex) +//---------------------------------------------------- +// local proxy creates a new mutex for each client type unsyncLocalClientCreator struct { app types.Application } -// NewUnsyncLocalClientCreator returns a ClientCreator for the given app, which -// will be running locally. Unlike NewLocalClientCreator, this leaves -// synchronization up to the application. +// NewUnsyncLocalClientCreator returns a [ClientCreator] for the given app. +// Unlike [NewLocalClientCreator], each call to NewABCIClient returns an ABCI +// client that maintains its own mutex over the application. func NewUnsyncLocalClientCreator(app types.Application) ClientCreator { return &unsyncLocalClientCreator{ app: app, } } -func (l *unsyncLocalClientCreator) NewABCIClient() (abcicli.Client, error) { - return abcicli.NewUnsyncLocalClient(l.app), nil +func (c *unsyncLocalClientCreator) NewABCIClient() (abcicli.Client, error) { + // Specifying nil for the mutex causes each instance to create its own + // mutex. + return abcicli.NewLocalClient(nil, c.app), nil } //--------------------------------------------------------------- @@ -88,23 +94,33 @@ func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) { return remoteApp, nil } -// DefaultClientCreator returns a default ClientCreator, which will create a -// local client if addr is one of: 'kvstore', -// 'persistent_kvstore' or 'noop', otherwise - a remote client. +// DefaultClientCreator returns a default [ClientCreator], which will create a +// local client if addr is one of "kvstore", "persistent_kvstore", "e2e", +// "noop". +// +// Otherwise a remote client will be created. +// +// Each of "kvstore", "persistent_kvstore" and "e2e" also currently have an +// "_unsync" variant (i.e. "kvstore_unsync", etc.), which attempts to replicate +// the same concurrency model as the remote client. func DefaultClientCreator(addr, transport, dbDir string) ClientCreator { switch addr { case "kvstore": return NewLocalClientCreator(kvstore.NewApplication()) + case "kvstore_unsync": + return NewUnsyncLocalClientCreator(kvstore.NewApplication()) case "persistent_kvstore": return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir)) + case "persistent_kvstore_unsync": + return NewUnsyncLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir)) case "e2e": app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir)) if err != nil { panic(err) } return NewLocalClientCreator(app) - case "e2e_sync": - app, err := e2e.NewSyncApplication(e2e.DefaultConfig(dbDir)) + case "e2e_unsync": + app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir)) if err != nil { panic(err) } diff --git a/test/e2e/app/app.go b/test/e2e/app/app.go index c145e03d1f3..505aab71675 100644 --- a/test/e2e/app/app.go +++ b/test/e2e/app/app.go @@ -88,7 +88,7 @@ func DefaultConfig(dir string) *Config { } // NewApplication creates the application. -func NewApplication(cfg *Config) (abci.Application, error) { +func NewApplication(cfg *Config) (*Application, error) { state, err := NewState(cfg.Dir, cfg.PersistInterval) if err != nil { return nil, err diff --git a/test/e2e/app/sync_app.go b/test/e2e/app/sync_app.go deleted file mode 100644 index 8df8da7a33e..00000000000 --- a/test/e2e/app/sync_app.go +++ /dev/null @@ -1,111 +0,0 @@ -package app - -import ( - "sync" - - abci "github.com/tendermint/tendermint/abci/types" -) - -// SyncApplication wraps an Application, managing its own synchronization. This -// allows it to be called from an unsynchronized local client, as it is -// implemented in a thread-safe way. -type SyncApplication struct { - mtx sync.RWMutex - app *Application -} - -var _ abci.Application = (*SyncApplication)(nil) - -func NewSyncApplication(cfg *Config) (abci.Application, error) { - app, err := NewApplication(cfg) - if err != nil { - return nil, err - } - return &SyncApplication{ - app: app.(*Application), - }, nil -} - -func (app *SyncApplication) Info(req abci.RequestInfo) abci.ResponseInfo { - app.mtx.RLock() - defer app.mtx.RUnlock() - return app.app.Info(req) -} - -func (app *SyncApplication) InitChain(req abci.RequestInitChain) abci.ResponseInitChain { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.InitChain(req) -} - -func (app *SyncApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { - app.mtx.RLock() - defer app.mtx.RUnlock() - return app.app.CheckTx(req) -} - -func (app *SyncApplication) PrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal { - // app.app.PrepareProposal does not modify state - app.mtx.RLock() - defer app.mtx.RUnlock() - return app.app.PrepareProposal(req) -} - -func (app *SyncApplication) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal { - // app.app.ProcessProposal does not modify state - app.mtx.RLock() - defer app.mtx.RUnlock() - return app.app.ProcessProposal(req) -} - -func (app *SyncApplication) DeliverTx(req abci.RequestDeliverTx) abci.ResponseDeliverTx { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.DeliverTx(req) -} - -func (app *SyncApplication) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.BeginBlock(req) -} - -func (app *SyncApplication) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.EndBlock(req) -} - -func (app *SyncApplication) Commit() abci.ResponseCommit { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.Commit() -} - -func (app *SyncApplication) Query(req abci.RequestQuery) abci.ResponseQuery { - app.mtx.RLock() - defer app.mtx.RUnlock() - return app.app.Query(req) -} - -func (app *SyncApplication) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.ResponseApplySnapshotChunk { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.ApplySnapshotChunk(req) -} - -func (app *SyncApplication) ListSnapshots(req abci.RequestListSnapshots) abci.ResponseListSnapshots { - // Calls app.snapshots.List(), which is thread-safe. - return app.app.ListSnapshots(req) -} - -func (app *SyncApplication) LoadSnapshotChunk(req abci.RequestLoadSnapshotChunk) abci.ResponseLoadSnapshotChunk { - // Calls app.snapshots.LoadChunk, which is thread-safe. - return app.app.LoadSnapshotChunk(req) -} - -func (app *SyncApplication) OfferSnapshot(req abci.RequestOfferSnapshot) abci.ResponseOfferSnapshot { - app.mtx.Lock() - defer app.mtx.Unlock() - return app.app.OfferSnapshot(req) -} diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index a898d67d8d2..e9806afb568 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -29,7 +29,7 @@ var ( nodeDatabases = uniformChoice{"goleveldb", "cleveldb", "rocksdb", "boltdb", "badgerdb"} ipv6 = uniformChoice{false, true} // FIXME: grpc disabled due to https://github.com/tendermint/tendermint/issues/5439 - nodeABCIProtocols = uniformChoice{"unix", "tcp", "builtin"} // "grpc" + nodeABCIProtocols = uniformChoice{"unix", "tcp", "builtin", "builtin_unsync"} // "grpc" nodePrivvalProtocols = uniformChoice{"file", "unix", "tcp"} nodeBlockSyncs = uniformChoice{"v0"} // "v2" nodeStateSyncs = uniformChoice{false, true} @@ -110,7 +110,7 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er // First we generate seed nodes, starting at the initial height. for i := 1; i <= numSeeds; i++ { manifest.Nodes[fmt.Sprintf("seed%02d", i)] = generateNode( - r, e2e.ModeSeed, false, 0, manifest.InitialHeight, false) + r, e2e.ModeSeed, 0, manifest.InitialHeight, false) } // Next, we generate validators. We make sure a BFT quorum of validators start @@ -125,12 +125,8 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er nextStartAt += 5 } name := fmt.Sprintf("validator%02d", i) - syncApp := false - if manifest.ABCIProtocol == string(e2e.ProtocolBuiltin) { - syncApp = r.Intn(100) >= 50 - } manifest.Nodes[name] = generateNode( - r, e2e.ModeValidator, syncApp, startAt, manifest.InitialHeight, i <= 2) + r, e2e.ModeValidator, startAt, manifest.InitialHeight, i <= 2) if startAt == 0 { (*manifest.Validators)[name] = int64(30 + r.Intn(71)) @@ -158,12 +154,8 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er startAt = nextStartAt nextStartAt += 5 } - syncApp := false - if manifest.ABCIProtocol == string(e2e.ProtocolBuiltin) { - syncApp = r.Intn(100) >= 50 - } manifest.Nodes[fmt.Sprintf("full%02d", i)] = generateNode( - r, e2e.ModeFull, syncApp, startAt, manifest.InitialHeight, false) + r, e2e.ModeFull, startAt, manifest.InitialHeight, false) } // We now set up peer discovery for nodes. Seed nodes are fully meshed with @@ -226,12 +218,11 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er // here, since we need to know the overall network topology and startup // sequencing. func generateNode( - r *rand.Rand, mode e2e.Mode, syncApp bool, startAt int64, initialHeight int64, forceArchive bool, + r *rand.Rand, mode e2e.Mode, startAt int64, initialHeight int64, forceArchive bool, ) *e2e.ManifestNode { node := e2e.ManifestNode{ Version: nodeVersions.Choose(r).(string), Mode: string(mode), - SyncApp: syncApp, StartAt: startAt, Database: nodeDatabases.Choose(r).(string), PrivvalProtocol: nodePrivvalProtocols.Choose(r).(string), diff --git a/test/e2e/networks/ci.toml b/test/e2e/networks/ci.toml index 67e088554a7..916deb7577c 100644 --- a/test/e2e/networks/ci.toml +++ b/test/e2e/networks/ci.toml @@ -60,7 +60,6 @@ perturb = ["kill"] persistent_peers = ["validator01"] database = "rocksdb" abci_protocol = "builtin" -sync_app = true perturb = ["pause"] [node.validator05] diff --git a/test/e2e/node/config.go b/test/e2e/node/config.go index a677ab12e9f..9faa9fe2d7b 100644 --- a/test/e2e/node/config.go +++ b/test/e2e/node/config.go @@ -7,7 +7,6 @@ import ( "github.com/BurntSushi/toml" "github.com/tendermint/tendermint/test/e2e/app" - e2e "github.com/tendermint/tendermint/test/e2e/pkg" ) // Config is the application configuration. @@ -17,7 +16,6 @@ type Config struct { Protocol string `toml:"protocol"` Dir string `toml:"dir"` Mode string `toml:"mode"` - SyncApp bool `toml:"sync_app"` PersistInterval uint64 `toml:"persist_interval"` SnapshotInterval uint64 `toml:"snapshot_interval"` RetainBlocks uint64 `toml:"retain_blocks"` @@ -62,12 +60,8 @@ func (cfg Config) Validate() error { switch { case cfg.ChainID == "": return errors.New("chain_id parameter is required") - case cfg.Listen == "" && cfg.Protocol != "builtin": + case cfg.Listen == "" && cfg.Protocol != "builtin" && cfg.Protocol != "builtin_unsync": return errors.New("listen parameter is required") - case cfg.SyncApp && cfg.Protocol != string(e2e.ProtocolBuiltin): - return errors.New("sync_app parameter is only relevant for builtin applications") - case cfg.SyncApp && cfg.Mode != string(e2e.ModeFull) && cfg.Mode != string(e2e.ModeValidator): - return errors.New("sync_app parameter is only relevant to full nodes and validators") default: return nil } diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index 954b4543fa6..232be0cabc0 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -62,7 +62,7 @@ func run(configFile string) error { if err = startSigner(cfg); err != nil { return err } - if cfg.Protocol == "builtin" { + if cfg.Protocol == "builtin" || cfg.Protocol == "builtin_unsync" { time.Sleep(1 * time.Second) } } @@ -71,7 +71,7 @@ func run(configFile string) error { switch cfg.Protocol { case "socket", "grpc": err = startApp(cfg) - case "builtin": + case "builtin", "builtin_unsync": if cfg.Mode == string(e2e.ModeLight) { err = startLightClient(cfg) } else { @@ -113,22 +113,9 @@ func startApp(cfg *Config) error { // // FIXME There is no way to simply load the configuration from a file, so we need to pull in Viper. func startNode(cfg *Config) error { - var cc proxy.ClientCreator - - if cfg.SyncApp { - app, err := app.NewSyncApplication(cfg.App()) - if err != nil { - return err - } - cc = proxy.NewUnsyncLocalClientCreator(app) - logger.Info("Using synchronized app with unsynchronized local client") - } else { - app, err := app.NewApplication(cfg.App()) - if err != nil { - return err - } - cc = proxy.NewLocalClientCreator(app) - logger.Info("Using regular app with synchronized (regular) local client") + app, err := app.NewApplication(cfg.App()) + if err != nil { + return err } tmcfg, nodeLogger, nodeKey, err := setupNode() @@ -136,10 +123,19 @@ func startNode(cfg *Config) error { return fmt.Errorf("failed to setup config: %w", err) } + var clientCreator proxy.ClientCreator + if cfg.Protocol == string(e2e.ProtocolBuiltinUnsync) { + clientCreator = proxy.NewUnsyncLocalClientCreator(app) + nodeLogger.Info("Using unsynchronized local client creator") + } else { + clientCreator = proxy.NewLocalClientCreator(app) + nodeLogger.Info("Using default (synchronized) local client creator") + } + n, err := node.NewNode(tmcfg, privval.LoadOrGenFilePV(tmcfg.PrivValidatorKeyFile(), tmcfg.PrivValidatorStateFile()), nodeKey, - cc, + clientCreator, node.DefaultGenesisDocProviderFunc(tmcfg), config.DefaultDBProvider, node.DefaultMetricsProvider(tmcfg.Instrumentation), diff --git a/test/e2e/pkg/infra/docker/docker.go b/test/e2e/pkg/infra/docker/docker.go index 5c118f03bdf..6e0d3560809 100644 --- a/test/e2e/pkg/infra/docker/docker.go +++ b/test/e2e/pkg/infra/docker/docker.go @@ -26,7 +26,7 @@ func (p *Provider) Setup() error { } //nolint: gosec // G306: Expect WriteFile permissions to be 0600 or less - err = os.WriteFile(filepath.Join(p.Testnet.Dir, "docker-compose.yml"), compose, 0644) + err = os.WriteFile(filepath.Join(p.Testnet.Dir, "docker-compose.yml"), compose, 0o644) if err != nil { return err } @@ -60,6 +60,9 @@ services: image: tendermint/e2e-node:{{ .Version }} {{- if eq .ABCIProtocol "builtin" }} entrypoint: /usr/bin/entrypoint-builtin +{{- else }}{{ if eq .ABCIProtocol "builtin_unsync" }} + entrypoint: /usr/bin/entrypoint-builtin +{{- end }} {{- end }} init: true ports: diff --git a/test/e2e/pkg/manifest.go b/test/e2e/pkg/manifest.go index 0a9a1da5f6b..5a88fb99012 100644 --- a/test/e2e/pkg/manifest.go +++ b/test/e2e/pkg/manifest.go @@ -57,9 +57,15 @@ type Manifest struct { Evidence int `toml:"evidence"` // ABCIProtocol specifies the protocol used to communicate with the ABCI - // application: "unix", "tcp", "grpc", or "builtin". Defaults to builtin. - // builtin will build a complete Tendermint node into the application and - // launch it instead of launching a separate Tendermint process. + // application: "unix", "tcp", "grpc", "builtin" or "builtin_unsync". + // + // Defaults to "builtin". "builtin" will build a complete Tendermint node + // into the application and launch it instead of launching a separate + // Tendermint process. + // + // "builtin_unsync" is basically the same as "builtin", except that it uses + // an "unsynchronized" local client creator, which attempts to replicate the + // same concurrency model locally as the socket client. ABCIProtocol string `toml:"abci_protocol"` // Add artificial delays to each of the main ABCI calls to mimic computation time @@ -88,15 +94,6 @@ type ManifestNode struct { // on the machine where the test is being run. Version string `toml:"version"` - // SyncApp specifies whether this node should use a synchronized application - // with an unsynchronized local client. By default this is `false`, meaning - // that the node will run an unsynchronized application with a synchronized - // local client. - // - // Only applies to validators and full nodes where their ABCI protocol is - // "builtin". - SyncApp bool `toml:"sync_app"` - // Seeds is the list of node names to use as P2P seed nodes. Defaults to none. Seeds []string `toml:"seeds"` diff --git a/test/e2e/pkg/testnet.go b/test/e2e/pkg/testnet.go index 2bd16f8c1fc..923ec44bfac 100644 --- a/test/e2e/pkg/testnet.go +++ b/test/e2e/pkg/testnet.go @@ -39,11 +39,12 @@ const ( ModeLight Mode = "light" ModeSeed Mode = "seed" - ProtocolBuiltin Protocol = "builtin" - ProtocolFile Protocol = "file" - ProtocolGRPC Protocol = "grpc" - ProtocolTCP Protocol = "tcp" - ProtocolUNIX Protocol = "unix" + ProtocolBuiltin Protocol = "builtin" + ProtocolBuiltinUnsync Protocol = "builtin_unsync" + ProtocolFile Protocol = "file" + ProtocolGRPC Protocol = "grpc" + ProtocolTCP Protocol = "tcp" + ProtocolUNIX Protocol = "unix" PerturbationDisconnect Perturbation = "disconnect" PerturbationKill Perturbation = "kill" @@ -82,7 +83,6 @@ type Node struct { Version string Testnet *Testnet Mode Mode - SyncApp bool // Should we use a synchronized app with an unsynchronized local client? PrivvalKey crypto.PrivKey NodeKey crypto.PrivKey IP net.IP @@ -183,7 +183,6 @@ func LoadTestnet(manifest Manifest, fname string, ifd InfrastructureData) (*Test IP: ind.IPAddress, ProxyPort: proxyPortGen.Next(), Mode: ModeValidator, - SyncApp: nodeManifest.SyncApp, Database: "goleveldb", ABCIProtocol: Protocol(testnet.ABCIProtocol), PrivvalProtocol: ProtocolFile, @@ -347,11 +346,11 @@ func (n Node) Validate(testnet Testnet) error { return fmt.Errorf("invalid database setting %q", n.Database) } switch n.ABCIProtocol { - case ProtocolBuiltin, ProtocolUNIX, ProtocolTCP, ProtocolGRPC: + case ProtocolBuiltin, ProtocolBuiltinUnsync, ProtocolUNIX, ProtocolTCP, ProtocolGRPC: default: return fmt.Errorf("invalid ABCI protocol setting %q", n.ABCIProtocol) } - if n.Mode == ModeLight && n.ABCIProtocol != ProtocolBuiltin { + if n.Mode == ModeLight && n.ABCIProtocol != ProtocolBuiltin && n.ABCIProtocol != ProtocolBuiltinUnsync { return errors.New("light client must use builtin protocol") } switch n.PrivvalProtocol { diff --git a/test/e2e/runner/setup.go b/test/e2e/runner/setup.go index c398bbe9545..fda6f8129ee 100644 --- a/test/e2e/runner/setup.go +++ b/test/e2e/runner/setup.go @@ -174,7 +174,7 @@ func MakeConfig(node *e2e.Node) (*config.Config, error) { case e2e.ProtocolGRPC: cfg.ProxyApp = AppAddressTCP cfg.ABCI = "grpc" - case e2e.ProtocolBuiltin: + case e2e.ProtocolBuiltin, e2e.ProtocolBuiltinUnsync: cfg.ProxyApp = "" cfg.ABCI = "" default: @@ -258,7 +258,6 @@ func MakeAppConfig(node *e2e.Node) ([]byte, error) { "dir": "data/app", "listen": AppAddressUNIX, "mode": node.Mode, - "sync_app": node.SyncApp, "proxy_port": node.ProxyPort, "protocol": "socket", "persist_interval": node.PersistInterval, @@ -277,9 +276,9 @@ func MakeAppConfig(node *e2e.Node) ([]byte, error) { case e2e.ProtocolGRPC: cfg["listen"] = AppAddressTCP cfg["protocol"] = "grpc" - case e2e.ProtocolBuiltin: + case e2e.ProtocolBuiltin, e2e.ProtocolBuiltinUnsync: delete(cfg, "listen") - cfg["protocol"] = "builtin" + cfg["protocol"] = string(node.ABCIProtocol) default: return nil, fmt.Errorf("unexpected ABCI protocol setting %q", node.ABCIProtocol) } From 82ec855be4f215e657c86ab582c2e96ffdd19d8a Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 16 Dec 2022 17:31:04 -0500 Subject: [PATCH 22/40] e2e: Remove extraneous abci_protocol params in CI test (#9896) Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson --- test/e2e/networks/ci.toml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/e2e/networks/ci.toml b/test/e2e/networks/ci.toml index 916deb7577c..8040124150c 100644 --- a/test/e2e/networks/ci.toml +++ b/test/e2e/networks/ci.toml @@ -8,6 +8,8 @@ initial_state = { initial01 = "a", initial02 = "b", initial03 = "c" } prepare_proposal_delay = "100ms" process_proposal_delay = "100ms" check_tx_delay = "0ms" +# The most common case (e.g. Cosmos SDK-based chains). +abci_protocol = "builtin" [validators] validator01 = 100 @@ -41,7 +43,6 @@ perturb = ["disconnect"] [node.validator02] seeds = ["seed01"] database = "boltdb" -abci_protocol = "tcp" privval_protocol = "tcp" persist_interval = 0 perturb = ["restart"] @@ -49,8 +50,6 @@ perturb = ["restart"] [node.validator03] seeds = ["seed01"] database = "badgerdb" -# FIXME: should be grpc, disabled due to https://github.com/tendermint/tendermint/issues/5439 -#abci_protocol = "grpc" privval_protocol = "unix" persist_interval = 3 retain_blocks = 10 @@ -59,7 +58,6 @@ perturb = ["kill"] [node.validator04] persistent_peers = ["validator01"] database = "rocksdb" -abci_protocol = "builtin" perturb = ["pause"] [node.validator05] @@ -68,8 +66,6 @@ start_at = 1005 # Becomes part of the validator set at 1010 persistent_peers = ["validator01", "full01"] database = "cleveldb" mempool_version = "v1" -# FIXME: should be grpc, disabled due to https://github.com/tendermint/tendermint/issues/5439 -#abci_protocol = "grpc" privval_protocol = "tcp" perturb = ["kill", "pause", "disconnect", "restart"] From 8b7ae932ffbd182d56d1702b8a3310464264f7b1 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Mon, 19 Dec 2022 07:59:22 -0500 Subject: [PATCH 23/40] ci: Add govulncheck workflow (#9903) * Add vulncheck target to Makefile Signed-off-by: Thane Thomson * ci: Add govulncheck workflow Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson --- .github/workflows/govulncheck.yml | 31 +++++++++++++++++++++++++++++++ Makefile | 4 ++++ 2 files changed, 35 insertions(+) create mode 100644 .github/workflows/govulncheck.yml diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml new file mode 100644 index 00000000000..84b99593c70 --- /dev/null +++ b/.github/workflows/govulncheck.yml @@ -0,0 +1,31 @@ +name: Check for Go vulnerabilities +# Runs https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck to proactively +# check for vulnerabilities in code packages if there were any changes made to +# any Go code or dependencies. +# +# Run `make vulncheck` from the root of the repo to run this workflow locally. +on: + pull_request: + push: + branches: + - main + - release/** + +jobs: + govulncheck: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + - uses: actions/checkout@v3 + - uses: technote-space/get-diff-action@v6 + with: + PATTERNS: | + **/*.go + go.mod + go.sum + Makefile + - name: govulncheck + run: make vulncheck + if: "env.GIT_DIFF != ''" diff --git a/Makefile b/Makefile index 97295c6cea8..f1c479bb670 100644 --- a/Makefile +++ b/Makefile @@ -274,6 +274,10 @@ lint: @go run github.com/golangci/golangci-lint/cmd/golangci-lint run .PHONY: lint +vulncheck: + @go run golang.org/x/vuln/cmd/govulncheck@latest ./... +.PHONY: vulncheck + DESTINATION = ./index.html.md ############################################################################### From bbcd1288462e458ca1c9d78ef700b54aef94844a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 13:01:51 +0000 Subject: [PATCH 24/40] build(deps): Bump bufbuild/buf-setup-action from 1.9.0 to 1.10.0 (#9909) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.9.0 to 1.10.0.
Release notes

Sourced from bufbuild/buf-setup-action's releases.

v1.10.0

Set the default buf version to v1.10.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=bufbuild/buf-setup-action&package-manager=github_actions&previous-version=1.9.0&new-version=1.10.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/proto-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index 806b86ebb0c..a6a6c328b9b 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.9.0 + - uses: bufbuild/buf-setup-action@v1.10.0 - uses: bufbuild/buf-lint-action@v1 with: input: 'proto' From 9dd34ce4a1457df850bf98e2790c338f2df49e5a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 08:34:26 -0500 Subject: [PATCH 25/40] build(deps): Bump goreleaser/goreleaser-action from 3 to 4 (#9910) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 3 to 4. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/v3...v4) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pre-release.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 8101a6d34d5..5b45af8298c 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -21,7 +21,7 @@ jobs: go-version: '1.18' - name: Build - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v4 if: ${{ github.event_name == 'pull_request' }} with: version: latest @@ -31,7 +31,7 @@ jobs: - run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG_PENDING.md > ../release_notes.md - name: Release - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v4 if: startsWith(github.ref, 'refs/tags/') with: version: latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7515d19dc02..5030ce10564 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: go-version: '1.18' - name: Build - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v4 if: ${{ github.event_name == 'pull_request' }} with: version: latest @@ -28,7 +28,7 @@ jobs: - run: echo https://github.com/tendermint/tendermint/blob/${GITHUB_REF#refs/tags/}/CHANGELOG.md#${GITHUB_REF#refs/tags/} > ../release_notes.md - name: Release - uses: goreleaser/goreleaser-action@v3 + uses: goreleaser/goreleaser-action@v4 if: startsWith(github.ref, 'refs/tags/') with: version: latest From b1fbe26ffadae6e4010a71bd75767c6680d1bf71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 14:57:53 +0000 Subject: [PATCH 26/40] build(deps): Bump github.com/prometheus/common from 0.38.0 to 0.39.0 (#9913) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.38.0 to 0.39.0.
Release notes

Sourced from github.com/prometheus/common's releases.

v0.39.0

  • [ENHANCEMENT] Add support for proxy connect headers. #409
  • [ENHANCEMENT] Add platform info to labels. #403
Commits
  • 296ec92 Merge pull request #409 from prometheus/mem/proxy_header
  • 18281a2 Merge pull request #424 from prometheus/repo_sync
  • 4a0d730 Add support for proxy connect headers
  • 017dec0 Update common Prometheus files
  • befeabf Merge pull request #422 from prometheus/superq/add_mod_check
  • 1bc7f65 Add platform info to labels (#403)
  • 82accf3 Add go mod version test
  • 00e3fd7 Merge pull request #418 from roidelapluie/go119
  • 045094f Update deps and test with go 1.19
  • ddb642f Merge pull request #421 from prometheus/superq/update_sigv4
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/prometheus/common&package-manager=go_modules&previous-version=0.38.0&new-version=0.39.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 4 ++-- go.sum | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 74b8b288ad6..079f2e67795 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/pointlander/peg v1.0.1 github.com/prometheus/client_golang v1.14.0 github.com/prometheus/client_model v0.3.0 - github.com/prometheus/common v0.38.0 + github.com/prometheus/common v0.39.0 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 github.com/rs/cors v1.8.2 github.com/sasha-s/go-deadlock v0.3.1 @@ -177,7 +177,7 @@ require ( 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.2 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect diff --git a/go.sum b/go.sum index da017675c85..86bf8de257b 100644 --- a/go.sum +++ b/go.sum @@ -742,8 +742,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= -github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= @@ -939,8 +939,8 @@ github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16 github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.38.0 h1:VTQitp6mXTdUoCmDMugDVOJ1opi6ADftKfp/yeqTR/E= -github.com/prometheus/common v0.38.0/go.mod h1:MBXfmBQZrK5XpbCkjofnXs96LD2QQ7fEq4C0xjC/yec= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= 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= @@ -1353,7 +1353,7 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ 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-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= 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= From 188069b1d52df2a8803a8a2171a5dc359e072c10 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Wed, 21 Dec 2022 17:06:14 -0500 Subject: [PATCH 27/40] e2e: Add multi-version support to generator (#9933) * ci: Add missing group to manual E2E workflow Signed-off-by: Thane Thomson * e2e: Improve help for multi-version CLI param Signed-off-by: Thane Thomson * e2e: Rename multiversion to multiVersion Signed-off-by: Thane Thomson * e2e: Extract generator params into struct Signed-off-by: Thane Thomson * e2e: Add support for more than 2 versions in multi-version tests Signed-off-by: Thane Thomson * e2e: Add generator logic to extract latest release tag from Git repo Signed-off-by: Thane Thomson * e2e: Cater for "dev-" prefixes in tags Signed-off-by: Thane Thomson * e2e: Add sophisticated weighted version parsing to generator Signed-off-by: Thane Thomson * e2e: Add note to E2E readme about multi-version testing Signed-off-by: Thane Thomson * e2e: Expand on Docker image comment in readme Signed-off-by: Thane Thomson * e2e: Print node version weights when generating testnets Signed-off-by: Thane Thomson * ci: Add manual E2E workflow to run multi-version tests Signed-off-by: Thane Thomson * e2e: Replace "HEAD" keyword with "local" Signed-off-by: Thane Thomson * e2e: Update readme to reflect "HEAD" -> "local" keyword change and expand on examples Signed-off-by: Thane Thomson * e2e: Clarify comment relating to Docker image versions Signed-off-by: Thane Thomson * Apply suggestions from code review Co-authored-by: Sergio Mena * e2e: Skip invalid tags instead of erroring in generator Signed-off-by: Thane Thomson * e2e: Add comment in version selection code Signed-off-by: Thane Thomson * ci: Replace "HEAD" with "local" keyword in multiversion workflow Signed-off-by: Thane Thomson * e2e: Use error format specifier when returning wrapped error Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson Co-authored-by: Sergio Mena --- .github/workflows/e2e-manual-multiversion.yml | 38 +++++ .github/workflows/e2e-manual.yml | 2 +- go.mod | 18 ++- go.sum | 63 +++++++- test/e2e/README.md | 29 ++++ test/e2e/generator/generate.go | 143 +++++++++++++++++- test/e2e/generator/generate_test.go | 47 ++++++ test/e2e/generator/main.go | 16 +- 8 files changed, 342 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/e2e-manual-multiversion.yml create mode 100644 test/e2e/generator/generate_test.go diff --git a/.github/workflows/e2e-manual-multiversion.yml b/.github/workflows/e2e-manual-multiversion.yml new file mode 100644 index 00000000000..a40e0349e1b --- /dev/null +++ b/.github/workflows/e2e-manual-multiversion.yml @@ -0,0 +1,38 @@ +# Manually run the nightly E2E tests for a particular branch, but test with +# multiple versions. +name: e2e-manual-multiversion +on: + workflow_dispatch: + +jobs: + e2e-manual-multiversion-test: + # Run parallel jobs for the listed testnet groups (must match the + # ./build/generator -g flag) + strategy: + fail-fast: false + matrix: + group: ['00', '01', '02', '03', '04'] + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/setup-go@v3 + with: + go-version: '1.18' + + - uses: actions/checkout@v3 + + - name: Build + working-directory: test/e2e + # Run make jobs in parallel, since we can't run steps in parallel. + run: make -j2 docker generator runner tests + + - name: Generate testnets + working-directory: test/e2e + # When changing -g, also change the matrix groups above + # Generate multi-version tests with double the quantity of E2E nodes + # based on the current branch as compared to the latest version. + run: ./build/generator -g 5 -m "latest:1,local:2" -d networks/nightly/ + + - name: Run ${{ matrix.p2p }} p2p testnets + working-directory: test/e2e + run: ./run-multiple.sh networks/nightly/*-group${{ matrix.group }}-*.toml diff --git a/.github/workflows/e2e-manual.yml b/.github/workflows/e2e-manual.yml index c0eade4bd6b..9e67271d33a 100644 --- a/.github/workflows/e2e-manual.yml +++ b/.github/workflows/e2e-manual.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - group: ['00', '01', '02', '03'] + group: ['00', '01', '02', '03', '04'] runs-on: ubuntu-latest timeout-minutes: 60 steps: diff --git a/go.mod b/go.mod index 079f2e67795..0c03872d077 100644 --- a/go.mod +++ b/go.mod @@ -44,9 +44,11 @@ require ( ) require ( + github.com/Masterminds/semver/v3 v3.2.0 github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cosmos/gogoproto v1.4.3 + github.com/go-git/go-git/v5 v5.5.1 github.com/gofrs/uuid v4.3.1+incompatible github.com/google/uuid v1.3.0 github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae @@ -69,6 +71,8 @@ require ( 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.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect + github.com/acomagu/bufpipe v1.0.3 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect @@ -86,6 +90,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/cloudflare/circl v1.3.1 // indirect github.com/containerd/containerd v1.6.9 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect @@ -103,6 +108,7 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect github.com/fatih/color v1.13.0 // indirect @@ -113,6 +119,8 @@ require ( github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-chi/chi/v5 v5.0.7 // indirect github.com/go-critic/go-critic v0.6.5 // indirect + github.com/go-git/gcfg v1.5.0 // indirect + github.com/go-git/go-billy/v5 v5.3.1 // 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 @@ -151,13 +159,16 @@ require ( 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/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect github.com/jgautheron/goconst v1.5.1 // 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/kevinburke/ssh_config v1.2.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect @@ -198,6 +209,7 @@ require ( 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/pjbgf/sha1cd v0.2.3 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/profile v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -218,11 +230,13 @@ require ( 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/sergi/go-diff v1.2.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/sivchari/containedctx v1.0.2 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect github.com/sivchari/tenv v1.7.0 // indirect + github.com/skeema/knownhosts v1.1.0 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect github.com/spf13/afero v1.9.2 // indirect @@ -243,6 +257,7 @@ require ( 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/xanzy/ssh-agent v0.3.3 // indirect github.com/yagipy/maintidx v1.0.0 // indirect github.com/yeya24/promlinter v0.2.0 // indirect gitlab.com/bosi/decorder v0.2.3 // indirect @@ -261,9 +276,10 @@ require ( golang.org/x/sys v0.3.0 // indirect golang.org/x/term v0.3.0 // indirect golang.org/x/text v0.5.0 // indirect - golang.org/x/tools v0.3.0 // indirect + golang.org/x/tools v0.4.0 // indirect google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.3.3 // indirect diff --git a/go.sum b/go.sum index 86bf8de257b..ca3fcc5ef48 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,11 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 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= @@ -83,11 +86,15 @@ 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.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= 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/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= 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= @@ -103,6 +110,8 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 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= @@ -112,6 +121,8 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.3.9/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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 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= @@ -180,6 +191,7 @@ github.com/bufbuild/protocompile v0.1.0 h1:HjgJBI85hY/qmW5tw/66sNDZ7z0UDdVSi/5r4 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/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= 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/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= @@ -208,6 +220,9 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp 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/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= +github.com/cloudflare/circl v1.3.1 h1:4OVCZRL62ijwEwxnF6I7hLwxvIYi3VaZt8TflkqtrtA= +github.com/cloudflare/circl v1.3.1/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -298,6 +313,8 @@ 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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= 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= @@ -344,10 +361,20 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS 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/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= 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-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= +github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.5.1 h1:5vtv2TB5PM/gPM+EvsHJ16hJh4uAkdGcKilcwY7FYwo= +github.com/go-git/go-git/v5 v5.5.1/go.mod h1:uz5PQ3d0gz7mSgzZhSJToM6ALPaKCdSnl58/Xb5hzr8= 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= @@ -613,6 +640,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= +github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -620,10 +648,13 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod 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/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 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/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/protoreflect v1.14.0 h1:MBbQK392K3u8NTLbKOCIi3XdI+y+c6yt5oMq0X3xviw= @@ -655,6 +686,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8 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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= @@ -717,6 +750,7 @@ github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vx github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -885,6 +919,8 @@ github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9oc github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= 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/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI= +github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1006,6 +1042,9 @@ github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvW 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/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -1025,6 +1064,8 @@ github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt 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/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= +github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY= @@ -1138,6 +1179,8 @@ github.com/vektra/mockery/v2 v2.15.0 h1:5Egbxoancm1hhkJUoAF+cf0FBzC9oxS28LL/ZKbC github.com/vektra/mockery/v2 v2.15.0/go.mod h1:RswGtsqDbCR9j4UcgBQuAZY7OFxI+TgtHevc0gR0kCY= 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/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 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= @@ -1231,6 +1274,10 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y 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-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1337,7 +1384,10 @@ golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qx 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-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1466,13 +1516,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.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-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1484,6 +1539,7 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1586,8 +1642,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= 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= @@ -1732,6 +1788,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -1743,6 +1800,7 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1756,6 +1814,7 @@ 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= diff --git a/test/e2e/README.md b/test/e2e/README.md index 70a63dac5f0..ed411440b31 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -30,6 +30,35 @@ Multiple testnets can be run with the `run-multiple.sh` script: ./run-multiple.sh networks/generated/gen-group3-*.toml ``` +Testnets running different versions of Tendermint can be generated by the +generator. For example: + +```sh +# Generate testnets randomly choosing between v0.34.21 (making up 1/3rd of the +# network) and v0.34.22 (making up 2/3rds of the network). +./build/generator -m "v0.34.21:1,v0.34.22:2" -d networks/generated/ + +# "local" refers to the current local code. The E2E node built from the local +# code will be run on 2/3rds of the network, whereas the v0.34.23 E2E node will +# be run on the remaining 1/3rd. +./build/generator -m "v0.34.23:1,local:2" -d networks/generated/ + +# Using "latest" will cause the generator to auto-detect the latest +# non-pre-release version tag in the current Git repository that is closest to +# the Tendermint version in the current local code (as specified in +# ../../version/version.go). +# +# In the example below, if the local version.TMCoreSemVer value is "v0.34.24", +# for example, and the latest official release is v0.34.23, then 1/3rd of the +# network will run v0.34.23 and the remaining 2/3rds will run the E2E node built +# from the local code. +./build/generator -m "latest:1,local:2" -d networks/generated/ +``` + +**NB**: The corresponding Docker images for the relevant versions of the E2E +node (the `tendermint/e2e-node` image) must be available on the local machine, +or via [Docker Hub](https://hub.docker.com/r/tendermint/e2e-node). + ## Test Stages The test runner has the following stages, which can also be executed explicitly by running `./build/runner -f `: diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index e9806afb568..a13774b5f2b 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -1,13 +1,19 @@ package main import ( + "errors" "fmt" "math/rand" "sort" + "strconv" "strings" "time" + "github.com/Masterminds/semver/v3" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" e2e "github.com/tendermint/tendermint/test/e2e/pkg" + "github.com/tendermint/tendermint/version" ) var ( @@ -51,14 +57,44 @@ var ( } ) +type generateConfig struct { + randSource *rand.Rand + outputDir string + multiVersion string +} + // Generate generates random testnets using the given RNG. -func Generate(r *rand.Rand, multiversion string) ([]e2e.Manifest, error) { - if multiversion != "" { - nodeVersions[multiversion] = 1 +func Generate(cfg *generateConfig) ([]e2e.Manifest, error) { + if cfg.multiVersion != "" { + var err error + nodeVersions, err = parseWeightedVersions(cfg.multiVersion) + if err != nil { + return nil, err + } + if _, ok := nodeVersions["local"]; ok { + nodeVersions[""] = nodeVersions["local"] + delete(nodeVersions, "local") + } + if _, ok := nodeVersions["latest"]; ok { + latestVersion, err := gitRepoLatestReleaseVersion(cfg.outputDir) + if err != nil { + return nil, err + } + nodeVersions[latestVersion] = nodeVersions["latest"] + delete(nodeVersions, "latest") + } + } + fmt.Println("Generating testnet with weighted versions:") + for ver, wt := range nodeVersions { + if ver == "" { + fmt.Printf("- local: %d\n", wt) + } else { + fmt.Printf("- %s: %d\n", ver, wt) + } } manifests := []e2e.Manifest{} for _, opt := range combinations(testnetCombinations) { - manifest, err := generateTestnet(r, opt) + manifest, err := generateTestnet(cfg.randSource, opt) if err != nil { return nil, err } @@ -269,6 +305,7 @@ func generateNode( func generateLightNode(r *rand.Rand, startAt int64, providers []string) *e2e.ManifestNode { return &e2e.ManifestNode{ Mode: string(e2e.ModeLight), + Version: nodeVersions.Choose(r).(string), StartAt: startAt, Database: nodeDatabases.Choose(r).(string), PersistInterval: ptrUint64(0), @@ -279,3 +316,101 @@ func generateLightNode(r *rand.Rand, startAt int64, providers []string) *e2e.Man func ptrUint64(i uint64) *uint64 { return &i } + +// Parses strings like "v0.34.21:1,v0.34.22:2" to represent two versions +// ("v0.34.21" and "v0.34.22") with weights of 1 and 2 respectively. +func parseWeightedVersions(s string) (weightedChoice, error) { + wc := make(weightedChoice) + wvs := strings.Split(strings.TrimSpace(s), ",") + for _, wv := range wvs { + parts := strings.Split(strings.TrimSpace(wv), ":") + if len(parts) != 2 { + return nil, fmt.Errorf("unexpected weight:version combination: %s", wv) + } + ver := strings.TrimSpace(parts[0]) + wt, err := strconv.Atoi(strings.TrimSpace(parts[1])) + if err != nil { + return nil, fmt.Errorf("unexpected weight \"%s\": %w", parts[1], err) + } + if wt < 1 { + return nil, errors.New("version weights must be >= 1") + } + wc[ver] = uint(wt) + } + return wc, nil +} + +// Extracts the latest release version from the given Git repository. Uses the +// current version of Tendermint Core to establish the "major" version +// currently in use. +func gitRepoLatestReleaseVersion(gitRepoDir string) (string, error) { + opts := &git.PlainOpenOptions{ + DetectDotGit: true, + } + r, err := git.PlainOpenWithOptions(gitRepoDir, opts) + if err != nil { + return "", err + } + tags := make([]string, 0) + tagObjs, err := r.TagObjects() + if err != nil { + return "", err + } + err = tagObjs.ForEach(func(tagObj *object.Tag) error { + tags = append(tags, tagObj.Name) + return nil + }) + if err != nil { + return "", err + } + return findLatestReleaseTag(version.TMCoreSemVer, tags) +} + +func findLatestReleaseTag(baseVer string, tags []string) (string, error) { + baseSemVer, err := semver.NewVersion(strings.Split(baseVer, "-")[0]) + if err != nil { + return "", fmt.Errorf("failed to parse base version \"%s\": %w", baseVer, err) + } + compVer := fmt.Sprintf("%d.%d", baseSemVer.Major(), baseSemVer.Minor()) + // Build our version comparison string + // See https://github.com/Masterminds/semver#caret-range-comparisons-major for details + compStr := "^ " + compVer + verCon, err := semver.NewConstraint(compStr) + if err != nil { + return "", err + } + var latestVer *semver.Version + for _, tag := range tags { + if !strings.HasPrefix(tag, "v") { + continue + } + curVer, err := semver.NewVersion(tag) + // Skip tags that are not valid semantic versions + if err != nil { + continue + } + // Skip pre-releases + if len(curVer.Prerelease()) != 0 { + continue + } + // Skip versions that don't match our constraints + if !verCon.Check(curVer) { + continue + } + if latestVer == nil || curVer.GreaterThan(latestVer) { + latestVer = curVer + } + } + // No relevant latest version (will cause the generator to only use the tip + // of the current branch) + if latestVer == nil { + return "", nil + } + // Ensure the version string has a "v" prefix, because all Tendermint E2E + // node Docker images' versions have a "v" prefix. + vs := latestVer.String() + if !strings.HasPrefix(vs, "v") { + return "v" + vs, nil + } + return vs, nil +} diff --git a/test/e2e/generator/generate_test.go b/test/e2e/generator/generate_test.go new file mode 100644 index 00000000000..a6af7453422 --- /dev/null +++ b/test/e2e/generator/generate_test.go @@ -0,0 +1,47 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVersionFinder(t *testing.T) { + testCases := []struct { + baseVer string + tags []string + expectedLatest string + }{ + { + baseVer: "v0.34.0", + tags: []string{"v0.34.0", "v0.34.1", "v0.34.2", "v0.34.3-rc1", "v0.34.3", "v0.35.0", "v0.35.1", "v0.36.0-rc1"}, + expectedLatest: "v0.34.3", + }, + { + baseVer: "v0.38.0-dev", + tags: []string{"v0.34.0", "v0.34.1", "v0.34.2", "v0.37.0-rc2", "dev-v0.38.0"}, + expectedLatest: "", + }, + { + baseVer: "v0.37.1-rc1", + tags: []string{"v0.36.0", "v0.37.0-rc1", "v0.37.0"}, + expectedLatest: "v0.37.0", + }, + { + baseVer: "v1.0.0", + tags: []string{"v0.34.0", "v0.35.0", "v1.0.0", "v1.0.1"}, + expectedLatest: "v1.0.1", + }, + { + baseVer: "v1.1.5", + tags: []string{"v0.35.0", "v1.0.0", "v1.0.1", "v1.1.1", "v1.1.2", "v1.1.3", "v1.1.4"}, + expectedLatest: "v1.1.4", + }, + } + for _, tc := range testCases { + actualLatest, err := findLatestReleaseTag(tc.baseVer, tc.tags) + require.NoError(t, err) + assert.Equal(t, tc.expectedLatest, actualLatest) + } +} diff --git a/test/e2e/generator/main.go b/test/e2e/generator/main.go index 16bcc1b5853..3ca00dddefb 100644 --- a/test/e2e/generator/main.go +++ b/test/e2e/generator/main.go @@ -44,31 +44,35 @@ func NewCLI() *CLI { if err != nil { return err } - multiversion, err := cmd.Flags().GetString("multi-version") + multiVersion, err := cmd.Flags().GetString("multi-version") if err != nil { return err } - return cli.generate(dir, groups, multiversion) + return cli.generate(dir, groups, multiVersion) }, } cli.root.PersistentFlags().StringP("dir", "d", "", "Output directory for manifests") _ = cli.root.MarkPersistentFlagRequired("dir") - cli.root.PersistentFlags().StringP("multi-version", "m", "", "Include multi-version testing."+ - "If multi-version is not specified, then only the current Tendermint version will be used in generated testnets.") + cli.root.PersistentFlags().StringP("multi-version", "m", "", "Comma-separated list of versions of Tendermint to test in the generated testnets, "+ + "or empty to only use this branch's version") cli.root.PersistentFlags().IntP("groups", "g", 0, "Number of groups") return cli } // generate generates manifests in a directory. -func (cli *CLI) generate(dir string, groups int, multiversion string) error { +func (cli *CLI) generate(dir string, groups int, multiVersion string) error { err := os.MkdirAll(dir, 0o755) if err != nil { return err } - manifests, err := Generate(rand.New(rand.NewSource(randomSeed)), multiversion) //nolint:gosec + cfg := &generateConfig{ + randSource: rand.New(rand.NewSource(randomSeed)), //nolint:gosec + multiVersion: multiVersion, + } + manifests, err := Generate(cfg) if err != nil { return err } From a9feb1c023e172b542c972605311af83b777855b Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Thu, 22 Dec 2022 07:52:21 +0700 Subject: [PATCH 28/40] markdownlint (#9834) Co-authored-by: Sergio Mena --- CHANGELOG_PENDING.md | 37 +++++---- README.md | 2 +- RELEASES.md | 64 +++++++------- abci/example/kvstore/README.md | 4 +- consensus/README.md | 4 +- crypto/merkle/README.md | 2 +- docs/app-dev/abci-cli.md | 2 +- docs/app-dev/getting-started.md | 2 +- docs/app-dev/indexing-transactions.md | 2 +- docs/introduction/architecture.md | 6 +- docs/introduction/what-is-tendermint.md | 10 +-- docs/rfc/rfc-002-ipc-ecosystem.md | 4 +- docs/rfc/rfc-003-performance-questions.md | 33 ++++---- docs/rfc/rfc-007-deterministic-proto-bytes.md | 22 +++-- .../rfc-009-consensus-parameter-upgrades.md | 4 +- docs/rfc/rfc-011-delete-gas.md | 2 - docs/rfc/rfc-012-custom-indexing.md | 3 +- docs/rfc/rfc-015-abci++-tx-mutation.md | 6 +- docs/rfc/rfc-018-bls-agg-exploration.md | 60 +++++++------- docs/rfc/rfc-021-socket-protocol.md | 34 ++++---- docs/rfc/rfc-023-semi-permanent-testnet.md | 2 + .../rfc-024-block-structure-consolidation.md | 10 +-- docs/rfc/rfc-025-support-app-side-mempool.md | 3 +- docs/tendermint-core/block-sync.md | 1 + docs/tendermint-core/running-in-production.md | 6 +- docs/tendermint-core/state-sync.md | 20 ++--- docs/tendermint-core/using-tendermint.md | 4 +- docs/tutorials/go-built-in.md | 77 +++++++++-------- docs/tutorials/go.md | 83 ++++++++++--------- libs/events/README.md | 2 +- spec/abci/abci++_app_requirements.md | 11 +-- spec/abci/abci++_basic_concepts.md | 64 +++++++------- spec/abci/abci++_client_server.md | 2 +- spec/abci/abci++_methods.md | 20 ++--- spec/abci/abci++_tmint_expected_behavior.md | 18 ++-- spec/consensus/light-client/detection.md | 2 +- .../pbts-algorithm_001_draft.md | 3 - .../pbts-sysmodel_001_draft.md | 5 -- .../pbts_001_draft.md | 1 - spec/core/data_structures.md | 64 +++++++------- spec/light-client/accountability/README.md | 2 +- .../attacks/isolate-attackers_002_reviewed.md | 1 - .../detection/detection_001_reviewed.md | 4 - .../detection/detection_003_reviewed.md | 1 - .../supervisor/supervisor_002_draft.md | 2 +- .../verification_001_published.md | 4 - .../verification/verification_002_draft.md | 3 - .../verification/verification_003_draft.md | 2 +- spec/p2p/messages/pex.md | 2 +- spec/p2p/v0.34/README.md | 16 ++-- spec/p2p/v0.34/addressbook.md | 3 +- spec/p2p/v0.34/configuration.md | 14 ++-- spec/p2p/v0.34/peer_manager.md | 6 +- spec/p2p/v0.34/pex-protocol.md | 2 +- spec/p2p/v0.34/pex.md | 6 +- spec/p2p/v0.34/switch.md | 7 +- spec/p2p/v0.34/transport.md | 2 +- spec/p2p/v0.34/types.md | 6 +- test/e2e/README.md | 6 +- 59 files changed, 390 insertions(+), 400 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5f0e93dd067..176631644e1 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -18,11 +18,11 @@ - Blockchain Protocol - Data Storage - - [state] \#6541 Move pruneBlocks from consensus/state to state/execution. (@JayT106) + - [state] \#6541 Move pruneBlocks from consensus/state to state/execution. (@JayT106) - Tooling - - [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106) - - [metrics] \#9682 move state-syncing and block-syncing metrics to their respective packages (@cmwaters) + - [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106) + - [metrics] \#9682 move state-syncing and block-syncing metrics to their respective packages (@cmwaters) labels have moved from block_syncing -> blocksync_syncing and state_syncing -> statesync_syncing - [inspect] \#9655 Add a new `inspect` command for introspecting the state and block store of a crashed tendermint node. (@williambanfield) @@ -56,24 +56,24 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ### BREAKING CHANGES - CLI/RPC/Config - - [config] \#9259 Rename the fastsync section and the fast_sync key blocksync and block_sync respectively + - [config] \#9259 Rename the fastsync section and the fast_sync key blocksync and block_sync respectively - Apps - - [abci/counter] \#6684 Delete counter example app - - [abci] \#5783 Make length delimiter encoding consistent (`uint64`) between ABCI and P2P wire-level protocols - - [abci] \#9145 Removes unused Response/Request `SetOption` from ABCI (@samricotta) - - [abci/params] \#9287 Deduplicate `ConsensusParams` and `BlockParams` so only `types` proto definitions are used (@cmwaters) - - Remove `TimeIotaMs` and use a hard-coded 1 millisecond value to ensure monotonically increasing block times. - - Rename `AppVersion` to `App` so as to not stutter. - - [types] \#9287 Reduce the use of protobuf types in core logic. (@cmwaters) - - `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams` have become native types. + - [abci/counter] \#6684 Delete counter example app + - [abci] \#5783 Make length delimiter encoding consistent (`uint64`) between ABCI and P2P wire-level protocols + - [abci] \#9145 Removes unused Response/Request `SetOption` from ABCI (@samricotta) + - [abci/params] \#9287 Deduplicate `ConsensusParams` and `BlockParams` so only `types` proto definitions are used (@cmwaters) + - Remove `TimeIotaMs` and use a hard-coded 1 millisecond value to ensure monotonically increasing block times. + - Rename `AppVersion` to `App` so as to not stutter. + - [types] \#9287 Reduce the use of protobuf types in core logic. (@cmwaters) + - `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams` have become native types. They still utilize protobuf when being sent over the wire or written to disk. - - Moved `ValidateConsensusParams` inside (now native type) `ConsensusParams`, and renamed it to `ValidateBasic`. - - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. - - [abci] \#8216 Renamed `EvidenceType` to `MisbehaviorType` and `Evidence` to `Misbehavior` as a more accurate label of their contents. (@williambanfield, @sergio-mena) - - [abci] \#9122 Renamed `LastCommitInfo` to `CommitInfo` in preparation for vote extensions. (@cmwaters) - - [abci] \#8656, \#8901 Added cli commands for `PrepareProposal` and `ProcessProposal`. (@jmalicevic, @hvanz) - - [abci] \#6403 Change the `key` and `value` fields from `[]byte` to `string` in the `EventAttribute` type. (@alexanderbez) + - Moved `ValidateConsensusParams` inside (now native type) `ConsensusParams`, and renamed it to `ValidateBasic`. + - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. + - [abci] \#8216 Renamed `EvidenceType` to `MisbehaviorType` and `Evidence` to `Misbehavior` as a more accurate label of their contents. (@williambanfield, @sergio-mena) + - [abci] \#9122 Renamed `LastCommitInfo` to `CommitInfo` in preparation for vote extensions. (@cmwaters) + - [abci] \#8656, \#8901 Added cli commands for `PrepareProposal` and `ProcessProposal`. (@jmalicevic, @hvanz) + - [abci] \#6403 Change the `key` and `value` fields from `[]byte` to `string` in the `EventAttribute` type. (@alexanderbez) - P2P Protocol @@ -89,6 +89,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. ### IMPROVEMENTS + - [crypto] \#9250 Update to use btcec v2 and the latest btcutil. (@wcsiu) - [cli] \#9171 add `--hard` flag to rollback command (and a boolean to the `RollbackState` method). This will rollback diff --git a/README.md b/README.md index ad3cadc2ceb..ced02ea7c9a 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ Currently supported versions include: - [Tendermint Core Blog](https://medium.com/tendermint/tagged/tendermint-core) - [Cosmos Blog](https://blog.cosmos.network/tendermint/home) -## Join us! +## Join us Tendermint Core is maintained by [Interchain GmbH](https://interchain.io). If you'd like to work full-time on Tendermint Core, diff --git a/RELEASES.md b/RELEASES.md index 3f8a9c7218f..d11043a8432 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -50,6 +50,7 @@ the 0.38.x line. in order to do this). 3. Create and push the backport branch: + ```sh git checkout -b v0.38.x git push origin v0.38.x @@ -81,6 +82,7 @@ the 0.38.x line. * `docs.tendermint.com/main` -> `docs.tendermint.com/v0.38` Once you have updated all of the relevant documentation: + ```sh # Create and push the PR. git checkout -b update-docs-v038x @@ -113,7 +115,7 @@ create an alpha or beta version, or release candidate (RC) for our friends and partners to test out. We use git tags to create pre-releases, and we build them off of backport branches, for example: -- `v0.38.0-alpha.1` - The first alpha release of `v0.38.0`. Subsequent alpha +* `v0.38.0-alpha.1` - The first alpha release of `v0.38.0`. Subsequent alpha releases will be numbered `v0.38.0-alpha.2`, `v0.38.0-alpha.3`, etc. Alpha releases are to be considered the _most_ unstable of pre-releases, and @@ -121,14 +123,14 @@ off of backport branches, for example: adopters to start integrating and testing new functionality before we're done with QA. -- `v0.38.0-beta.1` - The first beta release of `v0.38.0`. Subsequent beta +* `v0.38.0-beta.1` - The first beta release of `v0.38.0`. Subsequent beta releases will be numbered `v0.38.0-beta.2`, `v0.38.0-beta.3`, etc. Beta releases can be considered more stable than alpha releases in that we will have QA'd them better than alpha releases, but there still may be minor breaking API changes if users have strong demands for such changes. -- `v0.38.0-rc1` - The first release candidate (RC) of `v0.38.0`. Subsequent RCs +* `v0.38.0-rc1` - The first release candidate (RC) of `v0.38.0`. Subsequent RCs will be numbered `v0.38.0-rc2`, `v0.38.0-rc3`, etc. RCs are considered more stable than beta releases in that we will have @@ -146,18 +148,18 @@ backport branch (see above). Otherwise: 1. Start from the backport branch (e.g. `v0.38.x`). 2. Run the integration tests and the E2E nightlies (which can be triggered from the GitHub UI; - e.g., https://github.com/tendermint/tendermint/actions/workflows/e2e-nightly-37x.yml). + e.g., ). 3. Prepare the pre-release documentation: - - Ensure that all relevant changes are in the `CHANGELOG_PENDING.md` file. + * Ensure that all relevant changes are in the `CHANGELOG_PENDING.md` file. This file's contents must only be included in the `CHANGELOG.md` when we cut final releases. - - Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes + * Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes or other upgrading flows. 4. Prepare the versioning: - - Bump TMVersionDefault version in `version.go` - - Bump P2P and block protocol versions in `version.go`, if necessary. + * Bump TMVersionDefault version in `version.go` + * Bump P2P and block protocol versions in `version.go`, if necessary. Check the changelog for breaking changes in these components. - - Bump ABCI protocol version in `version.go`, if necessary + * Bump ABCI protocol version in `version.go`, if necessary 5. Open a PR with these changes against the backport branch. 6. Once these changes have landed on the backport branch, be sure to pull them back down locally. 7. Once you have the changes locally, create the new tag, specifying a name and a tag "message": @@ -179,33 +181,33 @@ Before performing these steps, be sure the 1. Start on the backport branch (e.g. `v0.38.x`) 2. Run integration tests (`make test_integrations`) and the e2e nightlies. 3. Prepare the release: - - "Squash" changes from the changelog entries for the pre-releases into a + * "Squash" changes from the changelog entries for the pre-releases into a single entry, and add all changes included in `CHANGELOG_PENDING.md`. (Squashing includes both combining all entries, as well as removing or simplifying any intra-pre-release changes. It may also help to alphabetize the entries by package name.) - - Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for + * Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all PRs - - Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes + * Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes or other upgrading flows. - - Bump TMVersionDefault version in `version.go` - - Bump P2P and block protocol versions in `version.go`, if necessary - - Bump ABCI protocol version in `version.go`, if necessary + * Bump TMVersionDefault version in `version.go` + * Bump P2P and block protocol versions in `version.go`, if necessary + * Bump ABCI protocol version in `version.go`, if necessary 4. Open a PR with these changes against the backport branch. 5. Once these changes are on the backport branch, push a tag with prepared release details. This will trigger the actual release `v0.38.0`. - - `git tag -a v0.38.0 -m 'Release v0.38.0'` - - `git push origin v0.38.0` + * `git tag -a v0.38.0 -m 'Release v0.38.0'` + * `git push origin v0.38.0` 6. Make sure that `main` is updated with the latest `CHANGELOG.md`, `CHANGELOG_PENDING.md`, and `UPGRADING.md`. 7. Add the release to the documentation site generator config (see [DOCS\_README.md](./docs/DOCS_README.md) for more details). In summary: - - Start on branch `main`. - - Add a new line at the bottom of [`docs/versions`](./docs/versions) to + * Start on branch `main`. + * Add a new line at the bottom of [`docs/versions`](./docs/versions) to ensure the newest release is the default for the landing page. - - Add a new entry to `themeConfig.versions` in + * Add a new entry to `themeConfig.versions` in [`docs/.vuepress/config.js`](./docs/.vuepress/config.js) to include the release in the dropdown versions menu. - - Commit these changes to `main` and backport them into the backport + * Commit these changes to `main` and backport them into the backport branch for this release. ## Patch release @@ -222,21 +224,21 @@ To create a patch release: 1. Checkout the long-lived backport branch: `git checkout v0.38.x` 2. Run integration tests (`make test_integrations`) and the nightlies. 3. Check out a new branch and prepare the release: - - Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md` - - Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues - - Run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the GitHub aliases of external contributors to the top of the CHANGELOG. To lookup an alias from an email, try `bash ./scripts/authors.sh ` - - Reset the `CHANGELOG_PENDING.md` - - Bump the TMDefaultVersion in `version.go` - - Bump the ABCI version number, if necessary. + * Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md` + * Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues + * Run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the GitHub aliases of external contributors to the top of the CHANGELOG. To lookup an alias from an email, try `bash ./scripts/authors.sh ` + * Reset the `CHANGELOG_PENDING.md` + * Bump the TMDefaultVersion in `version.go` + * Bump the ABCI version number, if necessary. (Note that ABCI follows semver, and that ABCI versions are the only versions which can change during patch releases, and only field additions are valid patch changes.) 4. Open a PR with these changes that will land them back on `v0.38.x` 5. Once this change has landed on the backport branch, make sure to pull it locally, then push a tag. - - `git tag -a v0.38.1 -m 'Release v0.38.1'` - - `git push origin v0.38.1` + * `git tag -a v0.38.1 -m 'Release v0.38.1'` + * `git push origin v0.38.1` 6. Create a pull request back to main with the CHANGELOG & version changes from the latest release. - - Remove all `R:patch` labels from the pull requests that were included in the release. - - Do not merge the backport branch into main. + * Remove all `R:patch` labels from the pull requests that were included in the release. + * Do not merge the backport branch into main. ## Minor Release Checklist diff --git a/abci/example/kvstore/README.md b/abci/example/kvstore/README.md index edc2c47a535..4a6e3a43db4 100644 --- a/abci/example/kvstore/README.md +++ b/abci/example/kvstore/README.md @@ -4,7 +4,7 @@ There are two app's here: the KVStoreApplication and the PersistentKVStoreApplic ## KVStoreApplication -The KVStoreApplication is a simple merkle key-value store. +The KVStoreApplication is a simple merkle key-value store. Transactions of the form `key=value` are stored as key-value pairs in the tree. Transactions without an `=` sign set the value to the key. The app has no replay protection (other than what the mempool provides). @@ -27,4 +27,4 @@ Validator set changes are effected using the following transaction format: where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one). To remove a validator from the validator set, set power to `0`. -There is no sybil protection against new validators joining. +There is no sybil protection against new validators joining. diff --git a/consensus/README.md b/consensus/README.md index eb173d6ef82..78acd94772e 100644 --- a/consensus/README.md +++ b/consensus/README.md @@ -1,3 +1,3 @@ -# Consensus +# Consensus -See the [consensus spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus) for more information. \ No newline at end of file +See the [consensus spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus) for more information. diff --git a/crypto/merkle/README.md b/crypto/merkle/README.md index 16b1abb5852..7ef172f0945 100644 --- a/crypto/merkle/README.md +++ b/crypto/merkle/README.md @@ -1,4 +1,4 @@ # Merkle Tree -For smaller static data structures that don't require immutable snapshots or mutability; +For smaller static data structures that don't require immutable snapshots or mutability; for instance the transactions and validation signatures of a block can be hashed using this simple merkle tree logic. diff --git a/docs/app-dev/abci-cli.md b/docs/app-dev/abci-cli.md index 50eecaac817..851def9b27d 100644 --- a/docs/app-dev/abci-cli.md +++ b/docs/app-dev/abci-cli.md @@ -262,7 +262,7 @@ deployment, the role of sending messages is taken by Tendermint, which connects to the app using three separate connections, each with its own pattern of messages. -For examples of running an ABCI app with Tendermint, see the +For examples of running an ABCI app with Tendermint, see the [getting started guide](./getting-started.md). ## Bounties diff --git a/docs/app-dev/getting-started.md b/docs/app-dev/getting-started.md index 081ca8dc6de..89977d41cfe 100644 --- a/docs/app-dev/getting-started.md +++ b/docs/app-dev/getting-started.md @@ -23,7 +23,7 @@ using Tendermint. The first apps we will work with are written in Go. To install them, you need to [install Go](https://golang.org/doc/install), put -`$GOPATH/bin` in your `$PATH` and enable go modules. If you use `bash`, +`$GOPATH/bin` in your `$PATH` and enable go modules. If you use `bash`, follow these instructions: ```bash diff --git a/docs/app-dev/indexing-transactions.md b/docs/app-dev/indexing-transactions.md index 0aba615837e..7fea2cc90e4 100644 --- a/docs/app-dev/indexing-transactions.md +++ b/docs/app-dev/indexing-transactions.md @@ -84,7 +84,7 @@ the `psql` indexer type. Example: ```shell -$ psql ... -f state/indexer/sink/psql/schema.sql +psql ... -f state/indexer/sink/psql/schema.sql ``` ## Default Indexes diff --git a/docs/introduction/architecture.md b/docs/introduction/architecture.md index 3b70e701516..954ca2da733 100644 --- a/docs/introduction/architecture.md +++ b/docs/introduction/architecture.md @@ -39,7 +39,7 @@ When writing a p2p service, there are two primary responsibilities: The first responsibility is handled by the Switch: - Responsible for routing connections between peers -- Notably _only handles TCP connections_; RPC/HTTP is separate +- Notably *only handles TCP connections*; RPC/HTTP is separate - Is a dependency for every reactor; all reactors expose a function `setSwitch` - Holds onto channels (channels on the TCP connection--NOT Go channels) and uses them to route - Is a global object, with a global namespace for messages @@ -56,7 +56,7 @@ The second responsibility is handled by a combination of the PEX and the Address Here are some relevant facts about TCP: 1. All TCP connections have a "frame window size" which represents the packet size to the "confidence;" i.e., if you are sending packets along a new connection, you must start out with small packets. As the packets are received successfully, you can start to send larger and larger packets. (This curve is illustrated below.) This means that TCP connections are slow to spin up. -2. The syn/ack process also means that there's a high overhead for small, frequent messages +2. The syn/ack process also means that there's a high overhead for small, frequent messages 3. Sockets are represented by file descriptors. ![tcp](../imgs/tcp-window.png) @@ -114,7 +114,7 @@ Furthermore, all reactors expose: The `receive` method can be called many times by the mconnection. It has the same signature across all reactors. -The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the _transport_, a thin wrapper around TCP connections. +The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the *transport*, a thin wrapper around TCP connections. The following is an exhaustive (?) list of reactors: diff --git a/docs/introduction/what-is-tendermint.md b/docs/introduction/what-is-tendermint.md index a35d39f94b4..85083be28e0 100644 --- a/docs/introduction/what-is-tendermint.md +++ b/docs/introduction/what-is-tendermint.md @@ -22,7 +22,7 @@ reformalization of BFT in a more modern setting, with emphasis on peer-to-peer networking and cryptographic authentication. The name derives from the way transactions are batched in blocks, where each block contains a cryptographic hash of the previous one, forming a -chain. +chain. Tendermint consists of two chief technical components: a blockchain consensus engine and a generic application interface. The consensus @@ -55,7 +55,7 @@ atop a classical, non-BFT consensus algorithm. Zookeeper uses an algorithm called Zookeeper Atomic Broadcast, while etcd and consul use the Raft log replication algorithm. A typical cluster contains 3-5 machines, and can tolerate crash failures -in less than 1/2 of the machines (e.g., 1 out of 3 or 2 out of 5), +in less than 1/2 of the machines (e.g., 1 out of 3 or 2 out of 5), but even a single Byzantine fault can jeopardize the whole system. Each offering provides a slightly different implementation of a @@ -142,7 +142,7 @@ in design and suffers from "spaghetti code". Another problem with monolithic design is that it limits you to the language of the blockchain stack (or vice versa). In the case of Ethereum which supports a Turing-complete bytecode virtual-machine, it -limits you to languages that compile down to that bytecode; while the +limits you to languages that compile down to that bytecode; while the [list](https://github.com/pirapira/awesome-ethereum-virtual-machine#programming-languages-that-compile-into-evm) is growing, it is still very limited. @@ -156,7 +156,7 @@ protocol. [Tendermint Core](https://github.com/tendermint/tendermint), the "consensus engine", communicates with the application via a socket -protocol that satisfies the ABCI, the Tendermint Socket Protocol +protocol that satisfies the ABCI, the Tendermint Socket Protocol (TSP, or Teaspoon). To draw an analogy, lets talk about a well-known cryptocurrency, @@ -267,7 +267,7 @@ committed in a chain, with one block at each **height**. A block may fail to be committed, in which case the protocol moves to the next **round**, and a new validator gets to propose a block for that height. Two stages of voting are required to successfully commit a block; we -call them **pre-vote** and **pre-commit**. +call them **pre-vote** and **pre-commit**. There is a picture of a couple doing the polka because validators are doing something like a polka dance. When more than two-thirds of the diff --git a/docs/rfc/rfc-002-ipc-ecosystem.md b/docs/rfc/rfc-002-ipc-ecosystem.md index 8a15ae4634a..d3eba00be56 100644 --- a/docs/rfc/rfc-002-ipc-ecosystem.md +++ b/docs/rfc/rfc-002-ipc-ecosystem.md @@ -332,11 +332,11 @@ some advantages over gRPC for our domain. Specifically: - We can still get the benefits of generated data types using protocol buffers, even without using gRPC: - - Protobuf defines a standard JSON encoding for all message types so + - Protobuf defines a standard JSON encoding for all message types so languages with protobuf support do not need to worry about type mapping oddities. - - Using JSON means that even languages _without_ good protobuf support can + - Using JSON means that even languages _without_ good protobuf support can implement the protocol with a bit more work, and I expect this situation to be rare. diff --git a/docs/rfc/rfc-003-performance-questions.md b/docs/rfc/rfc-003-performance-questions.md index cb1d986e804..fb4b582be28 100644 --- a/docs/rfc/rfc-003-performance-questions.md +++ b/docs/rfc/rfc-003-performance-questions.md @@ -68,13 +68,13 @@ a series of metrics to the P2P layer to better understand the inefficiencies it The following metrics can help us understand the sources of latency in the Tendermint P2P stack: -* Number of messages sent and received per second -* Time of a message spent on the P2P layer send and receive queues +- Number of messages sent and received per second +- Time of a message spent on the P2P layer send and receive queues The following metrics exist and should be leveraged in addition to those added: -* Number of peers node's connected to -* Number of bytes per channel sent and received from each peer +- Number of peers node's connected to +- Number of bytes per channel sent and received from each peer ### Sync @@ -88,6 +88,7 @@ over a network so that we understand how much overhead Tendermint actually adds. The operation is likely to be _incredibly_ dependent on the environment in which the node is being run. The factors that will influence syncing include: + 1. Number of peers that a syncing node may fetch from. 2. Speed of the disk that a validator is writing to. 3. Speed of the network connection between the different peers that node is @@ -103,9 +104,9 @@ how much overhead Tendermint incurs. We should additionally add metrics to the blocksync operation to more clearly pinpoint slow operations. The following metrics should be added to the block syncing operation: -* Time to fetch and validate each block -* Time to execute a block -* Blocks sync'd per unit time +- Time to fetch and validate each block +- Time to execute a block +- Blocks sync'd per unit time ### Application @@ -146,7 +147,7 @@ usecase of Tendermint and do not necessarily need to be addressed at this time. ### RPC -#### Claim: The Query API is slow. +#### Claim: The Query API is slow The query API locks a mutex across the ABCI connections. This causes consensus to slow during queries, as ABCI is no longer able to make progress. This is known @@ -192,11 +193,11 @@ it takes for popular chains with many validators to gather all votes within a st Metrics that would improve visibility into this include: -* Amount of time for a node to gather votes in a step. -* Amount of time for a node to gather all block parts. -* Number of votes each node sends to gossip (i.e. not its own votes, but votes it is +- Amount of time for a node to gather votes in a step. +- Amount of time for a node to gather all block parts. +- Number of votes each node sends to gossip (i.e. not its own votes, but votes it is transmitting for a peer). -* Total number of votes each node sends to receives (A node may receive duplicate votes +- Total number of votes each node sends to receives (A node may receive duplicate votes so understanding how frequently this occurs will be valuable in evaluating the performance of the gossip system). @@ -261,17 +262,17 @@ event system. This has implications for the consensus system, which [publishes e To better understand the performance of the event system, we should add metrics to track the timing of event sends. The following metrics would be a good start for tracking this performance: -* Time in event send, labeled by Event Type -* Time in event receive, labeled by subscriber -* Event throughput, measured in events per unit time. +- Time in event send, labeled by Event Type +- Time in event receive, labeled by subscriber +- Event throughput, measured in events per unit time. ### References + [modular-hashing]: https://github.com/tendermint/tendermint/pull/6773 [issue-2186]: https://github.com/tendermint/tendermint/issues/2186 [issue-2187]: https://github.com/tendermint/tendermint/issues/2187 [rfc-002]: https://github.com/tendermint/tendermint/pull/6913 [adr-57]: https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-057-RPC.md -[issue-1319]: https://github.com/tendermint/tendermint/issues/1319 [abci-commit-description]: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci++_methods.md#commit [abci-local-client-code]: https://github.com/tendermint/tendermint/blob/511bd3eb7f037855a793a27ff4c53c12f085b570/abci/client/local_client.go#L84 [hub-signature]: https://github.com/cosmos/gaia/blob/0ecb6ed8a244d835807f1ced49217d54a9ca2070/docs/resources/genesis.md#consensus-parameters diff --git a/docs/rfc/rfc-007-deterministic-proto-bytes.md b/docs/rfc/rfc-007-deterministic-proto-bytes.md index 0b55c22283d..c1521753bc1 100644 --- a/docs/rfc/rfc-007-deterministic-proto-bytes.md +++ b/docs/rfc/rfc-007-deterministic-proto-bytes.md @@ -44,13 +44,13 @@ Proto allows fields to be encoded in any order and even be repeated. 3. Presence or absence of default values. -Types in proto have defined default values similar to Go's zero values. +Types in proto have defined default values similar to Go's zero values. Writing or omitting a default value are both legal ways of encoding a wire message. -4. Serialization of 'unknown' fields. +4. Serialization of 'unknown' fields. -Unknown fields can be present when a message is created by a binary with a newer -version of the proto that contains fields that the deserializer in a different +Unknown fields can be present when a message is created by a binary with a newer +version of the proto that contains fields that the deserializer in a different binary does not yet know about. Deserializers in binaries that do not know about the field will maintain the bytes of the unknown field but not place them into the deserialized structure. @@ -60,26 +60,26 @@ We have a few options to consider when producing this stable representation. #### Use only compliant serializers and constrain field usage -According to [Cosmos-SDK ADR-27][cosmos-sdk-adr-27], when message types obey a simple +According to [Cosmos-SDK ADR-27][cosmos-sdk-adr-27], when message types obey a simple set of rules, gogoproto produces a consistent byte representation of serialized messages. This seems promising, although more research is needed to guarantee gogoproto always -produces a consistent set of bytes on serialized messages. This would solve the problem +produces a consistent set of bytes on serialized messages. This would solve the problem within Tendermint as written in Go, but would require ensuring that there are similar serializers written in other languages that produce the same output as gogoproto. -#### Reorder serialized bytes to ensure determinism. +#### Reorder serialized bytes to ensure determinism The serialized form of a proto message can be transformed into a canonical representation by applying simple rules to the serialized bytes. Re-ordering the serialized bytes would allow Tendermint to produce a canonical byte representation without having to simultaneously maintain a custom proto marshaller. -This could be implemented as a function in many languages that performed the following +This could be implemented as a function in many languages that performed the following producing bytes to sign or hashing: 1. Does not add any of the data from unknown fields into the type to hash. -Tendermint should not run into a case where it needs to verify the integrity of +Tendermint should not run into a case where it needs to verify the integrity of data with unknown fields for the following reasons: The purpose of checking hash equality within Tendermint is to ensure that @@ -91,7 +91,7 @@ despite not understanding what their internal structure is. It's not clear what mean to verify that a block contains data that a process does not know about. The same reasoning applies for signature verification within Tendermint. Processes -verify that a digital signature signed over a set of bytes by locally reconstructing the +verify that a digital signature signed over a set of bytes by locally reconstructing the data structure that the digital signature signed using the process's local data. 2. Reordered all message fields to be in tag-sorted order. @@ -133,8 +133,6 @@ properly. ### References [proto-spec-encoding]: https://developers.google.com/protocol-buffers/docs/encoding -[spec-issue]: https://github.com/tendermint/tendermint/issues/5005 [cosmos-sdk-adr-27]: https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-027-deterministic-protobuf-serialization.md -[cer-proto-3]: https://github.com/regen-network/canonical-proto3 [wire-pb]: https://github.com/creachadair/wirepb diff --git a/docs/rfc/rfc-009-consensus-parameter-upgrades.md b/docs/rfc/rfc-009-consensus-parameter-upgrades.md index d5077840db2..e89c4c1ab73 100644 --- a/docs/rfc/rfc-009-consensus-parameter-upgrades.md +++ b/docs/rfc/rfc-009-consensus-parameter-upgrades.md @@ -66,7 +66,7 @@ have been updated until a height at which the parameters existed. #### Only Update HashedParams on Hash-Breaking Releases An alternate solution to never hashing defaults is to not update the hashed -parameters on non-hash-breaking releases. This means that when new consensus +parameters on non-hash-breaking releases. This means that when new consensus parameters are added to Tendermint, there may be a release that makes use of the parameters but does not verify that they are the same across all validators by referencing them in the hash. This seems reasonably safe given the fact that @@ -107,7 +107,7 @@ default values of the new parameters for a single height. As documented in the upcoming [ADR-74][adr-74], popular chains often simply use the default values. Additionally, great care is being taken to ensure that logic governed by upcoming -consensus parameters is not liveness-breaking. This means that, at worst-case, +consensus parameters is not liveness-breaking. This means that, at worst-case, chains will experience a single slow height while waiting for the new values to by applied. diff --git a/docs/rfc/rfc-011-delete-gas.md b/docs/rfc/rfc-011-delete-gas.md index a4e643ef2fb..854ed73957d 100644 --- a/docs/rfc/rfc-011-delete-gas.md +++ b/docs/rfc/rfc-011-delete-gas.md @@ -156,7 +156,5 @@ gossiped along with the transaction. [cosmos-sdk-gas]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/gas-fees.md [cosmos-sdk-fees]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/tx-lifecycle.md#gas-and-fees [anoma-gas]: https://github.com/anoma/anoma/blob/6974fe1532a59db3574fc02e7f7e65d1216c1eb2/docs/src/specs/ledger.md#transaction-execution -[cosmos-sdk-fee]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/types/tx/tx.pb.go#L780-L794 -[issue-7750]: https://github.com/tendermint/tendermint/issues/7750 [reap-max-bytes-max-gas]: https://github.com/tendermint/tendermint/blob/1ac58469f32a98f1c0e2905ca1773d9eac7b7103/internal/mempool/types.go#L45 [add-mempool-error]: https://github.com/tendermint/tendermint/blob/205bfca66f6da1b2dded381efb9ad3792f9404cf/rpc/coretypes/responses.go#L239 diff --git a/docs/rfc/rfc-012-custom-indexing.md b/docs/rfc/rfc-012-custom-indexing.md index 64f9fc94b73..489bcccc1d2 100644 --- a/docs/rfc/rfc-012-custom-indexing.md +++ b/docs/rfc/rfc-012-custom-indexing.md @@ -329,7 +329,7 @@ something like this (subject to refinement): - [KV transaction indexer][kv-index] - [Pluggable custom event indexing][i7135] (#7135) - [PostgreSQL event sink][psql] - - [PostgreSQL database][postgres] + - [PostgreSQL database][postgres] - [Query filter language][query] - [Stream events to postgres for indexing][i1161] (#1161) - [Unbuffered event subscription slow down the consensus][i7247] (#7247) @@ -346,7 +346,6 @@ something like this (subject to refinement): [kv-index]: https://github.com/tendermint/tendermint/blob/main/state/indexer/block/kv [postgres]: https://postgresql.org/ [psql]: https://github.com/tendermint/tendermint/tree/main/state/indexer/sink/psql -[psql]: https://github.com/tendermint/tendermint/tree/main/state/indexer/sink/psql [query]: https://pkg.go.dev/github.com/tendermint/tendermint/internal/pubsub/query/syntax [sdk]: https://github.com/cosmos/cosmos-sdk [tmdb]: https://pkg.go.dev/github.com/tendermint/tm-db#DB diff --git a/docs/rfc/rfc-015-abci++-tx-mutation.md b/docs/rfc/rfc-015-abci++-tx-mutation.md index 3c7854ed356..92d9ed66877 100644 --- a/docs/rfc/rfc-015-abci++-tx-mutation.md +++ b/docs/rfc/rfc-015-abci++-tx-mutation.md @@ -77,7 +77,7 @@ from the mempool, so this would be a pretty straightforward change. Transaction replacement would would enable applications to aggregate or disaggregate transactions. For aggregation, a set of transactions that all related work, such as transferring -tokens between the same two accounts, could be replaced with a single transaction, +tokens between the same two accounts, could be replaced with a single transaction, i.e. one that transfers a single sum from one account to the other. Applications that make frequent use of aggregation may be able to achieve a higher throughput. Aggregation would decrease the space occupied by a single client-submitted transaction in the block, allowing @@ -189,7 +189,7 @@ it did not want executed. In this validation scheme, applications that allow replacement would check that each listed replaced transaction was correctly reflected in the replacement transaction. In order to perform such validation, the node would need to have the replaced transactions -locally. This could be accomplished one of a few ways: by querying the mempool, +locally. This could be accomplished one of a few ways: by querying the mempool, by adding an additional p2p gossip channel for transaction replacements, or by including the replaced transactions in the block. Replacement validation via mempool querying would require the node to have received all of the replaced transactions in the mempool which is far from @@ -255,7 +255,5 @@ power instead of immediately solving the problem for them. ### References [inclusion-proof]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/types/tx.go#L67 -[tx-serach-result]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/rpc/coretypes/responses.go#L267 -[tx-rpc-func]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/rpc/core/tx.go#L21 [tx-result-index]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/state/indexer/tx/kv/kv.go#L90 [abci-event-type]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/abci/types/types.pb.go#L3168 diff --git a/docs/rfc/rfc-018-bls-agg-exploration.md b/docs/rfc/rfc-018-bls-agg-exploration.md index 70ca171a091..6de7510ab47 100644 --- a/docs/rfc/rfc-018-bls-agg-exploration.md +++ b/docs/rfc/rfc-018-bls-agg-exploration.md @@ -16,29 +16,29 @@ become confusing quickly. Different sources appear to use slightly different meanings of each term and this can certainly add to the confusion. Below is a brief glossary that may be helpful in understanding the discussion that follows. -* **Short Signature**: A signature that does not vary in length with the +- **Short Signature**: A signature that does not vary in length with the number of signers. -* **Multi-Signature**: A signature generated over a single message +- **Multi-Signature**: A signature generated over a single message where, given the message and signature, a verifier is able to determine that all parties signed the message. May be short or may vary with the number of signers. -* **Aggregated Signature**: A _short_ signature generated over messages with +- **Aggregated Signature**: A _short_ signature generated over messages with possibly different content where, given the messages and signature, a verifier should be able to determine that all the parties signed the designated messages. -* **Threshold Signature**: A _short_ signature generated from multiple signers +- **Threshold Signature**: A _short_ signature generated from multiple signers where, given a message and the signature, a verifier is able to determine that a large enough share of the parties signed the message. The identities of the parties that contributed to the signature are not revealed. -* **BLS Signature**: An elliptic-curve pairing-based signature system that +- **BLS Signature**: An elliptic-curve pairing-based signature system that has some nice properties for short multi-signatures. May stand for -*Boneh-Lynn-Schacham* or *Barreto-Lynn-Scott* depending on the context. A +_Boneh-Lynn-Schacham_ or _Barreto-Lynn-Scott_ depending on the context. A BLS signature is type of signature scheme that is distinct from other forms of elliptic-curve signatures such as ECDSA and EdDSA. -* **Interactive**: Cryptographic scheme where parties need to perform one or +- **Interactive**: Cryptographic scheme where parties need to perform one or more request-response cycles to produce the cryptographic material. For example, an interactive signature scheme may require the signer and the verifier to cooperate to create and/or verify the signature, rather than a signature being created ahead of time. -* **Non-interactive**: Cryptographic scheme where parties do not need to +- **Non-interactive**: Cryptographic scheme where parties do not need to perform any request-response cycles to produce the cryptographic material. ### Brief notes on pairing-based elliptic-curve cryptography @@ -89,11 +89,11 @@ depth discussion, see the specific paper on BLS12-381, [Short signatures from BLS signatures have already gained traction within several popular projects. -* Algorand is working on an implementation. -* [Zcash][zcash-adoption] has adopted BLS12-381 into the protocol. -* [Ethereum 2.0][eth-2-adoption] has adopted BLS12-381 into the protocol. -* [Chia Network][chia-adoption] has adopted BLS for signing blocks. -* [Ostracon][line-ostracon-pr], a fork of Tendermint has adopted BLS for signing blocks. +- Algorand is working on an implementation. +- [Zcash][zcash-adoption] has adopted BLS12-381 into the protocol. +- [Ethereum 2.0][eth-2-adoption] has adopted BLS12-381 into the protocol. +- [Chia Network][chia-adoption] has adopted BLS for signing blocks. +- [Ostracon][line-ostracon-pr], a fork of Tendermint has adopted BLS for signing blocks. ### What systems may be affected by adding aggregated signatures? @@ -106,7 +106,7 @@ overhead. How costly this is is still subject to further investigation and performance testing. Even if vote signatures were aggregated before gossip, each validator would still -need to receive and verify vote extension data from each (individual) peer validator in +need to receive and verify vote extension data from each (individual) peer validator in order for consensus to proceed. That displaces any advantage gained by aggregating signatures across the vote message in the presence of vote extensions. #### Block Creation @@ -190,7 +190,7 @@ check an aggregated signature from 1024 validators versus our ed25519 library's #### Reduce Light-Client Verification Time -The light client aims to be a faster and lighter-weight way to verify that a +The light client aims to be a faster and lighter-weight way to verify that a block was voted on by a Tendermint network. The light client fetches Tendermint block headers and commit signatures, performing public key verification to ensure that the associated validator set signed the block. @@ -212,7 +212,7 @@ able to check if some singular validator's key signed the block. ##### Vote Gossip It is possible to aggregate subsets of signatures during voting, so that the -network need not gossip all *n* validator signatures to all *n* validators. +network need not gossip all _n_ validator signatures to all _n_ validators. Theoretically, subsets of the signatures could be aggregated during consensus and vote messages could carry those aggregated signatures. Implementing this would certainly increase the complexity of the gossip layer but could possibly @@ -243,12 +243,12 @@ possible for storing highly sensitive private key material. Below is a list of popular HSMs along with their support for BLS signatures. -* YubiKey - * [No support][yubi-key-bls-support] -* Amazon Cloud HSM - * [No support][cloud-hsm-support] -* Ledger - * [Lists support for the BLS12-381 curve][ledger-bls-announce] +- YubiKey + - [No support][yubi-key-bls-support] +- Amazon Cloud HSM + - [No support][cloud-hsm-support] +- Ledger + - [Lists support for the BLS12-381 curve][ledger-bls-announce] I cannot find support listed for Google Cloud, although perhaps it exists. @@ -261,7 +261,7 @@ reasonably unclear benefit. ### Can aggregated signatures be added as soft-upgrades? -In my estimation, yes. With the implementation of proposer-based timestamps, +In my estimation, yes. With the implementation of proposer-based timestamps, all validators now produce signatures on only one of two messages: 1. A [CanonicalVote][canonical-vote-proto] where the BlockID is the hash of the block or @@ -409,7 +409,7 @@ the block. ### Library Support -Libraries for BLS signature creation are limited in number, although active +Libraries for BLS signature creation are limited in number, although active development appears to be ongoing. Cryptographic algorithms are difficult to implement correctly and correctness issues are extremely serious and dangerous. No further exploration of BLS should be undertaken without strong assurance of @@ -422,7 +422,7 @@ and is supported by funds from the Ethereum foundation, adopting a new cryptogra library presents some serious risks. Namely, if the support for the library were to be discontinued, Tendermint may become saddled with the requirement of supporting a very complex piece of software or force a massive ecosystem-wide migration away -from BLS signatures. +from BLS signatures. This is one of the more serious reasons to avoid adopting BLS signatures at this time. There is no gold standard library. Some projects look promising, but no @@ -472,7 +472,7 @@ of re-aggregating the public key. Aggregation is _not_ constant time in the number of keys and instead grows linearly. When [benchmarked locally][blst-verify-bench-agg], blst public key aggregation of 128 keys took 2.43 milliseconds. This, along with the 1.5 milliseconds to verify a signature would raise light client signature -verification time to 3.9 milliseconds, a time above the previously mentioned +verification time to 3.9 milliseconds, a time above the previously mentioned batch verification time using our ed25519 library of 2.0 milliseconds. Schemes to cache aggregated subsets of keys could certainly cut this time down at the @@ -501,8 +501,8 @@ the associated protocols. ## Open Questions -* *Q*: Can you aggregate Ed25519 signatures in Tendermint? - * There is a suggested scheme in github issue [7892][suggested-ed25519-agg], +- _Q_: Can you aggregate Ed25519 signatures in Tendermint? + - There is a suggested scheme in github issue [7892][suggested-ed25519-agg], but additional rigor would be required to fully verify its correctness. ## Current Consideration @@ -523,9 +523,7 @@ standards develop. ### References -[line-ostracon-repo]: https://github.com/line/ostracon [line-ostracon-pr]: https://github.com/line/ostracon/pull/117 -[mit-BLS-lecture]: https://youtu.be/BFwc2XA8rSk?t=2521 [gcp-storage-pricing]: https://cloud.google.com/storage/pricing#north-america_2 [yubi-key-bls-support]: https://github.com/Yubico/yubihsm-shell/issues/66 [cloud-hsm-support]: https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-key-types.html @@ -533,7 +531,6 @@ standards develop. [bls-ietf-terms]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-1.3 [bls-ietf-pop]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3 [multi-signatures-smaller-blockchains]: https://eprint.iacr.org/2018/483.pdf -[ibc-tendermint]: https://github.com/cosmos/ibc/tree/master/spec/client/ics-007-tendermint-client [zcash-adoption]: https://github.com/zcash/zcash/issues/2502 [chia-adoption]: https://github.com/Chia-Network/chia-blockchain#chia-blockchain [bls-ietf-ecdsa-compare]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-1.1 @@ -551,5 +548,4 @@ standards develop. [bls-weil-pairing]: https://www.iacr.org/archive/asiacrypt2001/22480516.pdf [summing-zero-paper]: https://eprint.iacr.org/2021/323.pdf [circl]: https://github.com/cloudflare/circl -[light-client-evidence]: https://github.com/tendermint/tendermint/blob/a6fd1fe20116d4b1f7e819cded81cece8e5c1ac7/types/evidence.go#L245 [suggested-ed25519-agg]: https://github.com/tendermint/tendermint/issues/7892 diff --git a/docs/rfc/rfc-021-socket-protocol.md b/docs/rfc/rfc-021-socket-protocol.md index 61e95f6cb42..4b8fd2ab6d3 100644 --- a/docs/rfc/rfc-021-socket-protocol.md +++ b/docs/rfc/rfc-021-socket-protocol.md @@ -85,7 +85,7 @@ applications using it. In particular: the server that are not clearly documented anywhere, and it is very easy for small changes in both the client and the server to lead to tricky deadlocks, panics, race conditions, and slowdowns. As a recent example of this, see - https://github.com/tendermint/tendermint/pull/8581. + . These limitations are fixable, but one important question is whether it is worthwhile to fix them. We can add request and method identifiers, for @@ -190,28 +190,28 @@ design. - **Standardize on gRPC** - - ✅ Addresses existing performance and operational issues. - - ✅ Replaces custom code with a well-maintained widely-used library. - - ✅ Aligns with Cosmos SDK, which already uses gRPC extensively. - - ✅ Aligns with priv validator interface, for which the socket protocol is already deprecated for gRPC. - - ❓ Applications will be hard to implement in a language without gRPC support. - - ⛔ All users of the socket protocol have to migrate to gRPC, and we believe most current out-of-process applications use the socket protocol. + - ✅ Addresses existing performance and operational issues. + - ✅ Replaces custom code with a well-maintained widely-used library. + - ✅ Aligns with Cosmos SDK, which already uses gRPC extensively. + - ✅ Aligns with priv validator interface, for which the socket protocol is already deprecated for gRPC. + - ❓ Applications will be hard to implement in a language without gRPC support. + - ⛔ All users of the socket protocol have to migrate to gRPC, and we believe most current out-of-process applications use the socket protocol. - **Standardize on socket protocol** - - ✅ Less immediate impact for existing users (but see below). - - ✅ Simplifies ABCI API surface by removing gRPC. - - ❓ Users of the socket protocol will have a (smaller) migration. - - ❓ Potentially easier to implement for languages that do not have support. - - ⛔ Need to do all the work to fix the socket protocol (which will require existing users to update anyway later). - - ⛔ Ongoing maintenance burden for per-language server implementations. + - ✅ Less immediate impact for existing users (but see below). + - ✅ Simplifies ABCI API surface by removing gRPC. + - ❓ Users of the socket protocol will have a (smaller) migration. + - ❓ Potentially easier to implement for languages that do not have support. + - ⛔ Need to do all the work to fix the socket protocol (which will require existing users to update anyway later). + - ⛔ Ongoing maintenance burden for per-language server implementations. - **Keep both options** - - ✅ Less immediate impact for existing users (but see below). - - ❓ Users of the socket protocol will have a (smaller) migration. - - ⛔ Still need to do all the work to fix the socket protocol (which will require existing users to update anyway later). - - ⛔ Requires ongoing maintenance and support of both gRPC and socket protocol integrations. + - ✅ Less immediate impact for existing users (but see below). + - ❓ Users of the socket protocol will have a (smaller) migration. + - ⛔ Still need to do all the work to fix the socket protocol (which will require existing users to update anyway later). + - ⛔ Requires ongoing maintenance and support of both gRPC and socket protocol integrations. ## References diff --git a/docs/rfc/rfc-023-semi-permanent-testnet.md b/docs/rfc/rfc-023-semi-permanent-testnet.md index ddb31a90816..7f5e68cd512 100644 --- a/docs/rfc/rfc-023-semi-permanent-testnet.md +++ b/docs/rfc/rfc-023-semi-permanent-testnet.md @@ -42,6 +42,7 @@ Once the decision has been made to run and operate a service, one of the next strategic questions is that of deploying said service. The author strongly holds the opinion that, when possible, a continuous delivery model offers the most compelling set of advantages: + - The code on a particular branch (likely `main` or `master`) is exactly what is, or what will very soon be, running in production - There are no manual steps involved in deploying -- other than merging your pull request, @@ -50,6 +51,7 @@ a continuous delivery model offers the most compelling set of advantages: In summary, if the tendermint authors build, maintain, and continuously deliver an application intended to serve as a long-lived testnet, they will be able to state with confidence: + - We operate the software in a production-like environment and we have observed it to be stable and performant to our requirements - We have discovered issues in production before any external parties have consumed our software, diff --git a/docs/rfc/rfc-024-block-structure-consolidation.md b/docs/rfc/rfc-024-block-structure-consolidation.md index c8cab17f5ea..91dec2d63f5 100644 --- a/docs/rfc/rfc-024-block-structure-consolidation.md +++ b/docs/rfc/rfc-024-block-structure-consolidation.md @@ -140,7 +140,7 @@ these are not its primary concern. ### Data to consider removing -This section proposes a list of data that could be completely removed from the +This section proposes a list of data that could be completely removed from the Merkle tree with no loss to the functionality of our consensus algorithm. Where the change is possible but would hamper external protocols or make @@ -241,7 +241,7 @@ only one header. validation. The light client uses this field to ensure that the validator set it fetched from a full node is correct. It can be sure of the correctness of the retrieved structure by hashing it and checking the hash against the `ValidatorsHash` -of the block it is verifying. Because a validator that the light client trusts +of the block it is verifying. Because a validator that the light client trusts signed over the `ValidatorsHash`, it can be certain of the validity of the structure. Without this check, phony validator sets could be handed to the light client and the code tricked into believing a different validator set was present @@ -268,7 +268,7 @@ of basic information about the chain. #### ProofOfLockRound -The *proof of lock round* is the round of consensus for a height in which the +The _proof of lock round_ is the round of consensus for a height in which the Tendermint algorithm observed a super majority of voting power on the network for a block. @@ -318,7 +318,7 @@ or unchanged from previous blocks_. For example, we propagate the `ValidatorAddr for each block in the `CommitSig` structure even when it never changed from a previous height. We could achieve a speed-up in many cases by communicating the hashes _first_ and letting peers request additional information when they do not -recognize the communicated hash. +recognize the communicated hash. For example, in the case of the `ValidatorAddress`es, the node would first communicate the `ValidatorsHash` of the block to its peers. The peers would @@ -353,12 +353,10 @@ this would not be light client breaking. ## References -[light-verify-trusting]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/validation.go#L124 [part-set-header]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/part_set.go#L94 [block-id]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/block.go#L1090 [psh-check]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/part_set.go#L116 [proposer-selection]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/spec/consensus/proposer-selection.md -[chain-experiment]: https://github.com/williambanfield/tmtools/blob/master/hash-changes/RUN.txt [val-hash]: https://github.com/tendermint/tendermint/blob/29e5fbcc648510e4763bd0af0b461aed92c21f30/types/validator.go#L160 [proposer-check]: https://github.com/tendermint/tendermint/blob/29e5fbcc648510e4763bd0af0b461aed92c21f30/internal/state/validation.go#L102 [save-block]: https://github.com/tendermint/tendermint/blob/59f0236b845c83009bffa62ed44053b04370b8a9/internal/store/store.go#L490 diff --git a/docs/rfc/rfc-025-support-app-side-mempool.md b/docs/rfc/rfc-025-support-app-side-mempool.md index 6dfa83a0a92..63dea8696fa 100644 --- a/docs/rfc/rfc-025-support-app-side-mempool.md +++ b/docs/rfc/rfc-025-support-app-side-mempool.md @@ -12,7 +12,7 @@ of the Tendermint mempool becomes much less clear. This RFC discusses possible changes that should be considered to Tendermint to better support applications that intend to use `PrepareProposal` to implement much more powerful transaction ordering and filtering functionality than Tendermint can provide. It proposes -scoping down the responsibilities of Tendermint to suit this new use case. +scoping down the responsibilities of Tendermint to suit this new use case. ## Background @@ -293,7 +293,6 @@ future designs are made in this area: ## References -[mempool-cache]:https://github.com/tendermint/tendermint/blob/c8302c5fcb7f1ffafdefc5014a26047df1d27c99/mempool/v1/mempool.go#L41 [cache-when-clear]:https://github.com/tendermint/tendermint/issues/7723 [update-remove-from-cache]:https://github.com/tendermint/tendermint/pull/233 [update-keep-in-cache]:https://github.com/tendermint/tendermint/issues/2855 diff --git a/docs/tendermint-core/block-sync.md b/docs/tendermint-core/block-sync.md index 4d55d52b875..d0e2e6ea70c 100644 --- a/docs/tendermint-core/block-sync.md +++ b/docs/tendermint-core/block-sync.md @@ -3,6 +3,7 @@ order: 10 --- # Block Sync + *Formerly known as Fast Sync* In a proof of work blockchain, syncing with the chain is the same diff --git a/docs/tendermint-core/running-in-production.md b/docs/tendermint-core/running-in-production.md index 8da4b65a29c..52ec4a9a74a 100644 --- a/docs/tendermint-core/running-in-production.md +++ b/docs/tendermint-core/running-in-production.md @@ -220,8 +220,8 @@ Recovering from data corruption can be hard and time-consuming. Here are two app ./scripts/wal2json/wal2json "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal ``` -3) Search for a "CORRUPTED MESSAGE" line. -4) By looking at the previous message and the message after the corrupted one +3) Search for a "CORRUPTED MESSAGE" line. +4) By looking at the previous message and the message after the corrupted one and looking at the logs, try to rebuild the message. If the consequent messages are marked as corrupted too (this may happen if length header got corrupted or some writes did not make it to the WAL ~ truncation), @@ -232,7 +232,7 @@ Recovering from data corruption can be hard and time-consuming. Here are two app $EDITOR /tmp/corrupted_wal ``` -5) After editing, convert this file back into binary form by running: +5) After editing, convert this file back into binary form by running: ```sh ./scripts/json2wal/json2wal /tmp/corrupted_wal $TMHOME/data/cs.wal/wal diff --git a/docs/tendermint-core/state-sync.md b/docs/tendermint-core/state-sync.md index 8400a6ef9de..0f477302e29 100644 --- a/docs/tendermint-core/state-sync.md +++ b/docs/tendermint-core/state-sync.md @@ -4,41 +4,41 @@ order: 11 # State Sync -With block sync a node is downloading all of the data of an application from genesis and verifying it. -With state sync your node will download data related to the head or near the head of the chain and verify the data. -This leads to drastically shorter times for joining a network. +With block sync a node is downloading all of the data of an application from genesis and verifying it. +With state sync your node will download data related to the head or near the head of the chain and verify the data. +This leads to drastically shorter times for joining a network. ## Using State Sync State sync will continuously work in the background to supply nodes with chunked data when bootstrapping. -> NOTE: Before trying to use state sync, see if the application you are operating a node for supports it. +> NOTE: Before trying to use state sync, see if the application you are operating a node for supports it. Under the state sync section in `config.toml` you will find multiple settings that need to be configured in order for your node to use state sync. Lets breakdown the settings: - `enable`: Enable is to inform the node that you will be using state sync to bootstrap your node. -- `rpc_servers`: RPC servers are needed because state sync utilizes the light client for verification. - - 2 servers are required, more is always helpful. +- `rpc_servers`: RPC servers are needed because state sync utilizes the light client for verification. + - 2 servers are required, more is always helpful. - `temp_dir`: Temporary directory is store the chunks in the machines local storage, If nothing is set it will create a directory in `/tmp` -The next information you will need to acquire it through publicly exposed RPC's or a block explorer which you trust. +The next information you will need to acquire it through publicly exposed RPC's or a block explorer which you trust. - `trust_height`: Trusted height defines at which height your node should trust the chain. - `trust_hash`: Trusted hash is the hash in the `BlockID` corresponding to the trusted height. -- `trust_period`: Trust period is the period in which headers can be verified. +- `trust_period`: Trust period is the period in which headers can be verified. > :warning: This value should be significantly smaller than the unbonding period. If you are relying on publicly exposed RPC's to get the need information, you can use `curl`. -Example: +Example: ```bash curl -s https://233.123.0.140:26657/commit | jq "{height: .result.signed_header.header.height, hash: .result.signed_header.commit.block_id.hash}" ``` -The response will be: +The response will be: ```json { diff --git a/docs/tendermint-core/using-tendermint.md b/docs/tendermint-core/using-tendermint.md index 91421854d51..36eca6300ad 100644 --- a/docs/tendermint-core/using-tendermint.md +++ b/docs/tendermint-core/using-tendermint.md @@ -47,8 +47,8 @@ definition](https://github.com/tendermint/tendermint/blob/main/types/genesis.go) - `chain_id`: ID of the blockchain. **This must be unique for every blockchain.** If your testnet blockchains do not have unique 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. +- `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/tendermint/blob/main/spec/core/state.md#consensusparams) - `block` - `max_bytes`: Max block size, in bytes. diff --git a/docs/tutorials/go-built-in.md b/docs/tutorials/go-built-in.md index 3f38551cf14..f979fa81c04 100644 --- a/docs/tutorials/go-built-in.md +++ b/docs/tutorials/go-built-in.md @@ -13,10 +13,10 @@ experience with Tendermint Core. Tendermint Core is a service that provides a Byzantine Fault Tolerant consensus engine for state-machine replication. The replicated state-machine, or "application", can be written in any language that can send and receive protocol buffer messages in a client-server model. -Applications written in Go can also use Tendermint as a library and run the service in the same -process as the application. +Applications written in Go can also use Tendermint as a library and run the service in the same +process as the application. -By following along this tutorial you will create a Tendermint Core application called kvstore, +By following along this tutorial you will create a Tendermint Core application called kvstore, a (very) simple distributed BFT key-value store. The application will be written in Go and some understanding of the Go programming language is expected. @@ -30,15 +30,15 @@ We strongly advise against using unreleased commits for your development. ### Built-in app vs external app -On the one hand, to get maximum performance you can run your application in -the same process as the Tendermint Core, as long as your application is written in Go. +On the one hand, to get maximum performance you can run your application in +the same process as the Tendermint Core, as long as your application is written in Go. [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) is written -this way. +this way. This is the approach followed in this tutorial. -On the other hand, having a separate application might give you better security -guarantees as two processes would be communicating via established binary protocol. -Tendermint Core will not have access to application's state. +On the other hand, having a separate application might give you better security +guarantees as two processes would be communicating via established binary protocol. +Tendermint Core will not have access to application's state. If that is the way you wish to proceed, use the [Creating an application in Go](./go.md) guide instead of this one. @@ -90,7 +90,7 @@ go mod init kvstore go get github.com/tendermint/tendermint@latest ``` -After running the above commands you will see two generated files, `go.mod` and `go.sum`. +After running the above commands you will see two generated files, `go.mod` and `go.sum`. The go.mod file should look similar to: ```go @@ -114,11 +114,11 @@ go build ## 1.3 Writing a Tendermint Core application Tendermint Core communicates with the application through the Application -BlockChain Interface (ABCI). The messages exchanged through the interface are +BlockChain Interface (ABCI). The messages exchanged through the interface are defined in the ABCI [protobuf file](https://github.com/tendermint/tendermint/blob/main/proto/tendermint/abci/types.proto). -We begin by creating the basic scaffolding for an ABCI application by +We begin by creating the basic scaffolding for an ABCI application by creating a new type, `KVStoreApplication`, which implements the methods defined by the `abcitypes.Application` interface. @@ -203,7 +203,7 @@ to the project when you ran `go get`. If your IDE is not recognizing the types, go get github.com/tendermint/tendermint@latest ``` -Now go back to the `main.go` and modify the `main` function so it matches the following, +Now go back to the `main.go` and modify the `main` function so it matches the following, where an instance of the `KVStoreApplication` type is created. ```go @@ -221,17 +221,18 @@ and to start it along with the Tendermint Service. ### 1.3.1 Add a persistent data store + Our application will need to write its state out to persistent storage so that it can stop and start without losing all of its data. For this tutorial, we will use [BadgerDB](https://github.com/dgraph-io/badger), a -a fast embedded key-value store. +a fast embedded key-value store. First, add Badger as a dependency of your go module using the `go get` command: `go get github.com/dgraph-io/badger/v3` -Next, let's update the application and its constructor to receive a handle to the database, as follows: +Next, let's update the application and its constructor to receive a handle to the database, as follows: ```go type KVStoreApplication struct { @@ -246,7 +247,7 @@ func NewKVStoreApplication(db *badger.DB) *KVStoreApplication { } ``` -The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block +The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block is completed. Don't worry about it for now, we'll get to that later. Next, update the `import` stanza at the top to include the Badger library: @@ -265,7 +266,8 @@ Finally, update the `main.go` file to invoke the updated constructor: ``` ### 1.3.2 CheckTx -When Tendermint Core receives a new transaction from a client, or from another full node, Tendermint asks the application if + +When Tendermint Core receives a new transaction from a client, or from another full node, Tendermint asks the application if the transaction is acceptable, using the `CheckTx` method. Invalid transactions will not be shared with other nodes and will not become part of any blocks and, therefore, will not be executed by the application. @@ -295,17 +297,17 @@ func (app *KVStoreApplication) CheckTx(req abcitypes.RequestCheckTx) abcitypes.R } ``` -While this `CheckTx` is simple and only validates that the transaction is well-formed, +While this `CheckTx` is simple and only validates that the transaction is well-formed, it is very common for `CheckTx` to make more complex use of the state of an application. -For example, you may refuse to overwrite an existing value, or you can associate +For example, you may refuse to overwrite an existing value, or you can associate versions to the key/value pairs and allow the caller to specify a version to perform a conditional update. Depending on the checks and on the conditions violated, the function may return -different values, but any response with a non-zero code will be considered invalid -by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes -its validation checks. The specific value of the code is meaningless to Tendermint. -Non-zero codes are logged by Tendermint so applications can provide more specific +different values, but any response with a non-zero code will be considered invalid +by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes +its validation checks. The specific value of the code is meaningless to Tendermint. +Non-zero codes are logged by Tendermint so applications can provide more specific information on why the transaction was rejected. Note that `CheckTx` does not execute the transaction, it only verifies that that the transaction could be executed. We do not know yet if the rest of the network has agreed to accept this transaction into a block. @@ -334,7 +336,7 @@ receive a block. - `EndBlock` is called once to indicate to the application that no more transactions will be delivered to the application in within this block. -Note that, to implement these calls in our application we're going to make use of Badger's +Note that, to implement these calls in our application we're going to make use of Badger's transaction mechanism. We will always refer to these as Badger transactions, not to confuse them with the transactions included in the blocks delivered by Tendermint, the _application transactions_. @@ -372,26 +374,26 @@ func (app *KVStoreApplication) DeliverTx(req abcitypes.RequestDeliverTx) abcityp Note that we check the validity of the transaction _again_ during `DeliverTx`. Transactions are not guaranteed to be valid when they are delivered to an -application, even if they were valid when they were proposed. +application, even if they were valid when they were proposed. This can happen if the application state is used to determine transaction validity. Application state may have changed between the initial execution of `CheckTx` and the transaction delivery in `DeliverTx` in a way that rendered the transaction no longer valid. `EndBlock` is called to inform the application that the full block has been delivered -and give the application a chance to perform any other computation needed, before the +and give the application a chance to perform any other computation needed, before the effects of the transactions become permanent. -Note that `EndBlock` **cannot** yet commit the Badger transaction we were building +Note that `EndBlock` **cannot** yet commit the Badger transaction we were building in during `DeliverTx`. Since other methods, such as `Query`, rely on a consistent view of the application's -state, the application should only update its state by committing the Badger transactions +state, the application should only update its state by committing the Badger transactions when the full block has been delivered and the `Commit` method is invoked. -The `Commit` method tells the application to make permanent the effects of +The `Commit` method tells the application to make permanent the effects of the application transactions. Let's update the method to terminate the pending Badger transaction and -persist the resulting state: +persist the resulting state: ```go func (app *KVStoreApplication) Commit() abcitypes.ResponseCommit { @@ -416,10 +418,11 @@ import ( You may have noticed that the application we are writing will crash if it receives an unexpected error from the Badger database during the `DeliverTx` or `Commit` methods. -This is not an accident. If the application received an error from the database, there +This is not an accident. If the application received an error from the database, there is no deterministic way for it to make progress so the only safe option is to terminate. ### 1.3.4 Query + When a client tries to read some information from the `kvstore`, the request will be handled in the `Query` method. To do this, let's rewrite the `Query` method in `app.go`: @@ -454,11 +457,12 @@ Since it reads only committed data from the store, transactions that are part of that is being processed are not reflected in the query result. ### 1.3.5 PrepareProposal and ProcessProposal + `PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 to give the application more control over the construction and processing of transaction blocks. When Tendermint Core sees that valid transactions (validated through `CheckTx`) are available to be -included in blocks, it groups some of these transactions and then gives the application a chance +included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. The application is free to modify the group before returning from the call, as long as the resulting set @@ -476,7 +480,7 @@ func (app *KVStoreApplication) PrepareProposal(proposal abcitypes.RequestPrepare Once a proposed block is received by a node, the proposal is passed to the application to give its blessing before voting to accept the proposal. -This mechanism may be used for different reasons, for example to deal with blocks manipulated +This mechanism may be used for different reasons, for example to deal with blocks manipulated by malicious nodes, in which case the block should not be considered valid. The following code simply accepts all proposals: @@ -655,6 +659,7 @@ messages). Normally, you would use `SignerRemote` to connect to an external return nil, fmt.Errorf("failed to load node's key: %w", err) } ``` + Now we have everything set up to run the Tendermint node. We construct a node by passing it the configuration, the logger, a handle to our application and the genesis information: @@ -684,6 +689,7 @@ Finally, we start the node, i.e., the Tendermint Core service inside our applica node.Wait() }() ``` + The additional logic at the end of the file allows the program to catch SIGTERM. This means that the node can shut down gracefully when an operator tries to kill the program: ```go @@ -758,7 +764,8 @@ Open another terminal window and run the following curl command: ```bash curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"' ``` -If everything went well, you should see a response indicating which height the + +If everything went well, you should see a response indicating which height the transaction was included in the blockchain. Finally, let's make sure that transaction really was persisted by the application. @@ -779,7 +786,7 @@ The request returns a `json` object with a `key` and `value` field set. ``` Those values don't look like the `key` and `value` we sent to Tendermint. -What's going on here? +What's going on here? The response contains a `base64` encoded representation of the data we submitted. To get the original value out of this data, we can use the `base64` command line utility: diff --git a/docs/tutorials/go.md b/docs/tutorials/go.md index 5bd65aa16ea..df430962eac 100644 --- a/docs/tutorials/go.md +++ b/docs/tutorials/go.md @@ -13,10 +13,10 @@ experience with Tendermint Core. Tendermint Core is a service that provides a Byzantine Fault Tolerant consensus engine for state-machine replication. The replicated state-machine, or "application", can be written in any language that can send and receive protocol buffer messages in a client-server model. -Applications written in Go can also use Tendermint as a library and run the service in the same -process as the application. +Applications written in Go can also use Tendermint as a library and run the service in the same +process as the application. -By following along this tutorial you will create a Tendermint Core application called kvstore, +By following along this tutorial you will create a Tendermint Core application called kvstore, a (very) simple distributed BFT key-value store. The application will be written in Go and some understanding of the Go programming language is expected. @@ -28,15 +28,16 @@ Note: Please use the latest released version of this guide and of Tendermint. We strongly advise against using unreleased commits for your development. ### Built-in app vs external app -On the one hand, to get maximum performance you can run your application in -the same process as the Tendermint Core, as long as your application is written in Go. + +On the one hand, to get maximum performance you can run your application in +the same process as the Tendermint Core, as long as your application is written in Go. [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) is written -this way. +this way. If that is the way you wish to proceed, use the [Creating a built-in application in Go](./go-built-in.md) guide instead of this one. -On the other hand, having a separate application might give you better security -guarantees as two processes would be communicating via established binary protocol. -Tendermint Core will not have access to application's state. +On the other hand, having a separate application might give you better security +guarantees as two processes would be communicating via established binary protocol. +Tendermint Core will not have access to application's state. This is the approach followed in this tutorial. ## 1.1 Installing Go @@ -87,7 +88,7 @@ go mod init kvstore go get github.com/tendermint/tendermint@latest ``` -After running the above commands you will see two generated files, `go.mod` and `go.sum`. +After running the above commands you will see two generated files, `go.mod` and `go.sum`. The go.mod file should look similar to: ```go @@ -112,11 +113,11 @@ go build ## 1.3 Writing a Tendermint Core application Tendermint Core communicates with the application through the Application -BlockChain Interface (ABCI). The messages exchanged through the interface are +BlockChain Interface (ABCI). The messages exchanged through the interface are defined in the ABCI [protobuf file](https://github.com/tendermint/tendermint/blob/main/proto/tendermint/abci/types.proto). -We begin by creating the basic scaffolding for an ABCI application by +We begin by creating the basic scaffolding for an ABCI application by creating a new type, `KVStoreApplication`, which implements the methods defined by the `abcitypes.Application` interface. @@ -201,7 +202,7 @@ to the project when you ran `go get`. If your IDE is not recognizing the types, go get github.com/tendermint/tendermint@latest ``` -Now go back to the `main.go` and modify the `main` function so it matches the following, +Now go back to the `main.go` and modify the `main` function so it matches the following, where an instance of the `KVStoreApplication` type is created. @@ -220,17 +221,18 @@ and to start it along with the Tendermint Service. ### 1.3.1 Add a persistent data store + Our application will need to write its state out to persistent storage so that it can stop and start without losing all of its data. For this tutorial, we will use [BadgerDB](https://github.com/dgraph-io/badger), a -a fast embedded key-value store. +a fast embedded key-value store. First, add Badger as a dependency of your go module using the `go get` command: `go get github.com/dgraph-io/badger/v3` -Next, let's update the application and its constructor to receive a handle to the database, as follows: +Next, let's update the application and its constructor to receive a handle to the database, as follows: ```go type KVStoreApplication struct { @@ -245,7 +247,7 @@ func NewKVStoreApplication(db *badger.DB) *KVStoreApplication { } ``` -The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block +The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block is completed. Don't worry about it for now, we'll get to that later. Next, update the `import` stanza at the top to include the Badger library: @@ -265,7 +267,8 @@ Finally, update the `main.go` file to invoke the updated constructor: ### 1.3.2 CheckTx -When Tendermint Core receives a new transaction from a client, Tendermint asks the application if + +When Tendermint Core receives a new transaction from a client, Tendermint asks the application if the transaction is acceptable, using the `CheckTx` method. In our application, a transaction is a string with the form `key=value`, indicating a key and value to write to the store. @@ -294,17 +297,17 @@ func (app *KVStoreApplication) CheckTx(req abcitypes.RequestCheckTx) abcitypes.R } ``` -While this `CheckTx` is simple and only validates that the transaction is well-formed, +While this `CheckTx` is simple and only validates that the transaction is well-formed, it is very common for `CheckTx` to make more complex use of the state of an application. -For example, you may refuse to overwrite an existing value, or you can associate +For example, you may refuse to overwrite an existing value, or you can associate versions to the key/value pairs and allow the caller to specify a version to perform a conditional update. Depending on the checks and on the conditions violated, the function may return -different values, but any response with a non-zero code will be considered invalid -by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes -its validation checks. The specific value of the code is meaningless to Tendermint. -Non-zero codes are logged by Tendermint so applications can provide more specific +different values, but any response with a non-zero code will be considered invalid +by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes +its validation checks. The specific value of the code is meaningless to Tendermint. +Non-zero codes are logged by Tendermint so applications can provide more specific information on why the transaction was rejected. Note that `CheckTx` does not execute the transaction, it only verifies that that the transaction could be executed. We do not know yet if the rest of the network has agreed to accept this transaction into a block. @@ -333,7 +336,7 @@ receive a block. - `EndBlock` is called once to indicate to the application that no more transactions will be delivered to the application in within this block. -Note that, to implement these calls in our application we're going to make use of Badger's +Note that, to implement these calls in our application we're going to make use of Badger's transaction mechanism. We will always refer to these as Badger transactions, not to confuse them with the transactions included in the blocks delivered by Tendermint, the _application transactions_. @@ -371,26 +374,26 @@ func (app *KVStoreApplication) DeliverTx(req abcitypes.RequestDeliverTx) abcityp Note that we check the validity of the transaction _again_ during `DeliverTx`. Transactions are not guaranteed to be valid when they are delivered to an -application, even if they were valid when they were proposed. +application, even if they were valid when they were proposed. This can happen if the application state is used to determine transaction validity. Application state may have changed between the initial execution of `CheckTx` and the transaction delivery in `DeliverTx` in a way that rendered the transaction no longer valid. `EndBlock` is called to inform the application that the full block has been delivered -and give the application a chance to perform any other computation needed, before the +and give the application a chance to perform any other computation needed, before the effects of the transactions become permanent. -Note that `EndBlock` **cannot** yet commit the Badger transaction we were building +Note that `EndBlock` **cannot** yet commit the Badger transaction we were building in during `DeliverTx`. Since other methods, such as `Query`, rely on a consistent view of the application's -state, the application should only update its state by committing the Badger transactions +state, the application should only update its state by committing the Badger transactions when the full block has been delivered and the `Commit` method is invoked. -The `Commit` method tells the application to make permanent the effects of +The `Commit` method tells the application to make permanent the effects of the application transactions. Let's update the method to terminate the pending Badger transaction and -persist the resulting state: +persist the resulting state: ```go func (app *KVStoreApplication) Commit() abcitypes.ResponseCommit { @@ -415,10 +418,11 @@ import ( You may have noticed that the application we are writing will crash if it receives an unexpected error from the Badger database during the `DeliverTx` or `Commit` methods. -This is not an accident. If the application received an error from the database, there +This is not an accident. If the application received an error from the database, there is no deterministic way for it to make progress so the only safe option is to terminate. ### 1.3.4 Query + When a client tries to read some information from the `kvstore`, the request will be handled in the `Query` method. To do this, let's rewrite the `Query` method in `app.go`: @@ -453,11 +457,12 @@ Since it reads only committed data from the store, transactions that are part of that is being processed are not reflected in the query result. ### 1.3.5 PrepareProposal and ProcessProposal -`PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 + +`PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 to give the application more control over the construction and processing of transaction blocks. When Tendermint Core sees that valid transactions (validated through `CheckTx`) are available to be -included in blocks, it groups some of these transactions and then gives the application a chance +included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. The application is free to modify the group before returning from the call, as long as the resulting set @@ -475,7 +480,7 @@ func (app *KVStoreApplication) PrepareProposal(proposal abcitypes.RequestPrepare Once a proposed block is received by a node, the proposal is passed to the application to give its blessing before voting to accept the proposal. -This mechanism may be used for different reasons, for example to deal with blocks manipulated +This mechanism may be used for different reasons, for example to deal with blocks manipulated by malicious nodes, in which case the block should not be considered valid. The following code simply accepts all proposals: @@ -589,6 +594,7 @@ which connects to our server and send us transactions and other messages. signal.Notify(c, os.Interrupt, syscall.SIGTERM) <-c ``` + ## 1.5 Initializing and Running Our application is almost ready to run, but first we'll need to populate the Tendermint Core configuration files. @@ -631,8 +637,8 @@ I[2022-11-09|17:01:28.726] service start msg="Sta I[2022-11-09|17:01:28.726] Waiting for new connection... ``` -Then we need to start Tendermint Core service and point it to our application. -Open a new terminal window and cd to the same folder where the app is running. +Then we need to start Tendermint Core service and point it to our application. +Open a new terminal window and cd to the same folder where the app is running. Then execute the following command: ```bash @@ -672,7 +678,8 @@ Open another terminal window and run the following curl command: ```bash curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"' ``` -If everything went well, you should see a response indicating which height the + +If everything went well, you should see a response indicating which height the transaction was included in the blockchain. Finally, let's make sure that transaction really was persisted by the application. @@ -693,7 +700,7 @@ The request returns a `json` object with a `key` and `value` field set. ``` Those values don't look like the `key` and `value` we sent to Tendermint. -What's going on here? +What's going on here? The response contains a `base64` encoded representation of the data we submitted. To get the original value out of this data, we can use the `base64` command line utility: diff --git a/libs/events/README.md b/libs/events/README.md index 836e9c72eaf..aecef704bec 100644 --- a/libs/events/README.md +++ b/libs/events/README.md @@ -24,7 +24,7 @@ Pub-Sub in go with event caching ### Package files -[event_cache.go](./event_cache.go) [events.go](./events.go) +[event_cache.go](./event_cache.go) [events.go](./events.go) ## Type [EventCache](./event_cache.go?s=116:179#L5) diff --git a/spec/abci/abci++_app_requirements.md b/spec/abci/abci++_app_requirements.md index 4d2dc7011bb..3fd312c03ff 100644 --- a/spec/abci/abci++_app_requirements.md +++ b/spec/abci/abci++_app_requirements.md @@ -128,10 +128,11 @@ As a general rule, `VerifyVoteExtension` SHOULD always accept the vote extension --> * Requirement 9 [*all*, no-side-effects]: *p*'s calls to `RequestPrepareProposal`, - `RequestProcessProposal`, + `RequestProcessProposal`, + --> at height *h* do not modify *sp,h-1*. @@ -366,7 +367,7 @@ For more information, see Section [State Sync](#state-sync). ### Transaction Results For each transaction within a block, the Application is expected to return a result within -[`ResponseDeliverTx`](./abci%2B%2B_methods.md#delivertx). +[`ResponseDeliverTx`](./abci%2B%2B_methods.md#delivertx). -We plan to extend this to allow applications to intervene at the moment a (precommit) vote is sent/received. -The applications could then require their validators to do more than just validating blocks through the `ExtendVote` +We plan to extend this to allow applications to intervene at the moment a (precommit) vote is sent/received. +The applications could then require their validators to do more than just validating blocks through the `ExtendVote` and `VerifyVoteExtension` methods. ## Method overview @@ -64,7 +64,7 @@ Methods can be classified into four categories: *consensus*, *mempool*, *info*, The first time a new blockchain is started, Tendermint calls `InitChain`. From then on, methods `BeginBlock`, `DeliverTx` and `EndBlock` are executed upon the decision of each block, resulting in an updated Application -state. One `DeliverTx` is called for each transaction in the block. The result is an updated application state. +state. One `DeliverTx` is called for each transaction in the block. The result is an updated application state. Cryptographic commitments to the results of `DeliverTx`, and an application-provided hash in `Commit` are included in the header of the next block. During the execution of an instance of consensus, which decides the block for a given height, and before method `BeginBlock` is called, methods `PrepareProposal` and `ProcessProposal`, may be called several times. See @@ -82,7 +82,7 @@ call sequences of these methods. been locked at Tendermint level. Tendermint gathers outstanding transactions from the mempool, generates a block header, and uses them to create a block to propose. Then, it calls `RequestPrepareProposal` with the newly created proposal, called *raw proposal*. The Application - can make changes to the raw proposal, such as modifying the set of transactions or the order + can make changes to the raw proposal, such as modifying the set of transactions or the order in which they appear, and returns the (potentially) modified proposal, called *prepared proposal* in the `ResponsePrepareProposal` call. The logic modifying the raw proposal can be non-deterministic. @@ -98,14 +98,14 @@ call sequences of these methods. the proposal is invalid (e.g., an invalid transaction); the Application can ignore the invalid part of the prepared proposal at block execution time. -- [**BeginBlock:**](./abci++_methods.md#beginblock) Is called exactly once after a block has been decided +- [**BeginBlock:**](./abci++_methods.md#beginblock) Is called exactly once after a block has been decided and executes once before all `DeliverTx` method calls. -- [**DeliverTx**](./abci++_methods.md#delivertx) Upon completion of `BeginBlock`, +- [**DeliverTx**](./abci++_methods.md#delivertx) Upon completion of `BeginBlock`, `DeliverTx` is called once for each of the transactions within the block. The application defines further checks to confirm their - validity - for example a key-value store might verify that the key does not already exist. Note that - even if a transaction does not pass the check in `DeliverTx`, it will still be part of the block as the + validity - for example a key-value store might verify that the key does not already exist. Note that + even if a transaction does not pass the check in `DeliverTx`, it will still be part of the block as the block has already been voted on (unlike with `CheckTx` which would dismiss such a transaction). The responses returned by `DeliverTx` are included in the header of the next block. @@ -232,7 +232,7 @@ to accommodate the long block execution time and non-proposer nodes might time out and prevote `nil`. The proposal, in this case, will probably be rejected and a new round will be necessary. -Operators will need to adjust the default value of *TimeoutPropose* in Tendermint's configuration file, +Operators will need to adjust the default value of *TimeoutPropose* in Tendermint's configuration file, in order to suit the needs of the particular application being deployed. ## Deterministic State-Machine Replication @@ -298,7 +298,7 @@ on them. All other fields in the `Response*` must be strictly deterministic. [↑ Back to Outline](#outline) -Methods `BeginBlock, DeliverTx` and `EndBlock ` include an `events` field in their +Methods `BeginBlock, DeliverTx` and `EndBlock` include an `events` field in their `Response*`. Applications may respond to this ABCI++ method with an event list for each executed transaction, and a general event list for the block itself. @@ -309,7 +309,7 @@ and instead exist to power subscriptions and queries of Tendermint state. An `Event` contains a `type` and a list of `EventAttributes`, which are key-value string pairs denoting metadata about what happened during the method's (or transaction's) execution. `Event` values can be used to index transactions and blocks according to what -happened during their execution. +happened during their execution. Each event has a `type` which is meant to categorize the event for a particular `Response*` or `Tx`. A `Response*` or `Tx` may contain multiple events with duplicate @@ -423,7 +423,7 @@ these codes reports errors related to the transaction it is attached to. However, `FinalizeBlock` does not return errors at the top level, so the same considerations on critical issues made for `Echo`, `Info`, and `InitChain` also apply here. ---> +--> The handling of non-zero response codes by Tendermint is described below. @@ -433,10 +433,10 @@ When Tendermint receives a `ResponseCheckTx` with a non-zero `Code`, the associa transaction will not be added to Tendermint's mempool or it will be removed if it is already included. -### `DeliverTx` +### `DeliverTx` -The `DeliverTx` ABCI method delivers transactions from Tendermint to the application. -When Tendermint receives a `ResponseDeliverTx` with a non-zero `Code`, the response code is logged. +The `DeliverTx` ABCI method delivers transactions from Tendermint to the application. +When Tendermint receives a `ResponseDeliverTx` with a non-zero `Code`, the response code is logged. The transaction was already included in a block, so the `Code` does not influence Tendermint consensus. +--> ## Server Implementations To use ABCI in your programming language of choice, there must be an ABCI diff --git a/spec/abci/abci++_methods.md b/spec/abci/abci++_methods.md index dfaba34b90c..c45b0ae3770 100644 --- a/spec/abci/abci++_methods.md +++ b/spec/abci/abci++_methods.md @@ -201,14 +201,14 @@ title: Methods * **Usage**: * [**Required**] The core method of the application. - * `DeliverTx` is called once for each transaction in the block. - * When `DeliverTx` is called, the application must execute the transaction deterministically - in full before returning control to Tendermint. + * `DeliverTx` is called once for each transaction in the block. + * When `DeliverTx` is called, the application must execute the transaction deterministically + in full before returning control to Tendermint. * Alternatively, the application can apply a candidate state corresponding to the same block previously executed via `PrepareProposal` or `ProcessProposal` any time between the calls to `BeginBlock`, the various calls to `DeliverTx` and `EndBlock`. * `ResponseDeliverTx.Code == 0` only if the transaction is fully valid. - + ### EndBlock @@ -238,7 +238,7 @@ title: Methods * `consensus_param_updates` returned for block `H` apply to the consensus params for block `H+1`. For more information on the consensus parameters, see the [application spec entry on consensus parameters](abci++_app_requirements.md#consensus-parameters). - * `validator_updates` and `consensus_param_updates` may be empty. In this case, Tendermint will keep the current values. + * `validator_updates` and `consensus_param_updates` may be empty. In this case, Tendermint will keep the current values. @@ -261,7 +261,7 @@ title: Methods * Signal the application to persist the application state. * Return an (optional) Merkle root hash of the application state * `ResponseCommit.Data` is included as the `Header.AppHash` in the next block - * It may be empty or hard-coded, but MUST be **deterministic** - it must not be a function of anything that did not come from the parameters of the execution calls (` BeginBlock/DeliverTx/EndBlock methods`) and the previous committed state. + * It may be empty or hard-coded, but MUST be **deterministic** - it must not be a function of anything that did not come from the parameters of the execution calls (`BeginBlock/DeliverTx/EndBlock methods`) and the previous committed state. * Later calls to `Query` can return proofs about the application state anchored in this Merkle root hash * Use `RetainHeight` with caution! If all nodes in the network remove historical @@ -453,11 +453,11 @@ title: Methods returned in `ResponsePrepareProposal.txs` . * As a result of executing the prepared proposal, the Application may produce block events or transaction events. The Application must keep those events until a block is decided. It will then forward the events to the `BeginBlock-DeliverTx-EndBlock` functions depending on where each event should be placed, thereby returning the events to Tendermint. - * Tendermint does NOT provide any additional validity checks (such as checking for duplicate + * Tendermint does NOT provide any additional validity checks (such as checking for duplicate transactions). * If Tendermint fails to validate the `ResponsePrepareProposal`, Tendermint will assume the Application is faulty and crash. @@ -897,7 +897,7 @@ Most of the data structures used in ABCI are shared [common data structures](../ * **Usage**: * Indicates whether a validator signed the last block, allowing for rewards based on validator availability. * This information is extracted from Tendermint's data structures in the local process. - * `vote_extension` is reserved for future use when vote extensions are added. Currently, this field is always set to `nil`. + * `vote_extension` is reserved for future use when vote extensions are added. Currently, this field is always set to `nil`. ### CommitInfo @@ -994,4 +994,4 @@ enum VerifyStatus { --> -[protobuf-timestamp]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp \ No newline at end of file +[protobuf-timestamp]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp diff --git a/spec/abci/abci++_tmint_expected_behavior.md b/spec/abci/abci++_tmint_expected_behavior.md index 849fb3fd990..74b73336d61 100644 --- a/spec/abci/abci++_tmint_expected_behavior.md +++ b/spec/abci/abci++_tmint_expected_behavior.md @@ -23,12 +23,12 @@ what will happen during a block height _h_ in these frequent, benign conditions: * `VerifyVoteExtension` will be called exactly _n-1_ times at each validator process, where _n_ is the number of validators, and will always return _accept_ in its `Response*`; --> -* `BeginBlock` will be called exactly once at all processes, conveying the same prepared +* `BeginBlock` will be called exactly once at all processes, conveying the same prepared block header that all calls to `PrepareProposal` and `ProcessProposal` had previously reported for height _h_; and -* `DeliverTx` will be called exactly once for each transaction within the block. -* `EndBlock` will be called exactly once after `DeliverTx` has been executed for all transactions and marks - the end of processing for the block. +* `DeliverTx` will be called exactly once for each transaction within the block. +* `EndBlock` will be called exactly once after `DeliverTx` has been executed for all transactions and marks + the end of processing for the block. * `Commit` will finally be called exactly once at all processes at the end of height _h_. However, the Application logic must be ready to cope with any possible run of Tendermint for a given @@ -162,21 +162,23 @@ Let us now examine the grammar line by line, providing further details. >``` * For every round, if the local process is the proposer of the current round, Tendermint starts by - calling `PrepareProposal`, followed by `ProcessProposal`. + calling `PrepareProposal`, followed by `ProcessProposal`. + --> >```abnf >proposer = prepare-proposal process-proposal >``` * Also for every round, if the local process is _not_ the proposer of the current round, Tendermint - will call `ProcessProposal` at most once. + will call `ProcessProposal` at most once. . diff --git a/spec/light-client/attacks/isolate-attackers_002_reviewed.md b/spec/light-client/attacks/isolate-attackers_002_reviewed.md index 927c81bd6b8..8b430b8b683 100644 --- a/spec/light-client/attacks/isolate-attackers_002_reviewed.md +++ b/spec/light-client/attacks/isolate-attackers_002_reviewed.md @@ -197,7 +197,6 @@ For this fixed group membership, we have analyzed the attacks using the TLA+ spe [[detection]] The specification of the light client attack detection mechanism. -[[tendermint-accountability]]: TLA+ specification to check the types of attacks [tendermint-accountability]: https://github.com/tendermint/spec/blob/master/rust-spec/tendermint-accountability/README.md diff --git a/spec/light-client/detection/detection_001_reviewed.md b/spec/light-client/detection/detection_001_reviewed.md index bcd2c54bbe6..dfb67c9a884 100644 --- a/spec/light-client/detection/detection_001_reviewed.md +++ b/spec/light-client/detection/detection_001_reviewed.md @@ -771,13 +771,9 @@ Once a bogus block is recognized as such the secondary is removed. [supervisor]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/supervisor/supervisor.md -[block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md -[TMBC-FM-2THIRDS-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-fm-2thirds1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-sound-distr-poss-commit1 -[LCV-SEQ-SAFE-link]:https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#lcv-seq-safe1 [TMBC-VAL-CONTAINS-CORR-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-val-contains-corr1 diff --git a/spec/light-client/detection/detection_003_reviewed.md b/spec/light-client/detection/detection_003_reviewed.md index a300e403f09..28d3104c703 100644 --- a/spec/light-client/detection/detection_003_reviewed.md +++ b/spec/light-client/detection/detection_003_reviewed.md @@ -807,7 +807,6 @@ Once a bogus block is recognized as such the secondary is removed. [supervisor]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/supervisor/supervisor_001_draft.md -[block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md [TMBC-FM-2THIRDS-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification_002_draft.md#tmbc-fm-2thirds1 diff --git a/spec/light-client/supervisor/supervisor_002_draft.md b/spec/light-client/supervisor/supervisor_002_draft.md index 3926b75abd6..2649b305836 100644 --- a/spec/light-client/supervisor/supervisor_002_draft.md +++ b/spec/light-client/supervisor/supervisor_002_draft.md @@ -25,7 +25,7 @@ Types](https://github.com/tendermint/tendermint/blob/main/types/genesis.go). The light client is based on subjective initialization. It has to trust the initial data given to it by the user. It cannot perform any detection of an attack yet instead requires an initial point of trust. -There are three forms of initial data which are used to obtain the +There are three forms of initial data which are used to obtain the first trusted block: - A trusted block from a prior initialization diff --git a/spec/light-client/verification/verification_001_published.md b/spec/light-client/verification/verification_001_published.md index f446dda0209..8cdae0acf1b 100644 --- a/spec/light-client/verification/verification_001_published.md +++ b/spec/light-client/verification/verification_001_published.md @@ -1152,7 +1152,6 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md -[TMBC-HEADER-link]: #tmbc-header1 [TMBC-SEQ-link]: #tmbc-seq1 [TMBC-CorrFull-link]: #tmbc-corr-full1 [TMBC-Auth-Byz-link]: #tmbc-auth-byz1 @@ -1160,7 +1159,6 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [TMBC-FM-2THIRDS-link]: #tmbc-fm-2thirds1 [TMBC-VAL-CONTAINS-CORR-link]: #tmbc-val-contains-corr1 [TMBC-VAL-COMMIT-link]: #tmbc-val-commit1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: #tmbc-sound-distr-poss-commit1 [lightclient]: https://github.com/interchainio/tendermint-rs/blob/e2cb9aca0b95430fca2eac154edddc9588038982/docs/architecture/adr-002-lite-client.md [fork-detector]: https://github.com/tendermint/tendermint/tree/main/spec/light-client/detection @@ -1168,7 +1166,5 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [ibc-rs]:https://github.com/informalsystems/ibc-rs -[blockchain-validator-set]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md#validatorset -[fullnode-data-structures]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md [arXiv]: https://arxiv.org/abs/1807.04938 diff --git a/spec/light-client/verification/verification_002_draft.md b/spec/light-client/verification/verification_002_draft.md index 5082c5870aa..aaa9dc230f8 100644 --- a/spec/light-client/verification/verification_002_draft.md +++ b/spec/light-client/verification/verification_002_draft.md @@ -1045,7 +1045,6 @@ func Backwards (primary PeerID, root LightBlock, targetHeight Height) [TMBC-FM-2THIRDS-link]: #tmbc-fm-2thirds1 [TMBC-VAL-CONTAINS-CORR-link]: #tmbc-val-contains-corr1 [TMBC-VAL-COMMIT-link]: #tmbc-val-commit1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: #tmbc-sound-distr-poss-commit1 [lightclient]: https://github.com/interchainio/tendermint-rs/blob/e2cb9aca0b95430fca2eac154edddc9588038982/docs/architecture/adr-002-lite-client.md [attack-detector]: https://github.com/tendermint/tendermint/blob/main/spec/light-client/detection/detection_001_reviewed.md @@ -1053,7 +1052,5 @@ func Backwards (primary PeerID, root LightBlock, targetHeight Height) [ibc-rs]:https://github.com/informalsystems/ibc-rs -[blockchain-validator-set]: https://github.com/tendermint/tendermint/blob/main/spec/blockchain/blockchain.md#data-structures -[fullnode-data-structures]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md [arXiv]: https://arxiv.org/abs/1807.04938 diff --git a/spec/light-client/verification/verification_003_draft.md b/spec/light-client/verification/verification_003_draft.md index cd38e7e9676..6ff8f65419a 100644 --- a/spec/light-client/verification/verification_003_draft.md +++ b/spec/light-client/verification/verification_003_draft.md @@ -73,4 +73,4 @@ height int64, commit *Commit) error { return nil } -``` \ No newline at end of file +``` diff --git a/spec/p2p/messages/pex.md b/spec/p2p/messages/pex.md index 24215fd01d0..cab26ac2f41 100644 --- a/spec/p2p/messages/pex.md +++ b/spec/p2p/messages/pex.md @@ -14,7 +14,7 @@ Pex has one channel. The channel identifier is listed below. ## Message Types -The current PEX service has two versions. The first uses IP/port pair but since the p2p stack is moving towards a transport agnostic approach, +The current PEX service has two versions. The first uses IP/port pair but since the p2p stack is moving towards a transport agnostic approach, node endpoints require a `Protocol` and `Path` hence the V2 version uses a [url](https://golang.org/pkg/net/url/#URL) instead. ### PexRequest diff --git a/spec/p2p/v0.34/README.md b/spec/p2p/v0.34/README.md index cfb132ce444..b87761326d1 100644 --- a/spec/p2p/v0.34/README.md +++ b/spec/p2p/v0.34/README.md @@ -40,30 +40,30 @@ which implements the following abstractions: that is, between local and remote instances of the Tendermint protocols; - [PEX Reactor](./pex.md): a reactor is the implementation of a protocol which exchanges messages through the p2p layer. The PEX reactor manages the [Address Book](./addressbook.md) and implements both the [PEX protocol](./pex-protocol.md) and the [Peer Manager](./peer_manager.md) role. - - [Peer Exchange protocol](./pex-protocol.md): enables nodes to exchange peer addresses, thus implementing a peer discovery service; - - [Address Book](./addressbook.md): stores discovered peer addresses and + - [Peer Exchange protocol](./pex-protocol.md): enables nodes to exchange peer addresses, thus implementing a peer discovery service; + - [Address Book](./addressbook.md): stores discovered peer addresses and quality metrics associated to peers with which the node has interacted; - - [Peer Manager](./peer_manager.md): defines when and to which peers a node + - [Peer Manager](./peer_manager.md): defines when and to which peers a node should dial, in order to establish outbound connections; - Finally, [Types](./types.md) and [Configuration](./configuration.md) provide a list of existing types and configuration parameters used by the p2p layer implementation. -## Further References +## Further References Existing documentation referring to the p2p layer: -- https://github.com/tendermint/tendermint/tree/main/spec/p2p: p2p-related +- : p2p-related configuration flags; overview of connections, peer instances, and reactors; overview of peer discovery and node types; peer identity, secure connections and peer authentication handshake. -- https://github.com/tendermint/tendermint/tree/main/spec/p2p/messages: message +- : message types and channel IDs of Block Sync, Mempool, Evidence, State Sync, PEX, and Consensus reactors. -- https://docs.tendermint.com/v0.34/tendermint-core: the p2p layer +- : the p2p layer configuration and operation is documented in several pages. This content is not necessarily up-to-date, some settings and concepts may refer to the release `v0.35`, that was [discontinued][v35postmorten]. -- https://github.com/tendermint/tendermint/tree/master/docs/tendermint-core/pex: +- : peer types, peer discovery, peer management overview, address book and peer ranking. This documentation refers to the release `v0.35`, that was [discontinued][v35postmorten]. diff --git a/spec/p2p/v0.34/addressbook.md b/spec/p2p/v0.34/addressbook.md index b5133812154..8fd2cc3a2c8 100644 --- a/spec/p2p/v0.34/addressbook.md +++ b/spec/p2p/v0.34/addressbook.md @@ -203,6 +203,7 @@ number of addresses stored in the address book, but it should not be lower than --- nor greater than `250` (`maxGetSelection`). > The random selection is produced by: +> > - Retrieving all entries of the `addrLookup` map, which by definition are > returned in random order. > - Randomly shuffling the retrieved list, using the Fisher-Yates algorithm @@ -241,7 +242,7 @@ random order. ## Dial Attempts -The `MarkAttempt` method records a failed attempt to connect to an address. +The `MarkAttempt` method records a failed attempt to connect to an address. It is invoked by the Peer Manager when it fails dialing a peer, but the failure is not in the authentication step (`ErrSwitchAuthenticationFailure` error). diff --git a/spec/p2p/v0.34/configuration.md b/spec/p2p/v0.34/configuration.md index 1962f6ebc5f..929164772bf 100644 --- a/spec/p2p/v0.34/configuration.md +++ b/spec/p2p/v0.34/configuration.md @@ -1,12 +1,12 @@ # Tendermint p2p configuration -This document contains configurable parameters a node operator can use to tune the p2p behaviour. +This document contains configurable parameters a node operator can use to tune the p2p behaviour. | Parameter| Default| Description | | --- | --- | ---| | ListenAddress | "tcp://0.0.0.0:26656" | Address to listen for incoming connections (0.0.0.0:0 means any interface, any port) | | ExternalAddress | "" | Address to advertise to peers for them to dial | -| [Seeds](pex-protocol.md#seed-nodes) | empty | Comma separated list of seed nodes to connect to (ID@host:port )| +| [Seeds](pex-protocol.md#seed-nodes) | empty | Comma separated list of seed nodes to connect to (ID@host:port )| | [Persistent peers](peer_manager.md#persistent-peers) | empty | Comma separated list of nodes to keep persistent connections to (ID@host:port ) | | UPNP | false | UPNP port forwarding enabled | | [AddrBook](addressbook.md) | defaultAddrBookPath | Path do address book | @@ -33,19 +33,19 @@ These parameters can be set using the `$TMHOME/config/config.toml` file. A subse | --- | --- | ---| | Listen address| `p2p.laddr` | "tcp://0.0.0.0:26656" | | Seed nodes | `p2p.seeds` | `--p2p.seeds “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:4444”` | -| Persistent peers | `p2p.persistent_peers` | `--p2p.persistent_peers “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:26656”` | +| Persistent peers | `p2p.persistent_peers` | `--p2p.persistent_peers “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:26656”` | | Unconditional peers | `p2p.unconditional_peer_ids` | `--p2p.unconditional_peer_ids “id100000000000000000000000000000000,id200000000000000000000000000000000”` | - | UPNP | `p2p.upnp` | `--p2p.upnp` | - | PexReactor | `p2p.pex` | `--p2p.pex` | + | UPNP | `p2p.upnp` | `--p2p.upnp` | + | PexReactor | `p2p.pex` | `--p2p.pex` | | Seed mode | `p2p.seed_mode` | `--p2p.seed_mode` | | Private peer ids | `p2p.private_peer_ids` | `--p2p.private_peer_ids “id100000000000000000000000000000000,id200000000000000000000000000000000”` | **Note on persistent peers** - + If `persistent_peers_max_dial_period` is set greater than zero, the pause between each dial to each persistent peer will not exceed `persistent_peers_max_dial_period` during exponential backoff and we keep trying again without giving up. If `seeds` and `persistent_peers` intersect, the user will be warned that seeds may auto-close connections -and that the node may not be able to keep the connection persistent. \ No newline at end of file +and that the node may not be able to keep the connection persistent. diff --git a/spec/p2p/v0.34/peer_manager.md b/spec/p2p/v0.34/peer_manager.md index 00051ed0e7f..ba2e75ef323 100644 --- a/spec/p2p/v0.34/peer_manager.md +++ b/spec/p2p/v0.34/peer_manager.md @@ -10,7 +10,7 @@ but a role that is played by the [PEX reactor](./pex.md). The `ensurePeersRoutine` is a persistent routine intended to ensure that a node is connected to `MaxNumOutboundPeers` outbound peers. This routine is continuously executed by regular nodes, i.e. nodes not -operating in seed mode, as part of the PEX reactor implementation. +operating in seed mode, as part of the PEX reactor implementation. The logic defining when the node should dial peers, for selecting peers to dial and for actually dialing them is implemented in the `ensurePeers` method. @@ -70,7 +70,7 @@ They are contacted by a node when, after an invocation of the `ensurePeers` method, no suitable peer address to dial is retrieved from the address book (e.g., because it is empty). -Once a connection with a seed node is established, the node immediately +Once a connection with a seed node is established, the node immediately [sends a PEX request](./pex-protocol.md#Requesting-Addresses) to it, as it is added as an outbound peer. When the corresponding PEX response is received, the addresses provided by the @@ -137,7 +137,7 @@ A peer can be in the following states: - Connected peers: peers that a node has successfully dialed, added as outbound peers. - [Bad peers](addressbook.md#bad-peers): peers marked as bad in the address book due to exhibited [misbehavior](pex-protocol.md#misbehavior). - Peers can be reinstated after being marked as bad. + Peers can be reinstated after being marked as bad. ## Pending of documentation diff --git a/spec/p2p/v0.34/pex-protocol.md b/spec/p2p/v0.34/pex-protocol.md index 6497e138573..d4d7fc0894c 100644 --- a/spec/p2p/v0.34/pex-protocol.md +++ b/spec/p2p/v0.34/pex-protocol.md @@ -85,7 +85,7 @@ This leads the peer to be disconnected and [marked as a bad peer](addressbook.md When a node receives a `PexRequest` message from a peer, it replies with a `PexAddrs` message. -This message encodes a [random selection of peer addresses](./addressbook.md#random-selection) +This message encodes a [random selection of peer addresses](./addressbook.md#random-selection) retrieved from the address book. Sending a PEX response to a peer is implemented by the `SendAddrs` method of diff --git a/spec/p2p/v0.34/pex.md b/spec/p2p/v0.34/pex.md index f976cc83bd8..945969f8448 100644 --- a/spec/p2p/v0.34/pex.md +++ b/spec/p2p/v0.34/pex.md @@ -93,7 +93,7 @@ trustworthy than outbound peers. The `RemovePeer` method, from the `Reactor` interface, removes a peer from the PEX protocol. -The peer's ID is removed from the tables tracking PEX requests +The peer's ID is removed from the tables tracking PEX requests [sent](./pex-protocol.md#misbehavior) but not yet replied and PEX requests [received](./pex-protocol.md#misbehavior-1). @@ -105,7 +105,7 @@ handles a message received by the PEX protocol. A node receives two type of messages as part of the PEX protocol: - `PexRequest`: a request for addresses received from a peer, handled as - described [here](./pex-protocol.md#providing-addresses) + described [here](./pex-protocol.md#providing-addresses) - `PexAddrs`: a list of addresses received from a peer, as a reponse to a PEX - request sent by the node, as described [here](./pex-protocol.md#responses) + request sent by the node, as described [here](./pex-protocol.md#responses) diff --git a/spec/p2p/v0.34/switch.md b/spec/p2p/v0.34/switch.md index 54a0f63c2c3..dd2833a4b0a 100644 --- a/spec/p2p/v0.34/switch.md +++ b/spec/p2p/v0.34/switch.md @@ -47,7 +47,7 @@ this same `DialPeerWithAddress` method for dialing peers. ### Manual operation The `DialPeersAsync` method receives a list of peer addresses (strings) -and dials all of them in parallel. +and dials all of them in parallel. It is invoked in two situations: - In the [setup](https://github.com/tendermint/tendermint/blob/29c5a062d23aaef653f11195db55c45cd9e02715/node/node.go#L985) of a node, to establish connections with every configured @@ -61,7 +61,7 @@ In case of parsing errors, the method returns. An exception is made for DNS resolution `ErrNetAddressLookup` errors, which do not interrupt the procedure. As the peer addresses provided to this method are typically not known by the node, -contrarily to the addressed dialed using the `DialPeerWithAddress` method, +contrarily to the addressed dialed using the `DialPeerWithAddress` method, they are added to the node's address book, which is persisted to disk. The switch dials the provided peers in parallel. @@ -173,7 +173,7 @@ precisely, not providing to the switch any "reason" for that. In both cases the `Peer` instance is stopped, the peer is removed from all registered reactors, and finally from the list of connected peers. -> Issue https://github.com/tendermint/tendermint/issues/3338 is mentioned in +> Issue is mentioned in > the internal `stopAndRemovePeer` method explaining why removing the peer from > the list of connected peers is the last action taken. @@ -232,6 +232,7 @@ The return value (a boolean) of these calls are redirected to a channel that is returned by the method. > TODO: detail where this method is invoked: +> > - By the consensus protocol, in `broadcastNewRoundStepMessage`, > `broadcastNewValidBlockMessage`, and `broadcastHasVoteMessage` > - By the state sync protocol diff --git a/spec/p2p/v0.34/transport.md b/spec/p2p/v0.34/transport.md index 9bb486a3dcb..e072bfe6f58 100644 --- a/spec/p2p/v0.34/transport.md +++ b/spec/p2p/v0.34/transport.md @@ -71,7 +71,7 @@ as well any error returned in this process are added to a queue of accepted conn This queue is consumed by the `Accept` method. > Handling accepted connection asynchronously was introduced due to this issue: -> https://github.com/tendermint/tendermint/issues/2047 +> ## Connection Filtering diff --git a/spec/p2p/v0.34/types.md b/spec/p2p/v0.34/types.md index ba43980ee1c..88cdcafb336 100644 --- a/spec/p2p/v0.34/types.md +++ b/spec/p2p/v0.34/types.md @@ -48,7 +48,7 @@ but currently is not produced outside tests. `ErrTransportClosed` is produced by the [transport](#transportgo) and handled by the [switch](#switchgo). -`ErrNetAddressNoID`, `ErrNetAddressInvalid`, and `ErrNetAddressLookup` +`ErrNetAddressNoID`, `ErrNetAddressInvalid`, and `ErrNetAddressLookup` are parsing a string to create an instance of `NetAddress`. It can be returned in the setup of the [switch](#switchgo) and of the [PEX reactor](#pex_reactorgo), @@ -92,7 +92,7 @@ It is implemented by `DefaultNodeInfo` type. The [switch](#switchgo) stores the local `NodeInfo`. -The `NodeInfo` of connected peers is produced by the +The `NodeInfo` of connected peers is produced by the [transport](#transportgo) during the handshake, and stored in [`Peer`](#peergo) instances. ### `peer.go` @@ -236,4 +236,4 @@ Not imported by any other Tendermint source file. This package implementation was taken from "taipei-torrent". -It is used by the `probe-upnp` command of the Tendermint binary. +It is used by the `probe-upnp` command of the Tendermint binary. diff --git a/test/e2e/README.md b/test/e2e/README.md index ed411440b31..11e019f5fe3 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -155,9 +155,9 @@ Docker does not enable IPv6 by default. To do so, enter the following in It is also possible to run a simple benchmark on a testnet. This is done through the `benchmark` command. This manages the entire process: setting up the environment, starting the test net, waiting for a considerable amount of blocks to be used (currently 100), and then returning the following metrics from the sample of the blockchain: -- Average time to produce a block -- Standard deviation of producing a block -- Minimum and maximum time to produce a block +* Average time to produce a block +* Standard deviation of producing a block +* Minimum and maximum time to produce a block ## Running Individual Nodes From f01c18047bbc261d743849c0f8e1080d48225dff Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Thu, 22 Dec 2022 17:00:20 -0500 Subject: [PATCH 29/40] Update CODEOWNERS Signed-off-by: Thane Thomson --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8be48245c38..87f93c4cdc3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,6 +7,6 @@ # global owners are only requested if there isn't a more specific # codeowner specified below. For this reason, the global codeowners # are often repeated in package-level definitions. -* @ebuchman @tendermint/tendermint-engineering @adizere @lasarojc +* @CometBFT/engineering -/spec @ebuchman @tendermint/tendermint-research @tendermint/tendermint-engineering @adizere @lasarojc +/spec @CometBFT/research @CometBFT/engineering From 298c3d0712de7798d876b021e606e2d57c101c35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:08:06 -0500 Subject: [PATCH 30/40] build(deps): Bump actions/stale from 6 to 7 (#1) Bumps [actions/stale](https://github.com/actions/stale) from 6 to 7. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 51229cfb705..d5dbfbee1d7 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@v6 + - uses: actions/stale@v7 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-pr-message: "This pull request has been automatically marked as stale because it has not had From 11ebe3246a2b4f4a1e7bf1e4dead0eaeb4f5bbc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 17:08:25 -0500 Subject: [PATCH 31/40] build(deps): Bump bufbuild/buf-setup-action from 1.10.0 to 1.11.0 (#2) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.10.0 to 1.11.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.10.0...v1.11.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/proto-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/proto-lint.yml b/.github/workflows/proto-lint.yml index a6a6c328b9b..b9b01c413d9 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.10.0 + - uses: bufbuild/buf-setup-action@v1.11.0 - uses: bufbuild/buf-lint-action@v1 with: input: 'proto' From 238ab3589126947a8100c966746592f3437efdd5 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 23 Dec 2022 11:22:36 -0500 Subject: [PATCH 32/40] Update Dependabot and Mergify config to use new labels (#21) Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson --- .github/dependabot.yml | 24 ++++++++++++------------ .github/mergify.yml | 8 ++++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6dd968c201c..54e17557a09 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,8 +7,8 @@ updates: target-branch: "main" open-pull-requests-limit: 10 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge - package-ecosystem: github-actions directory: "/" @@ -17,8 +17,8 @@ updates: target-branch: "v0.37.x" open-pull-requests-limit: 10 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge - package-ecosystem: github-actions directory: "/" @@ -27,8 +27,8 @@ updates: target-branch: "v0.34.x" open-pull-requests-limit: 10 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge ################################### ## @@ -41,8 +41,8 @@ updates: target-branch: "main" open-pull-requests-limit: 10 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge - package-ecosystem: gomod directory: "/" @@ -53,8 +53,8 @@ updates: # branches. open-pull-requests-limit: 0 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge - package-ecosystem: gomod directory: "/" @@ -65,5 +65,5 @@ updates: # branches. open-pull-requests-limit: 0 labels: - - T:dependencies - - S:automerge + - dependencies + - automerge diff --git a/.github/mergify.yml b/.github/mergify.yml index e529d19f9b0..74f285949d7 100644 --- a/.github/mergify.yml +++ b/.github/mergify.yml @@ -2,13 +2,13 @@ queue_rules: - name: default conditions: - base=main - - label=S:automerge + - label=automerge pull_request_rules: - name: Automerge to main conditions: - base=main - - label=S:automerge + - label=automerge actions: queue: method: squash @@ -20,7 +20,7 @@ pull_request_rules: - name: backport patches to v0.37.x branch conditions: - base=main - - label=S:backport-to-v0.37.x + - label=backport-to-v0.37.x actions: backport: branches: @@ -28,7 +28,7 @@ pull_request_rules: - name: backport patches to v0.34.x branch conditions: - base=main - - label=S:backport-to-v0.34.x + - label=backport-to-v0.34.x actions: backport: branches: From 66252f8a16697ddcd8c2928dfd45b860e45f7850 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 14:05:43 -0500 Subject: [PATCH 33/40] build(deps): Bump github.com/bufbuild/buf from 1.10.0 to 1.11.0 (#4) Bumps [github.com/bufbuild/buf](https://github.com/bufbuild/buf) from 1.10.0 to 1.11.0. - [Release notes](https://github.com/bufbuild/buf/releases) - [Changelog](https://github.com/bufbuild/buf/blob/main/CHANGELOG.md) - [Commits](https://github.com/bufbuild/buf/compare/v1.10.0...v1.11.0) --- updated-dependencies: - dependency-name: github.com/bufbuild/buf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- go.mod | 38 +++++++++++-------------- go.sum | 90 ++++++++++++++++++++++++---------------------------------- 2 files changed, 54 insertions(+), 74 deletions(-) diff --git a/go.mod b/go.mod index 0c03872d077..7973e9c125a 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( ) require ( - github.com/bufbuild/buf v1.10.0 + github.com/bufbuild/buf v1.11.0 github.com/creachadair/taskgroup v0.3.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) @@ -83,7 +83,7 @@ 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.1.0 // indirect + github.com/bufbuild/connect-go v1.4.0 // indirect github.com/bufbuild/protocompile v0.1.0 // indirect github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect @@ -91,9 +91,7 @@ require ( github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect github.com/cloudflare/circl v1.3.1 // indirect - github.com/containerd/containerd v1.6.9 // indirect github.com/containerd/continuity v0.3.0 // indirect - github.com/containerd/typeurl v1.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.8.1 // indirect @@ -103,8 +101,10 @@ require ( 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/cli v20.10.21+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker v20.10.21+incompatible // indirect + github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.0 // indirect @@ -117,12 +117,10 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-chi/chi/v5 v5.0.7 // indirect + github.com/go-chi/chi/v5 v5.0.8 // indirect github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/go-billy/v5 v5.3.1 // 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.2 // indirect github.com/go-toolsmith/astequal v1.0.3 // indirect @@ -147,22 +145,22 @@ require ( 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.9 // indirect - github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e // indirect + github.com/google/go-containerregistry v0.12.1 // indirect + github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // 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/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/imdario/mergo v0.3.13 // indirect - github.com/inconshreveable/mousetrap v1.0.1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect + github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 // indirect github.com/jgautheron/goconst v1.5.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect @@ -172,7 +170,7 @@ require ( github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect - github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/compress v1.15.13 // 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 @@ -193,8 +191,7 @@ require ( github.com/mgechev/revive v1.2.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/buildkit v0.10.5 // indirect - github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect + github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // 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 @@ -263,14 +260,13 @@ require ( gitlab.com/bosi/decorder v0.2.3 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect - go.opentelemetry.io/otel v1.11.1 // indirect - go.opentelemetry.io/otel/metric v0.33.0 // indirect - go.opentelemetry.io/otel/trace v1.11.1 // indirect + go.opentelemetry.io/otel v1.11.2 // indirect + go.opentelemetry.io/otel/metric v0.34.0 // indirect + go.opentelemetry.io/otel/trace v1.11.2 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.23.0 // indirect - golang.org/x/exp v0.0.0-20221031165847-c99f073a8326 // indirect + go.uber.org/multierr v1.9.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20221211140036-ad323defaf05 // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/mod v0.7.0 // indirect golang.org/x/sys v0.3.0 // indirect diff --git a/go.sum b/go.sum index ca3fcc5ef48..7ee3c326689 100644 --- a/go.sum +++ b/go.sum @@ -23,15 +23,12 @@ 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.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= 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 v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= -cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= 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.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= @@ -183,10 +180,10 @@ 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.10.0 h1:t6rV4iP1cs/sJH5SYvcLanOshLvmtvwSC+Mt+GfG05s= -github.com/bufbuild/buf v1.10.0/go.mod h1:79BrOWh8uX1a0SVSoPyeYgtP0+Y0n5J3Tt6kjTSkLoU= -github.com/bufbuild/connect-go v1.1.0 h1:AUgqqO2ePdOJSpPOep6BPYz5v2moW1Lb8sQh0EeRzQ8= -github.com/bufbuild/connect-go v1.1.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I= +github.com/bufbuild/buf v1.11.0 h1:jq/ckkxg87GaEgyHMqGGvZkVh8FeZuYLBF9DyOQK1RU= +github.com/bufbuild/buf v1.11.0/go.mod h1:IoaGkUhois4gv4EqTGT7H+4bbhZUvlYutECLgfoE2cA= +github.com/bufbuild/connect-go v1.4.0 h1:N94D0tGxuM2cSI7hM/aL8mtxL6+8rtHuFcIj9oGRp5s= +github.com/bufbuild/connect-go v1.4.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= @@ -235,14 +232,11 @@ github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:z 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/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.6.9 h1:IN/r8DUes/B5lEGTNfIiUkfZBtIQJGx2ai703dV6lRA= -github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ= 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/containerd/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0= 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= @@ -267,8 +261,7 @@ github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6V github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/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/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= 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= @@ -296,11 +289,14 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm 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/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= +github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -363,8 +359,8 @@ github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlya github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= -github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= -github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= +github.com/go-chi/chi/v5 v5.0.8/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-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= @@ -392,11 +388,6 @@ 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-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.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -517,6 +508,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.12.1 h1:W1mzdNUTx4Zla4JaixCRLhORcR7G6KxE5hHl5fkPsp8= +github.com/google/go-containerregistry v0.12.1/go.mod h1:sdIK+oHQO7B93xI8UweYdl887YhuIwg9vz8BSLH3+8k= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -536,8 +529,8 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe 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-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= -github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e h1:F1LLQqQ8WoIbyoxLUY+JUZe1kuHdxThM6CPUATzE6Io= -github.com/google/pprof v0.0.0-20221102093814-76f304f74e5e/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -577,8 +570,6 @@ github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQ github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -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= @@ -642,16 +633,17 @@ github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1: github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-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/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -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/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co= +github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/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/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= @@ -699,8 +691,8 @@ github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkS 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.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0= +github.com/klauspost/compress v1.15.13/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= @@ -804,12 +796,10 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.10.5 h1:d9krS/lG3dn6N7y+R8o9PTgIixlYAaDk35f3/B4jZOw= -github.com/moby/buildkit v0.10.5/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/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= 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= @@ -1175,6 +1165,7 @@ 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/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/vektra/mockery/v2 v2.15.0 h1:5Egbxoancm1hhkJUoAF+cf0FBzC9oxS28LL/ZKbC980= github.com/vektra/mockery/v2 v2.15.0/go.mod h1:RswGtsqDbCR9j4UcgBQuAZY7OFxI+TgtHevc0gR0kCY= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -1220,14 +1211,12 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 h1:PRXhsszxTt5bbPriTjmaweWUsAnJYeWBhUMLRetUgBU= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4/go.mod h1:05eWWy6ZWzmpeImD3UowLTB3VjDMU1yxQ+ENuVWDM3c= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/metric v0.33.0 h1:xQAyl7uGEYvrLAiV/09iTJlp1pZnQ9Wl793qbVvED1E= -go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= +go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= +go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8= +go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8= +go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= +go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= 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= @@ -1242,15 +1231,15 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/multierr v1.3.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= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.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.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= -go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1293,8 +1282,8 @@ 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-20221031165847-c99f073a8326 h1:QfTh0HpN6hlw6D3vu8DAwC8pBIwikq0AI1evdm+FksE= -golang.org/x/exp v0.0.0-20221031165847-c99f073a8326/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20221211140036-ad323defaf05 h1:T8EldfGCcveFMewH5xAYxxoX3PSQMrsechlUGVFlQBU= +golang.org/x/exp v0.0.0-20221211140036-ad323defaf05/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= 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= @@ -1403,7 +1392,6 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ 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.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= 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= @@ -1569,7 +1557,6 @@ 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= @@ -1684,7 +1671,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1708,7 +1694,6 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1819,7 +1804,6 @@ 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= From 260819796e2735f3a866a21a758feaeeacabbaa4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 14:17:41 -0500 Subject: [PATCH 34/40] build(deps): Bump github.com/vektra/mockery/v2 from 2.15.0 to 2.16.0 (#5) Bumps [github.com/vektra/mockery/v2](https://github.com/vektra/mockery) from 2.15.0 to 2.16.0. - [Release notes](https://github.com/vektra/mockery/releases) - [Changelog](https://github.com/vektra/mockery/blob/master/.goreleaser.yml) - [Commits](https://github.com/vektra/mockery/compare/v2.15.0...v2.16.0) --- updated-dependencies: - dependency-name: github.com/vektra/mockery/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 3 ++- go.sum | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7973e9c125a..e9eec97a51e 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/gofrs/uuid v4.3.1+incompatible github.com/google/uuid v1.3.0 github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae - github.com/vektra/mockery/v2 v2.15.0 + github.com/vektra/mockery/v2 v2.16.0 golang.org/x/sync v0.1.0 gonum.org/v1/gonum v0.12.0 google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 @@ -90,6 +90,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/chigopher/pathlib v0.12.0 // indirect github.com/cloudflare/circl v1.3.1 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect diff --git a/go.sum b/go.sum index 7ee3c326689..e8b794d3a62 100644 --- a/go.sum +++ b/go.sum @@ -207,6 +207,8 @@ github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0 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/chigopher/pathlib v0.12.0 h1:1GM7fN/IwXXmOHbd1jkMqHD2wUhYqUvafgxTwmLT/q8= +github.com/chigopher/pathlib v0.12.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= 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= @@ -1070,6 +1072,7 @@ 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.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= @@ -1166,8 +1169,8 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= -github.com/vektra/mockery/v2 v2.15.0 h1:5Egbxoancm1hhkJUoAF+cf0FBzC9oxS28LL/ZKbC980= -github.com/vektra/mockery/v2 v2.15.0/go.mod h1:RswGtsqDbCR9j4UcgBQuAZY7OFxI+TgtHevc0gR0kCY= +github.com/vektra/mockery/v2 v2.16.0 h1:NMfQMZ4dKAHxR0rTHCt47HyJlBgFdYmrLlHhZIj2yeo= +github.com/vektra/mockery/v2 v2.16.0/go.mod h1:OZL0JSpvEWEHgyNr150zNbP1ktxr6yPZ/W82RHaTHl0= 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/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= From ff4ad2efc4a7ed71533963266df414a871e06c07 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Dec 2022 19:26:48 +0000 Subject: [PATCH 35/40] build(deps): Bump github.com/informalsystems/tm-load-test from 1.0.0 to 1.1.0 (#6) Bumps [github.com/informalsystems/tm-load-test](https://github.com/informalsystems/tm-load-test) from 1.0.0 to 1.1.0.
Release notes

Sourced from github.com/informalsystems/tm-load-test's releases.

v1.1.0

See the CHANGELOG for details regarding this release.

Changelog

  • e3e969e Add changelog for v1.1.0
  • e4d0b69 ci: Add govulncheck (#164)
  • 6e5d5ac Update dependencies (#163)
  • 25ac0df Bump goreleaser/goreleaser-action from 3 to 4 (#162)
  • 98f4369 Bump actions/checkout from 3.1.0 to 3.2.0 (#161)
  • f69d049 Bump golangci/golangci-lint-action from 3.2.0 to 3.3.1 (#160)
  • 9ccd414 Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 (#159)
  • c9e9af6 Bump github.com/spf13/cobra from 1.6.0 to 1.6.1 (#157)
  • a517a0a Bump github.com/spf13/cobra from 1.5.0 to 1.6.0 (#154)
  • 8b6f731 Bump actions/checkout from 3.0.2 to 3.1.0 (#153)
  • 91b2a64 Bump codecov/codecov-action from 3.1.0 to 3.1.1 (#152)
  • e19ec2b Fix links to GitHub to the specific version of Tendermint (#151)
  • 9634538 Bump actions/setup-go from 2 to 3.2.0 (#140)
  • dfb3fff Bump goreleaser/goreleaser-action from 2 to 3 (#139)
  • da601fc Bump codecov/codecov-action from 2.1.0 to 3.1.0 (#135)
  • 800d27b ci: Update for main and Go 1.18 (#150)
  • 0b5598b Update linting (#149)
  • e26e39e Merge pull request #134 from informalsystems/dependabot/github_actions/actions/checkout-3.0.2
  • 841107e Merge pull request #143 from informalsystems/dependabot/go_modules/github.com/spf13/cobra-1.5.0
  • bebf746 Bump github.com/spf13/cobra from 1.4.0 to 1.5.0
  • 3288a99 Bump actions/checkout from 2.4.0 to 3.0.2
  • ee9bf6e Merge pull request #136 from informalsystems/dependabot/github_actions/golangci/golangci-lint-action-3.2.0
  • e743f2f Merge pull request #126 from informalsystems/dependabot/go_modules/github.com/spf13/cobra-1.4.0
  • fc85d77 Merge pull request #121 from informalsystems/dependabot/go_modules/github.com/gorilla/websocket-1.5.0
  • d926e4a Bump golangci/golangci-lint-action from 2 to 3.2.0
  • aa39244 Bump github.com/spf13/cobra from 1.3.0 to 1.4.0
  • 0f351d5 Bump github.com/gorilla/websocket from 1.4.2 to 1.5.0
  • cf4664a Merge pull request #118 from informalsystems/dependabot/go_modules/github.com/prometheus/client_golang-1.12.0
  • 45bf4e9 Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.0
  • 985c187 Merge pull request #117 from informalsystems/dependabot/go_modules/github.com/spf13/cobra-1.3.0
  • a8afe84 Merge pull request #115 from informalsystems/dependabot/github_actions/actions/checkout-2.4.0
  • c926219 Bump github.com/spf13/cobra from 1.2.1 to 1.3.0
  • 7ce29d1 Bump actions/checkout from 2.3.5 to 2.4.0
  • 5dfc291 Prefix "v" on release version in future
Changelog

Sourced from github.com/informalsystems/tm-load-test's changelog.

v1.1.0

This minor release just bumps some dependencies.

  • #163 - Bump supported version of Tendermint Core to v0.34.24.
Commits
  • e3e969e Add changelog for v1.1.0
  • e4d0b69 ci: Add govulncheck (#164)
  • 6e5d5ac Update dependencies (#163)
  • 25ac0df Bump goreleaser/goreleaser-action from 3 to 4 (#162)
  • 98f4369 Bump actions/checkout from 3.1.0 to 3.2.0 (#161)
  • f69d049 Bump golangci/golangci-lint-action from 3.2.0 to 3.3.1 (#160)
  • 9ccd414 Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 (#159)
  • c9e9af6 Bump github.com/spf13/cobra from 1.6.0 to 1.6.1 (#157)
  • a517a0a Bump github.com/spf13/cobra from 1.5.0 to 1.6.0 (#154)
  • 8b6f731 Bump actions/checkout from 3.0.2 to 3.1.0 (#153)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/informalsystems/tm-load-test&package-manager=go_modules&previous-version=1.0.0&new-version=1.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 4 +- go.sum | 463 +-------------------------------------------------------- 2 files changed, 9 insertions(+), 458 deletions(-) diff --git a/go.mod b/go.mod index e9eec97a51e..853a5ef042c 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/golangci/golangci-lint v1.50.1 github.com/google/orderedcode v0.0.1 github.com/gorilla/websocket v1.5.0 - github.com/informalsystems/tm-load-test v1.0.0 + github.com/informalsystems/tm-load-test v1.1.0 github.com/lib/pq v1.10.7 github.com/libp2p/go-buffer-pool v0.1.0 github.com/minio/highwayhash v1.0.2 @@ -153,6 +153,7 @@ require ( 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/gotestyourself/gotestyourself v2.2.0+incompatible // 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 @@ -279,6 +280,7 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools v2.2.0+incompatible // 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 diff --git a/go.sum b/go.sum index e8b794d3a62..8aa3706bede 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ 4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= 4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= -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= @@ -20,9 +19,6 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -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/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= @@ -31,7 +27,6 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 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.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= @@ -49,31 +44,23 @@ github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwka github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.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/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.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/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 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= @@ -85,19 +72,12 @@ github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZ github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= -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/go.mod h1:Z+F2Rca0qCsVYDS8z7bAGm8f3UkzuWYS/oBZz5a7VVA= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= -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= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -110,38 +90,18 @@ github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqr github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -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-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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -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-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/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= @@ -153,8 +113,6 @@ 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/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.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.0 h1:V2/ZgjfDFIygAX3ZapeigkVBoVUtOJKSwrhZdlpSvaA= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= @@ -171,8 +129,6 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOF github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/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/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -189,11 +145,8 @@ github.com/bufbuild/protocompile v0.1.0/go.mod h1:ix/MMMdsT3fzxfw91dvbfzKW3fRRnu github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -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/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/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -205,19 +158,13 @@ github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= 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/chigopher/pathlib v0.12.0 h1:1GM7fN/IwXXmOHbd1jkMqHD2wUhYqUvafgxTwmLT/q8= github.com/chigopher/pathlib v0.12.0/go.mod h1:EJ5UtJ/sK8Nt6q3VWN+EwZLZ3g0afJiG8NegYiQQ/gQ= 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/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.1 h1:4OVCZRL62ijwEwxnF6I7hLwxvIYi3VaZt8TflkqtrtA= @@ -226,48 +173,31 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/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/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -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/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0= -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-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/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/gogoproto v1.4.3 h1:RP3yyVREh9snv/lsOvmsAPQt8f44LgL281X0IOIhhcI= github.com/cosmos/gogoproto v1.4.3/go.mod h1:0hLIG5TR7IvV1fme1HCFKjfzW9X2x0Mo+RooWXCnOWU= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creachadair/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.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= 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/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= @@ -287,10 +217,8 @@ github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLI 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= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -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.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= @@ -304,38 +232,24 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/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-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/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= 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-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.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= @@ -344,12 +258,8 @@ github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 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.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -378,11 +288,9 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 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= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -393,7 +301,6 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 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.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0= @@ -414,7 +321,6 @@ github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYw github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= -github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= 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= @@ -423,19 +329,12 @@ 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.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= github.com/gofrs/uuid v4.3.1+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.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= @@ -448,7 +347,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 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= @@ -464,12 +362,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 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/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= @@ -506,7 +401,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.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= @@ -528,29 +422,19 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf 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-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= -github.com/google/uuid v1.0.0/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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 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/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.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.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= @@ -570,65 +454,22 @@ github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -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.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/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= -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/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/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-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= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= 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/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.2.2/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/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/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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= @@ -638,10 +479,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/influxdata/influxdb1-client v0.0.0-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/informalsystems/tm-load-test v1.1.0 h1:rgOiaUdrTiq9lcJyRm8dw/j+t8VPK+kJ59X5GrzXAVQ= +github.com/informalsystems/tm-load-test v1.1.0/go.mod h1:qToYzfHknFzHB5hybRe8ffZ7Eg9BBqz3A5bZ2Pi0tNU= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co= @@ -656,33 +495,23 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz 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= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/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= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= @@ -691,8 +520,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o 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.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.13 h1:NFn1Wr8cfnenSJSA46lLq4wHCcBzKTSjnBIexDMMOV0= github.com/klauspost/compress v1.15.13/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= @@ -702,7 +529,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -722,20 +548,13 @@ github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3 github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= 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.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/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/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= @@ -747,24 +566,14 @@ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859 github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.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/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/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.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= @@ -776,29 +585,13 @@ github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwg github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= 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.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= -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/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/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.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= @@ -816,19 +609,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 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/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -836,54 +616,31 @@ github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMow 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 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= 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/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae h1:FatpGJD2jmJfhZiFDElaC0QhZUDQnxUeAwTGkfAHN3I= github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= 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/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= 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.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/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= 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/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= @@ -893,24 +650,15 @@ github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJ 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/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.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.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/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/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/pjbgf/sha1cd v0.2.3 h1:uKQP/7QOzNtKYH7UTohZLcjF5/55EnTw0jO/Ru4jZwI= github.com/pjbgf/sha1cd v0.2.3/go.mod h1:HOK9QrgzdHpbc2Kzip0Q1yi3M2MFGPADtR6HjG65m5M= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= @@ -919,7 +667,6 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA= github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= @@ -934,53 +681,32 @@ github.com/pointlander/peg v1.0.1 h1:mgA/GQE8TeS9MdkU6Xn6iEzBmQUQCNuWD7rHCK6Mjs0 github.com/pointlander/peg v1.0.1/go.mod h1:5hsGDQR2oZI4QoWz0/Kdg3VSVEC31iJw/b7WjqCBGRI= 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/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.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.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/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= 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/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/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.18 h1:sd+abO1PEI9fkYennwzHn9kl3nqP6M5vE7FiOzZ+5CE= github.com/quasilyte/go-ruleguard v0.3.18/go.mod h1:lOIzcYlgxrQ2sGJ735EHXmf/e9MJ516j16K/Ifcttvs= @@ -994,15 +720,11 @@ github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf 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/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/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.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= @@ -1016,11 +738,8 @@ github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1r 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/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/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= @@ -1029,8 +748,6 @@ github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiS 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/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= @@ -1043,7 +760,6 @@ github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxr 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= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -1058,14 +774,10 @@ github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/skeema/knownhosts v1.1.0 h1:Wvr9V0MxhjRbl3f9nMnKnFfiWTJmtECJ9Njkea3ysW0= github.com/skeema/knownhosts v1.1.0/go.mod h1:sKFq3RD6/TKZkSWn8boUbDC7Qkgcv+8XXijpFO6roag= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa h1:YJfZp12Z3AFhSBeXOlv4BO55RMwPn2NoQeDsrdWnBtY= github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa/go.mod h1:oJyF+mSPHbB5mVY2iO9KV3pTt/QbIkGaO8gQ2WrDbP4= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1073,43 +785,27 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b 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.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.3.0/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.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.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/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= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.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.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU= github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As= 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/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1126,7 +822,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 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= @@ -1137,8 +832,6 @@ github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTX 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= @@ -1151,20 +844,15 @@ github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDH github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= 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/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/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/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= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= @@ -1178,7 +866,6 @@ github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI 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/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= @@ -1193,25 +880,14 @@ github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 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.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-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/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= @@ -1221,49 +897,23 @@ go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2b go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= 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/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/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.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-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-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-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-20210616213533-5ff15b29337e/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-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1272,10 +922,7 @@ golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= -golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -1290,7 +937,6 @@ golang.org/x/exp v0.0.0-20221211140036-ad323defaf05/go.mod h1:CxIveKay+FTh1D0yPZ 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1304,7 +950,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1325,25 +970,18 @@ golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73r 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= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-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= @@ -1365,17 +1003,10 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/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-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= @@ -1391,9 +1022,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-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/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= @@ -1409,18 +1037,13 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/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= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1431,24 +1054,18 @@ golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1465,41 +1082,29 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-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-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-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-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1514,7 +1119,6 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.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-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1527,25 +1131,18 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -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-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-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1554,7 +1151,6 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1562,15 +1158,11 @@ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-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-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= @@ -1578,7 +1170,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-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= @@ -1616,7 +1207,6 @@ golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1625,7 +1215,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= 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.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= @@ -1638,13 +1227,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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= @@ -1664,11 +1248,7 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513 google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.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= @@ -1680,7 +1260,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn 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= @@ -1712,26 +1291,13 @@ google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20211101144312-62acf1d99145/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+Ca/rDdKubLIU9rcJ3xfy1DC/Wd2Oo= google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -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.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= @@ -1746,11 +1312,6 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.40.0/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.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= @@ -1777,20 +1338,14 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 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/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.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= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1801,14 +1356,12 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -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= @@ -1827,9 +1380,5 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jC mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From ddd01178cb68c7b6564a34f588706d3574f822f3 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Fri, 23 Dec 2022 14:45:41 -0500 Subject: [PATCH 36/40] ci: Update Docker build workflows (#59) Signed-off-by: Thane Thomson Signed-off-by: Thane Thomson --- .github/workflows/tendermint-docker.yml | 4 ++-- .github/workflows/testapp-docker.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tendermint-docker.yml b/.github/workflows/tendermint-docker.yml index 721a2717b66..1f65d8bf2bf 100644 --- a/.github/workflows/tendermint-docker.yml +++ b/.github/workflows/tendermint-docker.yml @@ -1,6 +1,6 @@ name: Docker # Build & Push rebuilds the Tendermint docker image on every push to main and creation of tags -# and pushes the image to https://hub.docker.com/r/tendermint/tendermint +# and pushes the image to https://hub.docker.com/r/cometbft/tendermint on: push: branches: @@ -19,7 +19,7 @@ jobs: - name: Prepare id: prep run: | - DOCKER_IMAGE=tendermint/tendermint + DOCKER_IMAGE=cometbft/tendermint VERSION=noop if [[ $GITHUB_REF == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} diff --git a/.github/workflows/testapp-docker.yml b/.github/workflows/testapp-docker.yml index 310e80e382f..c562f6efe4b 100644 --- a/.github/workflows/testapp-docker.yml +++ b/.github/workflows/testapp-docker.yml @@ -1,6 +1,6 @@ name: Docker E2E Node # Build & Push rebuilds the e2e Testapp docker image on every push to main and creation of tags -# and pushes the image to https://hub.docker.com/r/tendermint/e2e-node +# and pushes the image to https://hub.docker.com/r/cometbft/e2e-node on: push: branches: @@ -19,7 +19,7 @@ jobs: - name: Prepare id: prep run: | - DOCKER_IMAGE=tendermint/e2e-node + DOCKER_IMAGE=cometbft/e2e-node VERSION=noop if [[ $GITHUB_REF == refs/tags/* ]]; then VERSION=${GITHUB_REF#refs/tags/} From 3ea478a45c8b29ebb7da05d548d6c9c986a4dc01 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 08:08:18 -0500 Subject: [PATCH 37/40] build(deps): Bump github.com/rs/cors from 1.8.2 to 1.8.3 (#72) Bumps [github.com/rs/cors](https://github.com/rs/cors) from 1.8.2 to 1.8.3. - [Release notes](https://github.com/rs/cors/releases) - [Commits](https://github.com/rs/cors/compare/v1.8.2...v1.8.3) --- updated-dependencies: - dependency-name: github.com/rs/cors dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 853a5ef042c..58410c0b11e 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/prometheus/client_model v0.3.0 github.com/prometheus/common v0.39.0 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 - github.com/rs/cors v1.8.2 + github.com/rs/cors v1.8.3 github.com/sasha-s/go-deadlock v0.3.1 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa github.com/spf13/cobra v1.6.1 diff --git a/go.sum b/go.sum index 8aa3706bede..93a727ba104 100644 --- a/go.sum +++ b/go.sum @@ -725,8 +725,8 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn 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.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -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/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.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= From 46bdfc11d9db48dd41c3d879ad6428f913337e6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 08:19:03 -0500 Subject: [PATCH 38/40] build(deps): Bump github.com/creachadair/taskgroup from 0.3.2 to 0.4.2 (#71) Bumps [github.com/creachadair/taskgroup](https://github.com/creachadair/taskgroup) from 0.3.2 to 0.4.2. - [Release notes](https://github.com/creachadair/taskgroup/releases) - [Commits](https://github.com/creachadair/taskgroup/compare/v0.3.2...v0.4.2) --- updated-dependencies: - dependency-name: github.com/creachadair/taskgroup dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 58410c0b11e..9dd615d1ec7 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( require ( github.com/bufbuild/buf v1.11.0 - github.com/creachadair/taskgroup v0.3.2 + github.com/creachadair/taskgroup v0.4.2 github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/go.sum b/go.sum index 93a727ba104..d599ffe3783 100644 --- a/go.sum +++ b/go.sum @@ -191,8 +191,8 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc 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.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/creachadair/taskgroup v0.4.2 h1:jsBLdAJE42asreGss2xZGZ8fJra7WtwnHWeJFxv2Li8= +github.com/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= From 89d82e278e6a4be59197724bffd426544243a017 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 12:31:46 +0000 Subject: [PATCH 39/40] build(deps): Bump github.com/informalsystems/tm-load-test from 1.1.0 to 1.2.0 (#84) Bumps [github.com/informalsystems/tm-load-test](https://github.com/informalsystems/tm-load-test) from 1.1.0 to 1.2.0.
Release notes

Sourced from github.com/informalsystems/tm-load-test's releases.

v1.2.0

See the CHANGELOG for details regarding this release.

Changelog

  • a9c21a5 Update changelog for v1.2.0
  • 8dfaff8 Replace Tendermint Core dependency with Informal Systems fork (#167)
  • 28e6cba Bump golang.org/x/crypto from 0.4.0 to 0.5.0 (#166)
  • cd04834 Bump golang.org/x/crypto from 0.1.0 to 0.4.0 (#165)
Changelog

Sourced from github.com/informalsystems/tm-load-test's changelog.

v1.2.0

  • #167 - Temporarily replace the Tendermint Core dependency with Informal Systems' fork
Commits
  • a9c21a5 Update changelog for v1.2.0
  • 8dfaff8 Replace Tendermint Core dependency with Informal Systems fork (#167)
  • 28e6cba Bump golang.org/x/crypto from 0.4.0 to 0.5.0 (#166)
  • cd04834 Bump golang.org/x/crypto from 0.1.0 to 0.4.0 (#165)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/informalsystems/tm-load-test&package-manager=go_modules&previous-version=1.1.0&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 9dd615d1ec7..442ce31c9eb 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/golangci/golangci-lint v1.50.1 github.com/google/orderedcode v0.0.1 github.com/gorilla/websocket v1.5.0 - github.com/informalsystems/tm-load-test v1.1.0 + github.com/informalsystems/tm-load-test v1.2.0 github.com/lib/pq v1.10.7 github.com/libp2p/go-buffer-pool v0.1.0 github.com/minio/highwayhash v1.0.2 @@ -32,8 +32,8 @@ require ( github.com/spf13/viper v1.14.0 github.com/stretchr/testify v1.8.1 github.com/tendermint/tm-db v0.6.6 - golang.org/x/crypto v0.4.0 - golang.org/x/net v0.4.0 + golang.org/x/crypto v0.5.0 + golang.org/x/net v0.5.0 google.golang.org/grpc v1.51.0 ) @@ -271,9 +271,9 @@ require ( golang.org/x/exp v0.0.0-20221211140036-ad323defaf05 // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/mod v0.7.0 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/term v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect golang.org/x/tools v0.4.0 // indirect google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index d599ffe3783..c3a009ba87d 100644 --- a/go.sum +++ b/go.sum @@ -479,8 +479,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/informalsystems/tm-load-test v1.1.0 h1:rgOiaUdrTiq9lcJyRm8dw/j+t8VPK+kJ59X5GrzXAVQ= -github.com/informalsystems/tm-load-test v1.1.0/go.mod h1:qToYzfHknFzHB5hybRe8ffZ7Eg9BBqz3A5bZ2Pi0tNU= +github.com/informalsystems/tm-load-test v1.2.0 h1:dui5RccDOpB3eYjtJmOqjajKmItrD11FAds+PummELk= +github.com/informalsystems/tm-load-test v1.2.0/go.mod h1:CssE2CoyyubxqODOxioyT711laAhti6YtRYwMrSiRz4= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co= @@ -920,8 +920,8 @@ golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8= -golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1011,8 +1011,8 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= 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= @@ -1117,14 +1117,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= 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= @@ -1134,8 +1134,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 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= From fe8a78955cdff8d4c5350b33a3478ff729c78b7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Jan 2023 12:40:34 +0000 Subject: [PATCH 40/40] build(deps): Bump github.com/go-git/go-git/v5 from 5.5.1 to 5.5.2 (#86) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.5.1 to 5.5.2.
Release notes

Sourced from github.com/go-git/go-git/v5's releases.

v5.5.2

What's Changed

Full Changelog: https://github.com/go-git/go-git/compare/v5.5.1...v5.5.2

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-git/go-git/v5&package-manager=go_modules&previous-version=5.5.1&new-version=5.5.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- go.mod | 4 ++-- go.sum | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 442ce31c9eb..11688eaa99a 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,7 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cosmos/gogoproto v1.4.3 - github.com/go-git/go-git/v5 v5.5.1 + github.com/go-git/go-git/v5 v5.5.2 github.com/gofrs/uuid v4.3.1+incompatible github.com/google/uuid v1.3.0 github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae @@ -121,7 +121,7 @@ require ( github.com/go-chi/chi/v5 v5.0.8 // indirect github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.3.1 // indirect + github.com/go-git/go-billy/v5 v5.4.0 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.2 // indirect github.com/go-toolsmith/astequal v1.0.3 // indirect diff --git a/go.sum b/go.sum index c3a009ba87d..37361708d37 100644 --- a/go.sum +++ b/go.sum @@ -277,12 +277,13 @@ github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mW github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= +github.com/go-git/go-billy/v5 v5.4.0 h1:Vaw7LaSTRJOUric7pe4vnzBSgyuf2KrLsu2Y4ZpQBDE= +github.com/go-git/go-billy/v5 v5.4.0/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.1 h1:y5z6dd3qi8Hl+stezc8p3JxDkoTRqMAlKnXHuzrfjTQ= github.com/go-git/go-git-fixtures/v4 v4.3.1/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.5.1 h1:5vtv2TB5PM/gPM+EvsHJ16hJh4uAkdGcKilcwY7FYwo= -github.com/go-git/go-git/v5 v5.5.1/go.mod h1:uz5PQ3d0gz7mSgzZhSJToM6ALPaKCdSnl58/Xb5hzr8= +github.com/go-git/go-git/v5 v5.5.2 h1:v8lgZa5k9ylUw+OR/roJHTxR4QItsNFI5nKtAXFuynw= +github.com/go-git/go-git/v5 v5.5.2/go.mod h1:BE5hUJ5yaV2YMxhmaP4l6RBQ08kMxKSPD4BlxtH7OjI= 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=