diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6a2a5c934..ccfe5e092 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -41,17 +41,17 @@ jobs: platforms: all - name: Set up Docker Build - uses: docker/setup-buildx-action@v2.0.0 + uses: docker/setup-buildx-action@v2.1.0 - name: Login to DockerHub if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@v2.0.0 + 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.1.1 + uses: docker/build-push-action@v3.2.0 with: context: . file: ./DOCKER/Dockerfile diff --git a/.github/workflows/e2e-nightly-34x.yml b/.github/workflows/e2e-nightly-34x.yml index a01e769d2..944ba13ef 100644 --- a/.github/workflows/e2e-nightly-34x.yml +++ b/.github/workflows/e2e-nightly-34x.yml @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.22.0 + uses: slackapi/slack-github-action@v1.23.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK @@ -72,7 +72,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> that caused the failure." + "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." } } ] diff --git a/.github/workflows/e2e-nightly-37x.yml b/.github/workflows/e2e-nightly-37x.yml index c3f6b16aa..769a316b2 100644 --- a/.github/workflows/e2e-nightly-37x.yml +++ b/.github/workflows/e2e-nightly-37x.yml @@ -57,7 +57,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.22.0 + uses: slackapi/slack-github-action@v1.23.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK @@ -72,7 +72,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> that caused the failure." + "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." } } ] diff --git a/.github/workflows/e2e-nightly-main.yml b/.github/workflows/e2e-nightly-main.yml index 2bb00dc47..dd8b7abbb 100644 --- a/.github/workflows/e2e-nightly-main.yml +++ b/.github/workflows/e2e-nightly-main.yml @@ -46,7 +46,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.22.0 + uses: slackapi/slack-github-action@v1.23.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK @@ -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> that caused the failure." + "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." } } ] diff --git a/.github/workflows/fuzz-nightly.yml b/.github/workflows/fuzz-nightly.yml index b7ac5168c..0209501a1 100644 --- a/.github/workflows/fuzz-nightly.yml +++ b/.github/workflows/fuzz-nightly.yml @@ -76,7 +76,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Notify Slack on failure - uses: slackapi/slack-github-action@v1.22.0 + uses: slackapi/slack-github-action@v1.23.0 env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK diff --git a/.github/workflows/janitor.yml b/.github/workflows/janitor.yml index 28ae05b51..466ec37d3 100644 --- a/.github/workflows/janitor.yml +++ b/.github/workflows/janitor.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 3 steps: - - uses: styfle/cancel-workflow-action@0.10.1 + - uses: styfle/cancel-workflow-action@0.11.0 with: workflow_id: 1041851,1401230,2837803 access_token: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 103263181..798f93301 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,5 @@ proto/spec/**/*.pb.go *.pdf *.gz *.dvi +# Python virtual environments +.venv diff --git a/CHANGELOG.md b/CHANGELOG.md index a3f4a881e..e2b27c149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/cosmos). +## v0.34.22 + +This release includes several bug fixes, [one of +which](https://github.com/tendermint/tendermint/pull/9518) we discovered while +building up a baseline for v0.34 against which to compare our upcoming v0.37 +release during our [QA process](./docs/qa/). + +Special thanks to external contributors on this release: @RiccardoM + +### FEATURES + +- [rpc] [\#9423](https://github.com/tendermint/tendermint/pull/9423) Support + HTTPS URLs from the WebSocket client (@RiccardoM, @cmwaters) + +### BUG FIXES + +- [config] [\#9483](https://github.com/tendermint/tendermint/issues/9483) + Calling `tendermint init` would incorrectly leave out the new `[storage]` + section delimiter in the generated configuration file - this has now been + fixed +- [p2p] [\#9500](https://github.com/tendermint/tendermint/issues/9500) Prevent + peers who have errored being added to the peer set (@jmalicevic) +- [indexer] [\#9473](https://github.com/tendermint/tendermint/issues/9473) Fix + bug that caused the psql indexer to index empty blocks whenever one of the + transactions returned a non zero code. The relevant deduplication logic has + been moved within the kv indexer only (@cmwaters) +- [blocksync] [\#9518](https://github.com/tendermint/tendermint/issues/9518) A + block sync stall was observed during our QA process whereby the node was + unable to make progress. Retrying block requests after a timeout fixes this. + ## v0.34.21 Release highlights include: diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index 5f1bf8d3b..660a7b268 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -7,10 +7,9 @@ import ( context "context" fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - grpc1 "github.com/cosmos/gogoproto/grpc" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" types1 "github.com/tendermint/tendermint/proto/tendermint/types" grpc "google.golang.org/grpc" @@ -3682,10 +3681,10 @@ type ABCIApplicationClient interface { } type aBCIApplicationClient struct { - cc grpc1.ClientConn + cc *grpc.ClientConn } -func NewABCIApplicationClient(cc grpc1.ClientConn) ABCIApplicationClient { +func NewABCIApplicationClient(cc *grpc.ClientConn) ABCIApplicationClient { return &aBCIApplicationClient{cc} } @@ -3906,7 +3905,7 @@ func (*UnimplementedABCIApplicationServer) ProcessProposal(ctx context.Context, return nil, status.Errorf(codes.Unimplemented, "method ProcessProposal not implemented") } -func RegisterABCIApplicationServer(s grpc1.Server, srv ABCIApplicationServer) { +func RegisterABCIApplicationServer(s *grpc.Server, srv ABCIApplicationServer) { s.RegisterService(&_ABCIApplication_serviceDesc, srv) } @@ -4808,7 +4807,7 @@ func (m *RequestInitChain) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n18, err18 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n18, err18 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err18 != nil { return 0, err18 } @@ -5230,7 +5229,7 @@ func (m *RequestPrepareProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x3a } - n22, err22 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n22, err22 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err22 != nil { return 0, err22 } @@ -5318,7 +5317,7 @@ func (m *RequestProcessProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x3a } - n24, err24 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n24, err24 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err24 != nil { return 0, err24 } @@ -6987,7 +6986,7 @@ func (m *Misbehavior) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x28 } - n52, err52 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n52, err52 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err52 != nil { return 0, err52 } @@ -7336,7 +7335,7 @@ func (m *RequestInitChain) Size() (n int) { } var l int _ = l - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovTypes(uint64(l)) l = len(m.ChainId) if l > 0 { @@ -7548,7 +7547,7 @@ func (m *RequestPrepareProposal) Size() (n int) { if m.Height != 0 { n += 1 + sovTypes(uint64(m.Height)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovTypes(uint64(l)) l = len(m.NextValidatorsHash) if l > 0 { @@ -7588,7 +7587,7 @@ func (m *RequestProcessProposal) Size() (n int) { if m.Height != 0 { n += 1 + sovTypes(uint64(m.Height)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovTypes(uint64(l)) l = len(m.NextValidatorsHash) if l > 0 { @@ -8355,7 +8354,7 @@ func (m *Misbehavior) Size() (n int) { if m.Height != 0 { n += 1 + sovTypes(uint64(m.Height)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovTypes(uint64(l)) if m.TotalVotingPower != 0 { n += 1 + sovTypes(uint64(m.TotalVotingPower)) @@ -9347,7 +9346,7 @@ func (m *RequestInitChain) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -10779,7 +10778,7 @@ func (m *RequestPrepareProposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -11082,7 +11081,7 @@ func (m *RequestProcessProposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -15397,7 +15396,7 @@ func (m *Misbehavior) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/config/config.go b/config/config.go index 6ec62c004..76a89f953 100644 --- a/config/config.go +++ b/config/config.go @@ -703,9 +703,6 @@ type MempoolConfig struct { // Mempool version to use: // 1) "v0" - (default) FIFO mempool. // 2) "v1" - prioritized mempool. - // WARNING: There's a known memory leak with the prioritized mempool - // that the team are working on. Read more here: - // https://github.com/tendermint/tendermint/issues/8775 Version string `mapstructure:"version"` RootDir string `mapstructure:"home"` Recheck bool `mapstructure:"recheck"` diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 6b9594c60..4b21320e1 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -99,4 +99,4 @@ configuration file that we can update with PRs. Because the build processes are identical (as is the information contained herein), this file should be kept in sync as much as possible with its [counterpart in the Cosmos SDK -repo](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md). +repo](https://github.com/cosmos/cosmos-sdk/blob/main/docs/README.md). diff --git a/docs/architecture/adr-071-proposer-based-timestamps.md b/docs/architecture/adr-071-proposer-based-timestamps.md index 11fd70dae..e17226cce 100644 --- a/docs/architecture/adr-071-proposer-based-timestamps.md +++ b/docs/architecture/adr-071-proposer-based-timestamps.md @@ -61,7 +61,7 @@ The following protocols and application features require a reliable source of ti * Tendermint Light Clients [rely on correspondence between their known time](https://github.com/tendermint/tendermint/blob/main/spec/light-client/verification/README.md#definitions-1) and the block time for block verification. * Tendermint Evidence validity is determined [either in terms of heights or in terms of time](https://github.com/tendermint/tendermint/blob/8029cf7a0fcc89a5004e173ec065aa48ad5ba3c8/spec/consensus/evidence.md#verification). * Unbonding of staked assets in the Cosmos Hub [occurs after a period of 21 days](https://github.com/cosmos/governance/blob/ce75de4019b0129f6efcbb0e752cd2cc9e6136d3/params-change/Staking.md#unbondingtime). -* IBC packets can use either a [timestamp or a height to timeout packet delivery](https://docs.cosmos.network/v0.44/ibc/overview.html#acknowledgements) +* IBC packets can use either a [timestamp or a height to timeout packet delivery](https://docs.cosmos.network/v0.45/ibc/overview.html#acknowledgements) Finally, inflation distribution in the Cosmos Hub uses an approximation of time to calculate an annual percentage rate. This approximation of time is calculated using [block heights with an estimated number of blocks produced in a year](https://github.com/cosmos/governance/blob/master/params-change/Mint.md#blocksperyear). diff --git a/docs/qa/README.md b/docs/qa/README.md new file mode 100644 index 000000000..d322ccb6c --- /dev/null +++ b/docs/qa/README.md @@ -0,0 +1,23 @@ +--- +order: 1 +parent: + title: Tendermint Quality Assurance + description: This is a report on the process followed and results obtained when running v0.34.x on testnets + order: 2 +--- + +# Tendermint Quality Assurance + +This directory keeps track of the process followed by the Tendermint Core team +for Quality Assurance before cutting a release. +This directory is to live in multiple branches. On each release branch, +the contents of this directory reflect the status of the process +at the time the Quality Assurance process was applied for that release. + +File [method](./method.md) keeps track of the process followed to obtain the results +used to decide if a release is passing the Quality Assurance process. +The results obtained in each release are stored in their own directory. +The following releases have undergone the Quality Assurance process: + +* [v0.34.x](./v034/), which was tested just before releasing v0.34.22 +* [v0.37.x](./v037/), with v.34.x acting as a baseline diff --git a/docs/qa/method.md b/docs/qa/method.md new file mode 100644 index 000000000..cc4f82dfa --- /dev/null +++ b/docs/qa/method.md @@ -0,0 +1,214 @@ +--- +order: 1 +title: Method +--- + +# Method + +This document provides a detailed description of the QA process. +It is intended to be used by engineers reproducing the experimental setup for future tests of Tendermint. + +The (first iteration of the) QA process as described [in the RELEASES.md document][releases] +was applied to version v0.34.x in order to have a set of results acting as benchmarking baseline. +This baseline is then compared with results obtained in later versions. + +Out of the testnet-based test cases described in [the releases document][releases] we focused on two of them: +_200 Node Test_, and _Rotating Nodes Test_. + +[releases]: https://github.com/tendermint/tendermint/blob/v0.37.x/RELEASES.md#large-scale-testnets + +## Software Dependencies + +### Infrastructure Requirements to Run the Tests + +* An account at Digital Ocean (DO), with a high droplet limit (>202) +* The machine to orchestrate the tests should have the following installed: + * A clone of the [testnet repository][testnet-repo] + * This repository contains all the scripts mentioned in the reminder of this section + * [Digital Ocean CLI][doctl] + * [Terraform CLI][Terraform] + * [Ansible CLI][Ansible] + +[testnet-repo]: https://github.com/interchainio/tendermint-testnet +[Ansible]: https://docs.ansible.com/ansible/latest/index.html +[Terraform]: https://www.terraform.io/docs +[doctl]: https://docs.digitalocean.com/reference/doctl/how-to/install/ + +### Requirements for Result Extraction + +* Matlab or Octave +* [Prometheus][prometheus] server installed +* blockstore DB of one of the full nodes in the testnet +* Prometheus DB + +[prometheus]: https://prometheus.io/ + +## 200 Node Testnet + +### Running the test + +This section explains how the tests were carried out for reproducibility purposes. + +1. [If you haven't done it before] + Follow steps 1-4 of the `README.md` at the top of the testnet repository to configure Terraform, and `doctl`. +2. Copy file `testnets/testnet200.toml` onto `testnet.toml` (do NOT commit this change) +3. Set the variable `VERSION_TAG` in the `Makefile` to the git hash that is to be tested. +4. Follow steps 5-10 of the `README.md` to configure and start the 200 node testnet + * WARNING: Do NOT forget to run `make terraform-destroy` as soon as you are done with the tests (see step 9) +5. As a sanity check, connect to the Prometheus node's web interface and check the graph for the `tendermint_consensus_height` metric. + All nodes should be increasing their heights. +6. `ssh` into the `testnet-load-runner`, then copy script `script/200-node-loadscript.sh` and run it from the load runner node. + * Before running it, you need to edit the script to provide the IP address of a full node. + This node will receive all transactions from the load runner node. + * This script will take about 40 mins to run + * It is running 90-seconds-long experiments in a loop with different loads +7. Run `make retrieve-data` to gather all relevant data from the testnet into the orchestrating machine +8. Verify that the data was collected without errors + * at least one blockstore DB for a Tendermint validator + * the Prometheus database from the Prometheus node + * for extra care, you can run `zip -T` on the `prometheus.zip` file and (one of) the `blockstore.db.zip` file(s) +9. **Run `make terraform-destroy`** + * Don't forget to type `yes`! Otherwise you're in trouble. + +### Result Extraction + +The method for extracting the results described here is highly manual (and exploratory) at this stage. +The Core team should improve it at every iteration to increase the amount of automation. + +#### Steps + +1. Unzip the blockstore into a directory +2. Extract the latency report and the raw latencies for all the experiments. Run these commands from the directory containing the blockstore + * `go run github.com/tendermint/tendermint/test/loadtime/cmd/report@3ec6e424d --database-type goleveldb --data-dir ./ > results/report.txt` + * `go run github.com/tendermint/tendermint/test/loadtime/cmd/report@3ec6e424d --database-type goleveldb --data-dir ./ --csv results/raw.csv` +3. File `report.txt` contains an unordered list of experiments with varying concurrent connections and transaction rate + * Create files `report01.txt`, `report02.txt`, `report04.txt` and, for each experiment in file `report.txt`, + copy its related lines to the filename that matches the number of connections. + * Sort the experiments in `report01.txt` in ascending tx rate order. Likewise for `report02.txt` and `report04.txt`. +4. Generate file `report_tabbed.txt` by showing the contents `report01.txt`, `report02.txt`, `report04.txt` side by side + * This effectively creates a table where rows are a particular tx rate and columns are a particular number of websocket connections. +5. Extract the raw latencies from file `raw.csv` using the following bash loop. This creates a `.csv` file and a `.dat` file per experiment. + The format of the `.dat` files is amenable to loading them as matrices in Octave + + ```bash + uuids=($(cat report01.txt report02.txt report04.txt | grep '^Experiment ID: ' | awk '{ print $3 }')) + c=1 + for i in 01 02 04; do + for j in 0025 0050 0100 0200; do + echo $i $j $c "${uuids[$c]}" + filename=c${i}_r${j} + grep ${uuids[$c]} raw.csv > ${filename}.csv + cat ${filename}.csv | tr , ' ' | awk '{ print $2, $3 }' > ${filename}.dat + c=$(expr $c + 1) + done + done + ``` + +6. Enter Octave +7. Load all `.dat` files generated in step 5 into matrices using this Octave code snippet + + ```octave + conns = { "01"; "02"; "04" }; + rates = { "0025"; "0050"; "0100"; "0200" }; + for i = 1:length(conns) + for j = 1:length(rates) + filename = strcat("c", conns{i}, "_r", rates{j}, ".dat"); + load("-ascii", filename); + endfor + endfor + ``` + +8. Set variable release to the current release undergoing QA + + ```octave + release = "v0.34.x"; + ``` + +9. Generate a plot with all (or some) experiments, where the X axis is the experiment time, + and the y axis is the latency of transactions. + The following snippet plots all experiments. + + ```octave + legends = {}; + hold off; + for i = 1:length(conns) + for j = 1:length(rates) + data_name = strcat("c", conns{i}, "_r", rates{j}); + l = strcat("c=", conns{i}, " r=", rates{j}); + m = eval(data_name); plot((m(:,1) - min(m(:,1))) / 1e+9, m(:,2) / 1e+9, "."); + hold on; + legends(1, end+1) = l; + endfor + endfor + legend(legends, "location", "northeastoutside"); + xlabel("experiment time (s)"); + ylabel("latency (s)"); + t = sprintf("200-node testnet - %s", release); + title(t); + ``` + +10. Consider adjusting the axis, in case you want to compare your results to the baseline, for instance + + ```octave + axis([0, 100, 0, 30], "tic"); + ``` + +11. Use Octave's GUI menu to save the plot (e.g. as `.png`) + +12. Repeat steps 9 and 10 to obtain as many plots as deemed necessary. + +13. To generate a latency vs throughput plot, using the raw CSV file generated + in step 2, follow the instructions for the [`latency_throughput.py`] script. + +[`latency_throughput.py`]: ../../scripts/qa/reporting/README.md + +#### Extracting Prometheus Metrics + +1. Stop the prometheus server if it is running as a service (e.g. a `systemd` unit). +2. Unzip the prometheus database retrieved from the testnet, and move it to replace the + local prometheus database. +3. Start the prometheus server and make sure no error logs appear at start up. +4. Introduce the metrics you want to gather or plot. + +## Rotating Node Testnet + +### Running the test + +This section explains how the tests were carried out for reproducibility purposes. + +1. [If you haven't done it before] + Follow steps 1-4 of the `README.md` at the top of the testnet repository to configure Terraform, and `doctl`. +2. Copy file `testnet_rotating.toml` onto `testnet.toml` (do NOT commit this change) +3. Set variable `VERSION_TAG` to the git hash that is to be tested. +4. Run `make terraform-apply EPHEMERAL_SIZE=25` + * WARNING: Do NOT forget to run `make terraform-destroy` as soon as you are done with the tests +5. Follow steps 6-10 of the `README.md` to configure and start the "stable" part of the rotating node testnet +6. As a sanity check, connect to the Prometheus node's web interface and check the graph for the `tendermint_consensus_height` metric. + All nodes should be increasing their heights. +7. On a different shell, + * run `make runload ROTATE_CONNECTIONS=X ROTATE_TX_RATE=Y` + * `X` and `Y` should reflect a load below the saturation point (see, e.g., + [this paragraph](./v034/README.md#finding-the-saturation-point) for further info) +8. Run `make rotate` to start the script that creates the ephemeral nodes, and kills them when they are caught up. + * WARNING: If you run this command from your laptop, the laptop needs to be up and connected for full length + of the experiment. +9. When the height of the chain reaches 3000, stop the `make rotate` script +10. When the rotate script has made two iterations (i.e., all ephemeral nodes have caught up twice) + after height 3000 was reached, stop `make rotate` +11. Run `make retrieve-data` to gather all relevant data from the testnet into the orchestrating machine +12. Verify that the data was collected without errors + * at least one blockstore DB for a Tendermint validator + * the Prometheus database from the Prometheus node + * for extra care, you can run `zip -T` on the `prometheus.zip` file and (one of) the `blockstore.db.zip` file(s) +13. **Run `make terraform-destroy`** + +Steps 8 to 10 are highly manual at the moment and will be improved in next iterations. + +### Result Extraction + +In order to obtain a latency plot, follow the instructions above for the 200 node experiment, but: + +* The `results.txt` file contains only one experiment +* Therefore, no need for any `for` loops + +As for prometheus, the same method as for the 200 node experiment can be applied. diff --git a/docs/qa/v034/README.md b/docs/qa/v034/README.md new file mode 100644 index 000000000..b07b10291 --- /dev/null +++ b/docs/qa/v034/README.md @@ -0,0 +1,278 @@ +--- +order: 1 +parent: + title: Tendermint Quality Assurance Results for v0.34.x + description: This is a report on the results obtained when running v0.34.x on testnets + order: 2 +--- + +# v0.34.x + +## 200 Node Testnet + +### Finding the Saturation Point + +The first goal when examining the results of the tests is identifying the saturation point. +The saturation point is a setup with a transaction load big enough to prevent the testnet +from being stable: the load runner tries to produce slightly more transactions than can +be processed by the testnet. + +The following table summarizes the results for v0.34.x, for the different experiments +(extracted from file [`v034_report_tabbed.txt`](./img/v034_report_tabbed.txt)). + +The X axis of this table is `c`, the number of connections created by the load runner process to the target node. +The Y axis of this table is `r`, the rate or number of transactions issued per second. + +| | c=1 | c=2 | c=4 | +| :--- | ----: | ----: | ----: | +| r=25 | 2225 | 4450 | 8900 | +| r=50 | 4450 | 8900 | 17800 | +| r=100 | 8900 | 17800 | 35600 | +| r=200 | 17800 | 35600 | 38660 | + +The table shows the number of 1024-byte-long transactions that were produced by the load runner, +and processed by Tendermint, during the 90 seconds of the experiment's duration. +Each cell in the table refers to an experiment with a particular number of websocket connections (`c`) +to a chosen validator, and the number of transactions per second that the load runner +tries to produce (`r`). Note that the overall load that the tool attempts to generate is $c \cdot r$. + +We can see that the saturation point is beyond the diagonal that spans cells + +* `r=200,c=2` +* `r=100,c=4` + +given that the total transactions should be close to the product of the rate, the number of connections, +and the experiment time (89 seconds, since the last batch never gets sent). + +All experiments below the saturation diagonal (`r=200,c=4`) have in common that the total +number of transactions processed is noticeably less than the product $c \cdot r \cdot 89$, +which is the expected number of transactions when the system is able to deal well with the +load. +With `r=200,c=4`, we obtained 38660 whereas the theoretical number of transactions should +have been $200 \cdot 4 \cdot 89 = 71200$. + +At this point, we chose an experiment at the limit of the saturation diagonal, +in order to further study the performance of this release. +**The chosen experiment is `r=200,c=2`**. + +This is a plot of the CPU load (average over 1 minute, as output by `top`) of the load runner for `r=200,c=2`, +where we can see that the load stays close to 0 most of the time. + +![load-load-runner](./img/v034_r200c2_load-runner.png) + +### Examining latencies + +The method described [here](../method.md) allows us to plot the latencies of transactions +for all experiments. + +![all-latencies](./img/v034_200node_latencies.png) + +As we can see, even the experiments beyond the saturation diagonal managed to keep +transaction latency stable (i.e. not constantly increasing). +Our interpretation for this is that contention within Tendermint was propagated, +via the websockets, to the load runner, +hence the load runner could not produce the target load, but a fraction of it. + +Further examination of the Prometheus data (see below), showed that the mempool contained many transactions +at steady state, but did not grow much without quickly returning to this steady state. This demonstrates +that the transactions were able to be processed by the Tendermint network at least as quickly as they +were submitted to the mempool. Finally, the test script made sure that, at the end of an experiment, the +mempool was empty so that all transactions submitted to the chain were processed. + +Finally, the number of points present in the plot appears to be much less than expected given the +number of transactions in each experiment, particularly close to or above the saturation diagonal. +This is a visual effect of the plot; what appear to be points in the plot are actually potentially huge +clusters of points. To corroborate this, we have zoomed in the plot above by setting (carefully chosen) +tiny axis intervals. The cluster shown below looks like a single point in the plot above. + +![all-latencies-zoomed](./img/v034_200node_latencies_zoomed.png) + +The plot of latencies can we used as a baseline to compare with other releases. + +The following plot summarizes average latencies versus overall throughputs +across different numbers of WebSocket connections to the node into which +transactions are being loaded. + +![latency-vs-throughput](./img/v034_latency_throughput.png) + +### Prometheus Metrics on the Chosen Experiment + +As mentioned [above](#finding-the-saturation-point), the chosen experiment is `r=200,c=2`. +This section further examines key metrics for this experiment extracted from Prometheus data. + +#### Mempool Size + +The mempool size, a count of the number of transactions in the mempool, was shown to be stable and homogeneous +at all full nodes. It did not exhibit any unconstrained growth. +The plot below shows the evolution over time of the cumulative number of transactions inside all full nodes' mempools +at a given time. +The two spikes that can be observed correspond to a period where consensus instances proceeded beyond the initial round +at some nodes. + +![mempool-cumulative](./img/v034_r200c2_mempool_size.png) + +The plot below shows evolution of the average over all full nodes, which oscillates between 1500 and 2000 +outstanding transactions. + +![mempool-avg](./img/v034_r200c2_mempool_size_avg.png) + +The peaks observed coincide with the moments when some nodes proceeded beyond the initial round of consensus (see below). + +#### Peers + +The number of peers was stable at all nodes. +It was higher for the seed nodes (around 140) than for the rest (between 21 and 74). +The fact that non-seed nodes reach more than 50 peers is due to #9548. + +![peers](./img/v034_r200c2_peers.png) + +#### Consensus Rounds per Height + +Most heights took just one round, but some nodes needed to advance to round 1 at some point. + +![rounds](./img/v034_r200c2_rounds.png) + +#### Blocks Produced per Minute, Transactions Processed per Minute + +The blocks produced per minute are the slope of this plot. + +![heights](./img/v034_r200c2_heights.png) + +Over a period of 2 minutes, the height goes from 530 to 569. +This results in an average of 19.5 blocks produced per minute. + +The transactions processed per minute are the slope of this plot. + +![total-txs](./img/v034_r200c2_total-txs.png) + +Over a period of 2 minutes, the total goes from 64525 to 100125 transactions, +resulting in 17800 transactions per minute. However, we can see in the plot that +all transactions in the load are processed long before the two minutes. +If we adjust the time window when transactions are processed (approx. 105 seconds), +we obtain 20343 transactions per minute. + +#### Memory Resident Set Size + +Resident Set Size of all monitored processes is plotted below. + +![rss](./img/v034_r200c2_rss.png) + +The average over all processes oscillates around 1.2 GiB and does not demonstrate unconstrained growth. + +![rss-avg](./img/v034_r200c2_rss_avg.png) + +#### CPU utilization + +The best metric from Prometheus to gauge CPU utilization in a Unix machine is `load1`, +as it usually appears in the +[output of `top`](https://www.digitalocean.com/community/tutorials/load-average-in-linux). + +![load1](./img/v034_r200c2_load1.png) + +It is contained in most cases below 5, which is generally considered acceptable load. + +### Test Result + +**Result: N/A** (v0.34.x is the baseline) + +Date: 2022-10-14 + +Version: 3ec6e424d6ae4c96867c2dcf8310572156068bb6 + +## Rotating Node Testnet + +For this testnet, we will use a load that can safely be considered below the saturation +point for the size of this testnet (between 13 and 38 full nodes): `c=4,r=800`. + +N.B.: The version of Tendermint used for these tests is affected by #9539. +However, the reduced load that reaches the mempools is orthogonal to functionality +we are focusing on here. + +### Latencies + +The plot of all latencies can be seen in the following plot. + +![rotating-all-latencies](./img/v034_rotating_latencies.png) + +We can observe there are some very high latencies, towards the end of the test. +Upon suspicion that they are duplicate transactions, we examined the latencies +raw file and discovered there are more than 100K duplicate transactions. + +The following plot shows the latencies file where all duplicate transactions have +been removed, i.e., only the first occurrence of a duplicate transaction is kept. + +![rotating-all-latencies-uniq](./img/v034_rotating_latencies_uniq.png) + +This problem, existing in `v0.34.x`, will need to be addressed, perhaps in the same way +we addressed it when running the 200 node test with high loads: increasing the `cache_size` +configuration parameter. + +### Prometheus Metrics + +The set of metrics shown here are less than for the 200 node experiment. +We are only interested in those for which the catch-up process (blocksync) may have an impact. + +#### Blocks and Transactions per minute + +Just as shown for the 200 node test, the blocks produced per minute are the gradient of this plot. + +![rotating-heights](./img/v034_rotating_heights.png) + +Over a period of 5229 seconds, the height goes from 2 to 3638. +This results in an average of 41 blocks produced per minute. + +The following plot shows only the heights reported by ephemeral nodes +(which are also included in the plot above). Note that the _height_ metric +is only showed _once the node has switched to consensus_, hence the gaps +when nodes are killed, wiped out, started from scratch, and catching up. + +![rotating-heights-ephe](./img/v034_rotating_heights_ephe.png) + +The transactions processed per minute are the gradient of this plot. + +![rotating-total-txs](./img/v034_rotating_total-txs.png) + +The small lines we see periodically close to `y=0` are the transactions that +ephemeral nodes start processing when they are caught up. + +Over a period of 5229 minutes, the total goes from 0 to 387697 transactions, +resulting in 4449 transactions per minute. We can see some abrupt changes in +the plot's gradient. This will need to be investigated. + +#### Peers + +The plot below shows the evolution in peers throughout the experiment. +The periodic changes observed are due to the ephemeral nodes being stopped, +wiped out, and recreated. + +![rotating-peers](./img/v034_rotating_peers.png) + +The validators' plots are concentrated at the higher part of the graph, whereas the ephemeral nodes +are mostly at the lower part. + +#### Memory Resident Set Size + +The average Resident Set Size (RSS) over all processes seems stable, and slightly growing toward the end. +This might be related to the increased in transaction load observed above. + +![rotating-rss-avg](./img/v034_rotating_rss_avg.png) + +The memory taken by the validators and the ephemeral nodes (when they are up) is comparable. + +#### CPU utilization + +The plot shows metric `load1` for all nodes. + +![rotating-load1](./img/v034_rotating_load1.png) + +It is contained under 5 most of the time, which is considered normal load. +The purple line, which follows a different pattern is the validator receiving all +transactions, via RPC, from the load runner process. + +### Test Result + +**Result: N/A** + +Date: 2022-10-10 + +Version: a28c987f5a604ff66b515dd415270063e6fb069d diff --git a/docs/qa/v034/img/v034_200node_latencies.png b/docs/qa/v034/img/v034_200node_latencies.png new file mode 100644 index 000000000..afd1060ca Binary files /dev/null and b/docs/qa/v034/img/v034_200node_latencies.png differ diff --git a/docs/qa/v034/img/v034_200node_latencies_zoomed.png b/docs/qa/v034/img/v034_200node_latencies_zoomed.png new file mode 100644 index 000000000..1ff936442 Binary files /dev/null and b/docs/qa/v034/img/v034_200node_latencies_zoomed.png differ diff --git a/docs/qa/v034/img/v034_latency_throughput.png b/docs/qa/v034/img/v034_latency_throughput.png new file mode 100644 index 000000000..3674fe47b Binary files /dev/null and b/docs/qa/v034/img/v034_latency_throughput.png differ diff --git a/docs/qa/v034/img/v034_r200c2_heights.png b/docs/qa/v034/img/v034_r200c2_heights.png new file mode 100644 index 000000000..11f3bba43 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_heights.png differ diff --git a/docs/qa/v034/img/v034_r200c2_load-runner.png b/docs/qa/v034/img/v034_r200c2_load-runner.png new file mode 100644 index 000000000..70211b0d2 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_load-runner.png differ diff --git a/docs/qa/v034/img/v034_r200c2_load1.png b/docs/qa/v034/img/v034_r200c2_load1.png new file mode 100644 index 000000000..11012844d Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_load1.png differ diff --git a/docs/qa/v034/img/v034_r200c2_mempool_size.png b/docs/qa/v034/img/v034_r200c2_mempool_size.png new file mode 100644 index 000000000..c5d690200 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_mempool_size.png differ diff --git a/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png b/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png new file mode 100644 index 000000000..bda399fe5 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_mempool_size_avg.png differ diff --git a/docs/qa/v034/img/v034_r200c2_peers.png b/docs/qa/v034/img/v034_r200c2_peers.png new file mode 100644 index 000000000..a0aea7ada Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_peers.png differ diff --git a/docs/qa/v034/img/v034_r200c2_rounds.png b/docs/qa/v034/img/v034_r200c2_rounds.png new file mode 100644 index 000000000..215be100d Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rounds.png differ diff --git a/docs/qa/v034/img/v034_r200c2_rss.png b/docs/qa/v034/img/v034_r200c2_rss.png new file mode 100644 index 000000000..6d14dced0 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rss.png differ diff --git a/docs/qa/v034/img/v034_r200c2_rss_avg.png b/docs/qa/v034/img/v034_r200c2_rss_avg.png new file mode 100644 index 000000000..8dec67da2 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_rss_avg.png differ diff --git a/docs/qa/v034/img/v034_r200c2_total-txs.png b/docs/qa/v034/img/v034_r200c2_total-txs.png new file mode 100644 index 000000000..177d5f1c3 Binary files /dev/null and b/docs/qa/v034/img/v034_r200c2_total-txs.png differ diff --git a/docs/qa/v034/img/v034_report_tabbed.txt b/docs/qa/v034/img/v034_report_tabbed.txt new file mode 100644 index 000000000..251495474 --- /dev/null +++ b/docs/qa/v034/img/v034_report_tabbed.txt @@ -0,0 +1,52 @@ +Experiment ID: 3d5cf4ef-1a1a-4b46-aa2d-da5643d2e81e │Experiment ID: 80e472ec-13a1-4772-a827-3b0c907fb51d │Experiment ID: 07aca6cf-c5a4-4696-988f-e3270fc6333b + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 25 │ Rate: 25 │ Rate: 25 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 2225 │ Total Valid Tx: 4450 │ Total Valid Tx: 8900 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 599.404362ms │ Minimum Latency: 448.145181ms │ Minimum Latency: 412.485729ms + Maximum Latency: 3.539686885s │ Maximum Latency: 3.237392049s │ Maximum Latency: 12.026665368s + Average Latency: 1.441485349s │ Average Latency: 1.441267946s │ Average Latency: 2.150192457s + Standard Deviation: 541.049869ms │ Standard Deviation: 525.040007ms │ Standard Deviation: 2.233852478s + │ │ +Experiment ID: 953dc544-dd40-40e8-8712-20c34c3ce45e │Experiment ID: d31fc258-16e7-45cd-9dc8-13ab87bc0b0a │Experiment ID: 15d90a7e-b941-42f4-b411-2f15f857739e + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 50 │ Rate: 50 │ Rate: 50 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 4450 │ Total Valid Tx: 8900 │ Total Valid Tx: 17800 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 482.046942ms │ Minimum Latency: 435.458913ms │ Minimum Latency: 510.746448ms + Maximum Latency: 3.761483455s │ Maximum Latency: 7.175583584s │ Maximum Latency: 6.551497882s + Average Latency: 1.450408183s │ Average Latency: 1.681673116s │ Average Latency: 1.738083875s + Standard Deviation: 587.560056ms │ Standard Deviation: 1.147902047s │ Standard Deviation: 943.46522ms + │ │ +Experiment ID: 9a0b9980-9ce6-4db5-a80a-65ca70294b87 │Experiment ID: df8fa4f4-80af-4ded-8a28-356d15018b43 │Experiment ID: d0e41c2c-89c0-4f38-8e34-ca07adae593a + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 100 │ Rate: 100 │ Rate: 100 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 8900 │ Total Valid Tx: 17800 │ Total Valid Tx: 35600 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 477.417219ms │ Minimum Latency: 564.29247ms │ Minimum Latency: 840.71089ms + Maximum Latency: 6.63744785s │ Maximum Latency: 6.988553219s │ Maximum Latency: 9.555312398s + Average Latency: 1.561216103s │ Average Latency: 1.76419063s │ Average Latency: 3.200941683s + Standard Deviation: 1.011333552s │ Standard Deviation: 1.068459423s │ Standard Deviation: 1.732346601s + │ │ +Experiment ID: 493df3ee-4a36-4bce-80f8-6d65da66beda │Experiment ID: 13060525-f04f-46f6-8ade-286684b2fe50 │Experiment ID: 1777cbd2-8c96-42e4-9ec7-9b21f2225e4d + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 200 │ Rate: 200 │ Rate: 200 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 17800 │ Total Valid Tx: 35600 │ Total Valid Tx: 38660 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 493.705261ms │ Minimum Latency: 955.090573ms │ Minimum Latency: 1.9485821s + Maximum Latency: 7.440921872s │ Maximum Latency: 10.086673491s │ Maximum Latency: 17.73103976s + Average Latency: 1.875510582s │ Average Latency: 3.438130099s │ Average Latency: 8.143862237s + Standard Deviation: 1.304336995s │ Standard Deviation: 1.966391574s │ Standard Deviation: 3.943140002s + diff --git a/docs/qa/v034/img/v034_rotating_heights.png b/docs/qa/v034/img/v034_rotating_heights.png new file mode 100644 index 000000000..47913c282 Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_heights.png differ diff --git a/docs/qa/v034/img/v034_rotating_heights_ephe.png b/docs/qa/v034/img/v034_rotating_heights_ephe.png new file mode 100644 index 000000000..981b93d6c Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_heights_ephe.png differ diff --git a/docs/qa/v034/img/v034_rotating_latencies.png b/docs/qa/v034/img/v034_rotating_latencies.png new file mode 100644 index 000000000..f0a54ed5b Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_latencies.png differ diff --git a/docs/qa/v034/img/v034_rotating_latencies_uniq.png b/docs/qa/v034/img/v034_rotating_latencies_uniq.png new file mode 100644 index 000000000..e5d694a16 Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_latencies_uniq.png differ diff --git a/docs/qa/v034/img/v034_rotating_load1.png b/docs/qa/v034/img/v034_rotating_load1.png new file mode 100644 index 000000000..e9c385b85 Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_load1.png differ diff --git a/docs/qa/v034/img/v034_rotating_peers.png b/docs/qa/v034/img/v034_rotating_peers.png new file mode 100644 index 000000000..ab5c8732d Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_peers.png differ diff --git a/docs/qa/v034/img/v034_rotating_rss_avg.png b/docs/qa/v034/img/v034_rotating_rss_avg.png new file mode 100644 index 000000000..9a4167320 Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_rss_avg.png differ diff --git a/docs/qa/v034/img/v034_rotating_total-txs.png b/docs/qa/v034/img/v034_rotating_total-txs.png new file mode 100644 index 000000000..1ce5f47e9 Binary files /dev/null and b/docs/qa/v034/img/v034_rotating_total-txs.png differ diff --git a/docs/qa/v037/README.md b/docs/qa/v037/README.md new file mode 100644 index 000000000..680ffdaaa --- /dev/null +++ b/docs/qa/v037/README.md @@ -0,0 +1,326 @@ +--- +order: 1 +parent: + title: Tendermint Quality Assurance Results for v0.37.x + description: This is a report on the results obtained when running v0.37.x on testnets + order: 2 +--- + +# v0.37.x + +## Issues discovered + +During this iteration of the QA process, the following issues were found: + +* (critical, fixed) [\#9533] - This bug caused full nodes to sometimes get stuck + when blocksyncing, requiring a manual restart to unblock them. Importantly, + this bug was also present in v0.34.x and the fix was also backported in + [\#9534]. +* (critical, fixed) [\#9539] - `loadtime` is very likely to include more than + one "=" character in transactions, with is rejected by the e2e application. +* (critical, fixed) [\#9581] - Absent prometheus label makes Tendermint crash + when enabling Prometheus metric collection +* (non-critical, not fixed) [\#9548] - Full nodes can go over 50 connected + peers, which is not intended by the default configuration. +* (non-critical, not fixed) [\#9537] - With the default mempool cache setting, + duplicated transactions are not rejected when gossipped and eventually flood + all mempools. The 200 node testnets were thus run with a value of 200000 (as + opposed to the default 10000) + +## 200 Node Testnet + +### Finding the Saturation Point + +The first goal is to identify the saturation point and compare it with the baseline (v0.34.x). +For further details, see [this paragraph](../v034/README.md#finding-the-saturation-point) +in the baseline version. + +The following table summarizes the results for v0.37.x, for the different experiments +(extracted from file [`v037_report_tabbed.txt`](./img/v037_report_tabbed.txt)). + +The X axis of this table is `c`, the number of connections created by the load runner process to the target node. +The Y axis of this table is `r`, the rate or number of transactions issued per second. + +| | c=1 | c=2 | c=4 | +| :--- | ----: | ----: | ----: | +| r=25 | 2225 | 4450 | 8900 | +| r=50 | 4450 | 8900 | 17800 | +| r=100 | 8900 | 17800 | 35600 | +| r=200 | 17800 | 35600 | 38660 | + +For comparison, this is the table with the baseline version. + +| | c=1 | c=2 | c=4 | +| :--- | ----: | ----: | ----: | +| r=25 | 2225 | 4450 | 8900 | +| r=50 | 4450 | 8900 | 17800 | +| r=100 | 8900 | 17800 | 35400 | +| r=200 | 17800 | 35600 | 37358 | + +The saturation point is beyond the diagonal: + +* `r=200,c=2` +* `r=100,c=4` + +which is at the same place as the baseline. For more details on the saturation point, see +[this paragraph](../v034/README.md#finding-the-saturation-point) in the baseline version. + +The experiment chosen to examine Prometheus metrics is the same as in the baseline: +**`r=200,c=2`**. + +The load runner's CPU load was negligible (near 0) when running `r=200,c=2`. + +### Examining latencies + +The method described [here](../method.md) allows us to plot the latencies of transactions +for all experiments. + +![all-latencies](./img/v037_200node_latencies.png) + +The data seen in the plot is similar to that of the baseline. + +![all-latencies-bl](../v034/img/v034_200node_latencies.png) + +Therefore, for further details on these plots, +see [this paragraph](../v034/README.md#examining-latencies) in the baseline version. + +The following plot summarizes average latencies versus overall throughputs +across different numbers of WebSocket connections to the node into which +transactions are being loaded. + +![latency-vs-throughput](./img/v037_latency_throughput.png) + +This is similar to that of the baseline plot: + +![latency-vs-throughput-bl](../v034/img/v034_latency_throughput.png) + +### Prometheus Metrics on the Chosen Experiment + +As mentioned [above](#finding-the-saturation-point), the chosen experiment is `r=200,c=2`. +This section further examines key metrics for this experiment extracted from Prometheus data. + +#### Mempool Size + +The mempool size, a count of the number of transactions in the mempool, was shown to be stable and homogeneous +at all full nodes. It did not exhibit any unconstrained growth. +The plot below shows the evolution over time of the cumulative number of transactions inside all full nodes' mempools +at a given time. + +![mempool-cumulative](./img/v037_r200c2_mempool_size.png) + +The plot below shows evolution of the average over all full nodes, which oscillate between 1500 and 2000 outstanding transactions. + +![mempool-avg](./img/v037_r200c2_mempool_size_avg.png) + +The peaks observed coincide with the moments when some nodes reached round 1 of consensus (see below). + +**These plots yield similar results to the baseline**: + +![mempool-cumulative-bl](../v034/img/v034_r200c2_mempool_size.png) + +![mempool-avg-bl](../v034/img/v034_r200c2_mempool_size_avg.png) + +#### Peers + +The number of peers was stable at all nodes. +It was higher for the seed nodes (around 140) than for the rest (between 16 and 78). + +![peers](./img/v037_r200c2_peers.png) + +Just as in the baseline, the fact that non-seed nodes reach more than 50 peers is due to #9548. + +**This plot yields similar results to the baseline**: + +![peers-bl](../v034/img/v034_r200c2_peers.png) + +#### Consensus Rounds per Height + +Most heights took just one round, but some nodes needed to advance to round 1 at some point. + +![rounds](./img/v037_r200c2_rounds.png) + +**This plot yields slightly better results than the baseline**: + +![rounds-bl](../v034/img/v034_r200c2_rounds.png) + +#### Blocks Produced per Minute, Transactions Processed per Minute + +The blocks produced per minute are the gradient of this plot. + +![heights](./img/v037_r200c2_heights.png) + +Over a period of 2 minutes, the height goes from 477 to 524. +This results in an average of 23.5 blocks produced per minute. + +The transactions processed per minute are the gradient of this plot. + +![total-txs](./img/v037_r200c2_total-txs.png) + +Over a period of 2 minutes, the total goes from 64525 to 100125 transactions, +resulting in 17800 transactions per minute. However, we can see in the plot that +all transactions in the load are process long before the two minutes. +If we adjust the time window when transactions are processed (approx. 90 seconds), +we obtain 23733 transactions per minute. + +**These plots yield similar results to the baseline**: + +![heights-bl](../v034/img/v034_r200c2_heights.png) + +![total-txs](../v034/img/v034_r200c2_total-txs.png) + +#### Memory Resident Set Size + +Resident Set Size of all monitored processes is plotted below. + +![rss](./img/v037_r200c2_rss.png) + +The average over all processes oscillates around 380 MiB and does not demonstrate unconstrained growth. + +![rss-avg](./img/v037_r200c2_rss_avg.png) + +**These plots yield similar results to the baseline**: + +![rss-bl](../v034/img/v034_r200c2_rss.png) + +![rss-avg-bl](../v034/img/v034_r200c2_rss_avg.png) + +#### CPU utilization + +The best metric from Prometheus to gauge CPU utilization in a Unix machine is `load1`, +as it usually appears in the +[output of `top`](https://www.digitalocean.com/community/tutorials/load-average-in-linux). + +![load1](./img/v037_r200c2_load1.png) + +It is contained below 5 on most nodes. + +**This plot yields similar results to the baseline**: + +![load1](../v034/img/v034_r200c2_load1.png) + +### Test Result + +**Result: PASS** + +Date: 2022-10-14 + +Version: 1cf9d8e276afe8595cba960b51cd056514965fd1 + +## Rotating Node Testnet + +We use the same load as in the baseline: `c=4,r=800`. + +Just as in the baseline tests, the version of Tendermint used for these tests is affected by #9539. +See this paragraph in the [baseline report](../v034/README.md#rotating-node-testnet) for further details. +Finally, note that this setup allows for a fairer comparison between this version and the baseline. + +### Latencies + +The plot of all latencies can be seen here. + +![rotating-all-latencies](./img/v037_rotating_latencies.png) + +Which is similar to the baseline. + +![rotating-all-latencies-bl](../v034/img/v034_rotating_latencies_uniq.png) + +Note that we are comparing against the baseline plot with _unique_ +transactions. This is because the problem with duplicate transactions +detected during the baseline experiment did not show up for `v0.37`, +which is _not_ proof that the problem is not present in `v0.37`. + +### Prometheus Metrics + +The set of metrics shown here match those shown on the baseline (`v0.34`) for the same experiment. +We also show the baseline results for comparison. + +#### Blocks and Transactions per minute + +The blocks produced per minute are the gradient of this plot. + +![rotating-heights](./img/v037_rotating_heights.png) + +Over a period of 4446 seconds, the height goes from 5 to 3323. +This results in an average of 45 blocks produced per minute, +which is similar to the baseline, shown below. + +![rotating-heights-bl](../v034/img/v034_rotating_heights.png) + +The following two plots show only the heights reported by ephemeral nodes. +The second plot is the baseline plot for comparison. + +![rotating-heights-ephe](./img/v037_rotating_heights_ephe.png) + +![rotating-heights-ephe-bl](../v034/img/v034_rotating_heights_ephe.png) + +By the length of the segments, we can see that ephemeral nodes in `v0.37` +catch up slightly faster. + +The transactions processed per minute are the gradient of this plot. + +![rotating-total-txs](./img/v037_rotating_total-txs.png) + +Over a period of 3852 seconds, the total goes from 597 to 267298 transactions in one of the validators, +resulting in 4154 transactions per minute, which is slightly lower than the baseline, +although the baseline had to deal with duplicate transactions. + +For comparison, this is the baseline plot. + +![rotating-total-txs-bl](../v034/img/v034_rotating_total-txs.png) + +#### Peers + +The plot below shows the evolution of the number of peers throughout the experiment. + +![rotating-peers](./img/v037_rotating_peers.png) + +This is the baseline plot, for comparison. + +![rotating-peers-bl](../v034/img/v034_rotating_peers.png) + +The plotted values and their evolution are comparable in both plots. + +For further details on these plots, see the baseline report. + +#### Memory Resident Set Size + +The average Resident Set Size (RSS) over all processes looks slightly more stable +on `v0.37` (first plot) than on the baseline (second plot). + +![rotating-rss-avg](./img/v037_rotating_rss_avg.png) + +![rotating-rss-avg-bl](../v034/img/v034_rotating_rss_avg.png) + +The memory taken by the validators and the ephemeral nodes when they are up is comparable (not shown in the plots), +just as observed in the baseline. + +#### CPU utilization + +The plot shows metric `load1` for all nodes. + +![rotating-load1](./img/v037_rotating_load1.png) + +This is the baseline plot. + +![rotating-load1-bl](../v034/img/v034_rotating_load1.png) + +In both cases, it is contained under 5 most of the time, which is considered normal load. +The green line in the `v0.37` plot and the purple line in the baseline plot (`v0.34`) +correspond to the validators receiving all transactions, via RPC, from the load runner process. +In both cases, they oscillate around 5 (normal load). The main difference is that other +nodes are generally less loaded in `v0.37`. + +### Test Result + +**Result: PASS** + +Date: 2022-10-10 + +Version: 155110007b9d8b83997a799016c1d0844c8efbaf + +[\#9533]: https://github.com/tendermint/tendermint/pull/9533 +[\#9534]: https://github.com/tendermint/tendermint/pull/9534 +[\#9539]: https://github.com/tendermint/tendermint/issues/9539 +[\#9548]: https://github.com/tendermint/tendermint/issues/9548 +[\#9537]: https://github.com/tendermint/tendermint/issues/9537 +[\#9581]: https://github.com/tendermint/tendermint/issues/9581 diff --git a/docs/qa/v037/img/v037_200node_latencies.png b/docs/qa/v037/img/v037_200node_latencies.png new file mode 100644 index 000000000..ad469bb29 Binary files /dev/null and b/docs/qa/v037/img/v037_200node_latencies.png differ diff --git a/docs/qa/v037/img/v037_latency_throughput.png b/docs/qa/v037/img/v037_latency_throughput.png new file mode 100644 index 000000000..baf34b2c7 Binary files /dev/null and b/docs/qa/v037/img/v037_latency_throughput.png differ diff --git a/docs/qa/v037/img/v037_r200c2_heights.png b/docs/qa/v037/img/v037_r200c2_heights.png new file mode 100644 index 000000000..360283f14 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_heights.png differ diff --git a/docs/qa/v037/img/v037_r200c2_load1.png b/docs/qa/v037/img/v037_r200c2_load1.png new file mode 100644 index 000000000..11d6dfcf7 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_load1.png differ diff --git a/docs/qa/v037/img/v037_r200c2_mempool_size.png b/docs/qa/v037/img/v037_r200c2_mempool_size.png new file mode 100644 index 000000000..a2f3bd401 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_mempool_size.png differ diff --git a/docs/qa/v037/img/v037_r200c2_mempool_size_avg.png b/docs/qa/v037/img/v037_r200c2_mempool_size_avg.png new file mode 100644 index 000000000..480d4aebc Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_mempool_size_avg.png differ diff --git a/docs/qa/v037/img/v037_r200c2_peers.png b/docs/qa/v037/img/v037_r200c2_peers.png new file mode 100644 index 000000000..222da73f6 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_peers.png differ diff --git a/docs/qa/v037/img/v037_r200c2_rounds.png b/docs/qa/v037/img/v037_r200c2_rounds.png new file mode 100644 index 000000000..7afaaac57 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_rounds.png differ diff --git a/docs/qa/v037/img/v037_r200c2_rss.png b/docs/qa/v037/img/v037_r200c2_rss.png new file mode 100644 index 000000000..730a1bc49 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_rss.png differ diff --git a/docs/qa/v037/img/v037_r200c2_rss_avg.png b/docs/qa/v037/img/v037_r200c2_rss_avg.png new file mode 100644 index 000000000..3f6cf9f6d Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_rss_avg.png differ diff --git a/docs/qa/v037/img/v037_r200c2_total-txs.png b/docs/qa/v037/img/v037_r200c2_total-txs.png new file mode 100644 index 000000000..62dced2c8 Binary files /dev/null and b/docs/qa/v037/img/v037_r200c2_total-txs.png differ diff --git a/docs/qa/v037/img/v037_report_tabbed.txt b/docs/qa/v037/img/v037_report_tabbed.txt new file mode 100644 index 000000000..aa4aa4e60 --- /dev/null +++ b/docs/qa/v037/img/v037_report_tabbed.txt @@ -0,0 +1,52 @@ +Experiment ID: af129eae-7039-4c76-8c37-cff9ac636a84 │Experiment ID: 0f88bd33-9bf0-4197-8d1d-9a737c301ec6 │Experiment ID: 88227cad-2ba8-4eb6-b493-041d8120b46f + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 25 │ Rate: 25 │ Rate: 25 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 2225 │ Total Valid Tx: 4450 │ Total Valid Tx: 8900 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 506.248587ms │ Minimum Latency: 469.53452ms │ Minimum Latency: 588.900721ms + Maximum Latency: 3.032125789s │ Maximum Latency: 6.548830955s │ Maximum Latency: 6.533739843s + Average Latency: 1.427767726s │ Average Latency: 1.448582257s │ Average Latency: 1.717432341s + Standard Deviation: 524.11782ms │ Standard Deviation: 768.684133ms │ Standard Deviation: 1.000015768s + │ │ +Experiment ID: f03d39bd-0233-4b3c-b461-543445ae1d4b │Experiment ID: 46674f1c-e591-4e36-bb9b-f375c19fc475 │Experiment ID: 5385c159-8d4d-455b-bced-dcd4a3209988 + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 50 │ Rate: 50 │ Rate: 50 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 4450 │ Total Valid Tx: 8900 │ Total Valid Tx: 17800 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 477.46027ms │ Minimum Latency: 455.757111ms │ Minimum Latency: 594.749081ms + Maximum Latency: 2.483895394s │ Maximum Latency: 2.904715695s │ Maximum Latency: 9.294950389s + Average Latency: 1.407374662s │ Average Latency: 1.397385779s │ Average Latency: 2.621122536s + Standard Deviation: 505.150067ms │ Standard Deviation: 551.67603ms │ Standard Deviation: 1.772725794s + │ │ +Experiment ID: 9161b4a7-d75c-455f-b82d-2b5235d533cf │Experiment ID: 993a13a8-9db1-4b2b-9c20-71a5b85e4bbf │Experiment ID: ad1eb9e1-f4d6-41fd-9ba7-0f1f7dde1e3e + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 100 │ Rate: 100 │ Rate: 100 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 8900 │ Total Valid Tx: 17800 │ Total Valid Tx: 35400 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 448.050467ms │ Minimum Latency: 605.436195ms │ Minimum Latency: 1.16816912s + Maximum Latency: 3.789711139s │ Maximum Latency: 7.292770222s │ Maximum Latency: 11.378681842s + Average Latency: 1.451342158s │ Average Latency: 2.07457999s │ Average Latency: 3.918384209s + Standard Deviation: 644.075973ms │ Standard Deviation: 1.230204022s │ Standard Deviation: 2.172400458s + │ │ +Experiment ID: 3cbe9c3d-9c43-4c9f-b5ca-b567d20bbd57 │Experiment ID: af836c5e-d9b6-4d5d-971c-2fc7f07aa2a0 │Experiment ID: 77606397-4989-41d4-b13b-f1f4d1af063f + │ │ + Connections: 1 │ Connections: 2 │ Connections: 4 + Rate: 200 │ Rate: 200 │ Rate: 200 + Size: 1024 │ Size: 1024 │ Size: 1024 + │ │ + Total Valid Tx: 17800 │ Total Valid Tx: 35600 │ Total Valid Tx: 37358 + Total Negative Latencies: 0 │ Total Negative Latencies: 0 │ Total Negative Latencies: 0 + Minimum Latency: 519.984701ms │ Minimum Latency: 820.755087ms │ Minimum Latency: 1.712574804s + Maximum Latency: 12.609056712s │ Maximum Latency: 9.260798095s │ Maximum Latency: 25.739223696s + Average Latency: 2.717853101s │ Average Latency: 3.477731881s │ Average Latency: 8.547725264s + Standard Deviation: 2.390778155s │ Standard Deviation: 1.675000913s │ Standard Deviation: 4.76961569s + diff --git a/docs/qa/v037/img/v037_rotating_heights.png b/docs/qa/v037/img/v037_rotating_heights.png new file mode 100644 index 000000000..882de51e4 Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_heights.png differ diff --git a/docs/qa/v037/img/v037_rotating_heights_ephe.png b/docs/qa/v037/img/v037_rotating_heights_ephe.png new file mode 100644 index 000000000..1ab2521e8 Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_heights_ephe.png differ diff --git a/docs/qa/v037/img/v037_rotating_latencies.png b/docs/qa/v037/img/v037_rotating_latencies.png new file mode 100644 index 000000000..94548c8b9 Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_latencies.png differ diff --git a/docs/qa/v037/img/v037_rotating_load1.png b/docs/qa/v037/img/v037_rotating_load1.png new file mode 100644 index 000000000..03b7412da Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_load1.png differ diff --git a/docs/qa/v037/img/v037_rotating_peers.png b/docs/qa/v037/img/v037_rotating_peers.png new file mode 100644 index 000000000..86304760b Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_peers.png differ diff --git a/docs/qa/v037/img/v037_rotating_rss_avg.png b/docs/qa/v037/img/v037_rotating_rss_avg.png new file mode 100644 index 000000000..d45c045b7 Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_rss_avg.png differ diff --git a/docs/qa/v037/img/v037_rotating_total-txs.png b/docs/qa/v037/img/v037_rotating_total-txs.png new file mode 100644 index 000000000..50b4c2e3f Binary files /dev/null and b/docs/qa/v037/img/v037_rotating_total-txs.png differ diff --git a/go.mod b/go.mod index e3022a8b6..3e54e88e1 100644 --- a/go.mod +++ b/go.mod @@ -28,13 +28,13 @@ require ( github.com/rs/cors v1.8.2 github.com/sasha-s/go-deadlock v0.3.1 github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa - github.com/spf13/cobra v1.5.0 + github.com/spf13/cobra v1.6.0 github.com/spf13/viper v1.13.0 github.com/stretchr/testify v1.8.0 github.com/tendermint/tm-db v0.6.6 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/net v0.0.0-20220812174116-3211cb980234 - google.golang.org/grpc v1.50.0 + google.golang.org/grpc v1.50.1 ) require ( diff --git a/go.sum b/go.sum index 0a7b98bea..25128492b 100644 --- a/go.sum +++ b/go.sum @@ -1042,8 +1042,8 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL 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.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= @@ -1696,8 +1696,8 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ 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.50.0 h1:fPVVDxY9w++VjTZsYvXWqEf9Rqar/e+9zYfxKK+W+YU= -google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/proto/tendermint/blocksync/types.pb.go b/proto/tendermint/blocksync/types.pb.go index 17d76a278..fcbef7107 100644 --- a/proto/tendermint/blocksync/types.pb.go +++ b/proto/tendermint/blocksync/types.pb.go @@ -5,7 +5,7 @@ package blocksync import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" math "math" diff --git a/proto/tendermint/consensus/types.pb.go b/proto/tendermint/consensus/types.pb.go index 83eb0d216..053860743 100644 --- a/proto/tendermint/consensus/types.pb.go +++ b/proto/tendermint/consensus/types.pb.go @@ -6,7 +6,7 @@ package consensus import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" bits "github.com/tendermint/tendermint/proto/tendermint/libs/bits" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" diff --git a/proto/tendermint/consensus/wal.pb.go b/proto/tendermint/consensus/wal.pb.go index 3a4494941..5a097ea32 100644 --- a/proto/tendermint/consensus/wal.pb.go +++ b/proto/tendermint/consensus/wal.pb.go @@ -6,9 +6,9 @@ package consensus import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" _ "github.com/golang/protobuf/ptypes/duration" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" @@ -484,7 +484,7 @@ func (m *TimeoutInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x10 } - n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration):]) + n2, err2 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration):]) if err2 != nil { return 0, err2 } @@ -671,7 +671,7 @@ func (m *TimedWALMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - n8, err8 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n8, err8 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err8 != nil { return 0, err8 } @@ -714,7 +714,7 @@ func (m *TimeoutInfo) Size() (n int) { } var l int _ = l - l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration) + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.Duration) n += 1 + l + sovWal(uint64(l)) if m.Height != 0 { n += 1 + sovWal(uint64(m.Height)) @@ -806,7 +806,7 @@ func (m *TimedWALMessage) Size() (n int) { } var l int _ = l - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovWal(uint64(l)) if m.Msg != nil { l = m.Msg.Size() @@ -994,7 +994,7 @@ func (m *TimeoutInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1393,7 +1393,7 @@ func (m *TimedWALMessage) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/crypto/keys.pb.go b/proto/tendermint/crypto/keys.pb.go index bbd97d446..970233712 100644 --- a/proto/tendermint/crypto/keys.pb.go +++ b/proto/tendermint/crypto/keys.pb.go @@ -7,7 +7,7 @@ import ( bytes "bytes" fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/crypto/proof.pb.go b/proto/tendermint/crypto/proof.pb.go index 7a8315dc7..51e5d0445 100644 --- a/proto/tendermint/crypto/proof.pb.go +++ b/proto/tendermint/crypto/proof.pb.go @@ -6,7 +6,7 @@ package crypto import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/libs/bits/types.pb.go b/proto/tendermint/libs/bits/types.pb.go index ccaee7053..c0ebcb976 100644 --- a/proto/tendermint/libs/bits/types.pb.go +++ b/proto/tendermint/libs/bits/types.pb.go @@ -5,7 +5,7 @@ package bits import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/mempool/types.pb.go b/proto/tendermint/mempool/types.pb.go index f7d16a64c..11e259551 100644 --- a/proto/tendermint/mempool/types.pb.go +++ b/proto/tendermint/mempool/types.pb.go @@ -5,7 +5,7 @@ package mempool import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/p2p/conn.pb.go b/proto/tendermint/p2p/conn.pb.go index dccdbe4a0..1d6c0a6ef 100644 --- a/proto/tendermint/p2p/conn.pb.go +++ b/proto/tendermint/p2p/conn.pb.go @@ -6,7 +6,7 @@ package p2p import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" io "io" math "math" diff --git a/proto/tendermint/p2p/pex.pb.go b/proto/tendermint/p2p/pex.pb.go index 19ff524d9..34f260d51 100644 --- a/proto/tendermint/p2p/pex.pb.go +++ b/proto/tendermint/p2p/pex.pb.go @@ -6,7 +6,7 @@ package p2p import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/p2p/types.pb.go b/proto/tendermint/p2p/types.pb.go index 3f2ff71da..1e8b128be 100644 --- a/proto/tendermint/p2p/types.pb.go +++ b/proto/tendermint/p2p/types.pb.go @@ -6,7 +6,7 @@ package p2p import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/privval/types.pb.go b/proto/tendermint/privval/types.pb.go index de598e318..07f153512 100644 --- a/proto/tendermint/privval/types.pb.go +++ b/proto/tendermint/privval/types.pb.go @@ -6,7 +6,7 @@ package privval import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" types "github.com/tendermint/tendermint/proto/tendermint/types" io "io" diff --git a/proto/tendermint/rpc/grpc/types.pb.go b/proto/tendermint/rpc/grpc/types.pb.go index 6d0fecf0b..b9cbee03f 100644 --- a/proto/tendermint/rpc/grpc/types.pb.go +++ b/proto/tendermint/rpc/grpc/types.pb.go @@ -6,8 +6,7 @@ package coregrpc import ( context "context" fmt "fmt" - grpc1 "github.com/cosmos/gogoproto/grpc" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" types "github.com/tendermint/tendermint/abci/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -246,10 +245,10 @@ type BroadcastAPIClient interface { } type broadcastAPIClient struct { - cc grpc1.ClientConn + cc *grpc.ClientConn } -func NewBroadcastAPIClient(cc grpc1.ClientConn) BroadcastAPIClient { +func NewBroadcastAPIClient(cc *grpc.ClientConn) BroadcastAPIClient { return &broadcastAPIClient{cc} } @@ -288,7 +287,7 @@ func (*UnimplementedBroadcastAPIServer) BroadcastTx(ctx context.Context, req *Re return nil, status.Errorf(codes.Unimplemented, "method BroadcastTx not implemented") } -func RegisterBroadcastAPIServer(s grpc1.Server, srv BroadcastAPIServer) { +func RegisterBroadcastAPIServer(s *grpc.Server, srv BroadcastAPIServer) { s.RegisterService(&_BroadcastAPI_serviceDesc, srv) } diff --git a/proto/tendermint/state/types.pb.go b/proto/tendermint/state/types.pb.go index d5620344b..463e58478 100644 --- a/proto/tendermint/state/types.pb.go +++ b/proto/tendermint/state/types.pb.go @@ -6,9 +6,9 @@ package state import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" types "github.com/tendermint/tendermint/abci/types" types1 "github.com/tendermint/tendermint/proto/tendermint/types" version "github.com/tendermint/tendermint/proto/tendermint/version" @@ -843,7 +843,7 @@ func (m *State) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n11, err11 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.LastBlockTime):]) + n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.LastBlockTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime):]) if err11 != nil { return 0, err11 } @@ -998,7 +998,7 @@ func (m *State) Size() (n int) { } l = m.LastBlockID.Size() n += 1 + l + sovTypes(uint64(l)) - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.LastBlockTime) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.LastBlockTime) n += 1 + l + sovTypes(uint64(l)) if m.NextValidators != nil { l = m.NextValidators.Size() @@ -1798,7 +1798,7 @@ func (m *State) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.LastBlockTime, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.LastBlockTime, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/statesync/types.pb.go b/proto/tendermint/statesync/types.pb.go index 147e0f7d4..8391e0ead 100644 --- a/proto/tendermint/statesync/types.pb.go +++ b/proto/tendermint/statesync/types.pb.go @@ -5,7 +5,7 @@ package statesync import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/store/types.pb.go b/proto/tendermint/store/types.pb.go index 85c7dec6c..384fbe52a 100644 --- a/proto/tendermint/store/types.pb.go +++ b/proto/tendermint/store/types.pb.go @@ -5,7 +5,7 @@ package store import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/types/block.pb.go b/proto/tendermint/types/block.pb.go index 59c17fe40..b11d9a9e9 100644 --- a/proto/tendermint/types/block.pb.go +++ b/proto/tendermint/types/block.pb.go @@ -6,7 +6,7 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/types/canonical.pb.go b/proto/tendermint/types/canonical.pb.go index 5d3d4ce3a..5e9be8438 100644 --- a/proto/tendermint/types/canonical.pb.go +++ b/proto/tendermint/types/canonical.pb.go @@ -7,9 +7,9 @@ import ( encoding_binary "encoding/binary" fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" io "io" math "math" math_bits "math/bits" @@ -454,7 +454,7 @@ func (m *CanonicalProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n2, err2 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n2, err2 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err2 != nil { return 0, err2 } @@ -526,7 +526,7 @@ func (m *CanonicalVote) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err4 != nil { return 0, err4 } @@ -630,7 +630,7 @@ func (m *CanonicalProposal) Size() (n int) { l = m.BlockID.Size() n += 1 + l + sovCanonical(uint64(l)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovCanonical(uint64(l)) l = len(m.ChainID) if l > 0 { @@ -658,7 +658,7 @@ func (m *CanonicalVote) Size() (n int) { l = m.BlockID.Size() n += 1 + l + sovCanonical(uint64(l)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovCanonical(uint64(l)) l = len(m.ChainID) if l > 0 { @@ -1045,7 +1045,7 @@ func (m *CanonicalProposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1235,7 +1235,7 @@ func (m *CanonicalVote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/types/events.pb.go b/proto/tendermint/types/events.pb.go index 127efe976..a9aa26a79 100644 --- a/proto/tendermint/types/events.pb.go +++ b/proto/tendermint/types/events.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/proto/tendermint/types/evidence.pb.go b/proto/tendermint/types/evidence.pb.go index 37899ac8b..56bac3179 100644 --- a/proto/tendermint/types/evidence.pb.go +++ b/proto/tendermint/types/evidence.pb.go @@ -6,9 +6,9 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" io "io" math "math" math_bits "math/bits" @@ -451,7 +451,7 @@ func (m *DuplicateVoteEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n3, err3 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err3 != nil { return 0, err3 } @@ -516,7 +516,7 @@ func (m *LightClientAttackEvidence) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - n6, err6 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err6 != nil { return 0, err6 } @@ -667,7 +667,7 @@ func (m *DuplicateVoteEvidence) Size() (n int) { if m.ValidatorPower != 0 { n += 1 + sovEvidence(uint64(m.ValidatorPower)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovEvidence(uint64(l)) return n } @@ -694,7 +694,7 @@ func (m *LightClientAttackEvidence) Size() (n int) { if m.TotalVotingPower != 0 { n += 1 + sovEvidence(uint64(m.TotalVotingPower)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovEvidence(uint64(l)) return n } @@ -1008,7 +1008,7 @@ func (m *DuplicateVoteEvidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1199,7 +1199,7 @@ func (m *LightClientAttackEvidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/types/params.pb.go b/proto/tendermint/types/params.pb.go index 3d57b852c..763090dcf 100644 --- a/proto/tendermint/types/params.pb.go +++ b/proto/tendermint/types/params.pb.go @@ -6,8 +6,8 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" _ "github.com/golang/protobuf/ptypes/duration" io "io" math "math" @@ -720,7 +720,7 @@ func (m *EvidenceParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - n5, err5 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.MaxAgeDuration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxAgeDuration):]) + n5, err5 := github_com_gogo_protobuf_types.StdDurationMarshalTo(m.MaxAgeDuration, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAgeDuration):]) if err5 != nil { return 0, err5 } @@ -981,7 +981,7 @@ func (m *EvidenceParams) Size() (n int) { if m.MaxAgeNumBlocks != 0 { n += 1 + sovParams(uint64(m.MaxAgeNumBlocks)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.MaxAgeDuration) + l = github_com_gogo_protobuf_types.SizeOfStdDuration(m.MaxAgeDuration) n += 1 + l + sovParams(uint64(l)) if m.MaxBytes != 0 { n += 1 + sovParams(uint64(m.MaxBytes)) @@ -1396,7 +1396,7 @@ func (m *EvidenceParams) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.MaxAgeDuration, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdDurationUnmarshal(&m.MaxAgeDuration, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/types/types.pb.go b/proto/tendermint/types/types.pb.go index 11edb847f..41ed68e92 100644 --- a/proto/tendermint/types/types.pb.go +++ b/proto/tendermint/types/types.pb.go @@ -6,9 +6,9 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" _ "github.com/cosmos/gogoproto/types" - github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" version "github.com/tendermint/tendermint/proto/tendermint/version" io "io" @@ -29,7 +29,7 @@ var _ = time.Kitchen // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// BlockIdFlag indicates which BlcokID the signature is for +// BlockIdFlag indicates which BlockID the signature is for type BlockIDFlag int32 const ( @@ -1348,7 +1348,7 @@ func (m *Header) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x2a - n4, err4 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time):]) + n4, err4 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Time):]) if err4 != nil { return 0, err4 } @@ -1452,7 +1452,7 @@ func (m *Vote) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - n6, err6 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n6, err6 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err6 != nil { return 0, err6 } @@ -1572,7 +1572,7 @@ func (m *CommitSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - n9, err9 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err9 != nil { return 0, err9 } @@ -1622,7 +1622,7 @@ func (m *Proposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x3a } - n10, err10 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp):]) + n10, err10 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):]) if err10 != nil { return 0, err10 } @@ -1934,7 +1934,7 @@ func (m *Header) Size() (n int) { if m.Height != 0 { n += 1 + sovTypes(uint64(m.Height)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Time) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Time) n += 1 + l + sovTypes(uint64(l)) l = m.LastBlockId.Size() n += 1 + l + sovTypes(uint64(l)) @@ -2009,7 +2009,7 @@ func (m *Vote) Size() (n int) { } l = m.BlockID.Size() n += 1 + l + sovTypes(uint64(l)) - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovTypes(uint64(l)) l = len(m.ValidatorAddress) if l > 0 { @@ -2061,7 +2061,7 @@ func (m *CommitSig) Size() (n int) { if l > 0 { n += 1 + l + sovTypes(uint64(l)) } - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovTypes(uint64(l)) l = len(m.Signature) if l > 0 { @@ -2090,7 +2090,7 @@ func (m *Proposal) Size() (n int) { } l = m.BlockID.Size() n += 1 + l + sovTypes(uint64(l)) - l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.Timestamp) + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp) n += 1 + l + sovTypes(uint64(l)) l = len(m.Signature) if l > 0 { @@ -2677,7 +2677,7 @@ func (m *Header) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Time, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3271,7 +3271,7 @@ func (m *Vote) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3649,7 +3649,7 @@ func (m *CommitSig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -3875,7 +3875,7 @@ func (m *Proposal) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.Timestamp, dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/proto/tendermint/types/types.proto b/proto/tendermint/types/types.proto index 8d4f00972..bf3bc1600 100644 --- a/proto/tendermint/types/types.proto +++ b/proto/tendermint/types/types.proto @@ -9,15 +9,15 @@ import "tendermint/crypto/proof.proto"; import "tendermint/version/types.proto"; import "tendermint/types/validator.proto"; -// BlockIdFlag indicates which BlcokID the signature is for +// BlockIdFlag indicates which BlockID the signature is for enum BlockIDFlag { option (gogoproto.goproto_enum_stringer) = true; option (gogoproto.goproto_enum_prefix) = false; - BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; - BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; - BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; - BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; + BLOCK_ID_FLAG_UNKNOWN = 0 [(gogoproto.enumvalue_customname) = "BlockIDFlagUnknown"]; // indicates an error condition + BLOCK_ID_FLAG_ABSENT = 1 [(gogoproto.enumvalue_customname) = "BlockIDFlagAbsent"]; // the vote was not received + BLOCK_ID_FLAG_COMMIT = 2 [(gogoproto.enumvalue_customname) = "BlockIDFlagCommit"]; // voted for the block that received the majority + BLOCK_ID_FLAG_NIL = 3 [(gogoproto.enumvalue_customname) = "BlockIDFlagNil"]; // voted for nil } // SignedMsgType is a type of signed message in the consensus. diff --git a/proto/tendermint/types/validator.pb.go b/proto/tendermint/types/validator.pb.go index c3d39b73c..37679b997 100644 --- a/proto/tendermint/types/validator.pb.go +++ b/proto/tendermint/types/validator.pb.go @@ -6,7 +6,7 @@ package types import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" crypto "github.com/tendermint/tendermint/proto/tendermint/crypto" io "io" math "math" diff --git a/proto/tendermint/version/types.pb.go b/proto/tendermint/version/types.pb.go index 81aa55fdd..ef7633c86 100644 --- a/proto/tendermint/version/types.pb.go +++ b/proto/tendermint/version/types.pb.go @@ -6,7 +6,7 @@ package version import ( fmt "fmt" _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" diff --git a/rpc/grpc/types.pb.go b/rpc/grpc/types.pb.go index 6d0fecf0b..b9cbee03f 100644 --- a/rpc/grpc/types.pb.go +++ b/rpc/grpc/types.pb.go @@ -6,8 +6,7 @@ package coregrpc import ( context "context" fmt "fmt" - grpc1 "github.com/cosmos/gogoproto/grpc" - proto "github.com/cosmos/gogoproto/proto" + proto "github.com/gogo/protobuf/proto" types "github.com/tendermint/tendermint/abci/types" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" @@ -246,10 +245,10 @@ type BroadcastAPIClient interface { } type broadcastAPIClient struct { - cc grpc1.ClientConn + cc *grpc.ClientConn } -func NewBroadcastAPIClient(cc grpc1.ClientConn) BroadcastAPIClient { +func NewBroadcastAPIClient(cc *grpc.ClientConn) BroadcastAPIClient { return &broadcastAPIClient{cc} } @@ -288,7 +287,7 @@ func (*UnimplementedBroadcastAPIServer) BroadcastTx(ctx context.Context, req *Re return nil, status.Errorf(codes.Unimplemented, "method BroadcastTx not implemented") } -func RegisterBroadcastAPIServer(s grpc1.Server, srv BroadcastAPIServer) { +func RegisterBroadcastAPIServer(s *grpc.Server, srv BroadcastAPIServer) { s.RegisterService(&_BroadcastAPI_serviceDesc, srv) } diff --git a/scripts/qa/reporting/README.md b/scripts/qa/reporting/README.md new file mode 100644 index 000000000..088332837 --- /dev/null +++ b/scripts/qa/reporting/README.md @@ -0,0 +1,48 @@ +# Reporting Scripts + +This directory contains just one utility script at present that is used in +reporting/QA. + +## Latency vs Throughput Plotting + +[`latency_throughput.py`](./latency_throughput.py) is a Python script that uses +[matplotlib] to plot a graph of transaction latency vs throughput rate based on +the CSV output generated by the [loadtime reporting +tool](../../../test/loadtime/cmd/report/). + +### Setup + +Execute the following within this directory (the same directory as the +`latency_throughput.py` file). + +```bash +# Create a virtual environment into which to install your dependencies +python3 -m venv .venv + +# Activate the virtual environment +source .venv/bin/activate + +# Install dependencies listed in requirements.txt +pip install -r requirements.txt + +# Show usage instructions and parameters +./latency_throughput.py --help +``` + +### Running + +```bash +# Do the following while ensuring that the virtual environment is activated (see +# the Setup steps). +# +# This will generate a plot in a PNG file called 'tm034.png' in the current +# directory based on the reporting tool CSV output in the "raw.csv" file. The +# '-t' flag overrides the default title at the top of the plot. + +./latency_throughput.py \ + -t 'Tendermint v0.34.x Latency vs Throughput' \ + ./tm034.png \ + /path/to/csv/files/raw.csv +``` + +[matplotlib]: https://matplotlib.org/ diff --git a/scripts/qa/reporting/latency_throughput.py b/scripts/qa/reporting/latency_throughput.py new file mode 100755 index 000000000..2cdab72ac --- /dev/null +++ b/scripts/qa/reporting/latency_throughput.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +""" +A simple script to parse the CSV output from the loadtime reporting tool (see +https://github.com/tendermint/tendermint/tree/main/test/loadtime/cmd/report). + +Produces a plot of average transaction latency vs total transaction throughput +according to the number of load testing tool WebSocket connections to the +Tendermint node. +""" + +import argparse +import csv +import logging +import sys +import matplotlib.pyplot as plt +import numpy as np + +DEFAULT_TITLE = "Tendermint latency vs throughput" + + +def main(): + parser = argparse.ArgumentParser( + description="Renders a latency vs throughput diagram " + "for a set of transactions provided by the loadtime reporting tool", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('-t', + '--title', + default=DEFAULT_TITLE, + help='Plot title') + parser.add_argument('output_image', + help='Output image file (in PNG format)') + parser.add_argument( + 'input_csv_file', + nargs='+', + help="CSV input file from which to read transaction data " + "- must have been generated by the loadtime reporting tool") + args = parser.parse_args() + + logging.basicConfig(format='%(levelname)s\t%(message)s', + stream=sys.stdout, + level=logging.INFO) + plot_latency_vs_throughput(args.input_csv_file, + args.output_image, + title=args.title) + + +def plot_latency_vs_throughput(input_files, output_image, title=DEFAULT_TITLE): + avg_latencies, throughput_rates = process_input_files(input_files, ) + + fig, ax = plt.subplots() + + connections = sorted(avg_latencies.keys()) + for c in connections: + tr = np.array(throughput_rates[c]) + al = np.array(avg_latencies[c]) + label = '%d connection%s' % (c, '' if c == 1 else 's') + ax.plot(tr, al, 'o-', label=label) + + ax.set_title(title) + ax.set_xlabel('Throughput rate (tx/s)') + ax.set_ylabel('Average transaction latency (s)') + + plt.legend(loc='upper left') + plt.savefig(output_image) + + +def process_input_files(input_files): + # Experimental data from which we will derive the latency vs throughput + # statistics + experiments = {} + + for input_file in input_files: + logging.info('Reading %s...' % input_file) + + with open(input_file, 'rt') as inf: + reader = csv.DictReader(inf) + for tx in reader: + experiments = process_tx(experiments, tx) + + return compute_experiments_stats(experiments) + + +def process_tx(experiments, tx): + exp_id = tx['experiment_id'] + # Block time is nanoseconds from the epoch - convert to seconds + block_time = float(tx['block_time']) / (10**9) + # Duration is also in nanoseconds - convert to seconds + duration = float(tx['duration_ns']) / (10**9) + connections = int(tx['connections']) + rate = int(tx['rate']) + + if exp_id not in experiments: + experiments[exp_id] = { + 'connections': connections, + 'rate': rate, + 'block_time_min': block_time, + # We keep track of the latency associated with the minimum block + # time to estimate the start time of the experiment + 'block_time_min_duration': duration, + 'block_time_max': block_time, + 'total_latencies': duration, + 'tx_count': 1, + } + logging.info('Found experiment %s with rate=%d, connections=%d' % + (exp_id, rate, connections)) + else: + # Validation + for field in ['connections', 'rate']: + val = int(tx[field]) + if val != experiments[exp_id][field]: + raise Exception( + 'Found multiple distinct values for field ' + '"%s" for the same experiment (%s): %d and %d' % + (field, exp_id, val, experiments[exp_id][field])) + + if block_time < experiments[exp_id]['block_time_min']: + experiments[exp_id]['block_time_min'] = block_time + experiments[exp_id]['block_time_min_duration'] = duration + if block_time > experiments[exp_id]['block_time_max']: + experiments[exp_id]['block_time_max'] = block_time + + experiments[exp_id]['total_latencies'] += duration + experiments[exp_id]['tx_count'] += 1 + + return experiments + + +def compute_experiments_stats(experiments): + """Compute average latency vs throughput rate statistics from the given + experiments""" + stats = {} + + # Compute average latency and throughput rate for each experiment + for exp_id, exp in experiments.items(): + conns = exp['connections'] + avg_latency = exp['total_latencies'] / exp['tx_count'] + exp_start_time = exp['block_time_min'] - exp['block_time_min_duration'] + exp_duration = exp['block_time_max'] - exp_start_time + throughput_rate = exp['tx_count'] / exp_duration + if conns not in stats: + stats[conns] = [] + + stats[conns].append({ + 'avg_latency': avg_latency, + 'throughput_rate': throughput_rate, + }) + + # Sort stats for each number of connections in order of increasing + # throughput rate, and then extract average latencies and throughput rates + # as separate data series. + conns = sorted(stats.keys()) + avg_latencies = {} + throughput_rates = {} + for c in conns: + stats[c] = sorted(stats[c], key=lambda s: s['throughput_rate']) + avg_latencies[c] = [] + throughput_rates[c] = [] + for s in stats[c]: + avg_latencies[c].append(s['avg_latency']) + throughput_rates[c].append(s['throughput_rate']) + logging.info('For %d connection(s): ' + 'throughput rate = %.6f tx/s\t' + 'average latency = %.6fs' % + (c, s['throughput_rate'], s['avg_latency'])) + + return (avg_latencies, throughput_rates) + + +if __name__ == "__main__": + main() diff --git a/scripts/qa/reporting/requirements.txt b/scripts/qa/reporting/requirements.txt new file mode 100644 index 000000000..4486cd522 --- /dev/null +++ b/scripts/qa/reporting/requirements.txt @@ -0,0 +1,11 @@ +contourpy==1.0.5 +cycler==0.11.0 +fonttools==4.37.4 +kiwisolver==1.4.4 +matplotlib==3.6.1 +numpy==1.23.4 +packaging==21.3 +Pillow==9.2.0 +pyparsing==3.0.9 +python-dateutil==2.8.2 +six==1.16.0 diff --git a/spec/core/data_structures.md b/spec/core/data_structures.md index 1e8ad8b25..b336462f7 100644 --- a/spec/core/data_structures.md +++ b/spec/core/data_structures.md @@ -46,7 +46,7 @@ and a list of evidence of malfeasance (ie. signing conflicting votes). | Name | Type | Description | Validation | |--------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------| -| Header | [Header](#header) | Header corresponding to the block. This field contains information used throughout consensus and other areas of the protocol. To find out what it contains, visit [header] (#header) | Must adhere to the validation rules of [header](#header) | +| Header | [Header](#header) | Header corresponding to the block. This field contains information used throughout consensus and other areas of the protocol. To find out what it contains, visit [header](#header) | Must adhere to the validation rules of [header](#header) | | Data | [Data](#data) | Data contains a list of transactions. The contents of the transaction is unknown to Tendermint. | This field can be empty or populated, but no validation is performed. Applications can perform validation on individual transactions prior to block creation using [checkTx](https://github.com/tendermint/tendermint/blob/main/spec/abci/abci++_methods.md#checktx). | Evidence | [EvidenceList](#evidencelist) | Evidence contains a list of infractions committed by validators. | Can be empty, but when populated the validations rules from [evidenceList](#evidencelist) apply | | LastCommit | [Commit](#commit) | `LastCommit` includes one vote for every validator. All votes must either be for the previous block, nil or absent. If a vote is for the previous block it must have a valid signature from the corresponding validator. The sum of the voting power of the validators that voted must be greater than 2/3 of the total voting power of the complete validator set. The number of votes in a commit is limited to 10000 (see `types.MaxVotesCount`). | Must be empty for the initial height and must adhere to the validation rules of [commit](#commit). | @@ -202,12 +202,12 @@ Commit is a simple wrapper for a list of signatures, with one for each validator a particular `BlockID` or was absent. It's a part of the `Commit` and can be used to reconstruct the vote set given the validator set. -| Name | Type | Description | Validation | -|------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| -| BlockIDFlag | [BlockIDFlag](#blockidflag) | Represents the validators participation in consensus: Either voted for the block that received the majority, voted for another block, voted nil or did not vote | Must be one of the fields in the [BlockIDFlag](#blockidflag) enum | -| ValidatorAddress | [Address](#address) | Address of the validator | Must be of length 20 | -| Timestamp | [Time](#time) | This field will vary from `CommitSig` to `CommitSig`. It represents the timestamp of the validator. | [Time](#time) | -| Signature | [Signature](#signature) | Signature corresponding to the validators participation in consensus. | The length of the signature must be > 0 and < than 64 | +| Name | Type | Description | Validation | +|------------------|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| +| BlockIDFlag | [BlockIDFlag](#blockidflag) | Represents the validators participation in consensus: its vote was not received, voted for the block that received the majority, or voted for nil | Must be one of the fields in the [BlockIDFlag](#blockidflag) enum | +| ValidatorAddress | [Address](#address) | Address of the validator | Must be of length 20 | +| Timestamp | [Time](#time) | This field will vary from `CommitSig` to `CommitSig`. It represents the timestamp of the validator. | [Time](#time) | +| Signature | [Signature](#signature) | Signature corresponding to the validators participation in consensus. | The length of the signature must be > 0 and < than 64 | NOTE: `ValidatorAddress` and `Timestamp` fields may be removed in the future (see [ADR-25](https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-025-commit.md)). @@ -218,10 +218,10 @@ BlockIDFlag represents which BlockID the [signature](#commitsig) is for. ```go enum BlockIDFlag { - BLOCK_ID_FLAG_UNKNOWN = 0; - BLOCK_ID_FLAG_ABSENT = 1; // signatures for other blocks are also considered absent - BLOCK_ID_FLAG_COMMIT = 2; - BLOCK_ID_FLAG_NIL = 3; + BLOCK_ID_FLAG_UNKNOWN = 0; // indicates an error condition + BLOCK_ID_FLAG_ABSENT = 1; // the vote was not received + BLOCK_ID_FLAG_COMMIT = 2; // voted for the block that received the majority + BLOCK_ID_FLAG_NIL = 3; // voted for nil } ```