404
Looks like we've got some broken links.Take me home.
diff --git a/.circleci/config.yml b/.circleci/config.yml index babba409d..72e5dfa43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,7 @@ executors: machine: true docs: docker: - - image: tendermintdev/jq_curl + - image: tendermintdev/docker-website-deployment environment: AWS_REGION: us-east-1 @@ -80,7 +80,7 @@ jobs: script_path: abci/tests/test_app/test.sh # if this test fails, fix it and update the docs at: - # https://github.com/tendermint/tendermint/blob/develop/docs/abci-cli.md + # https://github.com/tendermint/tendermint/blob/master/docs/abci-cli.md test_abci_cli: executor: golang steps: @@ -191,30 +191,13 @@ jobs: deploy_docs: executor: docs steps: - - restore_cache: - name: "Restore source code cache" - keys: - - go-src-v1-{{ .Revision }} - checkout - run: - name: Trigger website build - command: | - curl --silent \ - --show-error \ - -X POST \ - --header "Content-Type: application/json" \ - -d "{\"branch\": \"$CIRCLE_BRANCH\"}" \ - "https://circleci.com/api/v1.1/project/github/$CIRCLE_PROJECT_USERNAME/$WEBSITE_REPO_NAME/build?circle-token=$TENDERBOT_API_TOKEN" > response.json - - RESULT=`jq -r '.status' response.json` - MESSAGE=`jq -r '.message' response.json` - - if [[ ${RESULT} == "null" ]] || [[ ${RESULT} -ne "200" ]]; then - echo "CircleCI API call failed: $MESSAGE" - exit 1 - else - echo "Website build started" - fi + name: "Build docs" + command: make build-docs + - run: + name: "Sync to S3" + command: make sync-docs prepare_build: executor: golang @@ -314,10 +297,6 @@ jobs: machine: image: ubuntu-1604:201903-01 steps: - - restore_cache: - name: "Restore source code cache" - keys: - - go-src-v1-{{ .Revision }} - checkout - attach_workspace: at: /tmp/workspace @@ -337,10 +316,6 @@ jobs: steps: - attach_workspace: at: /tmp/workspace - - restore_cache: - name: "Restore source code cache" - keys: - - go-src-v1-{{ .Revision }} - checkout - setup_remote_docker: docker_layer_caching: true @@ -398,10 +373,20 @@ workflows: test-suite: jobs: - deploy_docs: + context: tendermint-docs filters: branches: only: - master + tags: + only: + - /^v.*/ + - deploy_docs: + context: tendermint-docs-staging + filters: + branches: + only: + - docs-theme-latest - setup_dependencies - test_abci_apps: requires: @@ -457,3 +442,4 @@ workflows: branches: only: - /v[0-9]+\.[0-9]+/ + - master diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index df77531cc..2b513b158 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,7 @@ # CODEOWNERS: https://help.github.com/articles/about-codeowners/ -# Everything goes through Bucky, Anton, Alex. For now. -* @ebuchman @melekes @xla +# Everything goes through Bucky, Anton, Tess. For now. +* @ebuchman @melekes @tessr # Precious documentation /docs/README.md @zramsay diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..63c6e0f1f --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,47 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 60 + +# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 9 + +# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) +onlyLabels: [] + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - major-release + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: true + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: true + +# Set to true to ignore issues with an assignee (defaults to false) +exemptAssignees: false + +# Label to use when marking as stale +staleLabel: stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +Limit to only `issues` or `pulls` +only: pulls + +Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': +pulls: + daysUntilStale: 30 + markComment: > + This pull request has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9e2e5a9ea..dfca4da95 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ test/logs coverage.txt docs/_build docs/dist +docs/.vuepress/dist *.log abci-cli docs/node_modules/ diff --git a/.golangci.yml b/.golangci.yml index 0991cdf1e..4da1cbadb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,20 +1,58 @@ -run: - deadline: 1m - linters: - enable-all: true - disable: - - gocyclo - - golint - - maligned - - errcheck + enable: + - bodyclose + - deadcode + - depguard + - dogsled + - dupl + # - errcheck + # - funlen + # - gochecknoglobals + # - gochecknoinits + - goconst + - gocritic + # - gocyclo + # - godox + - gofmt + - goimports + # - golint + - gosec + - gosimple + - govet + - ineffassign - interfacer - - unparam - lll - - gochecknoglobals - - gochecknoinits - - stylecheck -# linters-settings: + - misspell + - maligned + - nakedret + - prealloc + - scopelint + - staticcheck + - structcheck + # - stylecheck + - typecheck + - unconvert + # - unparam + - unused + - varcheck + # - whitespace + # - wsl + # - gocognit + disable: + - errcheck + +issues: + exclude-rules: + - linters: + - lll + source: "https://" + +linters-settings: + dogsled: + max-blank-identifiers: 3 + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true # govet: # check-shadowing: true # golint: @@ -45,4 +83,3 @@ linters: # disabled-checks: # - wrapperFunc # - commentFormatting # https://github.com/go-critic/go-critic/issues/755 - diff --git a/CHANGELOG.md b/CHANGELOG.md index dbb60a3a1..a450fe121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,38 @@ # Changelog +## v0.32.8 + +Special thanks to external contributors on this release: @erikgrinaker, @guagualvcha, @hsyis, @cosmostuba, @whunmr, @austinabell + +Friendly reminder, we have a bug bounty program. + +### BREAKING CHANGES: + +- Go API + + - [libs/pubsub] [\#4070](https://github.com/tendermint/tendermint/pull/4070) `Query#(Matches|Conditions)` returns an error. + +### IMPROVEMENTS: + +- [mempool] [\#4083](https://github.com/tendermint/tendermint/pull/4083) Added TxInfo parameter to CheckTx(), and removed CheckTxWithInfo() (@erikgrinaker) +- [mempool] [\#4057](https://github.com/tendermint/tendermint/issues/4057) Include peer ID when logging rejected txns (@erikgrinaker) +- [tools] [\#4023](https://github.com/tendermint/tendermint/issues/4023) Improved `tm-monitor` formatting of start time and avg tx throughput (@erikgrinaker) +- [p2p] [\#3991](https://github.com/tendermint/tendermint/issues/3991) Log "has been established or dialed" as debug log instead of Error for connected peers (@whunmr) +- [rpc] [\#4077](https://github.com/tendermint/tendermint/pull/4077) Added support for `EXISTS` clause to the Websocket query interface. +- [privval] Add SignerDialerEndpointRetryWaitInterval option (@cosmostuba) +- [crypto] Add `RegisterKeyType` to amino to allow external key types registration (@austinabell) + +### BUG FIXES: + +- [libs/pubsub] [\#4070](https://github.com/tendermint/tendermint/pull/4070) Strip out non-numeric characters when attempting to match numeric values. +- [libs/pubsub] [\#4070](https://github.com/tendermint/tendermint/pull/4070) No longer panic in Query#(Matches|Conditions) preferring to return an error instead. +- [tools] [\#4023](https://github.com/tendermint/tendermint/issues/4023) Refresh `tm-monitor` health when validator count is updated (@erikgrinaker) +- [state] [\#4104](https://github.com/tendermint/tendermint/pull/4104) txindex/kv: Fsync data to disk immediately after receiving it (@guagualvcha) +- [state] [\#4095](https://github.com/tendermint/tendermint/pull/4095) txindex/kv: Return an error if there's one when the user searches for a tx (hash=X) (@hsyis) + ## v0.32.7 -*October 18, 2019* +_October 18, 2019_ This security release fixes a vulnerability found in the `consensus` package, where an attacker could construct a `BlockPartMessage` message in such a way @@ -29,7 +59,11 @@ program](https://hackerone.com/tendermint). ## v0.32.6 +<<<<<<< HEAD +_October 8, 2019_ +======= *October 8, 2019* +>>>>>>> origin/v0.32 The previous patch was insufficient because the attacker could still find a way to submit a `nil` pubkey by constructing a `PubKeyMultisigThreshold` pubkey @@ -52,7 +86,11 @@ program](https://hackerone.com/tendermint). ## v0.32.5 +<<<<<<< HEAD +_September 30, 2019_ +======= *September 30, 2019* +>>>>>>> origin/v0.32 This release fixes a major security vulnerability found in the `p2p` package. All clients are recommended to upgrade. See [TODO](hxxp://githublink) for @@ -66,11 +104,15 @@ program](https://hackerone.com/tendermint). ### SECURITY: +<<<<<<< HEAD +- [p2p] [\#4030](https://github.com/tendermint/tendermint/issues/4030) Fix for panic on nil public key send to a peer +======= - [p2p] [TODO](hxxp://githublink) Fix for panic on nil public key send to a peer +>>>>>>> origin/v0.32 ## v0.32.4 -*September 19, 2019* +_September 19, 2019_ Special thanks to external contributors on this release: @jon-certik, @gracenoah, @PSalant726, @gchaincl @@ -103,7 +145,7 @@ program](https://hackerone.com/tendermint). ## v0.32.3 -*August 28, 2019* +_August 28, 2019_ @climber73 wrote the [Writing a Tendermint Core application in Java (gRPC)](https://github.com/tendermint/tendermint/blob/master/docs/guides/java.md) @@ -130,7 +172,7 @@ program](https://hackerone.com/tendermint). ## v0.32.2 -*July 31, 2019* +_July 31, 2019_ Special thanks to external contributors on this release: @ruseinov, @bluele, @guagualvcha @@ -168,12 +210,13 @@ program](https://hackerone.com/tendermint). ## v0.32.1 -*July 15, 2019* +_July 15, 2019_ Special thanks to external contributors on this release: @ParthDesai, @climber73, @jim380, @ashleyvega This release contains a minor enhancement to the ABCI and some breaking changes to our libs folder, namely: + - CheckTx requests include a `CheckTxType` enum that can be set to `Recheck` to indicate to the application that this transaction was already checked/validated and certain expensive operations (like checking signatures) can be skipped - Removed various functions from `libs` pkgs @@ -184,7 +227,7 @@ program](https://hackerone.com/tendermint). - Go API - - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) The CheckTx and DeliverTx methods in the ABCI `Application` interface now take structs as arguments (RequestCheckTx and RequestDeliverTx, respectively), instead of just the raw tx bytes. This allows more information to be passed to these methods, for instance, indicating whether a tx has already been checked. + - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) The CheckTx and DeliverTx methods in the ABCI `Application` interface now take structs as arguments (RequestCheckTx and RequestDeliverTx, respectively), instead of just the raw tx bytes. This allows more information to be passed to these methods, for instance, indicating whether a tx has already been checked. - [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778) - [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778) - [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778) @@ -193,7 +236,7 @@ program](https://hackerone.com/tendermint). ### FEATURES: - [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized. -- [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass +- [node] [\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass custom reactors to run inside Tendermint node (@ParthDesai) - [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127)RequestCheckTx has a new field, `CheckTxType`, which can take values of `CheckTxType_New` and `CheckTxType_Recheck`, indicating whether this is a new tx being checked for the first time or whether this tx is being rechecked after a block commit. This allows applications to skip certain expensive operations, like signature checking, if they've already been done once. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection) @@ -209,16 +252,16 @@ program](https://hackerone.com/tendermint). - [behaviour] [\3772](https://github.com/tendermint/tendermint/pull/3772) Return correct reason in MessageOutOfOrder (@jim380) - [config] [\#3723](https://github.com/tendermint/tendermint/issues/3723) Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega) - ## v0.32.0 -*June 25, 2019* +_June 25, 2019_ Special thanks to external contributors on this release: @needkane, @SebastianElvis, @andynog, @Yawning, @wooparadog This release contains breaking changes to our build and release processes, ABCI, and the RPC, namely: + - Use Go modules instead of dep - Bring active development to the `master` Github branch - ABCI Tags are now Events - see @@ -230,7 +273,8 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + - [cli] [\#3613](https://github.com/tendermint/tendermint/issues/3613) Switch from golang/dep to Go Modules to resolve dependencies: It is recommended to switch to Go Modules if your project has tendermint as a dependency. Read more on Modules here: @@ -241,13 +285,15 @@ program](https://hackerone.com/tendermint). -> `results.deliver_tx`). See docs for details. - [rpc] [\#3724](https://github.com/tendermint/tendermint/issues/3724) RPC now binds to `127.0.0.1` by default instead of `0.0.0.0` -* Apps +- Apps + - [abci] [\#1859](https://github.com/tendermint/tendermint/issues/1859) `ResponseCheckTx`, `ResponseDeliverTx`, `ResponseBeginBlock`, and `ResponseEndBlock` now include `Events` instead of `Tags`. Each `Event` contains a `type` and a list of `attributes` (list of key-value pairs) allowing for inclusion of multiple distinct events in each response. -* Go API +- Go API + - [abci] [\#3193](https://github.com/tendermint/tendermint/issues/3193) Use RequestDeliverTx and RequestCheckTx in the ABCI Application interface - [libs/db] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed deprecated `LevelDBBackend` const @@ -255,42 +301,134 @@ program](https://hackerone.com/tendermint). change it to `goleveldb` or `cleveldb`. - [p2p] [\#3521](https://github.com/tendermint/tendermint/issues/3521) Remove NewNetAddressStringWithOptionalID -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: ### IMPROVEMENTS: + - [abci/examples] [\#3659](https://github.com/tendermint/tendermint/issues/3659) Change validator update tx format in the `persistent_kvstore` to use base64 for pubkeys instead of hex (@needkane) - [consensus] [\#3656](https://github.com/tendermint/tendermint/issues/3656) Exit if SwitchToConsensus fails - [p2p] [\#3666](https://github.com/tendermint/tendermint/issues/3666) Add per channel telemetry to improve reactor observability - [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog) ### BUG FIXES: + - [libs/db] [\#3717](https://github.com/tendermint/tendermint/issues/3717) Fixed the BoltDB backend's Batch.Delete implementation (@Yawning) - [libs/db] [\#3718](https://github.com/tendermint/tendermint/issues/3718) Fixed the BoltDB backend's Get and Iterator implementation (@Yawning) - [node] [\#3716](https://github.com/tendermint/tendermint/issues/3716) Fix a bug where `nil` is recorded as node's address - [node] [\#3741](https://github.com/tendermint/tendermint/issues/3741) Fix profiler blocking the entire node +## v0.31.11 + +_October 18, 2019_ + +This security release fixes a vulnerability found in the `consensus` package, +where an attacker could construct a `BlockPartMessage` message in such a way +that it will lead to consensus failure. A few similar issues have been +identified and fixed here. + +**All clients are recommended to upgrade** + +Special thanks to [elvishacker](https://hackerone.com/elvishacker) for finding +and reporting this. + +Friendly reminder, we have a [bug bounty +program](https://hackerone.com/tendermint). + +### BREAKING CHANGES: + +- Go API + - [consensus] Modify `WAL#Write` and `WAL#WriteSync` to return an error if + they fail to write a message + +### SECURITY: + +- [consensus] Validate incoming messages more throughly + +## v0.31.10 + +_October 8, 2019_ + +The previous patch was insufficient because the attacker could still find a way +to submit a `nil` pubkey by constructing a `PubKeyMultisigThreshold` pubkey +with `nil` subpubkeys for example. + +This release provides multiple fixes, which include recovering from panics when +accepting new peers and only allowing `ed25519` pubkeys. + +**All clients are recommended to upgrade** + +Special thanks to [fudongbai](https://hackerone.com/fudongbai) for pointing +this out. + +Friendly reminder, we have a [bug bounty +program](https://hackerone.com/tendermint). + +### SECURITY: + +- [p2p] [\#4030](https://github.com/tendermint/tendermint/issues/4030) Only allow ed25519 pubkeys when connecting + +## v0.31.9 + +_October 1, 2019_ + +This release fixes a major security vulnerability found in the `p2p` package. +All clients are recommended to upgrade. See +[\#4030](https://github.com/tendermint/tendermint/issues/4030) for details. + +Special thanks to [fudongbai](https://hackerone.com/fudongbai) for discovering +and reporting this issue. + +Friendly reminder, we have a [bug bounty +program](https://hackerone.com/tendermint). + +### SECURITY: + +- [p2p] [\#4030](https://github.com/tendermint/tendermint/issues/4030) Fix for panic on nil public key send to a peer + +### BUG FIXES: + +- [node] [\#3716](https://github.com/tendermint/tendermint/issues/3716) Fix a bug where `nil` is recorded as node's address +- [node] [\#3741](https://github.com/tendermint/tendermint/issues/3741) Fix profiler blocking the entire node + +## v0.31.8 + +_July 29, 2019_ + +This releases fixes one bug in the PEX reactor and adds a `recover` to the Go's +ABCI server, which allows it to properly cleanup. + +### IMPROVEMENTS: + +- [abci] [\#3809](https://github.com/tendermint/tendermint/issues/3809) Recover from application panics in `server/socket_server.go` to allow socket cleanup (@ruseinov) + +### BUG FIXES: + +- [p2p] [\#3338](https://github.com/tendermint/tendermint/issues/3338) Prevent "sent next PEX request too soon" errors by not calling + ensurePeers outside of ensurePeersRoutine + ## v0.31.7 -*June 3, 2019* +_June 3, 2019_ This releases fixes a regression in the mempool introduced in v0.31.6. The regression caused the invalid committed txs to be proposed in blocks over and over again. ### BUG FIXES: + - [mempool] [\#3699](https://github.com/tendermint/tendermint/issues/3699) Remove all committed txs from the mempool. - This reverts the change from v0.31.6 where we only remove valid txs from the mempool. - Note this means malicious proposals can cause txs to be dropped from the - mempools of other nodes by including them in blocks before they are valid. - See [\#3322](https://github.com/tendermint/tendermint/issues/3322). + This reverts the change from v0.31.6 where we only remove valid txs from the mempool. + Note this means malicious proposals can cause txs to be dropped from the + mempools of other nodes by including them in blocks before they are valid. + See [\#3322](https://github.com/tendermint/tendermint/issues/3322). ## v0.31.6 -*May 31st, 2019* +_May 31st, 2019_ This release contains many fixes and improvements, primarily for p2p functionality. It also fixes a security issue in the mempool package. @@ -305,7 +443,7 @@ Special thanks to external contributors on this release: ### BREAKING CHANGES: -* Go API +- Go API - [libs/common] Removed deprecated `PanicSanity`, `PanicCrisis`, `PanicConsensus` and `PanicQ` - [mempool, state] [\#2659](https://github.com/tendermint/tendermint/issues/2659) `Mempool` now an interface that lives in the mempool package. @@ -314,10 +452,12 @@ Special thanks to external contributors on this release: - [types] [\#1648](https://github.com/tendermint/tendermint/issues/1648) `Commit#VoteSignBytes` signature was changed ### FEATURES: + - [node] [\#2659](https://github.com/tendermint/tendermint/issues/2659) Add `node.Mempool()` method, which allows you to access mempool - [libs/db] [\#3604](https://github.com/tendermint/tendermint/pull/3604) Add experimental support for bolt db (etcd's fork of bolt) (@CrocdileChan) ### IMPROVEMENTS: + - [cli] [\#3585](https://github.com/tendermint/tendermint/issues/3585) Add `--keep-addr-book` option to `unsafe_reset_all` cmd to not clear the address book (@climber73) - [cli] [\#3160](https://github.com/tendermint/tendermint/issues/3160) Add @@ -328,10 +468,10 @@ Special thanks to external contributors on this release: - [crypto] [\#3672](https://github.com/tendermint/tendermint/issues/3672) Return more info in the `AddSignatureFromPubKey` error - [cs/replay] [\#3460](https://github.com/tendermint/tendermint/issues/3460) Check appHash for each block - [libs/db] [\#3611](https://github.com/tendermint/tendermint/issues/3611) Conditional compilation - * Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or + - Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or use `make build_c` / `make install_c` (full instructions can be found at https://tendermint.com/docs/introduction/install.html#compile-with-cleveldb-support) - * Use `boltdb` tag to compile Tendermint with bolt db + - Use `boltdb` tag to compile Tendermint with bolt db - [node] [\#3362](https://github.com/tendermint/tendermint/issues/3362) Return an error if `persistent_peers` list is invalid (except when IP lookup fails) - [p2p] [\#3463](https://github.com/tendermint/tendermint/pull/3463) Do not log "Can't add peer's address to addrbook" error for a private peer (@guagualvcha) @@ -342,12 +482,13 @@ Special thanks to external contributors on this release: incorrect (except when IP lookup fails) ### BUG FIXES: + - [consensus] [\#3067](https://github.com/tendermint/tendermint/issues/3067) Fix replay from appHeight==0 with validator set changes (@james-ray) - [consensus] [\#3304](https://github.com/tendermint/tendermint/issues/3304) Create a peer state in consensus reactor before the peer is started (@guagualvcha) - [lite] [\#3669](https://github.com/tendermint/tendermint/issues/3669) Add context parameter to RPC Handlers in proxy routes (@yutianwu) - [mempool] [\#3322](https://github.com/tendermint/tendermint/issues/3322) When a block is committed, only remove committed txs from the mempool -that were valid (ie. `ResponseDeliverTx.Code == 0`) + that were valid (ie. `ResponseDeliverTx.Code == 0`) - [p2p] [\#3338](https://github.com/tendermint/tendermint/issues/3338) Ensure `RemovePeer` is always called before `InitPeer` (upon a peer reconnecting to our node) - [p2p] [\#3532](https://github.com/tendermint/tendermint/issues/3532) Limit the number of attempts to connect to a peer in seed mode @@ -356,11 +497,12 @@ that were valid (ie. `ResponseDeliverTx.Code == 0`) - [pex] [\#3603](https://github.com/tendermint/tendermint/pull/3603) Dial seeds when addrbook needs more addresses (@defunctzombie) ### OTHERS: + - [networks] fixes ansible integration script (@carlosflrs) ## v0.31.5 -*April 16th, 2019* +_April 16th, 2019_ This release fixes a regression from v0.31.4 where, in existing chains that were upgraded, `/validators` could return an empty validator set. This is true @@ -383,7 +525,7 @@ Special thanks to external contributors on this release: ## v0.31.4 -*April 12th, 2019* +_April 12th, 2019_ This release fixes a regression from v0.31.3 which used the peer's `SocketAddr` to add the peer to the address book. This swallowed the peer's self-reported port which is important in case of reconnect. @@ -409,22 +551,23 @@ Special thanks to external contributors on this release: - [state] [\#3438](https://github.com/tendermint/tendermint/pull/3438) Persist validators every 100000 blocks even if no changes to the set occurred (@guagualvcha). This - 1) Prevents possible DoS attack using `/validators` or `/status` RPC - endpoints. Before response time was growing linearly with height if no - changes were made to the validator set. - 2) Fixes performance degradation in `ExecCommitBlock` where we call - `LoadValidators` for each `Evidence` in the block. + 1. Prevents possible DoS attack using `/validators` or `/status` RPC + endpoints. Before response time was growing linearly with height if no + changes were made to the validator set. + 2. Fixes performance degradation in `ExecCommitBlock` where we call + `LoadValidators` for each `Evidence` in the block. ## v0.31.3 -*April 1st, 2019* +_April 1st, 2019_ This release includes two security sensitive fixes: it ensures generated private keys are valid, and it prevents certain DNS lookups that would cause the node to panic if the lookup failed. ### BREAKING CHANGES: -* Go API + +- Go API - [crypto/secp256k1] [\#3439](https://github.com/tendermint/tendermint/issues/3439) The `secp256k1.GenPrivKeySecp256k1` function has changed to guarantee that it returns a valid key, which means it will return a different private key than in previous versions for the same secret. @@ -432,16 +575,16 @@ panic if the lookup failed. ### BUG FIXES: - [crypto/secp256k1] [\#3439](https://github.com/tendermint/tendermint/issues/3439) - Ensure generated private keys are valid by randomly sampling until a valid key is found. - Previously, it was possible (though rare!) to generate keys that exceeded the curve order. - Such keys would lead to invalid signatures. + Ensure generated private keys are valid by randomly sampling until a valid key is found. + Previously, it was possible (though rare!) to generate keys that exceeded the curve order. + Such keys would lead to invalid signatures. - [p2p] [\#3522](https://github.com/tendermint/tendermint/issues/3522) Memoize socket address in peer connections to avoid DNS lookups. Previously, failed DNS lookups could cause the node to panic. ## v0.31.2 -*March 30th, 2019* +_March 30th, 2019_ This release fixes a regression from v0.31.1 where Tendermint panics under mempool load for external ABCI apps. @@ -451,16 +594,17 @@ Special thanks to external contributors on this release: ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config -* Apps +- Apps + +- Go API -* Go API - [libs/autofile] [\#3504](https://github.com/tendermint/tendermint/issues/3504) Remove unused code in autofile package. Deleted functions: `Group.Search`, `Group.FindLast`, `GroupReader.ReadLine`, `GroupReader.PushLine`, `MakeSimpleSearchFunc` (@guagualvcha) -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: @@ -474,7 +618,7 @@ Special thanks to external contributors on this release: ## v0.31.1 -*March 27th, 2019* +_March 27th, 2019_ This release contains a major improvement for the mempool that reduce the amount of sent data by about 30% (see some numbers below). @@ -485,38 +629,39 @@ Special thanks to external contributors on this release: ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config -* Apps +- Apps + +- Go API -* Go API - [crypto] [\#3426](https://github.com/tendermint/tendermint/pull/3426) Remove `Ripemd160` helper method (@needkane) - [libs/common] [\#3429](https://github.com/tendermint/tendermint/pull/3429) Remove `RepeatTimer` (also `TimerMaker` and `Ticker` interface) - [rpc/client] [\#3458](https://github.com/tendermint/tendermint/issues/3458) Include `NetworkClient` interface into `Client` interface - [types] [\#3448](https://github.com/tendermint/tendermint/issues/3448) Remove method `PB2TM.ConsensusParams` -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: - - [rpc] [\#3419](https://github.com/tendermint/tendermint/issues/3419) Start HTTPS server if `rpc.tls_cert_file` and `rpc.tls_key_file` are provided in the config (@guagualvcha) +- [rpc] [\#3419](https://github.com/tendermint/tendermint/issues/3419) Start HTTPS server if `rpc.tls_cert_file` and `rpc.tls_key_file` are provided in the config (@guagualvcha) ### IMPROVEMENTS: - [docs] [\#3140](https://github.com/tendermint/tendermint/issues/3140) Formalize proposer election algorithm properties - [docs] [\#3482](https://github.com/tendermint/tendermint/issues/3482) Fix broken links (@brapse) - [mempool] [\#2778](https://github.com/tendermint/tendermint/issues/2778) No longer send txs back to peers who sent it to you. -Also, limit to 65536 active peers. -This vastly improves the bandwidth consumption of nodes. -For instance, for a 4 node localnet, in a test sending 250byte txs for 120 sec. at 500 txs/sec (total of 15MB): + Also, limit to 65536 active peers. + This vastly improves the bandwidth consumption of nodes. + For instance, for a 4 node localnet, in a test sending 250byte txs for 120 sec. at 500 txs/sec (total of 15MB): - total bytes received from 1st node: - - before: 42793967 (43MB) - - after: 30003256 (30MB) + - before: 42793967 (43MB) + - after: 30003256 (30MB) - total bytes sent to 1st node: - - before: 30569339 (30MB) - - after: 19304964 (19MB) + - before: 30569339 (30MB) + - after: 19304964 (19MB) - [p2p] [\#3475](https://github.com/tendermint/tendermint/issues/3475) Simplify `GetSelectionWithBias` for addressbook (@guagualvcha) - [rpc/lib/client] [\#3430](https://github.com/tendermint/tendermint/issues/3430) Disable compression for HTTP client to prevent GZIP-bomb DoS attacks (@guagualvcha) @@ -525,10 +670,9 @@ For instance, for a 4 node localnet, in a test sending 250byte txs for 120 sec. - [blockchain] [\#2699](https://github.com/tendermint/tendermint/issues/2699) Update the maxHeight when a peer is removed - [mempool] [\#3478](https://github.com/tendermint/tendermint/issues/3478) Fix memory-leak related to `broadcastTxRoutine` (@HaoyangLiu) - ## v0.31.0 -*March 16th, 2019* +_March 16th, 2019_ Special thanks to external contributors on this release: @danil-lashin, @guagualvcha, @siburu, @silasdavis, @srmo, @Stumble, @svenstaro @@ -549,7 +693,8 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + - [config] [\#2920](https://github.com/tendermint/tendermint/issues/2920) Remove `consensus.blocktime_iota` parameter - [rpc] [\#3227](https://github.com/tendermint/tendermint/issues/3227) New PubSub design does not block on clients when publishing messages. Slow clients may miss messages and receive an error, terminating @@ -559,36 +704,40 @@ program](https://hackerone.com/tendermint). - [rpc] [\#3435](https://github.com/tendermint/tendermint/issues/3435) Default ReadTimeout and WriteTimeout changed to 10s. WriteTimeout can increased by setting `rpc.timeout_broadcast_tx_commit` in the config. - [rpc/client] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Update `EventsClient` interface to reflect new pubsub/eventBus API [ADR-33](https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-033-pubsub.md). This includes `Subscribe`, `Unsubscribe`, and `UnsubscribeAll` methods. -* Apps +- Apps + - [abci] [\#3403](https://github.com/tendermint/tendermint/issues/3403) Remove `time_iota_ms` from BlockParams. This is a ConsensusParam but need not be exposed to the app for now. - [abci] [\#2920](https://github.com/tendermint/tendermint/issues/2920) Rename `consensus_params.block_size` to `consensus_params.block` in ABCI ConsensusParams -* Go API +- Go API + - [libs/common] TrapSignal accepts logger as a first parameter and does not block anymore - * previously it was dumping "captured ..." msg to os.Stdout - * TrapSignal should not be responsible for blocking thread of execution + - previously it was dumping "captured ..." msg to os.Stdout + - TrapSignal should not be responsible for blocking thread of execution - [libs/db] [\#3397](https://github.com/tendermint/tendermint/pull/3397) Add possibility to `Close()` `Batch` to prevent memory leak when using ClevelDB. (@Stumble) - [types] [\#3354](https://github.com/tendermint/tendermint/issues/3354) Remove RoundState from EventDataRoundState - [rpc] [\#3435](https://github.com/tendermint/tendermint/issues/3435) `StartHTTPServer` / `StartHTTPAndTLSServer` now require a Config (use `rpcserver.DefaultConfig`) -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: + - [config] [\#3269](https://github.com/tendermint/tendermint/issues/2826) New configuration values for controlling RPC subscriptions: - - `rpc.max_subscription_clients` sets the maximum number of unique clients - with open subscriptions - - `rpc.max_subscriptions_per_client`sets the maximum number of unique - subscriptions from a given client - - `rpc.timeout_broadcast_tx_commit` sets the time to wait for a tx to be committed during `/broadcast_tx_commit` + - `rpc.max_subscription_clients` sets the maximum number of unique clients + with open subscriptions + - `rpc.max_subscriptions_per_client`sets the maximum number of unique + subscriptions from a given client + - `rpc.timeout_broadcast_tx_commit` sets the time to wait for a tx to be committed during `/broadcast_tx_commit` - [types] [\#2920](https://github.com/tendermint/tendermint/issues/2920) Add `time_iota_ms` to block's consensus parameters (not exposed to the application) - [lite] [\#3269](https://github.com/tendermint/tendermint/issues/3269) Add `/unsubscribe_all` endpoint to unsubscribe from all events - [mempool] [\#3079](https://github.com/tendermint/tendermint/issues/3079) Bound mempool memory usage via the `mempool.max_txs_bytes` configuration value. Set to 1GB by default. The mempool's current `txs_total_bytes` is exposed via `total_bytes` field in `/num_unconfirmed_txs` and `/unconfirmed_txs` RPC endpoints. ### IMPROVEMENTS: + - [all] [\#3385](https://github.com/tendermint/tendermint/issues/3385), [\#3386](https://github.com/tendermint/tendermint/issues/3386) Various linting improvements - [crypto] [\#3371](https://github.com/tendermint/tendermint/issues/3371) Copy in secp256k1 package from go-ethereum instead of importing go-ethereum (@silasdavis) @@ -607,6 +756,7 @@ program](https://hackerone.com/tendermint). - [privval] [\#3351](https://github.com/tendermint/tendermint/pull/3351) First part of larger refactoring that clarifies and separates concerns in the privval package. ### BUG FIXES: + - [blockchain] [\#3358](https://github.com/tendermint/tendermint/pull/3358) Fix timer leak in `BlockPool` (@guagualvcha) - [cmd] [\#3408](https://github.com/tendermint/tendermint/issues/3408) Fix `testnet` command's panic when creating non-validator configs (using `--n` flag) (@srmo) - [libs/db/remotedb/grpcdb] [\#3402](https://github.com/tendermint/tendermint/issues/3402) Close Iterator/ReverseIterator after use @@ -619,7 +769,7 @@ program](https://hackerone.com/tendermint). ## v0.30.2 -*March 10th, 2019* +_March 10th, 2019_ This release fixes a CLevelDB memory leak. It was happening because we were not closing the WriteBatch object after use. See [levigo's @@ -630,15 +780,16 @@ fix here. ### BREAKING CHANGES: -* Go API +- Go API - [libs/db] [\#3842](https://github.com/cosmos/cosmos-sdk/issues/3842) Add Close() method to Batch interface (@Stumble) ### BUG FIXES: + - [libs/db] [\#3842](https://github.com/cosmos/cosmos-sdk/issues/3842) Fix CLevelDB memory leak (@Stumble) ## v0.30.1 -*February 20th, 2019* +_February 20th, 2019_ This release fixes a consensus halt and a DataCorruptionError after restart discovered in `game_of_stakes_6`. It also fixes a security issue in the p2p @@ -646,27 +797,27 @@ handshake by authenticating the NetAddress.ID of the peer we're dialing. ### IMPROVEMENTS: -* [config] [\#3291](https://github.com/tendermint/tendermint/issues/3291) Make +- [config] [\#3291](https://github.com/tendermint/tendermint/issues/3291) Make config.ResetTestRootWithChainID() create concurrency-safe test directories. ### BUG FIXES: -* [consensus] [\#3295](https://github.com/tendermint/tendermint/issues/3295) +- [consensus] [\#3295](https://github.com/tendermint/tendermint/issues/3295) Flush WAL on stop to prevent data corruption during graceful shutdown. -* [consensus] [\#3302](https://github.com/tendermint/tendermint/issues/3302) +- [consensus] [\#3302](https://github.com/tendermint/tendermint/issues/3302) Fix possible halt by resetting TriggeredTimeoutPrecommit before starting next height. -* [rpc] [\#3251](https://github.com/tendermint/tendermint/issues/3251) Fix +- [rpc] [\#3251](https://github.com/tendermint/tendermint/issues/3251) Fix `/net_info#peers#remote_ip` format. New format spec: - * dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address - * IPv6 ("2001:db8::1"), if ip is a valid IPv6 address -* [cmd] [\#3314](https://github.com/tendermint/tendermint/issues/3314) Return + - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address + - IPv6 ("2001:db8::1"), if ip is a valid IPv6 address +- [cmd] [\#3314](https://github.com/tendermint/tendermint/issues/3314) Return an error on `show_validator` when the private validator file does not exist. -* [p2p] [\#3010](https://github.com/tendermint/tendermint/issues/3010#issuecomment-464287627) +- [p2p] [\#3010](https://github.com/tendermint/tendermint/issues/3010#issuecomment-464287627) Authenticate a peer against its NetAddress.ID when dialing. ## v0.30.0 -*February 8th, 2019* +_February 8th, 2019_ This release fixes yet another issue with the proposer selection algorithm. We hope it's the last one, but we won't be surprised if it's not. @@ -681,21 +832,24 @@ piece of evidence in more than one block. This issue was reported by @chengwenxi ### BREAKING CHANGES: -* Apps +- Apps + - [state] [\#3222](https://github.com/tendermint/tendermint/issues/3222) Duplicate updates for the same validator are forbidden. Apps must ensure that a given `ResponseEndBlock.ValidatorUpdates` contains only one entry per pubkey. -* Go API +- Go API + - [types] [\#3222](https://github.com/tendermint/tendermint/issues/3222) Remove `Add` and `Update` methods from `ValidatorSet` in favor of new `UpdateWithChangeSet`. This allows updates to be applied as a set, instead of one at a time. -* Block Protocol +- Block Protocol + - [state] [\#3286](https://github.com/tendermint/tendermint/issues/3286) Blocks that include already committed evidence are invalid. -* P2P Protocol +- P2P Protocol - [consensus] [\#3222](https://github.com/tendermint/tendermint/issues/3222) Validator updates are applied as a set, instead of one at a time, thus impacting the proposer priority calculation. This ensures that the proposer @@ -703,9 +857,11 @@ piece of evidence in more than one block. This issue was reported by @chengwenxi `ResponseEndBlock.ValidatorUpdates`. ### IMPROVEMENTS: + - [crypto] [\#3279](https://github.com/tendermint/tendermint/issues/3279) Use `btcec.S256().N` directly instead of hard coding a copy. ### BUG FIXES: + - [state] [\#3222](https://github.com/tendermint/tendermint/issues/3222) Fix validator set updates so they are applied as a set, rather than one at a time. This makes the proposer selection algorithm independent of the order of updates in `ResponseEndBlock.ValidatorUpdates`. @@ -713,13 +869,14 @@ piece of evidence in more than one block. This issue was reported by @chengwenxi ## v0.29.2 -*February 7th, 2019* +_February 7th, 2019_ Special thanks to external contributors on this release: @ackratos, @rickyyangz **Note**: This release contains security sensitive patches in the `p2p` and `crypto` packages: + - p2p: - Partial fix for MITM attacks on the p2p connection. MITM conditions may still exist. See [\#3010](https://github.com/tendermint/tendermint/issues/3010). @@ -732,13 +889,14 @@ Special thanks to external contributors on this release: ### BREAKING CHANGES: -* Go API +- Go API - [crypto] [\#3278](https://github.com/tendermint/tendermint/issues/3278) Remove MixEntropy functions - [types] [\#3245](https://github.com/tendermint/tendermint/issues/3245) Commit uses `type CommitSig Vote` instead of `Vote` directly. In preparation for removing redundant fields from the commit [\#1648](https://github.com/tendermint/tendermint/issues/1648) ### IMPROVEMENTS: + - [consensus] [\#3246](https://github.com/tendermint/tendermint/issues/3246) Better logging and notes on recovery for corrupted WAL file - [crypto] [\#3163](https://github.com/tendermint/tendermint/issues/3163) Use ethereum's libsecp256k1 go-wrapper for signatures when cgo is available - [crypto] [\#3162](https://github.com/tendermint/tendermint/issues/3162) Wrap btcd instead of forking it to keep up with fixes (used if cgo is not available) @@ -748,6 +906,7 @@ Special thanks to external contributors on this release: - [tests] [\#3258](https://github.com/tendermint/tendermint/issues/3258) Fixed a bunch of non-deterministic test failures ### BUG FIXES: + - [node] [\#3186](https://github.com/tendermint/tendermint/issues/3186) EventBus and indexerService should be started before first block (for replay last block on handshake) execution (@ackratos) - [p2p] [\#3232](https://github.com/tendermint/tendermint/issues/3232) Fix infinite loop leading to addrbook deadlock for seed nodes - [p2p] [\#3247](https://github.com/tendermint/tendermint/issues/3247) Fix panic in SeedMode when calling FlushStop and OnStop @@ -757,7 +916,7 @@ Special thanks to external contributors on this release: ## v0.29.1 -*January 24, 2019* +_January 24, 2019_ Special thanks to external contributors on this release: @infinytum, @gauthamzz @@ -770,17 +929,19 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint). ### IMPROVEMENTS: + - [pex] [\#3037](https://github.com/tendermint/tendermint/issues/3037) Only log "Reached max attempts to dial" once - [rpc] [\#3159](https://github.com/tendermint/tendermint/issues/3159) Expose `triggered_timeout_commit` in the `/dump_consensus_state` ### BUG FIXES: + - [consensus] [\#3199](https://github.com/tendermint/tendermint/issues/3199) Fix consensus halt with no empty blocks from not resetting triggeredTimeoutCommit - [p2p] [\#2967](https://github.com/tendermint/tendermint/issues/2967) Fix file descriptor leak ## v0.29.0 -*January 21, 2019* +_January 21, 2019_ Special thanks to external contributors on this release: @bradyjoestar, @kunaldhariwal, @gauthamzz, @hrharder @@ -812,38 +973,43 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + +- Apps -* Apps - [state] [\#3049](https://github.com/tendermint/tendermint/issues/3049) Total voting power of the validator set is upper bounded by `MaxInt64 / 8`. Apps must ensure they do not return changes to the validator set that cause this maximum to be exceeded. -* Go API +- Go API + - [node] [\#3082](https://github.com/tendermint/tendermint/issues/3082) MetricsProvider now requires you to pass a chain ID - [types] [\#2713](https://github.com/tendermint/tendermint/issues/2713) Rename `TxProof.LeafHash` to `TxProof.Leaf` - [crypto/merkle] [\#2713](https://github.com/tendermint/tendermint/issues/2713) `SimpleProof.Verify` takes a `leaf` instead of a `leafHash` and performs the hashing itself -* Blockchain Protocol - * [crypto/merkle] [\#2713](https://github.com/tendermint/tendermint/issues/2713) Merkle trees now match the RFC 6962 specification - * [types] [\#3078](https://github.com/tendermint/tendermint/issues/3078) Re-order Timestamp and BlockID in CanonicalVote so it's +- Blockchain Protocol + + - [crypto/merkle] [\#2713](https://github.com/tendermint/tendermint/issues/2713) Merkle trees now match the RFC 6962 specification + - [types] [\#3078](https://github.com/tendermint/tendermint/issues/3078) Re-order Timestamp and BlockID in CanonicalVote so it's consistent with CanonicalProposal (BlockID comes first) - * [types] [\#3165](https://github.com/tendermint/tendermint/issues/3165) Hash of ConsensusParams only includes BlockSize.MaxBytes and + - [types] [\#3165](https://github.com/tendermint/tendermint/issues/3165) Hash of ConsensusParams only includes BlockSize.MaxBytes and BlockSize.MaxGas -* P2P Protocol +- P2P Protocol - [consensus] [\#3049](https://github.com/tendermint/tendermint/issues/3049) Normalize priorities to not exceed `2*TotalVotingPower` to mitigate unfair proposer selection heavily preferring earlier joined validators in the case of an early bonded large validator unbonding ### FEATURES: ### IMPROVEMENTS: + - [rpc] [\#3065](https://github.com/tendermint/tendermint/issues/3065) Return maxPerPage (100), not defaultPerPage (30) if `per_page` is greater than the max 100. - [instrumentation] [\#3082](https://github.com/tendermint/tendermint/issues/3082) Add `chain_id` label for all metrics ### BUG FIXES: + - [crypto] [\#3164](https://github.com/tendermint/tendermint/issues/3164) Update `btcd` fork for rare signRFC6979 bug - [lite] [\#3171](https://github.com/tendermint/tendermint/issues/3171) Fix verifying large validator set changes - [log] [\#3125](https://github.com/tendermint/tendermint/issues/3125) Fix year format @@ -852,7 +1018,7 @@ program](https://hackerone.com/tendermint). ## v0.28.1 -*January 18th, 2019* +_January 18th, 2019_ Special thanks to external contributors on this release: @HaoyangLiu @@ -861,11 +1027,12 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint). ### BUG FIXES: + - [consensus] Fix consensus halt from proposing blocks with too much evidence ## v0.28.0 -*January 16th, 2019* +_January 16th, 2019_ Special thanks to external contributors on this release: @fmauricios, @gianfelipe93, @husio, @needkane, @srmo, @yutianwu @@ -881,7 +1048,8 @@ See [UPGRADING.md](UPGRADING.md) for more details. ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + - [cli] Removed `--proxy_app=dummy` option. Use `kvstore` (`persistent_kvstore`) instead. - [cli] Renamed `--proxy_app=nilapp` to `--proxy_app=noop`. - [config] [\#2992](https://github.com/tendermint/tendermint/issues/2992) `allow_duplicate_ip` is now set to false @@ -889,19 +1057,22 @@ See [UPGRADING.md](UPGRADING.md) for more details. - [privval] [\#2926](https://github.com/tendermint/tendermint/issues/2926) Split up `PubKeyMsg` into `PubKeyRequest` and `PubKeyResponse` to be consistent with other message types - [privval] [\#2923](https://github.com/tendermint/tendermint/issues/2923) Listen for unix socket connections instead of dialing them -* Apps +- Apps + +- Go API -* Go API - [types] [\#2981](https://github.com/tendermint/tendermint/issues/2981) Remove `PrivValidator.GetAddress()` -* Blockchain Protocol +- Blockchain Protocol -* P2P Protocol +- P2P Protocol ### FEATURES: + - [rpc] [\#3052](https://github.com/tendermint/tendermint/issues/3052) Include peer's remote IP in `/net_info` ### IMPROVEMENTS: + - [consensus] [\#3086](https://github.com/tendermint/tendermint/issues/3086) Log peerID on ignored votes (@srmo) - [docs] [\#3061](https://github.com/tendermint/tendermint/issues/3061) Added specification for signing consensus msgs at ./docs/spec/consensus/signing.md @@ -920,7 +1091,7 @@ See [UPGRADING.md](UPGRADING.md) for more details. ## v0.27.4 -*December 21st, 2018* +_December 21st, 2018_ ### BUG FIXES: @@ -930,17 +1101,17 @@ See [UPGRADING.md](UPGRADING.md) for more details. ## v0.27.3 -*December 16th, 2018* +_December 16th, 2018_ ### BREAKING CHANGES: -* Go API +- Go API - [dep] [\#3027](https://github.com/tendermint/tendermint/issues/3027) Revert to mainline Go crypto library, eliminating the modified `bcrypt.GenerateFromPassword` ## v0.27.2 -*December 16th, 2018* +_December 16th, 2018_ ### IMPROVEMENTS: @@ -948,26 +1119,29 @@ See [UPGRADING.md](UPGRADING.md) for more details. ### BUG FIXES: -- [p2p] [\#3025](https://github.com/tendermint/tendermint/pull/3025) Revert to using defers in addrbook. Fixes deadlocks in pex and consensus upon invalid ExternalAddr/ListenAddr configuration. +- [p2p] [\#3025](https://github.com/tendermint/tendermint/pull/3025) Revert to using defers in addrbook. Fixes deadlocks in pex and consensus upon invalid ExternalAddr/ListenAddr configuration. ## v0.27.1 -*December 15th, 2018* +_December 15th, 2018_ Special thanks to external contributors on this release: @danil-lashin, @hleb-albau, @james-ray, @leo-xinwang ### FEATURES: + - [rpc] [\#2964](https://github.com/tendermint/tendermint/issues/2964) Add `UnconfirmedTxs(limit)` and `NumUnconfirmedTxs()` methods to HTTP/Local clients (@danil-lashin) - [docs] [\#3004](https://github.com/tendermint/tendermint/issues/3004) Enable full-text search on docs pages ### IMPROVEMENTS: + - [consensus] [\#2971](https://github.com/tendermint/tendermint/issues/2971) Return error if ValidatorSet is empty after InitChain (@leo-xinwang) - [ci/cd] [\#3005](https://github.com/tendermint/tendermint/issues/3005) Updated CircleCI job to trigger website build when docs are updated - [docs] Various updates ### BUG FIXES: + - [cmd] [\#2983](https://github.com/tendermint/tendermint/issues/2983) `testnet` command always sets `addr_book_strict = false` - [config] [\#2980](https://github.com/tendermint/tendermint/issues/2980) Fix CORS options formatting - [kv indexer] [\#2912](https://github.com/tendermint/tendermint/issues/2912) Don't ignore key when executing CONTAINS @@ -978,7 +1152,7 @@ Special thanks to external contributors on this release: ## v0.27.0 -*December 5th, 2018* +_December 5th, 2018_ Special thanks to external contributors on this release: @danil-lashin, @srmo @@ -999,21 +1173,24 @@ message. ### BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + - [rpc] [\#2932](https://github.com/tendermint/tendermint/issues/2932) Rename `accum` to `proposer_priority` -* Go API +- Go API + - [db] [\#2913](https://github.com/tendermint/tendermint/pull/2913) ReverseIterator API change: start < end, and end is exclusive. - [types] [\#2932](https://github.com/tendermint/tendermint/issues/2932) Rename `Validator.Accum` to `Validator.ProposerPriority` -* Blockchain Protocol +- Blockchain Protocol + - [state] [\#2714](https://github.com/tendermint/tendermint/issues/2714) Validators can now only use pubkeys allowed within ConsensusParams.Validator.PubKeyTypes -* P2P Protocol +- P2P Protocol - [consensus] [\#2871](https://github.com/tendermint/tendermint/issues/2871) - Remove *ProposalHeartbeat* message as it serves no real purpose (@srmo) + Remove _ProposalHeartbeat_ message as it serves no real purpose (@srmo) - [state] Fixes for proposer selection: - [\#2785](https://github.com/tendermint/tendermint/issues/2785) Accum for new validators is `-1.125*totalVotingPower` instead of 0 - [\#2941](https://github.com/tendermint/tendermint/issues/2941) val.Accum is preserved during ValidatorSet.Update to avoid being @@ -1035,8 +1212,8 @@ message. - [rpc] [\#2408](https://github.com/tendermint/tendermint/issues/2408) `/broadcast_tx_commit`: Fix "interface conversion: interface {} in nil, not EventDataTx" panic (could happen if somebody sent a tx using `/broadcast_tx_commit` while Tendermint was being stopped) - [state] [\#2785](https://github.com/tendermint/tendermint/issues/2785) Fix accum for new validators to be `-1.125*totalVotingPower` instead of 0, forcing them to wait before becoming the proposer. Also: - - do not batch clip - - keep accums averaged near 0 + - do not batch clip + - keep accums averaged near 0 - [txindex/kv] [\#2925](https://github.com/tendermint/tendermint/issues/2925) Don't return false positives when range searching for a prefix of a tag value - [types] [\#2938](https://github.com/tendermint/tendermint/issues/2938) Fix regression in v0.26.4 where we panic on empty genDoc.Validators @@ -1045,7 +1222,7 @@ message. ## v0.26.4 -*November 27th, 2018* +_November 27th, 2018_ Special thanks to external contributors on this release: @ackratos, @goolAdapter, @james-ray, @joe-bowman, @kostko, @@ -1058,16 +1235,16 @@ program](https://hackerone.com/tendermint). - [rpc] [\#2747](https://github.com/tendermint/tendermint/issues/2747) Enable subscription to tags emitted from `BeginBlock`/`EndBlock` (@kostko) - [types] [\#2747](https://github.com/tendermint/tendermint/issues/2747) Add `ResultBeginBlock` and `ResultEndBlock` fields to `EventDataNewBlock` - and `EventDataNewBlockHeader` to support subscriptions (@kostko) + and `EventDataNewBlockHeader` to support subscriptions (@kostko) - [types] [\#2918](https://github.com/tendermint/tendermint/issues/2918) Add Marshal, MarshalTo, Unmarshal methods to various structs to support Protobuf compatibility (@nagarajmanjunath) ### IMPROVEMENTS: - [config] [\#2877](https://github.com/tendermint/tendermint/issues/2877) Add `blocktime_iota` to the config.toml (@ackratos) - - NOTE: this should be a ConsensusParam, not part of the config, and will be - removed from the config at a later date - ([\#2920](https://github.com/tendermint/tendermint/issues/2920). + - NOTE: this should be a ConsensusParam, not part of the config, and will be + removed from the config at a later date + ([\#2920](https://github.com/tendermint/tendermint/issues/2920). - [mempool] [\#2882](https://github.com/tendermint/tendermint/issues/2882) Add txs from Update to cache - [mempool] [\#2891](https://github.com/tendermint/tendermint/issues/2891) Remove local int64 counter from being stored in every tx - [node] [\#2866](https://github.com/tendermint/tendermint/issues/2866) Add ability to instantiate IPCVal (@joe-bowman) @@ -1077,8 +1254,8 @@ program](https://hackerone.com/tendermint). - [blockchain] [\#2731](https://github.com/tendermint/tendermint/issues/2731) Retry both blocks if either is bad to avoid getting stuck during fast sync (@goolAdapter) - [consensus] [\#2893](https://github.com/tendermint/tendermint/issues/2893) Use genDoc.Validators instead of state.NextValidators on replay when appHeight==0 (@james-ray) - [log] [\#2868](https://github.com/tendermint/tendermint/issues/2868) Fix `module=main` setting overriding all others - - NOTE: this changes the default logging behaviour to be much less verbose. - Set `log_level="info"` to restore the previous behaviour. + - NOTE: this changes the default logging behaviour to be much less verbose. + Set `log_level="info"` to restore the previous behaviour. - [rpc] [\#2808](https://github.com/tendermint/tendermint/issues/2808) Fix `accum` field in `/validators` by calling `IncrementAccum` if necessary - [rpc] [\#2811](https://github.com/tendermint/tendermint/issues/2811) Allow integer IDs in JSON-RPC requests (@tomtau) - [txindex/kv] [\#2759](https://github.com/tendermint/tendermint/issues/2759) Fix tx.height range queries @@ -1087,7 +1264,7 @@ program](https://hackerone.com/tendermint). ## v0.26.3 -*November 17th, 2018* +_November 17th, 2018_ Special thanks to external contributors on this release: @danil-lashin, @kevlubkcm, @krhubert, @srmo @@ -1097,13 +1274,13 @@ program](https://hackerone.com/tendermint). ### BREAKING CHANGES: -* Go API +- Go API - [rpc] [\#2791](https://github.com/tendermint/tendermint/issues/2791) Functions that start HTTP servers are now blocking: - Impacts `StartHTTPServer`, `StartHTTPAndTLSServer`, and `StartGRPCServer` - These functions now take a `net.Listener` instead of an address - [rpc] [\#2767](https://github.com/tendermint/tendermint/issues/2767) Subscribing to events - `NewRound` and `CompleteProposal` return new types `EventDataNewRound` and - `EventDataCompleteProposal`, respectively, instead of the generic `EventDataRoundState`. (@kevlubkcm) + `NewRound` and `CompleteProposal` return new types `EventDataNewRound` and + `EventDataCompleteProposal`, respectively, instead of the generic `EventDataRoundState`. (@kevlubkcm) ### FEATURES: @@ -1122,6 +1299,7 @@ program](https://hackerone.com/tendermint). - [state] [\#2848](https://github.com/tendermint/tendermint/issues/2848) Make "Update to validators" msg value pretty (@danil-lashin) ### BUG FIXES: + - [consensus] [\#2819](https://github.com/tendermint/tendermint/issues/2819) Don't send proposalHearbeat if not a validator - [docs] [\#2859](https://github.com/tendermint/tendermint/issues/2859) Fix ConsensusParams details in spec - [libs/autofile] [\#2760](https://github.com/tendermint/tendermint/issues/2760) Comment out autofile permissions check - should fix @@ -1134,7 +1312,7 @@ program](https://hackerone.com/tendermint). ## v0.26.2 -*November 15th, 2018* +_November 15th, 2018_ Special thanks to external contributors on this release: @hleb-albau, @zhuzeyu @@ -1153,7 +1331,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ## v0.26.1 -*November 11, 2018* +_November 11, 2018_ Special thanks to external contributors on this release: @katakonst @@ -1164,8 +1342,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - [consensus] [\#2704](https://github.com/tendermint/tendermint/issues/2704) Simplify valid POL round logic - [docs] [\#2749](https://github.com/tendermint/tendermint/issues/2749) Deduplicate some ABCI docs - [mempool] More detailed log messages - - [\#2724](https://github.com/tendermint/tendermint/issues/2724) - - [\#2762](https://github.com/tendermint/tendermint/issues/2762) + - [\#2724](https://github.com/tendermint/tendermint/issues/2724) + - [\#2762](https://github.com/tendermint/tendermint/issues/2762) ### BUG FIXES: @@ -1179,7 +1357,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ## v0.26.0 -*November 2, 2018* +_November 2, 2018_ Special thanks to external contributors on this release: @bradyjoestar, @connorwstein, @goolAdapter, @HaoyangLiu, @@ -1208,90 +1386,95 @@ increasing attention to backwards compatibility. Thanks for bearing with us! ### BREAKING CHANGES: -* CLI/RPC/Config - * [config] [\#2232](https://github.com/tendermint/tendermint/issues/2232) Timeouts are now strings like "3s" and "100ms", not ints - * [config] [\#2505](https://github.com/tendermint/tendermint/issues/2505) Remove Mempool.RecheckEmpty (it was effectively useless anyways) - * [config] [\#2490](https://github.com/tendermint/tendermint/issues/2490) `mempool.wal` is disabled by default - * [privval] [\#2459](https://github.com/tendermint/tendermint/issues/2459) Split `SocketPVMsg`s implementations into Request and Response, where the Response may contain a error message (returned by the remote signer) - * [state] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version field to State, breaking the format of State as +- CLI/RPC/Config + + - [config] [\#2232](https://github.com/tendermint/tendermint/issues/2232) Timeouts are now strings like "3s" and "100ms", not ints + - [config] [\#2505](https://github.com/tendermint/tendermint/issues/2505) Remove Mempool.RecheckEmpty (it was effectively useless anyways) + - [config] [\#2490](https://github.com/tendermint/tendermint/issues/2490) `mempool.wal` is disabled by default + - [privval] [\#2459](https://github.com/tendermint/tendermint/issues/2459) Split `SocketPVMsg`s implementations into Request and Response, where the Response may contain a error message (returned by the remote signer) + - [state] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version field to State, breaking the format of State as encoded on disk. - * [rpc] [\#2298](https://github.com/tendermint/tendermint/issues/2298) `/abci_query` takes `prove` argument instead of `trusted` and switches the default + - [rpc] [\#2298](https://github.com/tendermint/tendermint/issues/2298) `/abci_query` takes `prove` argument instead of `trusted` and switches the default behaviour to `prove=false` - * [rpc] [\#2654](https://github.com/tendermint/tendermint/issues/2654) Remove all `node_info.other.*_version` fields in `/status` and + - [rpc] [\#2654](https://github.com/tendermint/tendermint/issues/2654) Remove all `node_info.other.*_version` fields in `/status` and `/net_info` - * [rpc] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Remove + - [rpc] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Remove `_params` suffix from fields in `consensus_params`. -* Apps - * [abci] [\#2298](https://github.com/tendermint/tendermint/issues/2298) ResponseQuery.Proof is now a structured merkle.Proof, not just - arbitrary bytes - * [abci] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version to Header and shift all fields by one - * [abci] [\#2662](https://github.com/tendermint/tendermint/issues/2662) Bump the field numbers for some `ResponseInfo` fields to make room for - `AppVersion` - * [abci] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Updates to ConsensusParams - * Remove `Params` suffix from field names - * Add `Params` suffix to message types - * Add new field and type, `Validator ValidatorParams`, to control what types of validator keys are allowed. +- Apps -* Go API - * [config] [\#2232](https://github.com/tendermint/tendermint/issues/2232) Timeouts are time.Duration, not ints - * [crypto/merkle & lite] [\#2298](https://github.com/tendermint/tendermint/issues/2298) Various changes to accomodate General Merkle trees - * [crypto/merkle] [\#2595](https://github.com/tendermint/tendermint/issues/2595) Remove all Hasher objects in favor of byte slices - * [crypto/merkle] [\#2635](https://github.com/tendermint/tendermint/issues/2635) merkle.SimpleHashFromTwoHashes is no longer exported - * [node] [\#2479](https://github.com/tendermint/tendermint/issues/2479) Remove node.RunForever - * [rpc/client] [\#2298](https://github.com/tendermint/tendermint/issues/2298) `ABCIQueryOptions.Trusted` -> `ABCIQueryOptions.Prove` - * [types] [\#2298](https://github.com/tendermint/tendermint/issues/2298) Remove `Index` and `Total` fields from `TxProof`. - * [types] [\#2598](https://github.com/tendermint/tendermint/issues/2598) + - [abci] [\#2298](https://github.com/tendermint/tendermint/issues/2298) ResponseQuery.Proof is now a structured merkle.Proof, not just + arbitrary bytes + - [abci] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version to Header and shift all fields by one + - [abci] [\#2662](https://github.com/tendermint/tendermint/issues/2662) Bump the field numbers for some `ResponseInfo` fields to make room for + `AppVersion` + - [abci] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Updates to ConsensusParams + - Remove `Params` suffix from field names + - Add `Params` suffix to message types + - Add new field and type, `Validator ValidatorParams`, to control what types of validator keys are allowed. + +- Go API + + - [config] [\#2232](https://github.com/tendermint/tendermint/issues/2232) Timeouts are time.Duration, not ints + - [crypto/merkle & lite] [\#2298](https://github.com/tendermint/tendermint/issues/2298) Various changes to accomodate General Merkle trees + - [crypto/merkle] [\#2595](https://github.com/tendermint/tendermint/issues/2595) Remove all Hasher objects in favor of byte slices + - [crypto/merkle] [\#2635](https://github.com/tendermint/tendermint/issues/2635) merkle.SimpleHashFromTwoHashes is no longer exported + - [node] [\#2479](https://github.com/tendermint/tendermint/issues/2479) Remove node.RunForever + - [rpc/client] [\#2298](https://github.com/tendermint/tendermint/issues/2298) `ABCIQueryOptions.Trusted` -> `ABCIQueryOptions.Prove` + - [types] [\#2298](https://github.com/tendermint/tendermint/issues/2298) Remove `Index` and `Total` fields from `TxProof`. + - [types] [\#2598](https://github.com/tendermint/tendermint/issues/2598) `VoteTypeXxx` are now of type `SignedMsgType byte` and named `XxxType`, eg. `PrevoteType`, `PrecommitType`. - * [types] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Rename fields in ConsensusParams to remove `Params` suffixes - * [types] [\#2735](https://github.com/tendermint/tendermint/issues/2735) Simplify Proposal message to align with spec + - [types] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Rename fields in ConsensusParams to remove `Params` suffixes + - [types] [\#2735](https://github.com/tendermint/tendermint/issues/2735) Simplify Proposal message to align with spec -* Blockchain Protocol - * [crypto/tmhash] [\#2732](https://github.com/tendermint/tendermint/issues/2732) TMHASH is now full 32-byte SHA256 - * All hashes in the block header and Merkle trees are now 32-bytes - * PubKey Addresses are still only 20-bytes - * [state] [\#2587](https://github.com/tendermint/tendermint/issues/2587) Require block.Time of the fist block to be genesis time - * [state] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Require block.Version to match state.Version - * [types] Update SignBytes for `Vote`/`Proposal`/`Heartbeat`: - * [\#2459](https://github.com/tendermint/tendermint/issues/2459) Use amino encoding instead of JSON in `SignBytes`. - * [\#2598](https://github.com/tendermint/tendermint/issues/2598) Reorder fields and use fixed sized encoding. - * [\#2598](https://github.com/tendermint/tendermint/issues/2598) Change `Type` field from `string` to `byte` and use new +- Blockchain Protocol + + - [crypto/tmhash] [\#2732](https://github.com/tendermint/tendermint/issues/2732) TMHASH is now full 32-byte SHA256 + - All hashes in the block header and Merkle trees are now 32-bytes + - PubKey Addresses are still only 20-bytes + - [state] [\#2587](https://github.com/tendermint/tendermint/issues/2587) Require block.Time of the fist block to be genesis time + - [state] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Require block.Version to match state.Version + - [types] Update SignBytes for `Vote`/`Proposal`/`Heartbeat`: + - [\#2459](https://github.com/tendermint/tendermint/issues/2459) Use amino encoding instead of JSON in `SignBytes`. + - [\#2598](https://github.com/tendermint/tendermint/issues/2598) Reorder fields and use fixed sized encoding. + - [\#2598](https://github.com/tendermint/tendermint/issues/2598) Change `Type` field from `string` to `byte` and use new `SignedMsgType` to enumerate. - * [types] [\#2730](https://github.com/tendermint/tendermint/issues/2730) Use + - [types] [\#2730](https://github.com/tendermint/tendermint/issues/2730) Use same order for fields in `Vote` as in the SignBytes - * [types] [\#2732](https://github.com/tendermint/tendermint/issues/2732) Remove the address field from the validator hash - * [types] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version struct to Header - * [types] [\#2609](https://github.com/tendermint/tendermint/issues/2609) ConsensusParams.Hash() is the hash of the amino encoded + - [types] [\#2732](https://github.com/tendermint/tendermint/issues/2732) Remove the address field from the validator hash + - [types] [\#2644](https://github.com/tendermint/tendermint/issues/2644) Add Version struct to Header + - [types] [\#2609](https://github.com/tendermint/tendermint/issues/2609) ConsensusParams.Hash() is the hash of the amino encoded struct instead of the Merkle tree of the fields - * [types] [\#2670](https://github.com/tendermint/tendermint/issues/2670) Header.Hash() builds Merkle tree out of fields in the same + - [types] [\#2670](https://github.com/tendermint/tendermint/issues/2670) Header.Hash() builds Merkle tree out of fields in the same order they appear in the header, instead of sorting by field name - * [types] [\#2682](https://github.com/tendermint/tendermint/issues/2682) Use proto3 `varint` encoding for ints that are usually unsigned (instead of zigzag encoding). - * [types] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Add Validator field to ConsensusParams - (Used to control which pubkey types validators can use, by abci type). + - [types] [\#2682](https://github.com/tendermint/tendermint/issues/2682) Use proto3 `varint` encoding for ints that are usually unsigned (instead of zigzag encoding). + - [types] [\#2636](https://github.com/tendermint/tendermint/issues/2636) Add Validator field to ConsensusParams + (Used to control which pubkey types validators can use, by abci type). -* P2P Protocol - * [consensus] [\#2652](https://github.com/tendermint/tendermint/issues/2652) +- P2P Protocol + - [consensus] [\#2652](https://github.com/tendermint/tendermint/issues/2652) Replace `CommitStepMessage` with `NewValidBlockMessage` - * [consensus] [\#2735](https://github.com/tendermint/tendermint/issues/2735) Simplify `Proposal` message to align with spec - * [consensus] [\#2730](https://github.com/tendermint/tendermint/issues/2730) + - [consensus] [\#2735](https://github.com/tendermint/tendermint/issues/2735) Simplify `Proposal` message to align with spec + - [consensus] [\#2730](https://github.com/tendermint/tendermint/issues/2730) Add `Type` field to `Proposal` and use same order of fields as in the SignBytes for both `Proposal` and `Vote` - * [p2p] [\#2654](https://github.com/tendermint/tendermint/issues/2654) Add `ProtocolVersion` struct with protocol versions to top of + - [p2p] [\#2654](https://github.com/tendermint/tendermint/issues/2654) Add `ProtocolVersion` struct with protocol versions to top of DefaultNodeInfo and require `ProtocolVersion.Block` to match during peer handshake - ### FEATURES: + - [abci] [\#2557](https://github.com/tendermint/tendermint/issues/2557) Add `Codespace` field to `Response{CheckTx, DeliverTx, Query}` - [abci] [\#2662](https://github.com/tendermint/tendermint/issues/2662) Add `BlockVersion` and `P2PVersion` to `RequestInfo` - [crypto/merkle] [\#2298](https://github.com/tendermint/tendermint/issues/2298) General Merkle Proof scheme for chaining various types of Merkle trees together - [docs/architecture] [\#1181](https://github.com/tendermint/tendermint/issues/1181) S -plit immutable and mutable parts of priv_validator.json + plit immutable and mutable parts of priv_validator.json ### IMPROVEMENTS: + - Additional Metrics - - [consensus] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) - - [p2p] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) + - [consensus] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) + - [p2p] [\#2169](https://github.com/cosmos/cosmos-sdk/issues/2169) - [config] [\#2232](https://github.com/tendermint/tendermint/issues/2232) Added ValidateBasic method, which performs basic checks - [crypto/ed25519] [\#2558](https://github.com/tendermint/tendermint/issues/2558) Switch to use latest `golang.org/x/crypto` through our fork at github.com/tendermint/crypto @@ -1299,6 +1482,7 @@ plit immutable and mutable parts of priv_validator.json - [tools] [\#2238](https://github.com/tendermint/tendermint/issues/2238) Binary dependencies are now locked to a specific git commit ### BUG FIXES: + - [\#2711](https://github.com/tendermint/tendermint/issues/2711) Validate all incoming reactor messages. Fixes various bugs due to negative ints. - [autofile] [\#2428](https://github.com/tendermint/tendermint/issues/2428) Group.RotateFile need call Flush() before rename (@goolAdapter) - [common] [\#2533](https://github.com/tendermint/tendermint/issues/2533) Fixed a bug in the `BitArray.Or` method @@ -1322,7 +1506,7 @@ plit immutable and mutable parts of priv_validator.json ## v0.25.0 -*September 22, 2018* +_September 22, 2018_ Special thanks to external contributors on this release: @scriptionist, @bradyjoestar, @WALL-E @@ -1336,26 +1520,29 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi BREAKING CHANGES: -* CLI/RPC/Config - * [rpc] [\#2391](https://github.com/tendermint/tendermint/issues/2391) /status `result.node_info.other` became a map - * [types] [\#2364](https://github.com/tendermint/tendermint/issues/2364) Remove `TxSize` and `BlockGossip` from `ConsensusParams` - * Maximum tx size is now set implicitly via the `BlockSize.MaxBytes` - * The size of block parts in the consensus is now fixed to 64kB +- CLI/RPC/Config -* Apps - * [mempool] [\#2360](https://github.com/tendermint/tendermint/issues/2360) Mempool tracks the `ResponseCheckTx.GasWanted` and + - [rpc] [\#2391](https://github.com/tendermint/tendermint/issues/2391) /status `result.node_info.other` became a map + - [types] [\#2364](https://github.com/tendermint/tendermint/issues/2364) Remove `TxSize` and `BlockGossip` from `ConsensusParams` + - Maximum tx size is now set implicitly via the `BlockSize.MaxBytes` + - The size of block parts in the consensus is now fixed to 64kB + +- Apps + + - [mempool] [\#2360](https://github.com/tendermint/tendermint/issues/2360) Mempool tracks the `ResponseCheckTx.GasWanted` and `ConsensusParams.BlockSize.MaxGas` and enforces: - `GasWanted <= MaxGas` for every tx - `(sum of GasWanted in block) <= MaxGas` for block proposal -* Go API - * [libs/common] [\#2431](https://github.com/tendermint/tendermint/issues/2431) Remove Word256 due to lack of use - * [libs/common] [\#2452](https://github.com/tendermint/tendermint/issues/2452) Remove the following functions due to lack of use: - * byteslice.go: cmn.IsZeros, cmn.RightPadBytes, cmn.LeftPadBytes, cmn.PrefixEndBytes - * strings.go: cmn.IsHex, cmn.StripHex - * int.go: Uint64Slice, all put/get int64 methods +- Go API + - [libs/common] [\#2431](https://github.com/tendermint/tendermint/issues/2431) Remove Word256 due to lack of use + - [libs/common] [\#2452](https://github.com/tendermint/tendermint/issues/2452) Remove the following functions due to lack of use: + - byteslice.go: cmn.IsZeros, cmn.RightPadBytes, cmn.LeftPadBytes, cmn.PrefixEndBytes + - strings.go: cmn.IsHex, cmn.StripHex + - int.go: Uint64Slice, all put/get int64 methods FEATURES: + - [rpc] [\#2415](https://github.com/tendermint/tendermint/issues/2415) New `/consensus_params?height=X` endpoint to query the consensus params at any height (@scriptonist) - [types] [\#1714](https://github.com/tendermint/tendermint/issues/1714) Add Address to GenesisValidator @@ -1363,12 +1550,14 @@ FEATURES: - [libs] [\#2286](https://github.com/tendermint/tendermint/issues/2286) Panic if `autofile` or `db/fsdb` permissions change from 0600. IMPROVEMENTS: + - [libs/db] [\#2371](https://github.com/tendermint/tendermint/issues/2371) Output error instead of panic when the given `db_backend` is not initialised (@bradyjoestar) - [mempool] [\#2399](https://github.com/tendermint/tendermint/issues/2399) Make mempool cache a proper LRU (@bradyjoestar) - [p2p] [\#2126](https://github.com/tendermint/tendermint/issues/2126) Introduce PeerTransport interface to improve isolation of concerns - [libs/common] [\#2326](https://github.com/tendermint/tendermint/issues/2326) Service returns ErrNotStarted BUG FIXES: + - [node] [\#2294](https://github.com/tendermint/tendermint/issues/2294) Delay starting node until Genesis time - [consensus] [\#2048](https://github.com/tendermint/tendermint/issues/2048) Correct peer statistics for marking peer as good - [rpc] [\#2460](https://github.com/tendermint/tendermint/issues/2460) StartHTTPAndTLSServer() now passes StartTLS() errors back to the caller rather than hanging forever. @@ -1377,7 +1566,7 @@ BUG FIXES: ## 0.24.0 -*September 6th, 2018* +_September 6th, 2018_ Special thanks to external contributors with PRs included in this release: ackratos, james-ray, bradyjoestar, peerlink, Ahmah2009, bluele, b00f. @@ -1404,12 +1593,14 @@ breaking](https://github.com/tendermint/tendermint/issues?q=is%3Aopen+is%3Aissue BREAKING CHANGES: -* CLI/RPC/Config +- CLI/RPC/Config + - [config] [\#2169](https://github.com/tendermint/tendermint/issues/2169) Replace MaxNumPeers with MaxNumInboundPeers and MaxNumOutboundPeers - [config] [\#2300](https://github.com/tendermint/tendermint/issues/2300) Reduce default mempool size from 100k to 5k, until ABCI rechecking is implemented. - [rpc] [\#1815](https://github.com/tendermint/tendermint/issues/1815) `/commit` returns a `signed_header` field instead of everything being top-level -* Apps +- Apps + - [abci] Added address of the original proposer of the block to Header - [abci] Change ABCI Header to match Tendermint exactly - [abci] [\#2159](https://github.com/tendermint/tendermint/issues/2159) Update use of `Validator` (see @@ -1421,7 +1612,8 @@ BREAKING CHANGES: - [state] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Validator set changes are now delayed by one block - updates returned in ResponseEndBlock for block H will be included in RequestBeginBlock for block H+2 -* Go API +- Go API + - [lite] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Complete refactor of the package - [node] [\#2212](https://github.com/tendermint/tendermint/issues/2212) NewNode now accepts a `*p2p.NodeKey` (@bradyjoestar) - [libs/common] [\#2199](https://github.com/tendermint/tendermint/issues/2199) Remove Fmt, in favor of fmt.Sprintf @@ -1431,7 +1623,8 @@ BREAKING CHANGES: - [libs/clist] Panics if list extends beyond MaxLength - [crypto] [\#2205](https://github.com/tendermint/tendermint/issues/2205) Rename AminoRoute variables to no longer be prefixed by signature type. -* Blockchain Protocol +- Blockchain Protocol + - [state] [\#1815](https://github.com/tendermint/tendermint/issues/1815) Validator set changes are now delayed by one block (!) - Add NextValidatorSet to State, changes on-disk representation of state - [state] [\#2184](https://github.com/tendermint/tendermint/issues/2184) Enforce ConsensusParams.BlockSize.MaxBytes (See @@ -1450,13 +1643,13 @@ BREAKING CHANGES: - format changed from DER to `r || s`, both little endian encoded as 32 bytes. - malleability removed by requiring `s` to be in canonical form. -* P2P Protocol +- P2P Protocol - [p2p] [\#2263](https://github.com/tendermint/tendermint/issues/2263) Update secret connection to use a little endian encoded nonce - [blockchain] [\#2213](https://github.com/tendermint/tendermint/issues/2213) Fix Amino routes for blockchain reactor messages (@peerlink) - FEATURES: + - [types] [\#2015](https://github.com/tendermint/tendermint/issues/2015) Allow genesis file to have 0 validators (@b00f) - Initial validator set can be determined by the app in ResponseInitChain - [rpc] [\#2161](https://github.com/tendermint/tendermint/issues/2161) New event `ValidatorSetUpdates` for when the validator set changes @@ -1464,6 +1657,7 @@ FEATURES: - [libs/db] [\#2293](https://github.com/tendermint/tendermint/issues/2293) Allow passing options through when creating instances of leveldb dbs IMPROVEMENTS: + - [docs] Lint documentation with `write-good` and `stop-words`. - [docs] [\#2249](https://github.com/tendermint/tendermint/issues/2249) Refactor, deduplicate, and improve the ABCI docs and spec (with thanks to @ttmc). - [scripts] [\#2196](https://github.com/tendermint/tendermint/issues/2196) Added json2wal tool, which is supposed to help our users restore (@bradyjoestar) @@ -1472,6 +1666,7 @@ IMPROVEMENTS: - [mempool] [\#2166](https://github.com/tendermint/tendermint/issues/2166) Set explicit capacity for map when updating txs (@bluele) BUG FIXES: + - [config] [\#2284](https://github.com/tendermint/tendermint/issues/2284) Replace `db_path` with `db_dir` from automatically generated configuration files. - [mempool] [\#2188](https://github.com/tendermint/tendermint/issues/2188) Fix OOM issue from cache map and list getting out of sync - [state] [\#2051](https://github.com/tendermint/tendermint/issues/2051) KV store index supports searching by `tx.height` (@ackratos) @@ -1481,15 +1676,16 @@ BUG FIXES: ## 0.23.1 -*August 22nd, 2018* +_August 22nd, 2018_ BUG FIXES: + - [libs/autofile] [\#2261](https://github.com/tendermint/tendermint/issues/2261) Fix log rotation so it actually happens. - - Fixes issues with consensus WAL growing unbounded ala [\#2259](https://github.com/tendermint/tendermint/issues/2259) + - Fixes issues with consensus WAL growing unbounded ala [\#2259](https://github.com/tendermint/tendermint/issues/2259) ## 0.23.0 -*August 5th, 2018* +_August 5th, 2018_ This release includes breaking upgrades in our P2P encryption, some ABCI messages, and how we encode time and signatures. @@ -1497,38 +1693,42 @@ some ABCI messages, and how we encode time and signatures. A few more changes are still coming to the Header, ABCI, and validator set handling to better support light clients, BFT time, and upgrades. Most notably, validator set changes will be delayed by one block (see -[#1815][i1815]). +[#1815] [i1815]). We also removed `make ensure_deps` in favour of `make get_vendor_deps`. BREAKING CHANGES: + - [abci] Changed time format from int64 to google.protobuf.Timestamp - [abci] Changed Validators to LastCommitInfo in RequestBeginBlock - [abci] Removed Fee from ResponseDeliverTx and ResponseCheckTx - [crypto] Switch crypto.Signature from interface to []byte for space efficiency [#2128](https://github.com/tendermint/tendermint/pull/2128) - - NOTE: this means signatures no longer have the prefix bytes in Amino - binary nor the `type` field in Amino JSON. They're just bytes. + - NOTE: this means signatures no longer have the prefix bytes in Amino + binary nor the `type` field in Amino JSON. They're just bytes. - [p2p] Remove salsa and ripemd primitives, in favor of using chacha as a stream cipher, and hkdf [#2054](https://github.com/tendermint/tendermint/pull/2054) - [tools] Removed `make ensure_deps` in favor of `make get_vendor_deps` - [types] CanonicalTime uses nanoseconds instead of clipping to ms - - breaks serialization/signing of all messages with a timestamp + - breaks serialization/signing of all messages with a timestamp FEATURES: + - [tools] Added `make check_dep` - - ensures gopkg.lock is synced with gopkg.toml - - ensures no branches are used in the gopkg.toml + - ensures gopkg.lock is synced with gopkg.toml + - ensures no branches are used in the gopkg.toml IMPROVEMENTS: + - [blockchain] Improve fast-sync logic [#1805](https://github.com/tendermint/tendermint/pull/1805) - - tweak params - - only process one block at a time to avoid starving + - tweak params + - only process one block at a time to avoid starving - [common] bit array functions which take in another parameter are now thread safe - [crypto] Switch hkdfchachapoly1305 to xchachapoly1305 - [p2p] begin connecting to peers as soon a seed node provides them to you ([#2093](https://github.com/tendermint/tendermint/issues/2093)) BUG FIXES: + - [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) - [privval] fix a deadline for accepting new connections in socket private validator. @@ -1539,7 +1739,7 @@ BUG FIXES: ## 0.22.8 -*July 26th, 2018* +_July 26th, 2018_ BUG FIXES @@ -1547,7 +1747,7 @@ BUG FIXES ## 0.22.7 -*July 26th, 2018* +_July 26th, 2018_ BUG FIXES @@ -1556,35 +1756,38 @@ BUG FIXES ## 0.22.6 -*July 24th, 2018* +_July 24th, 2018_ BUG FIXES - [rpc] Fix `/blockchain` endpoint - - (#2049) Fix OOM attack by returning error on negative input - - Fix result length to have max 20 (instead of 21) block metas + - (#2049) Fix OOM attack by returning error on negative input + - Fix result length to have max 20 (instead of 21) block metas - [rpc] Validate height is non-negative in `/abci_query` -- [consensus] (#2050) Include evidence in proposal block parts (previously evidence was +- [consensus](#2050) Include evidence in proposal block parts (previously evidence was not being included in blocks!) -- [p2p] (#2046) Close rejected inbound connections so file descriptor doesn't +- [p2p](#2046) Close rejected inbound connections so file descriptor doesn't leak -- [Gopkg] (#2053) Fix versions in the toml +- [Gopkg](#2053) Fix versions in the toml ## 0.22.5 -*July 23th, 2018* +_July 23th, 2018_ BREAKING CHANGES: + - [crypto] Refactor `tendermint/crypto` into many subpackages - [libs/common] remove exponentially distributed random numbers IMPROVEMENTS: + - [abci, libs/common] Generated gogoproto static marshaller methods - [config] Increase default send/recv rates to 5 mB/s - [p2p] reject addresses coming from private peers - [p2p] allow persistent peers to be private BUG FIXES: + - [mempool] fixed a race condition when `create_empty_blocks=false` where a transaction is published at an old height. - [p2p] dial external IP setup by `persistent_peers`, not internal NAT IP @@ -1592,16 +1795,19 @@ BUG FIXES: ## 0.22.4 -*July 14th, 2018* +_July 14th, 2018_ BREAKING CHANGES: + - [genesis] removed deprecated `app_options` field. - [types] Genesis.AppStateJSON -> Genesis.AppState FEATURES: + - [tools] Merged in from github.com/tendermint/tools BUG FIXES: + - [tools/tm-bench] Various fixes - [consensus] Wait for WAL to stop on shutdown - [abci] Fix #1891, pending requests cannot hang when abci server dies. @@ -1609,71 +1815,74 @@ BUG FIXES: ## 0.22.3 -*July 10th, 2018* +_July 10th, 2018_ IMPROVEMENTS + - Update dependencies - * pin all values in Gopkg.toml to version or commit - * update golang/protobuf to v1.1.0 + - pin all values in Gopkg.toml to version or commit + - update golang/protobuf to v1.1.0 ## 0.22.2 -*July 10th, 2018* +_July 10th, 2018_ IMPROVEMENTS + - More cleanup post repo merge! - [docs] Include `ecosystem.json` and `tendermint-bft.md` from deprecated `aib-data` repository. - [config] Add `instrumentation.max_open_connections`, which limits the number of requests in flight to Prometheus server (if enabled). Default: 3. - BUG FIXES + - [rpc] Allow unquoted integers in requests - - NOTE: this is only for URI requests. JSONRPC requests and all responses - will use quoted integers (the proto3 JSON standard). + - NOTE: this is only for URI requests. JSONRPC requests and all responses + will use quoted integers (the proto3 JSON standard). - [consensus] Fix halt on shutdown ## 0.22.1 -*July 5th, 2018* +_July 5th, 2018_ IMPROVEMENTS -* Cleanup post repo-merge. -* [docs] Various improvements. +- Cleanup post repo-merge. +- [docs] Various improvements. BUG FIXES -* [state] Return error when EndBlock returns a 0-power validator that isn't +- [state] Return error when EndBlock returns a 0-power validator that isn't already in the validator set. -* [consensus] Shut down WAL properly. - +- [consensus] Shut down WAL properly. ## 0.22.0 -*July 2nd, 2018* +_July 2nd, 2018_ BREAKING CHANGES: + - [config] - * Remove `max_block_size_txs` and `max_block_size_bytes` in favor of - consensus params from the genesis file. - * Rename `skip_upnp` to `upnp`, and turn it off by default. - * Change `max_packet_msg_size` back to `max_packet_msg_payload_size` + - Remove `max_block_size_txs` and `max_block_size_bytes` in favor of + consensus params from the genesis file. + - Rename `skip_upnp` to `upnp`, and turn it off by default. + - Change `max_packet_msg_size` back to `max_packet_msg_payload_size` - [rpc] - * All integers are encoded as strings (part of the update for Amino v0.10.1) - * `syncing` is now called `catching_up` + - All integers are encoded as strings (part of the update for Amino v0.10.1) + - `syncing` is now called `catching_up` - [types] Update Amino to v0.10.1 - * Amino is now fully proto3 compatible for the basic types - * JSON-encoded types now use the type name instead of the prefix bytes - * Integers are encoded as strings + - Amino is now fully proto3 compatible for the basic types + - JSON-encoded types now use the type name instead of the prefix bytes + - Integers are encoded as strings - [crypto] Update go-crypto to v0.10.0 and merge into `crypto` - * privKey.Sign returns error. - * ed25519 address changed to the first 20-bytes of the SHA256 of the raw pubkey bytes - * `tmlibs/merkle` -> `crypto/merkle`. Uses SHA256 instead of RIPEMD160 + - privKey.Sign returns error. + - ed25519 address changed to the first 20-bytes of the SHA256 of the raw pubkey bytes + - `tmlibs/merkle` -> `crypto/merkle`. Uses SHA256 instead of RIPEMD160 - [tmlibs] Update to v0.9.0 and merge into `libs` - * remove `merkle` package (moved to `crypto/merkle`) + - remove `merkle` package (moved to `crypto/merkle`) FEATURES + - [cmd] Added metrics (served under `/metrics` using a Prometheus client; disabled by default). See the new `instrumentation` section in the config and [metrics](https://tendermint.readthedocs.io/projects/tools/en/develop/metrics.html) @@ -1683,6 +1892,7 @@ FEATURES peers to dial IMPROVEMENT + - [rpc/client] Supports https and wss now. - [crypto] Make public key size into public constants - [mempool] Log tx hash, not entire tx @@ -1692,6 +1902,7 @@ IMPROVEMENT - [docs] Move from .rst to .md BUG FIXES: + - [rpc] Limit maximum number of HTTP/WebSocket connections (`rpc.max_open_connections`) and gRPC connections (`rpc.grpc_max_open_connections`). Check out "Running In Production" guide if @@ -1702,7 +1913,7 @@ BUG FIXES: ## 0.21.0 -*June 21th, 2018* +_June 21th, 2018_ BREAKING CHANGES @@ -1724,7 +1935,7 @@ BUG FIXES ## 0.20.0 -*June 6th, 2018* +_June 6th, 2018_ This is the first in a series of breaking releases coming to Tendermint after soliciting developer feedback and conducting security audits. @@ -1744,7 +1955,7 @@ BREAKING CHANGES ## 0.19.9 -*June 5th, 2018* +_June 5th, 2018_ BREAKING CHANGES @@ -1766,7 +1977,7 @@ BUG FIXES ## 0.19.8 -*June 4th, 2018* +_June 4th, 2018_ BREAKING: @@ -1781,7 +1992,7 @@ BUG FIXES ## 0.19.7 -*May 31st, 2018* +_May 31st, 2018_ BREAKING: @@ -1792,7 +2003,7 @@ FEATURES - [rpc] the RPC documentation is now published to https://tendermint.github.io/slate - [p2p] AllowDuplicateIP config option to refuse connections from same IP. - - true by default for now, false by default in next breaking release + - true by default for now, false by default in next breaking release - [docs] Add docs for query, tx indexing, events, pubsub - [docs] Add some notes about running Tendermint in production @@ -1805,7 +2016,7 @@ IMPROVEMENTS: ## 0.19.6 -*May 29th, 2018* +_May 29th, 2018_ BUG FIXES @@ -1819,7 +2030,7 @@ BUG FIX: ## 0.19.5 -*May 20th, 2018* +_May 20th, 2018_ BREAKING CHANGES @@ -1923,6 +2134,7 @@ Some of these are breaking in the RPC response, but they're really bugs! ## 0.19.0 (April 13th, 2018) BREAKING: + - [cmd] improved `testnet` command; now it can fill in `persistent_peers` for you in the config file and much more (see `tendermint testnet --help` for details) - [cmd] `show_node_id` now returns an error if there is no node key - [rpc]: changed the output format for the `/status` endpoint (see https://godoc.org/github.com/tendermint/tendermint/rpc/core#Status) @@ -1956,12 +2168,14 @@ FEATURES: - [rpc] Include peer NodeIDs in `/net_info` IMPROVEMENTS: + - [config] trim whitespace from elements of lists (like `persistent_peers`) - [rpc] `/tx_search` results are sorted by height - [p2p] do not try to connect to ourselves (ok, maybe only once) - [p2p] seeds respond with a bias towards good peers BUG FIXES: + - [rpc] fix subscribing using an abci.ResponseDeliverTx tag - [rpc] fix tx_indexers matchRange - [rpc] fix unsubscribing (see tmlibs v0.8.0) @@ -1969,14 +2183,17 @@ BUG FIXES: ## 0.17.1 (March 27th, 2018) BUG FIXES: + - [types] Actually support `app_state` in genesis as `AppStateJSON` ## 0.17.0 (March 27th, 2018) BREAKING: + - [types] WriteSignBytes -> SignBytes IMPROVEMENTS: + - [all] renamed `dummy` (`persistent_dummy`) to `kvstore` (`persistent_kvstore`) (name "dummy" is deprecated and will not work in the next breaking release) - [docs] note on determinism (docs/determinism.rst) - [genesis] `app_options` field is deprecated. please rename it to `app_state` in your genesis file(s). `app_options` will not work in the next breaking release @@ -1990,27 +2207,31 @@ IMPROVEMENTS: - [wire] prep work for upgrading to new go-wire (which is now called go-amino) FEATURES: + - [config] exposed `auth_enc` flag to enable/disable encryption - [config] added the `--p2p.private_peer_ids` flag and `PrivatePeerIDs` config variable (see config for description) - [rpc] added `/health` endpoint, which returns empty result for now - [types/priv_validator] new format and socket client, allowing for remote signing BUG FIXES: + - [consensus] fix liveness bug by introducing ValidBlock mechanism ## 0.16.0 (February 20th, 2018) BREAKING CHANGES: -- [config] use $TMHOME/config for all config and json files + +- [config] use \$TMHOME/config for all config and json files - [p2p] old `--p2p.seeds` is now `--p2p.persistent_peers` (persistent peers to which TM will always connect to) - [p2p] now `--p2p.seeds` only used for getting addresses (if addrbook is empty; not persistent) - [p2p] NodeInfo: remove RemoteAddr and add Channels - - we must have at least one overlapping channel with peer - - we only send msgs for channels the peer advertised + - we must have at least one overlapping channel with peer + - we only send msgs for channels the peer advertised - [p2p/conn] pong timeout - [lite] comment out IAVL related code FEATURES: + - [p2p] added new `/dial_peers&persistent=_` **unsafe** endpoint - [p2p] persistent node key in `$THMHOME/config/node_key.json` - [p2p] introduce peer ID and authenticate peers by ID using addresses like `ID@IP:PORT` @@ -2019,12 +2240,14 @@ FEATURES: - [config] P2P.SeedMode (`--p2p.seed_mode`) IMPROVEMENT: + - [p2p/pex] stricter rules in the PEX reactor for better handling of abuse - [p2p] various improvements to code structure including subpackages for `pex` and `conn` - [docs] new spec! - [all] speed up the tests! BUG FIX: + - [blockchain] StopPeerForError on timeout - [consensus] StopPeerForError on a bad Maj23 message - [state] flush mempool conn before calling commit @@ -2035,6 +2258,7 @@ BUG FIX: ## 0.15.0 (December 29, 2017) BREAKING CHANGES: + - [p2p] enable the Peer Exchange reactor by default - [types] add Timestamp field to Proposal/Vote - [types] add new fields to Header: TotalTxs, ConsensusParamsHash, LastResultsHash, EvidenceHash @@ -2044,6 +2268,7 @@ BREAKING CHANGES: - [state] Enforce <1/3 of validator set can change at a time FEATURES: + - [state] Send indices of absent validators and addresses of byzantine validators in BeginBlock - [state] Historical ConsensusParams and ABCIResponses - [docs] Specification for the base Tendermint data structures. @@ -2051,9 +2276,11 @@ FEATURES: - [rpc] `/block_results?height=X` returns the DeliverTx results for a given height. IMPROVEMENTS: + - [consensus] Better handling of corrupt WAL file BUG FIXES: + - [lite] fix race - [state] validate block.Header.ValidatorsHash - [p2p] allow seed addresses to be prefixed with eg. `tcp://` @@ -2063,24 +2290,29 @@ BUG FIXES: ## 0.14.0 (December 11, 2017) BREAKING CHANGES: + - consensus/wal: removed separator - rpc/client: changed Subscribe/Unsubscribe/UnsubscribeAll funcs signatures to be identical to event bus. FEATURES: + - new `tendermint lite` command (and `lite/proxy` pkg) for running a light-client RPC proxy. - NOTE it is currently insecure and its APIs are not yet covered by semver + NOTE it is currently insecure and its APIs are not yet covered by semver IMPROVEMENTS: + - rpc/client: can act as event bus subscriber (See https://github.com/tendermint/tendermint/issues/945). - p2p: use exponential backoff from seconds to hours when attempting to reconnect to persistent peer - config: moniker defaults to the machine's hostname instead of "anonymous" BUG FIXES: + - p2p: no longer exit if one of the seed addresses is incorrect ## 0.13.0 (December 6, 2017) BREAKING CHANGES: + - abci: update to v0.8 using gogo/protobuf; includes tx tags, vote info in RequestBeginBlock, data.Bytes everywhere, use int64, etc. - types: block heights are now `int64` everywhere - types & node: EventSwitch and EventCache have been replaced by EventBus and EventBuffer; event types have been overhauled @@ -2094,12 +2326,14 @@ BREAKING CHANGES: - mempool: cached transactions return an error instead of an ABCI response with BadNonce FEATURES: + - rpc: new `/unsubscribe_all` WebSocket RPC endpoint - rpc: new `/tx_search` endpoint for filtering transactions by more complex queries - p2p/trust: new trust metric for tracking peers. See ADR-006 - config: TxIndexConfig allows to set what DeliverTx tags to index IMPROVEMENTS: + - New asynchronous events system using `tmlibs/pubsub` - logging: Various small improvements - consensus: Graceful shutdown when app crashes @@ -2107,86 +2341,101 @@ IMPROVEMENTS: - p2p: more defensive programming BUG FIXES: + - consensus: fix panic where prs.ProposalBlockParts is not initialized - p2p: fix panic on bad channel ## 0.12.1 (November 27, 2017) BUG FIXES: + - upgrade tmlibs dependency to enable Windows builds for Tendermint ## 0.12.0 (October 27, 2017) BREAKING CHANGES: - - rpc/client: websocket ResultsCh and ErrorsCh unified in ResponsesCh. - - rpc/client: ABCIQuery no longer takes `prove` - - state: remove GenesisDoc from state. - - consensus: new binary WAL format provides efficiency and uses checksums to detect corruption - - use scripts/wal2json to convert to json for debugging + +- rpc/client: websocket ResultsCh and ErrorsCh unified in ResponsesCh. +- rpc/client: ABCIQuery no longer takes `prove` +- state: remove GenesisDoc from state. +- consensus: new binary WAL format provides efficiency and uses checksums to detect corruption + - use scripts/wal2json to convert to json for debugging FEATURES: - - new `Verifiers` pkg contains the tendermint light-client library (name subject to change)! - - rpc: `/genesis` includes the `app_options` . - - rpc: `/abci_query` takes an additional `height` parameter to support historical queries. - - rpc/client: new ABCIQueryWithOptions supports options like `trusted` (set false to get a proof) and `height` to query a historical height. + +- new `Verifiers` pkg contains the tendermint light-client library (name subject to change)! +- rpc: `/genesis` includes the `app_options` . +- rpc: `/abci_query` takes an additional `height` parameter to support historical queries. +- rpc/client: new ABCIQueryWithOptions supports options like `trusted` (set false to get a proof) and `height` to query a historical height. IMPROVEMENTS: - - rpc: `/genesis` result includes `app_options` - - rpc/lib/client: add jitter to reconnects. - - rpc/lib/types: `RPCError` satisfies the `error` interface. + +- rpc: `/genesis` result includes `app_options` +- rpc/lib/client: add jitter to reconnects. +- rpc/lib/types: `RPCError` satisfies the `error` interface. BUG FIXES: - - rpc/client: fix ws deadlock after stopping - - blockchain: fix panic on AddBlock when peer is nil - - mempool: fix sending on TxsAvailable when a tx has been invalidated - - consensus: dont run WAL catchup if we fast synced + +- rpc/client: fix ws deadlock after stopping +- blockchain: fix panic on AddBlock when peer is nil +- mempool: fix sending on TxsAvailable when a tx has been invalidated +- consensus: dont run WAL catchup if we fast synced ## 0.11.1 (October 10, 2017) IMPROVEMENTS: - - blockchain/reactor: respondWithNoResponseMessage for missing height + +- blockchain/reactor: respondWithNoResponseMessage for missing height BUG FIXES: - - rpc: fixed client WebSocket timeout - - rpc: client now resubscribes on reconnection - - rpc: fix panics on missing params - - rpc: fix `/dump_consensus_state` to have normal json output (NOTE: technically breaking, but worth a bug fix label) - - types: fixed out of range error in VoteSet.addVote - - consensus: fix wal autofile via https://github.com/tendermint/tmlibs/blob/master/CHANGELOG.md#032-october-2-2017 + +- rpc: fixed client WebSocket timeout +- rpc: client now resubscribes on reconnection +- rpc: fix panics on missing params +- rpc: fix `/dump_consensus_state` to have normal json output (NOTE: technically breaking, but worth a bug fix label) +- types: fixed out of range error in VoteSet.addVote +- consensus: fix wal autofile via https://github.com/tendermint/tmlibs/blob/master/CHANGELOG.md#032-october-2-2017 ## 0.11.0 (September 22, 2017) BREAKING: - - genesis file: validator `amount` is now `power` - - abci: Info, BeginBlock, InitChain all take structs - - rpc: various changes to match JSONRPC spec (http://www.jsonrpc.org/specification), including breaking ones: - - requests that previously returned HTTP code 4XX now return 200 with an error code in the JSONRPC. - - `rpctypes.RPCResponse` uses new `RPCError` type instead of `string`. - - cmd: if there is no genesis, exit immediately instead of waiting around for one to show. - - types: `Signer.Sign` returns an error. - - state: every validator set change is persisted to disk, which required some changes to the `State` structure. - - p2p: new `p2p.Peer` interface used for all reactor methods (instead of `*p2p.Peer` struct). +- genesis file: validator `amount` is now `power` +- abci: Info, BeginBlock, InitChain all take structs +- rpc: various changes to match JSONRPC spec (http://www.jsonrpc.org/specification), including breaking ones: + + - requests that previously returned HTTP code 4XX now return 200 with an error code in the JSONRPC. + - `rpctypes.RPCResponse` uses new `RPCError` type instead of `string`. + +- cmd: if there is no genesis, exit immediately instead of waiting around for one to show. +- types: `Signer.Sign` returns an error. +- state: every validator set change is persisted to disk, which required some changes to the `State` structure. +- p2p: new `p2p.Peer` interface used for all reactor methods (instead of `*p2p.Peer` struct). FEATURES: - - rpc: `/validators?height=X` allows querying of validators at previous heights. - - rpc: Leaving the `height` param empty for `/block`, `/validators`, and `/commit` will return the value for the latest height. + +- rpc: `/validators?height=X` allows querying of validators at previous heights. +- rpc: Leaving the `height` param empty for `/block`, `/validators`, and `/commit` will return the value for the latest height. IMPROVEMENTS: - - docs: Moved all docs from the website and tools repo in, converted to `.rst`, and cleaned up for presentation on `tendermint.readthedocs.io` + +- docs: Moved all docs from the website and tools repo in, converted to `.rst`, and cleaned up for presentation on `tendermint.readthedocs.io` BUG FIXES: - - fix WAL openning issue on Windows + +- fix WAL openning issue on Windows ## 0.10.4 (September 5, 2017) IMPROVEMENTS: + - docs: Added Slate docs to each rpc function (see rpc/core) - docs: Ported all website docs to Read The Docs - config: expose some p2p params to tweak performance: RecvRate, SendRate, and MaxMsgPacketPayloadSize - rpc: Upgrade the websocket client and server, including improved auto reconnect, and proper ping/pong BUG FIXES: + - consensus: fix panic on getVoteBitArray - consensus: hang instead of panicking on byzantine consensus failures - cmd: dont load config for version command @@ -2194,6 +2443,7 @@ BUG FIXES: ## 0.10.3 (August 10, 2017) FEATURES: + - control over empty block production: - new flag, `--consensus.create_empty_blocks`; when set to false, blocks are only created when there are txs or when the AppHash changes. - new config option, `consensus.create_empty_blocks_interval`; an empty block is created after this many seconds. @@ -2203,17 +2453,21 @@ FEATURES: - rpc: Add `syncing` field to response returned by `/status`. Is `true` while in fast-sync mode. IMPROVEMENTS: + - various improvements to documentation and code comments BUG FIXES: + - mempool: pass height into constructor so it doesn't always start at 0 ## 0.10.2 (July 10, 2017) FEATURES: + - Enable lower latency block commits by adding consensus reactor sleep durations and p2p flush throttle timeout to the config IMPROVEMENTS: + - More detailed logging in the consensus reactor and state machine - More in-code documentation for many exposed functions, especially in consensus/reactor.go and p2p/switch.go - Improved readability for some function definitions and code blocks with long lines @@ -2221,11 +2475,13 @@ IMPROVEMENTS: ## 0.10.1 (June 28, 2017) FEATURES: + - Use `--trace` to get stack traces for logged errors - types: GenesisDoc.ValidatorHash returns the hash of the genesis validator set - types: GenesisDocFromFile parses a GenesiDoc from a JSON file IMPROVEMENTS: + - Add a Code of Conduct - Variety of improvements as suggested by `megacheck` tool - rpc: deduplicate tests between rpc/client and rpc/tests @@ -2234,6 +2490,7 @@ IMPROVEMENTS: - DOCKER: automate build/push BUG FIXES: + - Fix log statements using keys with spaces (logger does not currently support spaces) - rpc: set logger on websocket connection - rpc: fix ws connection stability by setting write deadline on pings @@ -2246,8 +2503,9 @@ Also includes the Grand Repo-Merge of 2017. BREAKING CHANGES: - Config and Flags: + - The `config` map is replaced with a [`Config` struct](https://github.com/tendermint/tendermint/blob/master/config/config.go#L11), -containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusConfig`, `RPCConfig` + containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusConfig`, `RPCConfig` - This affects the following flags: - `--seeds` is now `--p2p.seeds` - `--node_laddr` is now `--p2p.laddr` @@ -2256,6 +2514,7 @@ containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusCon - `--rpc_laddr` is now `--rpc.laddr` - `--grpc_laddr` is now `--rpc.grpc_laddr` - Any configuration option now within a substract must come under that heading in the `config.toml`, for instance: + ``` [p2p] laddr="tcp://1.2.3.4:46656" @@ -2263,17 +2522,20 @@ containing substructs: `BaseConfig`, `P2PConfig`, `MempoolConfig`, `ConsensusCon [consensus] timeout_propose=1000 ``` + - Use viper and `DefaultConfig() / TestConfig()` functions to handle defaults, and remove `config/tendermint` and `config/tendermint_test` - Change some function and method signatures to - Change some [function and method signatures](https://gist.github.com/ebuchman/640d5fc6c2605f73497992fe107ebe0b) accomodate new config - Logger + - Replace static `log15` logger with a simple interface, and provide a new implementation using `go-kit`. -See our new [logging library](https://github.com/tendermint/tmlibs/log) and [blog post](https://tendermint.com/blog/abstracting-the-logger-interface-in-go) for more details + See our new [logging library](https://github.com/tendermint/tmlibs/log) and [blog post](https://tendermint.com/blog/abstracting-the-logger-interface-in-go) for more details - Levels `warn` and `notice` are removed (you may need to change them in your `config.toml`!) - Change some [function and method signatures](https://gist.github.com/ebuchman/640d5fc6c2605f73497992fe107ebe0b) to accept a logger - JSON serialization: + - Replace `[TypeByte, Xxx]` with `{"type": "some-type", "data": Xxx}` in RPC and all `.json` files by using `go-wire/data`. For instance, a public key is now: ``` "pub_key": { @@ -2291,7 +2553,6 @@ See our new [logging library](https://github.com/tendermint/tmlibs/log) and [blo - Do not include the `Accum` field when computing the validator hash. This makes the ValidatorSetHash unique for a given validator set, rather than changing with every block (as the Accum changes) - Unsafe RPC calls are not enabled by default. This includes `/dial_seeds`, and all calls prefixed with `unsafe`. Use the `--rpc.unsafe` flag to enable. - FEATURES: - Per-module log levels. For instance, the new default is `state:info,*:error`, which means the `state` package logs at `info` level, and everything else logs at `error` level @@ -2314,7 +2575,6 @@ IMPROVEMENTS: - Color code different instances of the consensus for tests - Isolate viper to `cmd/tendermint/commands` and do not read config from file for tests - ## 0.9.2 (April 26, 2017) BUG FIXES: @@ -2369,7 +2629,6 @@ message ResponseQuery{ } ``` - - `BlockMeta` data type unifies its Hash and PartSetHash under a `BlockID`: ``` @@ -2408,7 +2667,6 @@ BUG FIXES: - Fix proposer selection logic in ValidatorSet by taking the address into account in the `accumComparable` - Fix inconcistencies with `ValidatorSet.Proposer` across restarts by persisting it in the `State` - ## 0.8.0 (January 13, 2017) BREAKING CHANGES: @@ -2439,11 +2697,10 @@ type Vote struct { - Update TMSP to v0.3.0, where it is now called ABCI and AppendTx is DeliverTx - Hex strings in the RPC are now "0x" prefixed - FEATURES: - New message type on the ConsensusReactor, `Maj23Msg`, for peers to alert others they've seen a Maj23, -in order to track and handle conflicting votes intelligently to prevent Byzantine faults from causing halts: + in order to track and handle conflicting votes intelligently to prevent Byzantine faults from causing halts: ``` type VoteSetMaj23Message struct { @@ -2478,7 +2735,6 @@ BUG FIXES: - Actually send BeginBlock message - Fix a liveness issues caused by Byzantine proposals/votes. Uses the new `Maj23Msg`. - ## 0.7.4 (December 14, 2016) FEATURES: @@ -2514,9 +2770,7 @@ BUG FIXES: FEATURES: - New TMSP connection for Query/Info -- New RPC endpoints: - - `tmsp_query` - - `tmsp_info` +- New RPC endpoints: - `tmsp_query` - `tmsp_info` - Allow application to filter peers through Query (off by default) IMPROVEMENTS: @@ -2539,17 +2793,12 @@ BREAKING CHANGES: - Validation types now called Commit - NewBlock event only returns the block header - FEATURES: - TMSP and RPC support TCP and UNIX sockets - Addition config options including block size and consensus parameters - New WAL mode `cswal_light`; logs only the validator's own votes -- New RPC endpoints: - - for starting/stopping profilers, and for updating config - - `/broadcast_tx_commit`, returns when tx is included in a block, else an error - - `/unsafe_flush_mempool`, empties the mempool - +- New RPC endpoints: - for starting/stopping profilers, and for updating config - `/broadcast_tx_commit`, returns when tx is included in a block, else an error - `/unsafe_flush_mempool`, empties the mempool IMPROVEMENTS: @@ -2566,7 +2815,7 @@ BUG FIXES: Strict versioning only began with the release of v0.7.0, in late summer 2016. The project itself began in early summer 2014 and was workable decentralized cryptocurrency software by the end of that year. -Through the course of 2015, in collaboration with Eris Industries (now Monax Indsutries), +Through the course of 2015, in collaboration with Eris Industries (now Monax Industries), many additional features were integrated, including an implementation from scratch of the Ethereum Virtual Machine. That implementation now forms the heart of [Burrow](https://github.com/hyperledger/burrow). In the later half of 2015, the consensus algorithm was upgraded with a more asynchronous design and a more deterministic and robust implementation. diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 126633cfe..a1e632678 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -1,4 +1,4 @@ -## v0.32.8 +## v0.32.9 \*\* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1b9ea4409..8b0f32be9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -185,7 +185,7 @@ includes its continuous integration status using a badge in the `README.md`. ### RPC Testing -If you contribute to the RPC endpoints it's important to document your changes in the [Swagger file](./docs/spec/rpc/swagger.yaml) +If you contribute to the RPC endpoints it's important to document your changes in the [Swagger file](./rpc/swagger/swagger.yaml) To test your changes you should install `nodejs` and run: ```bash diff --git a/DOCKER/Dockerfile b/DOCKER/Dockerfile index 6a7f289f5..c3c186e05 100644 --- a/DOCKER/Dockerfile +++ b/DOCKER/Dockerfile @@ -36,4 +36,3 @@ STOPSIGNAL SIGTERM ARG BINARY=tendermint COPY $BINARY /usr/bin/tendermint - diff --git a/DOCKER/Dockerfile.abci b/DOCKER/Dockerfile.abci deleted file mode 100644 index 52a3d9e0b..000000000 --- a/DOCKER/Dockerfile.abci +++ /dev/null @@ -1,23 +0,0 @@ -FROM golang:latest - -RUN mkdir -p /go/src/github.com/tendermint/abci -WORKDIR /go/src/github.com/tendermint/abci - -COPY Makefile /go/src/github.com/tendermint/abci/ - -# see make protoc for details on ldconfig -RUN make get_protoc && ldconfig - -# killall is used in tests -RUN apt-get update && apt-get install -y \ - psmisc \ - && rm -rf /var/lib/apt/lists/* - -COPY Gopkg.toml /go/src/github.com/tendermint/abci/ -COPY Gopkg.lock /go/src/github.com/tendermint/abci/ -RUN make tools - -# see https://github.com/golang/dep/issues/1312 -RUN dep ensure -vendor-only - -COPY . /go/src/github.com/tendermint/abci diff --git a/DOCKER/Dockerfile.testing b/DOCKER/Dockerfile.testing index a658aeb10..7f86ee180 100644 --- a/DOCKER/Dockerfile.testing +++ b/DOCKER/Dockerfile.testing @@ -1,5 +1,4 @@ -FROM golang:1.12 - +FROM golang:latest # Grab deps (jq, hexdump, xxd, killall) RUN apt-get update && \ @@ -15,4 +14,3 @@ VOLUME /go EXPOSE 26656 EXPOSE 26657 - diff --git a/DOCKER/Makefile b/DOCKER/Makefile index 41fb60ac8..8f6dff372 100644 --- a/DOCKER/Makefile +++ b/DOCKER/Makefile @@ -4,16 +4,10 @@ build: push: @sh -c "'$(CURDIR)/push.sh'" -build_develop: - docker build -t "tendermint/tendermint:develop" -f Dockerfile.develop . - build_testing: docker build --tag tendermint/testing -f ./Dockerfile.testing . -push_develop: - docker push "tendermint/tendermint:develop" - build_amazonlinux_buildimage: docker build -t "tendermint/tendermint:build_c-amazonlinux" -f Dockerfile.build_c-amazonlinux . -.PHONY: build build_develop push push_develop +.PHONY: build push build_testing build_amazonlinux_buildimage diff --git a/DOCKER/README.md b/DOCKER/README.md index 57e631aaa..775922248 100644 --- a/DOCKER/README.md +++ b/DOCKER/README.md @@ -2,27 +2,19 @@ ## Supported tags and respective `Dockerfile` links -- `0.17.1`, `latest` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/208ac32fa266657bd6c304e84ec828aa252bb0b8/DOCKER/Dockerfile) -- `0.15.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/170777300ea92dc21a8aec1abc16cb51812513a4/DOCKER/Dockerfile) -- `0.13.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/a28b3fff49dce2fb31f90abb2fc693834e0029c2/DOCKER/Dockerfile) -- `0.12.1` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/457c688346b565e90735431619ca3ca597ef9007/DOCKER/Dockerfile) -- `0.12.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/70d8afa6e952e24c573ece345560a5971bf2cc0e/DOCKER/Dockerfile) -- `0.11.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/9177cc1f64ca88a4a0243c5d1773d10fba67e201/DOCKER/Dockerfile) -- `0.10.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/e5342f4054ab784b2cd6150e14f01053d7c8deb2/DOCKER/Dockerfile) -- `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) -- `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) -- `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) +DockerHub tags for official releases are [here](https://hub.docker.com/r/tendermint/tendermint/tags/). The "latest" tag will always point to the highest version number. + +Official releases can be found [here](https://github.com/tendermint/tendermint/releases). + +The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/master/DOCKER/Dockerfile). + +Respective versioned files can be found https://raw.githubusercontent.com/tendermint/tendermint/vX.XX.XX/DOCKER/Dockerfile (replace the Xs with the version number). ## Quick reference -- **Where to get help:** - [cosmos.network/ecosystem](https://cosmos.network/ecosystem) - -- **Where to file issues:** - [Tendermint Issues](https://github.com/tendermint/tendermint/issues) - -- **Supported Docker versions:** - [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis) +- **Where to get help:** https://tendermint.com/ +- **Where to file issues:** https://github.com/tendermint/tendermint/issues +- **Supported Docker versions:** [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis) ## Tendermint diff --git a/Makefile b/Makefile index e7937cfc6..472b3a0ea 100644 --- a/Makefile +++ b/Makefile @@ -153,6 +153,26 @@ lint: DESTINATION = ./index.html.md +########################################################### +### Documentation + +build-docs: + cd docs && \ + while read p; do \ + (git checkout $${p} && npm install && VUEPRESS_BASE="/$${p}/" npm run build) ; \ + mkdir -p ~/output/$${p} ; \ + cp -r .vuepress/dist/* ~/output/$${p}/ ; \ + cp ~/output/$${p}/index.html ~/output ; \ + done < versions ; + +sync-docs: + cd ~/output && \ + echo "role_arn = ${DEPLOYMENT_ROLE_ARN}" >> /root/.aws/config ; \ + echo "CI job = ${CIRCLE_BUILD_URL}" >> version.html ; \ + aws s3 sync . s3://${WEBSITE_BUCKET} --profile terraform --delete ; \ + aws cloudfront create-invalidation --distribution-id ${CF_DISTRIBUTION_ID} --profile terraform --path "/*" ; +.PHONY: sync-docs + ########################################################### ### Docker image @@ -227,7 +247,7 @@ contract-tests: # unless there is a reason not to. # https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html .PHONY: check build build_race build_abci dist install install_abci check_tools tools update_tools draw_deps \ - get_protoc protoc_abci protoc_libs gen_certs clean_certs grpc_dbserver fmt rpc-docs build-linux localnet-start \ + get_protoc protoc_abci protoc_libs gen_certs clean_certs grpc_dbserver fmt build-linux localnet-start \ localnet-stop build-docker build-docker-localnode sentry-start sentry-config sentry-stop protoc_grpc protoc_all \ build_c install_c test_with_deadlock cleanup_after_test_with_deadlock lint build-contract-tests-hooks contract-tests \ build_c-amazonlinux diff --git a/README.md b/README.md index d7928f668..c1d26ed68 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Sessions](/docs/DEV_SESSIONS.md) and read some [Architectural Decision Records](https://github.com/tendermint/tendermint/tree/master/docs/architecture). Learn more by reading the code and comparing it to the -[specification](https://github.com/tendermint/tendermint/tree/develop/docs/spec). +[specification](https://github.com/tendermint/tendermint/tree/master/docs/spec). ## Versioning diff --git a/UPGRADING.md b/UPGRADING.md index af42d2a66..fc98982a7 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -110,7 +110,6 @@ The ABCI Application interface changed slightly so the CheckTx and DeliverTx methods now take Request structs. The contents of these structs are just the raw tx bytes, which were previously passed in as the argument. - ## v0.31.6 There are no breaking changes in this release except Go API of p2p and @@ -193,13 +192,15 @@ due to changes in how various data structures are hashed. Any implementations of Tendermint blockchain verification, including lite clients, will need to be updated. For specific details: + - [Merkle tree](./docs/spec/blockchain/encoding.md#merkle-trees) - [ConsensusParams](./docs/spec/blockchain/state.md#consensusparams) There was also a small change to field ordering in the vote struct. Any implementations of an out-of-process validator (like a Key-Management Server) will need to be updated. For specific details: -- [Vote](https://github.com/tendermint/tendermint/blob/develop/docs/spec/consensus/signing.md#votes) + +- [Vote](https://github.com/tendermint/tendermint/blob/master/docs/spec/consensus/signing.md#votes) Finally, the proposer selection algorithm continues to evolve. See the [work-in-progress @@ -438,7 +439,6 @@ required to maintain a map from validator addresses to pubkeys since v0.23 (when pubkeys were removed from RequestBeginBlock), but now they may need to track multiple validator sets at once to accomodate this delay. - ### Block Size The `ConsensusParams.BlockSize.MaxTxs` was removed in favour of diff --git a/abci/client/socket_client.go b/abci/client/socket_client.go index 7b1e4cd8d..062d50d4e 100644 --- a/abci/client/socket_client.go +++ b/abci/client/socket_client.go @@ -5,6 +5,7 @@ import ( "container/list" "errors" "fmt" + "io" "net" "reflect" "sync" @@ -119,7 +120,7 @@ func (cli *socketClient) SetResponseCallback(resCb Callback) { //---------------------------------------- -func (cli *socketClient) sendRequestsRoutine(conn net.Conn) { +func (cli *socketClient) sendRequestsRoutine(conn io.Writer) { w := bufio.NewWriter(conn) for { @@ -151,7 +152,7 @@ func (cli *socketClient) sendRequestsRoutine(conn net.Conn) { } } -func (cli *socketClient) recvResponseRoutine(conn net.Conn) { +func (cli *socketClient) recvResponseRoutine(conn io.Reader) { r := bufio.NewReader(conn) // Buffer reads for { diff --git a/abci/cmd/abci-cli/abci-cli.go b/abci/cmd/abci-cli/abci-cli.go index 31721b21b..32560f427 100644 --- a/abci/cmd/abci-cli/abci-cli.go +++ b/abci/cmd/abci-cli/abci-cli.go @@ -111,16 +111,28 @@ func Execute() error { } func addGlobalFlags() { - RootCmd.PersistentFlags().StringVarP(&flagAddress, "address", "", "tcp://0.0.0.0:26658", "address of application socket") + RootCmd.PersistentFlags().StringVarP(&flagAddress, + "address", + "", + "tcp://0.0.0.0:26658", + "address of application socket") RootCmd.PersistentFlags().StringVarP(&flagAbci, "abci", "", "socket", "either socket or grpc") - RootCmd.PersistentFlags().BoolVarP(&flagVerbose, "verbose", "v", false, "print the command and results as if it were a console session") + RootCmd.PersistentFlags().BoolVarP(&flagVerbose, + "verbose", + "v", + false, + "print the command and results as if it were a console session") RootCmd.PersistentFlags().StringVarP(&flagLogLevel, "log_level", "", "debug", "set the logger level") } func addQueryFlags() { queryCmd.PersistentFlags().StringVarP(&flagPath, "path", "", "/store", "path to prefix query with") queryCmd.PersistentFlags().IntVarP(&flagHeight, "height", "", 0, "height to query the blockchain at") - queryCmd.PersistentFlags().BoolVarP(&flagProve, "prove", "", false, "whether or not to return a merkle proof of the query result") + queryCmd.PersistentFlags().BoolVarP(&flagProve, + "prove", + "", + false, + "whether or not to return a merkle proof of the query result") } func addCounterFlags() { diff --git a/abci/example/example_test.go b/abci/example/example_test.go index 74510700b..163545055 100644 --- a/abci/example/example_test.go +++ b/abci/example/example_test.go @@ -111,7 +111,7 @@ func dialerFunc(ctx context.Context, addr string) (net.Conn, error) { return cmn.Connect(addr) } -func testGRPCSync(t *testing.T, app *types.GRPCApplication) { +func testGRPCSync(t *testing.T, app types.ABCIApplicationServer) { numDeliverTxs := 2000 // Start the listener diff --git a/abci/example/kvstore/kvstore_test.go b/abci/example/kvstore/kvstore_test.go index 80e60fdec..d931c3b13 100644 --- a/abci/example/kvstore/kvstore_test.go +++ b/abci/example/kvstore/kvstore_test.go @@ -175,7 +175,12 @@ func TestValUpdates(t *testing.T) { } -func makeApplyBlock(t *testing.T, kvstore types.Application, heightInt int, diff []types.ValidatorUpdate, txs ...[]byte) { +func makeApplyBlock( + t *testing.T, + kvstore types.Application, + heightInt int, + diff []types.ValidatorUpdate, + txs ...[]byte) { // make and apply block height := int64(heightInt) hash := []byte("foo") diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index 3e1d775d7..8dbd934b4 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -144,7 +144,7 @@ func (s *SocketServer) waitForClose(closeConn chan error, connID int) { } // Read requests from conn and deal with them -func (s *SocketServer) handleRequests(closeConn chan error, conn net.Conn, responses chan<- *types.Response) { +func (s *SocketServer) handleRequests(closeConn chan error, conn io.Reader, responses chan<- *types.Response) { var count int var bufReader = bufio.NewReader(conn) @@ -215,7 +215,7 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types } // Pull responses from 'responses' and write them to conn. -func (s *SocketServer) handleResponses(closeConn chan error, conn net.Conn, responses <-chan *types.Response) { +func (s *SocketServer) handleResponses(closeConn chan error, conn io.Writer, responses <-chan *types.Response) { var count int var bufWriter = bufio.NewWriter(conn) for { diff --git a/abci/tests/benchmarks/simple/simple.go b/abci/tests/benchmarks/simple/simple.go index b0819799b..b5cfb044d 100644 --- a/abci/tests/benchmarks/simple/simple.go +++ b/abci/tests/benchmarks/simple/simple.go @@ -3,8 +3,8 @@ package main import ( "bufio" "fmt" + "io" "log" - "net" "reflect" "github.com/tendermint/tendermint/abci/types" @@ -33,7 +33,7 @@ func main() { } } -func makeRequest(conn net.Conn, req *types.Request) (*types.Response, error) { +func makeRequest(conn io.ReadWriter, req *types.Request) (*types.Response, error) { var bufWriter = bufio.NewWriter(conn) // Write desired request diff --git a/abci/tests/test_app/main.go b/abci/tests/test_app/main.go index 8f45cec3c..c7524cb1c 100644 --- a/abci/tests/test_app/main.go +++ b/abci/tests/test_app/main.go @@ -36,7 +36,7 @@ func ensureABCIIsUp(typ string, n int) error { } for i := 0; i < n; i++ { - cmd := exec.Command("bash", "-c", cmdString) // nolint: gas + cmd := exec.Command("bash", "-c", cmdString) _, err = cmd.CombinedOutput() if err == nil { break @@ -53,7 +53,7 @@ func testCounter() { } fmt.Printf("Running %s test with abci=%s\n", abciApp, abciType) - cmd := exec.Command("bash", "-c", fmt.Sprintf("abci-cli %s", abciApp)) // nolint: gas + cmd := exec.Command("bash", "-c", fmt.Sprintf("abci-cli %s", abciApp)) //nolint:gosec cmd.Stdout = os.Stdout if err := cmd.Start(); err != nil { log.Fatalf("starting %q err: %v", abciApp, err) diff --git a/abci/types/application.go b/abci/types/application.go index 90518851d..9dd77c4ef 100644 --- a/abci/types/application.go +++ b/abci/types/application.go @@ -18,7 +18,7 @@ type Application interface { CheckTx(RequestCheckTx) ResponseCheckTx // Validate a tx for the mempool // Consensus Connection - InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain with validators and other info from TendermintCore + InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain w validators/other info from TendermintCore BeginBlock(RequestBeginBlock) ResponseBeginBlock // Signals the beginning of a block DeliverTx(RequestDeliverTx) ResponseDeliverTx // Deliver a tx for full processing EndBlock(RequestEndBlock) ResponseEndBlock // Signals the end of a block, returns changes to the validator set diff --git a/behaviour/reporter.go b/behaviour/reporter.go index f8a0693bf..0a1467168 100644 --- a/behaviour/reporter.go +++ b/behaviour/reporter.go @@ -63,10 +63,12 @@ func NewMockReporter() *MockReporter { } // Report stores the PeerBehaviour produced by the peer identified by peerID. -func (mpbr *MockReporter) Report(behaviour PeerBehaviour) { +func (mpbr *MockReporter) Report(behaviour PeerBehaviour) error { mpbr.mtx.Lock() defer mpbr.mtx.Unlock() mpbr.pb[behaviour.peerID] = append(mpbr.pb[behaviour.peerID], behaviour) + + return nil } // GetBehaviours returns all behaviours reported on the peer identified by peerID. diff --git a/behaviour/reporter_test.go b/behaviour/reporter_test.go index eae94e7bd..9822cfc6d 100644 --- a/behaviour/reporter_test.go +++ b/behaviour/reporter_test.go @@ -131,9 +131,24 @@ func TestMockPeerBehaviourReporterConcurrency(t *testing.T) { }{ {"1", []bh.PeerBehaviour{bh.ConsensusVote("1", "")}}, {"2", []bh.PeerBehaviour{bh.ConsensusVote("2", ""), bh.ConsensusVote("2", ""), bh.ConsensusVote("2", "")}}, - {"3", []bh.PeerBehaviour{bh.BlockPart("3", ""), bh.ConsensusVote("3", ""), bh.BlockPart("3", ""), bh.ConsensusVote("3", "")}}, - {"4", []bh.PeerBehaviour{bh.ConsensusVote("4", ""), bh.ConsensusVote("4", ""), bh.ConsensusVote("4", ""), bh.ConsensusVote("4", "")}}, - {"5", []bh.PeerBehaviour{bh.BlockPart("5", ""), bh.ConsensusVote("5", ""), bh.BlockPart("5", ""), bh.ConsensusVote("5", "")}}, + { + "3", + []bh.PeerBehaviour{bh.BlockPart("3", ""), + bh.ConsensusVote("3", ""), + bh.BlockPart("3", ""), + bh.ConsensusVote("3", "")}}, + { + "4", + []bh.PeerBehaviour{bh.ConsensusVote("4", ""), + bh.ConsensusVote("4", ""), + bh.ConsensusVote("4", ""), + bh.ConsensusVote("4", "")}}, + { + "5", + []bh.PeerBehaviour{bh.BlockPart("5", ""), + bh.ConsensusVote("5", ""), + bh.BlockPart("5", ""), + bh.ConsensusVote("5", "")}}, } ) diff --git a/benchmarks/atomic_test.go b/benchmarks/atomic_test.go deleted file mode 100644 index 5fe4832df..000000000 --- a/benchmarks/atomic_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package benchmarks - -import ( - "sync/atomic" - "testing" - "unsafe" -) - -func BenchmarkAtomicUintPtr(b *testing.B) { - b.StopTimer() - pointers := make([]uintptr, 1000) - b.Log(unsafe.Sizeof(pointers[0])) - b.StartTimer() - - for j := 0; j < b.N; j++ { - atomic.StoreUintptr(&pointers[j%1000], uintptr(j)) - } -} - -func BenchmarkAtomicPointer(b *testing.B) { - b.StopTimer() - pointers := make([]unsafe.Pointer, 1000) - b.Log(unsafe.Sizeof(pointers[0])) - b.StartTimer() - - for j := 0; j < b.N; j++ { - atomic.StorePointer(&pointers[j%1000], unsafe.Pointer(uintptr(j))) - } -} diff --git a/benchmarks/blockchain/.gitignore b/benchmarks/blockchain/.gitignore deleted file mode 100644 index 9e67bd47d..000000000 --- a/benchmarks/blockchain/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -data - diff --git a/benchmarks/blockchain/localsync.sh b/benchmarks/blockchain/localsync.sh deleted file mode 100755 index 2dc3e49c0..000000000 --- a/benchmarks/blockchain/localsync.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash - -DATA=$GOPATH/src/github.com/tendermint/tendermint/benchmarks/blockchain/data -if [ ! -d $DATA ]; then - echo "no data found, generating a chain... (this only has to happen once)" - - tendermint init --home $DATA - cp $DATA/config.toml $DATA/config2.toml - echo " - [consensus] - timeout_commit = 0 - " >> $DATA/config.toml - - echo "starting node" - tendermint node \ - --home $DATA \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56656 \ - --rpc.laddr tcp://127.0.0.1:56657 \ - --log_level error & - - echo "making blocks for 60s" - sleep 60 - - mv $DATA/config2.toml $DATA/config.toml - - kill %1 - - echo "done generating chain." -fi - -# validator node -HOME1=$TMPDIR$RANDOM$RANDOM -cp -R $DATA $HOME1 -echo "starting validator node" -tendermint node \ - --home $HOME1 \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56656 \ - --rpc.laddr tcp://127.0.0.1:56657 \ - --log_level error & -sleep 1 - -# downloader node -HOME2=$TMPDIR$RANDOM$RANDOM -tendermint init --home $HOME2 -cp $HOME1/genesis.json $HOME2 -printf "starting downloader node" -tendermint node \ - --home $HOME2 \ - --proxy_app kvstore \ - --p2p.laddr tcp://127.0.0.1:56666 \ - --rpc.laddr tcp://127.0.0.1:56667 \ - --p2p.persistent_peers 127.0.0.1:56656 \ - --log_level error & - -# wait for node to start up so we only count time where we are actually syncing -sleep 0.5 -while curl localhost:56667/status 2> /dev/null | grep "\"latest_block_height\": 0," > /dev/null -do - printf '.' - sleep 0.2 -done -echo - -echo "syncing blockchain for 10s" -for i in {1..10} -do - sleep 1 - HEIGHT="$(curl localhost:56667/status 2> /dev/null \ - | grep 'latest_block_height' \ - | grep -o ' [0-9]*' \ - | xargs)" - let 'RATE = HEIGHT / i' - echo "height: $HEIGHT, blocks/sec: $RATE" -done - -kill %1 -kill %2 -rm -rf $HOME1 $HOME2 diff --git a/benchmarks/chan_test.go b/benchmarks/chan_test.go deleted file mode 100644 index 78b70c9be..000000000 --- a/benchmarks/chan_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package benchmarks - -import ( - "testing" -) - -func BenchmarkChanMakeClose(b *testing.B) { - b.StopTimer() - b.StartTimer() - - for j := 0; j < b.N; j++ { - foo := make(chan struct{}) - close(foo) - something, ok := <-foo - if ok { - b.Error(something, ok) - } - } -} diff --git a/benchmarks/codec_test.go b/benchmarks/codec_test.go deleted file mode 100644 index 64c0e72cf..000000000 --- a/benchmarks/codec_test.go +++ /dev/null @@ -1,123 +0,0 @@ -package benchmarks - -import ( - "testing" - "time" - - amino "github.com/tendermint/go-amino" - - proto "github.com/tendermint/tendermint/benchmarks/proto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/p2p" - ctypes "github.com/tendermint/tendermint/rpc/core/types" -) - -func testNodeInfo(id p2p.ID) p2p.DefaultNodeInfo { - return p2p.DefaultNodeInfo{ - ProtocolVersion: p2p.ProtocolVersion{P2P: 1, Block: 2, App: 3}, - ID_: id, - Moniker: "SOMENAME", - Network: "SOMENAME", - ListenAddr: "SOMEADDR", - Version: "SOMEVER", - Other: p2p.DefaultNodeInfoOther{ - TxIndex: "on", - RPCAddress: "0.0.0.0:26657", - }, - } -} - -func BenchmarkEncodeStatusWire(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} - status := &ctypes.ResultStatus{ - NodeInfo: testNodeInfo(nodeKey.ID()), - SyncInfo: ctypes.SyncInfo{ - LatestBlockHash: []byte("SOMEBYTES"), - LatestBlockHeight: 123, - LatestBlockTime: time.Unix(0, 1234), - }, - ValidatorInfo: ctypes.ValidatorInfo{ - PubKey: nodeKey.PubKey(), - }, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes, err := cdc.MarshalJSON(status) - if err != nil { - panic(err) - } - counter += len(jsonBytes) - } - -} - -func BenchmarkEncodeNodeInfoWire(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} - nodeInfo := testNodeInfo(nodeKey.ID()) - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes, err := cdc.MarshalJSON(nodeInfo) - if err != nil { - panic(err) - } - counter += len(jsonBytes) - } -} - -func BenchmarkEncodeNodeInfoBinary(b *testing.B) { - b.StopTimer() - cdc := amino.NewCodec() - ctypes.RegisterAmino(cdc) - nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} - nodeInfo := testNodeInfo(nodeKey.ID()) - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - jsonBytes := cdc.MustMarshalBinaryBare(nodeInfo) - counter += len(jsonBytes) - } - -} - -func BenchmarkEncodeNodeInfoProto(b *testing.B) { - b.StopTimer() - nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} - nodeID := string(nodeKey.ID()) - someName := "SOMENAME" - someAddr := "SOMEADDR" - someVer := "SOMEVER" - someString := "SOMESTRING" - otherString := "OTHERSTRING" - nodeInfo := proto.NodeInfo{ - Id: &proto.ID{Id: &nodeID}, - Moniker: &someName, - Network: &someName, - ListenAddr: &someAddr, - Version: &someVer, - Other: []string{someString, otherString}, - } - b.StartTimer() - - counter := 0 - for i := 0; i < b.N; i++ { - bytes, err := nodeInfo.Marshal() - if err != nil { - b.Fatal(err) - return - } - //jsonBytes := wire.JSONBytes(nodeInfo) - counter += len(bytes) - } - -} diff --git a/benchmarks/empty.go b/benchmarks/empty.go deleted file mode 100644 index 20f08f14b..000000000 --- a/benchmarks/empty.go +++ /dev/null @@ -1 +0,0 @@ -package benchmarks diff --git a/benchmarks/map_test.go b/benchmarks/map_test.go deleted file mode 100644 index d13a19edf..000000000 --- a/benchmarks/map_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package benchmarks - -import ( - "testing" - - cmn "github.com/tendermint/tendermint/libs/common" -) - -func BenchmarkSomething(b *testing.B) { - b.StopTimer() - numItems := 100000 - numChecks := 100000 - keys := make([]string, numItems) - for i := 0; i < numItems; i++ { - keys[i] = cmn.RandStr(100) - } - txs := make([]string, numChecks) - for i := 0; i < numChecks; i++ { - txs[i] = cmn.RandStr(100) - } - b.StartTimer() - - counter := 0 - for j := 0; j < b.N; j++ { - foo := make(map[string]string) - for _, key := range keys { - foo[key] = key - } - for _, tx := range txs { - if _, ok := foo[tx]; ok { - counter++ - } - } - } -} diff --git a/benchmarks/os_test.go b/benchmarks/os_test.go deleted file mode 100644 index 406038b9d..000000000 --- a/benchmarks/os_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package benchmarks - -import ( - "os" - "testing" - - cmn "github.com/tendermint/tendermint/libs/common" -) - -func BenchmarkFileWrite(b *testing.B) { - b.StopTimer() - file, err := os.OpenFile("benchmark_file_write.out", - os.O_RDWR|os.O_CREATE|os.O_APPEND, 0600) - if err != nil { - b.Error(err) - } - testString := cmn.RandStr(200) + "\n" - b.StartTimer() - - for i := 0; i < b.N; i++ { - _, err := file.Write([]byte(testString)) - if err != nil { - b.Error(err) - } - } - - if err := file.Close(); err != nil { - b.Error(err) - } - if err := os.Remove("benchmark_file_write.out"); err != nil { - b.Error(err) - } -} diff --git a/benchmarks/proto/README b/benchmarks/proto/README deleted file mode 100644 index 87ece2576..000000000 --- a/benchmarks/proto/README +++ /dev/null @@ -1,2 +0,0 @@ -Doing some protobuf tests here. -Using gogoprotobuf. diff --git a/benchmarks/proto/test.pb.go b/benchmarks/proto/test.pb.go deleted file mode 100644 index d430eeb08..000000000 --- a/benchmarks/proto/test.pb.go +++ /dev/null @@ -1,1456 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: test.proto - -/* - Package test is a generated protocol buffer package. - - It is generated from these files: - test.proto - - It has these top-level messages: - ResultStatus - NodeInfo - ID - PubKey - PubKeyEd25519 -*/ -package test - -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" - -import io "io" - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package - -type ResultStatus struct { - NodeInfo *NodeInfo `protobuf:"bytes,1,opt,name=nodeInfo" json:"nodeInfo,omitempty"` - PubKey *PubKey `protobuf:"bytes,2,req,name=pubKey" json:"pubKey,omitempty"` - LatestBlockHash []byte `protobuf:"bytes,3,req,name=latestBlockHash" json:"latestBlockHash,omitempty"` - LatestBlockHeight *int64 `protobuf:"varint,4,req,name=latestBlockHeight" json:"latestBlockHeight,omitempty"` - LatestBlocktime *int64 `protobuf:"varint,5,req,name=latestBlocktime" json:"latestBlocktime,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ResultStatus) Reset() { *m = ResultStatus{} } -func (m *ResultStatus) String() string { return proto.CompactTextString(m) } -func (*ResultStatus) ProtoMessage() {} -func (*ResultStatus) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{0} } - -func (m *ResultStatus) GetNodeInfo() *NodeInfo { - if m != nil { - return m.NodeInfo - } - return nil -} - -func (m *ResultStatus) GetPubKey() *PubKey { - if m != nil { - return m.PubKey - } - return nil -} - -func (m *ResultStatus) GetLatestBlockHash() []byte { - if m != nil { - return m.LatestBlockHash - } - return nil -} - -func (m *ResultStatus) GetLatestBlockHeight() int64 { - if m != nil && m.LatestBlockHeight != nil { - return *m.LatestBlockHeight - } - return 0 -} - -func (m *ResultStatus) GetLatestBlocktime() int64 { - if m != nil && m.LatestBlocktime != nil { - return *m.LatestBlocktime - } - return 0 -} - -type NodeInfo struct { - Id *ID `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` - Moniker *string `protobuf:"bytes,2,req,name=moniker" json:"moniker,omitempty"` - Network *string `protobuf:"bytes,3,req,name=network" json:"network,omitempty"` - RemoteAddr *string `protobuf:"bytes,4,req,name=remoteAddr" json:"remoteAddr,omitempty"` - ListenAddr *string `protobuf:"bytes,5,req,name=listenAddr" json:"listenAddr,omitempty"` - Version *string `protobuf:"bytes,6,req,name=version" json:"version,omitempty"` - Other []string `protobuf:"bytes,7,rep,name=other" json:"other,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *NodeInfo) Reset() { *m = NodeInfo{} } -func (m *NodeInfo) String() string { return proto.CompactTextString(m) } -func (*NodeInfo) ProtoMessage() {} -func (*NodeInfo) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{1} } - -func (m *NodeInfo) GetId() *ID { - if m != nil { - return m.Id - } - return nil -} - -func (m *NodeInfo) GetMoniker() string { - if m != nil && m.Moniker != nil { - return *m.Moniker - } - return "" -} - -func (m *NodeInfo) GetNetwork() string { - if m != nil && m.Network != nil { - return *m.Network - } - return "" -} - -func (m *NodeInfo) GetRemoteAddr() string { - if m != nil && m.RemoteAddr != nil { - return *m.RemoteAddr - } - return "" -} - -func (m *NodeInfo) GetListenAddr() string { - if m != nil && m.ListenAddr != nil { - return *m.ListenAddr - } - return "" -} - -func (m *NodeInfo) GetVersion() string { - if m != nil && m.Version != nil { - return *m.Version - } - return "" -} - -func (m *NodeInfo) GetOther() []string { - if m != nil { - return m.Other - } - return nil -} - -type ID struct { - Id *string `protobuf:"bytes,1,req,name=id" json:"id,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *ID) Reset() { *m = ID{} } -func (m *ID) String() string { return proto.CompactTextString(m) } -func (*ID) ProtoMessage() {} -func (*ID) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{2} } - -func (m *ID) GetId() string { - if m != nil && m.Id != nil { - return *m.Id - } - return "" -} - -type PubKey struct { - Ed25519 *PubKeyEd25519 `protobuf:"bytes,1,opt,name=ed25519" json:"ed25519,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PubKey) Reset() { *m = PubKey{} } -func (m *PubKey) String() string { return proto.CompactTextString(m) } -func (*PubKey) ProtoMessage() {} -func (*PubKey) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{3} } - -func (m *PubKey) GetEd25519() *PubKeyEd25519 { - if m != nil { - return m.Ed25519 - } - return nil -} - -type PubKeyEd25519 struct { - Bytes []byte `protobuf:"bytes,1,req,name=bytes" json:"bytes,omitempty"` - XXX_unrecognized []byte `json:"-"` -} - -func (m *PubKeyEd25519) Reset() { *m = PubKeyEd25519{} } -func (m *PubKeyEd25519) String() string { return proto.CompactTextString(m) } -func (*PubKeyEd25519) ProtoMessage() {} -func (*PubKeyEd25519) Descriptor() ([]byte, []int) { return fileDescriptorTest, []int{4} } - -func (m *PubKeyEd25519) GetBytes() []byte { - if m != nil { - return m.Bytes - } - return nil -} - -func init() { - proto.RegisterType((*ResultStatus)(nil), "ResultStatus") - proto.RegisterType((*NodeInfo)(nil), "NodeInfo") - proto.RegisterType((*ID)(nil), "ID") - proto.RegisterType((*PubKey)(nil), "PubKey") - proto.RegisterType((*PubKeyEd25519)(nil), "PubKeyEd25519") -} -func (m *ResultStatus) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ResultStatus) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.NodeInfo != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.NodeInfo.Size())) - n1, err := m.NodeInfo.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n1 - } - if m.PubKey == nil { - return 0, proto.NewRequiredNotSetError("pubKey") - } else { - dAtA[i] = 0x12 - i++ - i = encodeVarintTest(dAtA, i, uint64(m.PubKey.Size())) - n2, err := m.PubKey.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n2 - } - if m.LatestBlockHash == nil { - return 0, proto.NewRequiredNotSetError("latestBlockHash") - } else { - dAtA[i] = 0x1a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(m.LatestBlockHash))) - i += copy(dAtA[i:], m.LatestBlockHash) - } - if m.LatestBlockHeight == nil { - return 0, proto.NewRequiredNotSetError("latestBlockHeight") - } else { - dAtA[i] = 0x20 - i++ - i = encodeVarintTest(dAtA, i, uint64(*m.LatestBlockHeight)) - } - if m.LatestBlocktime == nil { - return 0, proto.NewRequiredNotSetError("latestBlocktime") - } else { - dAtA[i] = 0x28 - i++ - i = encodeVarintTest(dAtA, i, uint64(*m.LatestBlocktime)) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *NodeInfo) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *NodeInfo) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Id == nil { - return 0, proto.NewRequiredNotSetError("id") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.Id.Size())) - n3, err := m.Id.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n3 - } - if m.Moniker == nil { - return 0, proto.NewRequiredNotSetError("moniker") - } else { - dAtA[i] = 0x12 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Moniker))) - i += copy(dAtA[i:], *m.Moniker) - } - if m.Network == nil { - return 0, proto.NewRequiredNotSetError("network") - } else { - dAtA[i] = 0x1a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Network))) - i += copy(dAtA[i:], *m.Network) - } - if m.RemoteAddr == nil { - return 0, proto.NewRequiredNotSetError("remoteAddr") - } else { - dAtA[i] = 0x22 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.RemoteAddr))) - i += copy(dAtA[i:], *m.RemoteAddr) - } - if m.ListenAddr == nil { - return 0, proto.NewRequiredNotSetError("listenAddr") - } else { - dAtA[i] = 0x2a - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.ListenAddr))) - i += copy(dAtA[i:], *m.ListenAddr) - } - if m.Version == nil { - return 0, proto.NewRequiredNotSetError("version") - } else { - dAtA[i] = 0x32 - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Version))) - i += copy(dAtA[i:], *m.Version) - } - if len(m.Other) > 0 { - for _, s := range m.Other { - dAtA[i] = 0x3a - i++ - l = len(s) - for l >= 1<<7 { - dAtA[i] = uint8(uint64(l)&0x7f | 0x80) - l >>= 7 - i++ - } - dAtA[i] = uint8(l) - i++ - i += copy(dAtA[i:], s) - } - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *ID) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *ID) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Id == nil { - return 0, proto.NewRequiredNotSetError("id") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(len(*m.Id))) - i += copy(dAtA[i:], *m.Id) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *PubKey) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PubKey) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Ed25519 != nil { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(m.Ed25519.Size())) - n4, err := m.Ed25519.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n4 - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func (m *PubKeyEd25519) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalTo(dAtA) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *PubKeyEd25519) MarshalTo(dAtA []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Bytes == nil { - return 0, proto.NewRequiredNotSetError("bytes") - } else { - dAtA[i] = 0xa - i++ - i = encodeVarintTest(dAtA, i, uint64(len(m.Bytes))) - i += copy(dAtA[i:], m.Bytes) - } - if m.XXX_unrecognized != nil { - i += copy(dAtA[i:], m.XXX_unrecognized) - } - return i, nil -} - -func encodeVarintTest(dAtA []byte, offset int, v uint64) int { - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return offset + 1 -} -func (m *ResultStatus) Size() (n int) { - var l int - _ = l - if m.NodeInfo != nil { - l = m.NodeInfo.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.PubKey != nil { - l = m.PubKey.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.LatestBlockHash != nil { - l = len(m.LatestBlockHash) - n += 1 + l + sovTest(uint64(l)) - } - if m.LatestBlockHeight != nil { - n += 1 + sovTest(uint64(*m.LatestBlockHeight)) - } - if m.LatestBlocktime != nil { - n += 1 + sovTest(uint64(*m.LatestBlocktime)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *NodeInfo) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.Moniker != nil { - l = len(*m.Moniker) - n += 1 + l + sovTest(uint64(l)) - } - if m.Network != nil { - l = len(*m.Network) - n += 1 + l + sovTest(uint64(l)) - } - if m.RemoteAddr != nil { - l = len(*m.RemoteAddr) - n += 1 + l + sovTest(uint64(l)) - } - if m.ListenAddr != nil { - l = len(*m.ListenAddr) - n += 1 + l + sovTest(uint64(l)) - } - if m.Version != nil { - l = len(*m.Version) - n += 1 + l + sovTest(uint64(l)) - } - if len(m.Other) > 0 { - for _, s := range m.Other { - l = len(s) - n += 1 + l + sovTest(uint64(l)) - } - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *ID) Size() (n int) { - var l int - _ = l - if m.Id != nil { - l = len(*m.Id) - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *PubKey) Size() (n int) { - var l int - _ = l - if m.Ed25519 != nil { - l = m.Ed25519.Size() - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *PubKeyEd25519) Size() (n int) { - var l int - _ = l - if m.Bytes != nil { - l = len(m.Bytes) - n += 1 + l + sovTest(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func sovTest(x uint64) (n int) { - for { - n++ - x >>= 7 - if x == 0 { - break - } - } - return n -} - -func (m *ResultStatus) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ResultStatus: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ResultStatus: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field NodeInfo", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.NodeInfo == nil { - m.NodeInfo = &NodeInfo{} - } - if err := m.NodeInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubKey", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.PubKey == nil { - m.PubKey = &PubKey{} - } - if err := m.PubKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlockHash", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.LatestBlockHash = append(m.LatestBlockHash[:0], dAtA[iNdEx:postIndex]...) - if m.LatestBlockHash == nil { - m.LatestBlockHash = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 4: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlockHeight", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LatestBlockHeight = &v - hasFields[0] |= uint64(0x00000004) - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field LatestBlocktime", wireType) - } - var v int64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - v |= (int64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - m.LatestBlocktime = &v - hasFields[0] |= uint64(0x00000008) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("pubKey") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return proto.NewRequiredNotSetError("latestBlockHash") - } - if hasFields[0]&uint64(0x00000004) == 0 { - return proto.NewRequiredNotSetError("latestBlockHeight") - } - if hasFields[0]&uint64(0x00000008) == 0 { - return proto.NewRequiredNotSetError("latestBlocktime") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *NodeInfo) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: NodeInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: NodeInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Id == nil { - m.Id = &ID{} - } - if err := m.Id.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Moniker", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Moniker = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000002) - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Network = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000004) - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RemoteAddr", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.RemoteAddr = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000008) - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ListenAddr", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.ListenAddr = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000010) - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Version = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000020) - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Other", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Other = append(m.Other, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("id") - } - if hasFields[0]&uint64(0x00000002) == 0 { - return proto.NewRequiredNotSetError("moniker") - } - if hasFields[0]&uint64(0x00000004) == 0 { - return proto.NewRequiredNotSetError("network") - } - if hasFields[0]&uint64(0x00000008) == 0 { - return proto.NewRequiredNotSetError("remoteAddr") - } - if hasFields[0]&uint64(0x00000010) == 0 { - return proto.NewRequiredNotSetError("listenAddr") - } - if hasFields[0]&uint64(0x00000020) == 0 { - return proto.NewRequiredNotSetError("version") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *ID) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: ID: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ID: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + intStringLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - s := string(dAtA[iNdEx:postIndex]) - m.Id = &s - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("id") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PubKey) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PubKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PubKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ed25519", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + msglen - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Ed25519 == nil { - m.Ed25519 = &PubKeyEd25519{} - } - if err := m.Ed25519.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PubKeyEd25519) Unmarshal(dAtA []byte) error { - var hasFields [1]uint64 - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: PubKeyEd25519: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PubKeyEd25519: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Bytes", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTest - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTest - } - postIndex := iNdEx + byteLen - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Bytes = append(m.Bytes[:0], dAtA[iNdEx:postIndex]...) - if m.Bytes == nil { - m.Bytes = []byte{} - } - iNdEx = postIndex - hasFields[0] |= uint64(0x00000001) - default: - iNdEx = preIndex - skippy, err := skipTest(dAtA[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthTest - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - if hasFields[0]&uint64(0x00000001) == 0 { - return proto.NewRequiredNotSetError("bytes") - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTest(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - return iNdEx, nil - case 1: - iNdEx += 8 - return iNdEx, nil - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - iNdEx += length - if length < 0 { - return 0, ErrInvalidLengthTest - } - return iNdEx, nil - case 3: - for { - var innerWire uint64 - var start int = iNdEx - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTest - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - innerWire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - innerWireType := int(innerWire & 0x7) - if innerWireType == 4 { - break - } - next, err := skipTest(dAtA[start:]) - if err != nil { - return 0, err - } - iNdEx = start + next - } - return iNdEx, nil - case 4: - return iNdEx, nil - case 5: - iNdEx += 4 - return iNdEx, nil - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - } - panic("unreachable") -} - -var ( - ErrInvalidLengthTest = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTest = fmt.Errorf("proto: integer overflow") -) - -func init() { proto.RegisterFile("test.proto", fileDescriptorTest) } - -var fileDescriptorTest = []byte{ - // 342 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x91, 0x41, 0x4b, 0xf3, 0x30, - 0x1c, 0xc6, 0x49, 0xfb, 0x6e, 0x5d, 0xff, 0xeb, 0x3b, 0x31, 0xee, 0x90, 0x53, 0x2d, 0x85, 0x41, - 0x0f, 0x52, 0xb0, 0xb0, 0x83, 0x47, 0xc7, 0x04, 0x87, 0x20, 0x23, 0x7e, 0x82, 0xcd, 0xfe, 0x75, - 0x65, 0x5d, 0x33, 0x92, 0x4c, 0xd9, 0xe7, 0xf3, 0xe2, 0xd1, 0xa3, 0x47, 0xd9, 0x27, 0x91, 0xa6, - 0xed, 0x9c, 0xf3, 0xf8, 0xfc, 0x7e, 0xe5, 0xc9, 0xd3, 0x04, 0x40, 0xa3, 0xd2, 0xf1, 0x5a, 0x0a, - 0x2d, 0xc2, 0x4f, 0x02, 0x1e, 0x47, 0xb5, 0xc9, 0xf5, 0x83, 0x9e, 0xe9, 0x8d, 0xa2, 0x03, 0xe8, - 0x14, 0x22, 0xc5, 0x49, 0xf1, 0x24, 0x18, 0x09, 0x48, 0xd4, 0x4d, 0xdc, 0xf8, 0xbe, 0x06, 0x7c, - 0xaf, 0xe8, 0x39, 0xb4, 0xd7, 0x9b, 0xf9, 0x1d, 0x6e, 0x99, 0x15, 0x58, 0x51, 0x37, 0x71, 0xe2, - 0xa9, 0x89, 0xbc, 0xc6, 0x34, 0x82, 0x93, 0x7c, 0x56, 0x1e, 0x34, 0xca, 0xc5, 0xe3, 0xf2, 0x76, - 0xa6, 0x16, 0xcc, 0x0e, 0xac, 0xc8, 0xe3, 0xc7, 0x98, 0x5e, 0xc0, 0xe9, 0x21, 0xc2, 0xec, 0x79, - 0xa1, 0xd9, 0xbf, 0xc0, 0x8a, 0x6c, 0xfe, 0x57, 0x1c, 0xf5, 0xea, 0x6c, 0x85, 0xac, 0x65, 0xbe, - 0x3d, 0xc6, 0xe1, 0x1b, 0x81, 0x4e, 0xb3, 0x9c, 0x9e, 0x81, 0x95, 0xa5, 0x8c, 0x98, 0xad, 0x76, - 0x3c, 0x19, 0x73, 0x2b, 0x4b, 0x29, 0x03, 0x67, 0x25, 0x8a, 0x6c, 0x89, 0xd2, 0xfc, 0x85, 0xcb, - 0x9b, 0x58, 0x9a, 0x02, 0xf5, 0xab, 0x90, 0x4b, 0xb3, 0xda, 0xe5, 0x4d, 0xa4, 0x3e, 0x80, 0xc4, - 0x95, 0xd0, 0x78, 0x9d, 0xa6, 0xd2, 0xcc, 0x74, 0xf9, 0x01, 0x29, 0x7d, 0x9e, 0x29, 0x8d, 0x85, - 0xf1, 0xad, 0xca, 0xff, 0x90, 0xb2, 0xf9, 0x05, 0xa5, 0xca, 0x44, 0xc1, 0xda, 0x55, 0x73, 0x1d, - 0x69, 0x1f, 0x5a, 0x42, 0x2f, 0x50, 0x32, 0x27, 0xb0, 0x23, 0x97, 0x57, 0x21, 0xec, 0x83, 0x35, - 0x19, 0xd3, 0xde, 0x7e, 0xbe, 0x5b, 0x2e, 0x0f, 0x13, 0x68, 0x4f, 0x9b, 0x7b, 0x76, 0x30, 0x4d, - 0x86, 0xc3, 0xcb, 0xab, 0xfa, 0xb9, 0x7a, 0xf5, 0x4b, 0xdc, 0x54, 0x94, 0x37, 0x3a, 0x1c, 0xc0, - 0xff, 0x5f, 0xa6, 0x3c, 0x70, 0xbe, 0xd5, 0xa8, 0x4c, 0xaf, 0xc7, 0xab, 0x30, 0xf2, 0xde, 0x77, - 0x3e, 0xf9, 0xd8, 0xf9, 0xe4, 0x6b, 0xe7, 0x93, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xee, - 0x6b, 0xdd, 0x2c, 0x02, 0x00, 0x00, -} diff --git a/benchmarks/proto/test.proto b/benchmarks/proto/test.proto deleted file mode 100644 index 6d770d98a..000000000 --- a/benchmarks/proto/test.proto +++ /dev/null @@ -1,29 +0,0 @@ -message ResultStatus { - optional NodeInfo nodeInfo = 1; - required PubKey pubKey = 2; - required bytes latestBlockHash = 3; - required int64 latestBlockHeight = 4; - required int64 latestBlocktime = 5; -} - -message NodeInfo { - required ID id = 1; - required string moniker = 2; - required string network = 3; - required string remoteAddr = 4; - required string listenAddr = 5; - required string version = 6; - repeated string other = 7; -} - -message ID { - required string id = 1; -} - -message PubKey { - optional PubKeyEd25519 ed25519 = 1; -} - -message PubKeyEd25519 { - required bytes bytes = 1; -} diff --git a/benchmarks/simu/counter.go b/benchmarks/simu/counter.go deleted file mode 100644 index c24eddf8a..000000000 --- a/benchmarks/simu/counter.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "context" - "encoding/binary" - "fmt" - "time" - - cmn "github.com/tendermint/tendermint/libs/common" - rpcclient "github.com/tendermint/tendermint/rpc/lib/client" -) - -func main() { - wsc := rpcclient.NewWSClient("127.0.0.1:26657", "/websocket") - err := wsc.Start() - if err != nil { - cmn.Exit(err.Error()) - } - defer wsc.Stop() - - // Read a bunch of responses - go func() { - for { - _, ok := <-wsc.ResponsesCh - if !ok { - break - } - //fmt.Println("Received response", string(wire.JSONBytes(res))) - } - }() - - // Make a bunch of requests - buf := make([]byte, 32) - for i := 0; ; i++ { - binary.BigEndian.PutUint64(buf, uint64(i)) - //txBytes := hex.EncodeToString(buf[:n]) - fmt.Print(".") - err = wsc.Call(context.TODO(), "broadcast_tx", map[string]interface{}{"tx": buf[:8]}) - if err != nil { - cmn.Exit(err.Error()) - } - if i%1000 == 0 { - fmt.Println(i) - } - time.Sleep(time.Microsecond * 1000) - } -} diff --git a/blockchain/v0/pool.go b/blockchain/v0/pool.go index 7733dc5ff..a1901842e 100644 --- a/blockchain/v0/pool.go +++ b/blockchain/v0/pool.go @@ -247,7 +247,14 @@ func (pool *BlockPool) AddBlock(peerID p2p.ID, block *types.Block, blockSize int requester := pool.requesters[block.Height] if requester == nil { - pool.Logger.Info("peer sent us a block we didn't expect", "peer", peerID, "curHeight", pool.height, "blockHeight", block.Height) + pool.Logger.Info( + "peer sent us a block we didn't expect", + "peer", + peerID, + "curHeight", + pool.height, + "blockHeight", + block.Height) diff := pool.height - block.Height if diff < 0 { diff *= -1 @@ -422,14 +429,14 @@ func (pool *BlockPool) debug() string { //------------------------------------- type bpPeer struct { + didTimeout bool + numPending int32 + height int64 pool *BlockPool id p2p.ID recvMonitor *flow.Monitor - height int64 - numPending int32 - timeout *time.Timer - didTimeout bool + timeout *time.Timer logger log.Logger } diff --git a/blockchain/v0/pool_test.go b/blockchain/v0/pool_test.go index d741d59df..a573b27b2 100644 --- a/blockchain/v0/pool_test.go +++ b/blockchain/v0/pool_test.go @@ -42,7 +42,8 @@ func (p testPeer) runInputRoutine() { func (p testPeer) simulateInput(input inputData) { block := &types.Block{Header: types.Header{Height: input.request.Height}} input.pool.AddBlock(input.request.PeerID, block, 123) - // TODO: uncommenting this creates a race which is detected by: https://github.com/golang/go/blob/2bd767b1022dd3254bcec469f0ee164024726486/src/testing/testing.go#L854-L856 + // TODO: uncommenting this creates a race which is detected by: + // https://github.com/golang/go/blob/2bd767b1022dd3254bcec469f0ee164024726486/src/testing/testing.go#L854-L856 // see: https://github.com/tendermint/tendermint/issues/3390#issue-418379890 // input.t.Logf("Added block from peer %v (height: %v)", input.request.PeerID, input.request.Height) } diff --git a/blockchain/v0/reactor_test.go b/blockchain/v0/reactor_test.go index 0a88dbd74..6c4c8333d 100644 --- a/blockchain/v0/reactor_test.go +++ b/blockchain/v0/reactor_test.go @@ -50,7 +50,11 @@ type BlockchainReactorPair struct { app proxy.AppConns } -func newBlockchainReactor(logger log.Logger, genDoc *types.GenesisDoc, privVals []types.PrivValidator, maxBlockHeight int64) BlockchainReactorPair { +func newBlockchainReactor( + logger log.Logger, + genDoc *types.GenesisDoc, + privVals []types.PrivValidator, + maxBlockHeight int64) BlockchainReactorPair { if len(privVals) != 1 { panic("only support one validator") } @@ -88,7 +92,12 @@ func newBlockchainReactor(logger log.Logger, genDoc *types.GenesisDoc, privVals lastBlockMeta := blockStore.LoadBlockMeta(blockHeight - 1) lastBlock := blockStore.LoadBlock(blockHeight - 1) - vote, err := types.MakeVote(lastBlock.Header.Height, lastBlockMeta.BlockID, state.Validators, privVals[0], lastBlock.Header.ChainID) + vote, err := types.MakeVote( + lastBlock.Header.Height, + lastBlockMeta.BlockID, + state.Validators, + privVals[0], + lastBlock.Header.ChainID) if err != nil { panic(err) } diff --git a/blockchain/v1/pool_test.go b/blockchain/v1/pool_test.go index 5530ecd41..e612eb43e 100644 --- a/blockchain/v1/pool_test.go +++ b/blockchain/v1/pool_test.go @@ -198,14 +198,22 @@ func TestBlockPoolRemovePeer(t *testing.T) { poolWanted: makeBlockPool(testBcR, 100, []BpPeer{}, map[int64]tPBlocks{}), }, { - name: "delete the shortest of two peers without blocks", - pool: makeBlockPool(testBcR, 100, []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, map[int64]tPBlocks{}), + name: "delete the shortest of two peers without blocks", + pool: makeBlockPool( + testBcR, + 100, + []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, + map[int64]tPBlocks{}), args: args{"P1", nil}, poolWanted: makeBlockPool(testBcR, 100, []BpPeer{{ID: "P2", Height: 120}}, map[int64]tPBlocks{}), }, { - name: "delete the tallest of two peers without blocks", - pool: makeBlockPool(testBcR, 100, []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, map[int64]tPBlocks{}), + name: "delete the tallest of two peers without blocks", + pool: makeBlockPool( + testBcR, + 100, + []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 120}}, + map[int64]tPBlocks{}), args: args{"P2", nil}, poolWanted: makeBlockPool(testBcR, 100, []BpPeer{{ID: "P1", Height: 100}}, map[int64]tPBlocks{}), }, @@ -308,8 +316,12 @@ func TestBlockPoolSendRequestBatch(t *testing.T) { expnumPendingBlockRequests: 2, }, { - name: "n peers - send n*maxRequestsPerPeer block requests", - pool: makeBlockPool(testBcR, 10, []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}}, map[int64]tPBlocks{}), + name: "n peers - send n*maxRequestsPerPeer block requests", + pool: makeBlockPool( + testBcR, + 10, + []BpPeer{{ID: "P1", Height: 100}, {ID: "P2", Height: 100}}, + map[int64]tPBlocks{}), maxRequestsPerPeer: 2, expRequests: map[int64]bool{10: true, 11: true}, expPeerResults: []testPeerResult{ diff --git a/blockchain/v1/reactor_fsm.go b/blockchain/v1/reactor_fsm.go index 4bfef64ea..8d3a363ae 100644 --- a/blockchain/v1/reactor_fsm.go +++ b/blockchain/v1/reactor_fsm.go @@ -162,10 +162,12 @@ var ( errNoTallerPeer = errors.New("fast sync timed out on waiting for a peer taller than this node") // reported eventually to the switch - errPeerLowersItsHeight = errors.New("fast sync peer reports a height lower than previous") // handle return - errNoPeerResponseForCurrentHeights = errors.New("fast sync timed out on peer block response for current heights") // handle return - errNoPeerResponse = errors.New("fast sync timed out on peer block response") // xx - errBadDataFromPeer = errors.New("fast sync received block from wrong peer or block is bad") // xx + // handle return + errPeerLowersItsHeight = errors.New("fast sync peer reports a height lower than previous") + // handle return + errNoPeerResponseForCurrentHeights = errors.New("fast sync timed out on peer block response for current heights") + errNoPeerResponse = errors.New("fast sync timed out on peer block response") // xx + errBadDataFromPeer = errors.New("fast sync received block from wrong peer or block is bad") // xx errDuplicateBlock = errors.New("fast sync received duplicate block from peer") errBlockVerificationFailure = errors.New("fast sync block verification failure") // xx errSlowPeer = errors.New("fast sync peer is not sending us data fast enough") // xx diff --git a/blockchain/v1/reactor_test.go b/blockchain/v1/reactor_test.go index 00f7b0968..d9cc99af6 100644 --- a/blockchain/v1/reactor_test.go +++ b/blockchain/v1/reactor_test.go @@ -45,7 +45,11 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G }, privValidators } -func makeVote(header *types.Header, blockID types.BlockID, valset *types.ValidatorSet, privVal types.PrivValidator) *types.Vote { +func makeVote( + header *types.Header, + blockID types.BlockID, + valset *types.ValidatorSet, + privVal types.PrivValidator) *types.Vote { addr := privVal.GetPubKey().Address() idx, _ := valset.GetByAddress(addr) vote := &types.Vote{ @@ -68,7 +72,11 @@ type BlockchainReactorPair struct { conR *consensusReactorTest } -func newBlockchainReactor(logger log.Logger, genDoc *types.GenesisDoc, privVals []types.PrivValidator, maxBlockHeight int64) *BlockchainReactor { +func newBlockchainReactor( + logger log.Logger, + genDoc *types.GenesisDoc, + privVals []types.PrivValidator, + maxBlockHeight int64) *BlockchainReactor { if len(privVals) != 1 { panic("only support one validator") } @@ -129,7 +137,11 @@ func newBlockchainReactor(logger log.Logger, genDoc *types.GenesisDoc, privVals return bcReactor } -func newBlockchainReactorPair(logger log.Logger, genDoc *types.GenesisDoc, privVals []types.PrivValidator, maxBlockHeight int64) BlockchainReactorPair { +func newBlockchainReactorPair( + logger log.Logger, + genDoc *types.GenesisDoc, + privVals []types.PrivValidator, + maxBlockHeight int64) BlockchainReactorPair { consensusReactor := &consensusReactorTest{} consensusReactor.BaseReactor = *p2p.NewBaseReactor("Consensus reactor", consensusReactor) diff --git a/blockchain/v2/processor.go b/blockchain/v2/processor.go new file mode 100644 index 000000000..22b46ede3 --- /dev/null +++ b/blockchain/v2/processor.go @@ -0,0 +1,186 @@ +package v2 + +import ( + "fmt" + + "github.com/tendermint/tendermint/p2p" + tdState "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" +) + +type peerError struct { + priorityHigh + peerID p2p.ID +} + +type pcDuplicateBlock struct { + priorityNormal +} + +type pcShortBlock struct { + priorityNormal +} + +type bcBlockResponse struct { + priorityNormal + peerID p2p.ID + block *types.Block + height int64 +} + +type pcBlockVerificationFailure struct { + priorityNormal + peerID p2p.ID + height int64 +} + +type pcBlockProcessed struct { + priorityNormal + height int64 + peerID p2p.ID +} + +type pcProcessBlock struct { + priorityNormal +} + +type pcStop struct { + priorityNormal +} + +type pcFinished struct { + priorityNormal + height int64 + blocksSynced int64 +} + +func (p pcFinished) Error() string { + return "finished" +} + +type queueItem struct { + block *types.Block + peerID p2p.ID +} + +type blockQueue map[int64]queueItem + +type pcState struct { + height int64 // height of the last synced block + queue blockQueue // blocks waiting to be processed + chainID string + blocksSynced int64 + draining bool + tdState tdState.State + context processorContext +} + +func (state *pcState) String() string { + return fmt.Sprintf("height: %d queue length: %d draining: %v blocks synced: %d", + state.height, len(state.queue), state.draining, state.blocksSynced) +} + +// newPcState returns a pcState initialized with the last verified block enqueued +func newPcState(initHeight int64, tdState tdState.State, chainID string, context processorContext) *pcState { + return &pcState{ + height: initHeight, + queue: blockQueue{}, + chainID: chainID, + draining: false, + blocksSynced: 0, + context: context, + tdState: tdState, + } +} + +// nextTwo returns the next two unverified blocks +func (state *pcState) nextTwo() (queueItem, queueItem, error) { + if first, ok := state.queue[state.height+1]; ok { + if second, ok := state.queue[state.height+2]; ok { + return first, second, nil + } + } + return queueItem{}, queueItem{}, fmt.Errorf("not found") +} + +// synced returns true when at most the last verified block remains in the queue +func (state *pcState) synced() bool { + return len(state.queue) <= 1 +} + +func (state *pcState) advance() { + state.height++ + delete(state.queue, state.height) + state.blocksSynced++ +} + +func (state *pcState) enqueue(peerID p2p.ID, block *types.Block, height int64) error { + if _, ok := state.queue[height]; ok { + return fmt.Errorf("duplicate queue item") + } + state.queue[height] = queueItem{block: block, peerID: peerID} + return nil +} + +// purgePeer moves all unprocessed blocks from the queue +func (state *pcState) purgePeer(peerID p2p.ID) { + // what if height is less than state.height? + for height, item := range state.queue { + if item.peerID == peerID { + delete(state.queue, height) + } + } +} + +// handle processes FSM events +func (state *pcState) handle(event Event) (Event, error) { + switch event := event.(type) { + case *bcBlockResponse: + if event.height <= state.height { + return pcShortBlock{}, nil + } + err := state.enqueue(event.peerID, event.block, event.height) + if err != nil { + return pcDuplicateBlock{}, nil + } + + case pcProcessBlock: + firstItem, secondItem, err := state.nextTwo() + if err != nil { + if state.draining { + return noOp, pcFinished{height: state.height} + } + return noOp, nil + } + first, second := firstItem.block, secondItem.block + + firstParts := first.MakePartSet(types.BlockPartSizeBytes) + firstPartsHeader := firstParts.Header() + firstID := types.BlockID{Hash: first.Hash(), PartsHeader: firstPartsHeader} + + err = state.context.verifyCommit(state.chainID, firstID, first.Height, second.LastCommit) + if err != nil { + return pcBlockVerificationFailure{peerID: firstItem.peerID, height: first.Height}, nil + } + + state.context.saveBlock(first, firstParts, second.LastCommit) + + state.tdState, err = state.context.applyBlock(state.tdState, firstID, first) + if err != nil { + panic(fmt.Sprintf("failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) + } + state.advance() + return pcBlockProcessed{height: first.Height, peerID: firstItem.peerID}, nil + + case *peerError: + state.purgePeer(event.peerID) + + case pcStop: + if state.synced() { + return noOp, pcFinished{height: state.height, blocksSynced: state.blocksSynced} + } + state.draining = true + } + + return noOp, nil +} diff --git a/blockchain/v2/processor_context.go b/blockchain/v2/processor_context.go new file mode 100644 index 000000000..c4c8770cd --- /dev/null +++ b/blockchain/v2/processor_context.go @@ -0,0 +1,76 @@ +package v2 + +import ( + "fmt" + + "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/store" + "github.com/tendermint/tendermint/types" +) + +type processorContext interface { + applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) + verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error + saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) +} + +// nolint:unused +type pContext struct { + store *store.BlockStore + executor *state.BlockExecutor + state *state.State +} + +// nolint:unused,deadcode +func newProcessorContext(st *store.BlockStore, ex *state.BlockExecutor, s *state.State) *pContext { + return &pContext{ + store: st, + executor: ex, + state: s, + } +} + +func (pc *pContext) applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) { + return pc.executor.ApplyBlock(state, blockID, block) +} + +func (pc *pContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error { + return pc.state.Validators.VerifyCommit(chainID, blockID, height, commit) +} + +func (pc *pContext) saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) { + pc.store.SaveBlock(block, blockParts, seenCommit) +} + +type mockPContext struct { + applicationBL []int64 + verificationBL []int64 +} + +func newMockProcessorContext(verificationBlackList []int64, applicationBlackList []int64) *mockPContext { + return &mockPContext{ + applicationBL: applicationBlackList, + verificationBL: verificationBlackList, + } +} + +func (mpc *mockPContext) applyBlock(state state.State, blockID types.BlockID, block *types.Block) (state.State, error) { + for _, h := range mpc.applicationBL { + if h == block.Height { + return state, fmt.Errorf("generic application error") + } + } + return state, nil +} + +func (mpc *mockPContext) verifyCommit(chainID string, blockID types.BlockID, height int64, commit *types.Commit) error { + for _, h := range mpc.verificationBL { + if h == height { + return fmt.Errorf("generic verification error") + } + } + return nil +} + +func (mpc *mockPContext) saveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) { +} diff --git a/blockchain/v2/processor_test.go b/blockchain/v2/processor_test.go new file mode 100644 index 000000000..195df3618 --- /dev/null +++ b/blockchain/v2/processor_test.go @@ -0,0 +1,336 @@ +package v2 + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/p2p" + tdState "github.com/tendermint/tendermint/state" + "github.com/tendermint/tendermint/types" +) + +// pcBlock is a test helper structure with simple types. Its purpose is to help with test readability. +type pcBlock struct { + pid string + height int64 +} + +// params is a test structure used to create processor state. +type params struct { + height int64 + items []pcBlock + blocksSynced int64 + verBL []int64 + appBL []int64 + draining bool +} + +// makePcBlock makes an empty block. +func makePcBlock(height int64) *types.Block { + return &types.Block{Header: types.Header{Height: height}} +} + +// makeState takes test parameters and creates a specific processor state. +func makeState(p *params) *pcState { + var ( + tdState = tdState.State{} + context = newMockProcessorContext(p.verBL, p.appBL) + ) + state := newPcState(p.height, tdState, "test", context) + + for _, item := range p.items { + _ = state.enqueue(p2p.ID(item.pid), makePcBlock(item.height), item.height) + } + + state.blocksSynced = p.blocksSynced + state.draining = p.draining + return state +} + +func mBlockResponse(peerID p2p.ID, height int64) *bcBlockResponse { + return &bcBlockResponse{ + peerID: peerID, + block: makePcBlock(height), + height: height, + } +} + +type pcFsmMakeStateValues struct { + currentState *params + event Event + wantState *params + wantNextEvent Event + wantErr error + wantPanic bool +} + +type testFields struct { + name string + steps []pcFsmMakeStateValues +} + +func executeProcessorTests(t *testing.T, tests []testFields) { + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + var state *pcState + for _, step := range tt.steps { + defer func() { + r := recover() + if (r != nil) != step.wantPanic { + t.Errorf("recover = %v, wantPanic = %v", r, step.wantPanic) + } + }() + + // First step must always initialise the currentState as state. + if step.currentState != nil { + state = makeState(step.currentState) + } + if state == nil { + panic("Bad (initial?) step") + } + + nextEvent, err := state.handle(step.event) + t.Log(state) + assert.Equal(t, step.wantErr, err) + assert.Equal(t, makeState(step.wantState), state) + assert.Equal(t, step.wantNextEvent, nextEvent) + // Next step may use the wantedState as their currentState. + state = makeState(step.wantState) + } + }) + } +} + +func TestPcBlockResponse(t *testing.T) { + tests := []testFields{ + + { + name: "add one block", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{}, event: mBlockResponse("P1", 1), + wantState: ¶ms{items: []pcBlock{{"P1", 1}}}, wantNextEvent: noOp, + }, + }, + }, + { + name: "add two blocks", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{}, event: mBlockResponse("P1", 3), + wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: noOp, + }, + { // use previous wantState as currentState, + event: mBlockResponse("P1", 4), + wantState: ¶ms{items: []pcBlock{{"P1", 3}, {"P1", 4}}}, wantNextEvent: noOp, + }, + }, + }, + { + name: "add duplicate block from same peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{}, event: mBlockResponse("P1", 3), + wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: noOp, + }, + { // use previous wantState as currentState, + event: mBlockResponse("P1", 3), + wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcDuplicateBlock{}, + }, + }, + }, + { + name: "add duplicate block from different peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{}, event: mBlockResponse("P1", 3), + wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: noOp, + }, + { // use previous wantState as currentState, + event: mBlockResponse("P2", 3), + wantState: ¶ms{items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcDuplicateBlock{}, + }, + }, + }, + { + name: "attempt to add block with height equal to state.height", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, event: mBlockResponse("P1", 2), + wantState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcShortBlock{}, + }, + }, + }, + { + name: "attempt to add block with height smaller than state.height", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, event: mBlockResponse("P1", 1), + wantState: ¶ms{height: 2, items: []pcBlock{{"P1", 3}}}, wantNextEvent: pcShortBlock{}, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} + +func TestPcProcessBlockSuccess(t *testing.T) { + tests := []testFields{ + { + name: "noop - no blocks over current height", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{}, event: pcProcessBlock{}, + wantState: ¶ms{}, wantNextEvent: noOp, + }, + }, + }, + { + name: "noop - high new blocks", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 5, items: []pcBlock{{"P1", 30}, {"P2", 31}}}, event: pcProcessBlock{}, + wantState: ¶ms{height: 5, items: []pcBlock{{"P1", 30}, {"P2", 31}}}, wantNextEvent: noOp, + }, + }, + }, + { + name: "blocks H+1 and H+2 present", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, event: pcProcessBlock{}, + wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}}, blocksSynced: 1}, + wantNextEvent: pcBlockProcessed{height: 1, peerID: "P1"}, + }, + }, + }, + { + name: "blocks H+1 and H+2 present after draining", + steps: []pcFsmMakeStateValues{ + { // some contiguous blocks - on stop check draining is set + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P1", 4}}}, event: pcStop{}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}, {"P1", 4}}, draining: true}, + wantNextEvent: noOp, + }, + { + event: pcProcessBlock{}, + wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}, {"P1", 4}}, blocksSynced: 1, draining: true}, + wantNextEvent: pcBlockProcessed{height: 1, peerID: "P1"}, + }, + { // finish when H+1 or/and H+2 are missing + event: pcProcessBlock{}, + wantState: ¶ms{height: 1, items: []pcBlock{{"P2", 2}, {"P1", 4}}, blocksSynced: 1, draining: true}, + wantNextEvent: noOp, + wantErr: pcFinished{height: 1}, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} + +func TestPcProcessBlockFailures(t *testing.T) { + tests := []testFields{ + { + name: "blocks H+1 and H+2 present - H+1 verification fails ", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, verBL: []int64{1}}, event: pcProcessBlock{}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, verBL: []int64{1}}, + wantNextEvent: pcBlockVerificationFailure{peerID: "P1", height: 1}, + }, + }, + }, + { + name: "blocks H+1 and H+2 present - H+1 applyBlock fails ", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, appBL: []int64{1}}, event: pcProcessBlock{}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}, appBL: []int64{1}}, wantPanic: true, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} + +func TestPcPeerError(t *testing.T) { + tests := []testFields{ + { + name: "peer not present", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, event: &peerError{peerID: "P3"}, + wantState: ¶ms{items: []pcBlock{{"P1", 1}, {"P2", 2}}}, + wantNextEvent: noOp, + }, + }, + }, + { + name: "some blocks are from errored peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 100}, {"P1", 99}, {"P2", 101}}}, event: &peerError{peerID: "P1"}, + wantState: ¶ms{items: []pcBlock{{"P2", 101}}}, + wantNextEvent: noOp, + }, + }, + }, + { + name: "all blocks are from errored peer", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{items: []pcBlock{{"P1", 100}, {"P1", 99}}}, event: &peerError{peerID: "P1"}, + wantState: ¶ms{}, + wantNextEvent: noOp, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} + +func TestStop(t *testing.T) { + tests := []testFields{ + { + name: "no blocks", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 100, items: []pcBlock{}, blocksSynced: 100}, event: pcStop{}, + wantState: ¶ms{height: 100, items: []pcBlock{}, blocksSynced: 100}, + wantNextEvent: noOp, + wantErr: pcFinished{height: 100, blocksSynced: 100}, + }, + }, + }, + { + name: "maxHeight+1 block present", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}}, blocksSynced: 100}, event: pcStop{}, + wantState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}}, blocksSynced: 100}, + wantNextEvent: noOp, + wantErr: pcFinished{height: 100, blocksSynced: 100}, + }, + }, + }, + { + name: "more blocks present", + steps: []pcFsmMakeStateValues{ + { + currentState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}, {"P1", 102}}, blocksSynced: 100}, event: pcStop{}, + wantState: ¶ms{height: 100, items: []pcBlock{{"P1", 101}, {"P1", 102}}, blocksSynced: 100, draining: true}, + wantNextEvent: noOp, + wantErr: nil, + }, + }, + }, + } + + executeProcessorTests(t, tests) +} diff --git a/blockchain/v2/reactor.go b/blockchain/v2/reactor.go index 25ec41224..8f7143083 100644 --- a/blockchain/v2/reactor.go +++ b/blockchain/v2/reactor.go @@ -69,6 +69,7 @@ func (r *Reactor) Start() { }() } +// XXX: How to make this deterministic? // XXX: Would it be possible here to provide some kind of type safety for the types // of events that each routine can produce and consume? func (r *Reactor) demux() { diff --git a/blockchain/v2/schedule.go b/blockchain/v2/schedule.go index db3819b81..38c6c5d2d 100644 --- a/blockchain/v2/schedule.go +++ b/blockchain/v2/schedule.go @@ -164,6 +164,7 @@ func (sc *schedule) removePeer(peerID p2p.ID) error { return nil } +// TODO - keep track of highest height func (sc *schedule) setPeerHeight(peerID p2p.ID, height int64) error { peer, ok := sc.peers[peerID] if !ok { diff --git a/cmd/tendermint/commands/lite.go b/cmd/tendermint/commands/lite.go index 906af930b..1cc82ab2e 100644 --- a/cmd/tendermint/commands/lite.go +++ b/cmd/tendermint/commands/lite.go @@ -40,7 +40,11 @@ func init() { LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Tendermint node at this address") LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Tendermint chain ID") LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory") - LiteCmd.Flags().IntVar(&maxOpenConnections, "max-open-connections", 900, "Maximum number of simultaneous connections (including WebSocket).") + LiteCmd.Flags().IntVar( + &maxOpenConnections, + "max-open-connections", + 900, + "Maximum number of simultaneous connections (including WebSocket).") LiteCmd.Flags().IntVar(&cacheSize, "cache-size", 10, "Specify the memory trust store cache size") } diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index 70de9aba7..2faffc5ab 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -16,22 +16,37 @@ func AddNodeFlags(cmd *cobra.Command) { cmd.Flags().String("moniker", config.Moniker, "Node Name") // priv val flags - cmd.Flags().String("priv_validator_laddr", config.PrivValidatorListenAddr, "Socket address to listen on for connections from external priv_validator process") + cmd.Flags().String( + "priv_validator_laddr", + config.PrivValidatorListenAddr, + "Socket address to listen on for connections from external priv_validator process") // node flags cmd.Flags().Bool("fast_sync", config.FastSyncMode, "Fast blockchain syncing") // abci flags - cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or one of: 'kvstore', 'persistent_kvstore', 'counter', 'counter_serial' or 'noop' for local testing.") + cmd.Flags().String( + "proxy_app", + config.ProxyApp, + "Proxy app address, or one of: 'kvstore',"+ + " 'persistent_kvstore',"+ + " 'counter',"+ + " 'counter_serial' or 'noop' for local testing.") cmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)") // rpc flags cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") - cmd.Flags().String("rpc.grpc_laddr", config.RPC.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required") + cmd.Flags().String( + "rpc.grpc_laddr", + config.RPC.GRPCListenAddress, + "GRPC listen address (BroadcastTx only). Port required") cmd.Flags().Bool("rpc.unsafe", config.RPC.Unsafe, "Enabled unsafe rpc methods") // p2p flags - cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") + cmd.Flags().String( + "p2p.laddr", + config.P2P.ListenAddress, + "Node listen address. (0.0.0.0:0 means any interface, any port)") cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma-delimited ID@host:port seed nodes") cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma-delimited ID@host:port persistent peers") cmd.Flags().Bool("p2p.upnp", config.P2P.UPNP, "Enable/disable UPNP port forwarding") @@ -40,7 +55,10 @@ func AddNodeFlags(cmd *cobra.Command) { cmd.Flags().String("p2p.private_peer_ids", config.P2P.PrivatePeerIDs, "Comma-delimited private peer IDs") // consensus flags - cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes") + cmd.Flags().Bool( + "consensus.create_empty_blocks", + config.Consensus.CreateEmptyBlocks, + "Set this to false to only produce blocks when there are txs or when the AppHash changes") } // NewRunNodeCmd returns the command that allows the CLI to start a node. diff --git a/cmd/tendermint/commands/testnet.go b/cmd/tendermint/commands/testnet.go index 5e2dc1a3a..5f199908e 100644 --- a/cmd/tendermint/commands/testnet.go +++ b/cmd/tendermint/commands/testnet.go @@ -51,13 +51,19 @@ func init() { "Prefix the directory name for each node with (node results in node0, node1, ...)") TestnetFilesCmd.Flags().BoolVar(&populatePersistentPeers, "populate-persistent-peers", true, - "Update config of each node with the list of persistent peers build using either hostname-prefix or starting-ip-address") + "Update config of each node with the list of persistent peers build using either"+ + " hostname-prefix or"+ + " starting-ip-address") TestnetFilesCmd.Flags().StringVar(&hostnamePrefix, "hostname-prefix", "node", "Hostname prefix (\"node\" results in persistent peers list ID0@node0:26656, ID1@node1:26656, ...)") TestnetFilesCmd.Flags().StringVar(&hostnameSuffix, "hostname-suffix", "", - "Hostname suffix (\".xyz.com\" results in persistent peers list ID0@node0.xyz.com:26656, ID1@node1.xyz.com:26656, ...)") + "Hostname suffix ("+ + "\".xyz.com\""+ + " results in persistent peers list ID0@node0.xyz.com:26656, ID1@node1.xyz.com:26656, ...)") TestnetFilesCmd.Flags().StringVar(&startingIPAddress, "starting-ip-address", "", - "Starting IP address (\"192.168.0.1\" results in persistent peers list ID0@192.168.0.1:26656, ID1@192.168.0.2:26656, ...)") + "Starting IP address ("+ + "\"192.168.0.1\""+ + " results in persistent peers list ID0@192.168.0.1:26656, ID1@192.168.0.2:26656, ...)") TestnetFilesCmd.Flags().StringArrayVar(&hostnames, "hostname", []string{}, "Manually override all hostnames of validators and non-validators (use --hostname multiple times for multiple hosts)") TestnetFilesCmd.Flags().IntVar(&p2pPort, "p2p-port", 26656, diff --git a/config/config.go b/config/config.go index 3e4bf9340..c5d42c7e8 100644 --- a/config/config.go +++ b/config/config.go @@ -140,7 +140,7 @@ func (cfg *Config) ValidateBasic() error { // BaseConfig // BaseConfig defines the base configuration for a Tendermint node -type BaseConfig struct { +type BaseConfig struct { //nolint: maligned // chainID is unexposed and immutable but here for convenience chainID string @@ -371,13 +371,15 @@ type RPCConfig struct { // the certFile should be the concatenation of the server's certificate, any intermediates, // and the CA's certificate. // - // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. + // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + // Otherwise, HTTP server is run. TLSCertFile string `mapstructure:"tls_cert_file"` // The path to a file containing matching private key that is used to create the HTTPS server. // Migth be either absolute path or path related to tendermint's config directory. // - // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. + // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. + // Otherwise, HTTP server is run. TLSKeyFile string `mapstructure:"tls_key_file"` } @@ -471,7 +473,7 @@ func (cfg RPCConfig) IsTLSEnabled() bool { // P2PConfig // P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer -type P2PConfig struct { +type P2PConfig struct { //nolint: maligned RootDir string `mapstructure:"home"` // Address to listen for incoming connections @@ -814,7 +816,8 @@ func (cfg *ConsensusConfig) Precommit(round int) time.Duration { ) * time.Nanosecond } -// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). +// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits +// for a single block (ie. a commit). func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { return t.Add(cfg.TimeoutCommit) } @@ -878,7 +881,8 @@ type TxIndexConfig struct { // // Options: // 1) "null" - // 2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend). + // 2) "kv" (default) - the simplest possible indexer, + // backed by key-value storage (defaults to levelDB; see DBBackend). Indexer string `mapstructure:"indexer"` // Comma-separated list of tags to index (by default the only tag is "tx.hash") diff --git a/config/toml.go b/config/toml.go index 268c96ff9..b9d4b6a8b 100644 --- a/config/toml.go +++ b/config/toml.go @@ -67,6 +67,11 @@ func WriteConfigFile(configFilePath string, config *Config) { const defaultConfigTemplate = `# This is a TOML config file. # For more information, see https://github.com/toml-lang/toml +# NOTE: Any path below can be absolute (e.g. "/var/myawesomeapp/data") or +# relative to the home directory (e.g. "data"). The home directory is +# "$HOME/.tendermint" by default, but could be changed via $TMHOME env variable +# or --home cmd flag. + ##### main base config options ##### # TCP or UNIX socket address of the ABCI application, @@ -203,12 +208,14 @@ max_header_bytes = {{ .RPC.MaxHeaderBytes }} # If the certificate is signed by a certificate authority, # the certFile should be the concatenation of the server's certificate, any intermediates, # and the CA's certificate. -# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. +# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. +# Otherwise, HTTP server is run. tls_cert_file = "{{ .RPC.TLSCertFile }}" # The path to a file containing matching private key that is used to create the HTTPS server. # Migth be either absolute path or path related to tendermint's config directory. -# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. +# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. +# Otherwise, HTTP server is run. tls_key_file = "{{ .RPC.TLSKeyFile }}" ##### peer to peer configuration options ##### diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 1c52e79ad..1129f69c4 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -206,7 +206,14 @@ func byzantineDecideProposalFunc(t *testing.T, height int64, round int, cs *Cons } } -func sendProposalAndParts(height int64, round int, cs *ConsensusState, peer p2p.Peer, proposal *types.Proposal, blockHash []byte, parts *types.PartSet) { +func sendProposalAndParts( + height int64, + round int, + cs *ConsensusState, + peer p2p.Peer, + proposal *types.Proposal, + blockHash []byte, + parts *types.PartSet) { // proposal msg := &ProposalMessage{Proposal: proposal} peer.Send(DataChannel, cdc.MustMarshalBinaryBare(msg)) diff --git a/consensus/common_test.go b/consensus/common_test.go index 61d29d849..2cc3a3288 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -77,7 +77,10 @@ func NewValidatorStub(privValidator types.PrivValidator, valIndex int) *validato } } -func (vs *validatorStub) signVote(voteType types.SignedMsgType, hash []byte, header types.PartSetHeader) (*types.Vote, error) { +func (vs *validatorStub) signVote( + voteType types.SignedMsgType, + hash []byte, + header types.PartSetHeader) (*types.Vote, error) { addr := vs.PrivValidator.GetPubKey().Address() vote := &types.Vote{ ValidatorIndex: vs.Index, @@ -101,7 +104,11 @@ func signVote(vs *validatorStub, voteType types.SignedMsgType, hash []byte, head return v } -func signVotes(voteType types.SignedMsgType, hash []byte, header types.PartSetHeader, vss ...*validatorStub) []*types.Vote { +func signVotes( + voteType types.SignedMsgType, + hash []byte, + header types.PartSetHeader, + vss ...*validatorStub) []*types.Vote { votes := make([]*types.Vote, len(vss)) for i, vs := range vss { votes[i] = signVote(vs, voteType, hash, header) @@ -148,7 +155,11 @@ func startTestRound(cs *ConsensusState, height int64, round int) { } // Create proposal block from cs1 but sign it with vs. -func decideProposal(cs1 *ConsensusState, vs *validatorStub, height int64, round int) (proposal *types.Proposal, block *types.Block) { +func decideProposal( + cs1 *ConsensusState, + vs *validatorStub, + height int64, + round int) (proposal *types.Proposal, block *types.Block) { cs1.mtx.Lock() block, blockParts := cs1.createProposalBlock() validRound := cs1.ValidRound @@ -173,7 +184,12 @@ func addVotes(to *ConsensusState, votes ...*types.Vote) { } } -func signAddVotes(to *ConsensusState, voteType types.SignedMsgType, hash []byte, header types.PartSetHeader, vss ...*validatorStub) { +func signAddVotes( + to *ConsensusState, + voteType types.SignedMsgType, + hash []byte, + header types.PartSetHeader, + vss ...*validatorStub) { votes := signVotes(voteType, hash, header, vss...) addVotes(to, votes...) } @@ -208,7 +224,14 @@ func validateLastPrecommit(t *testing.T, cs *ConsensusState, privVal *validatorS } } -func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { +func validatePrecommit( + t *testing.T, + cs *ConsensusState, + thisRound, + lockRound int, + privVal *validatorStub, + votedBlockHash, + lockedBlockHash []byte) { precommits := cs.Votes.Precommits(thisRound) address := privVal.GetPubKey().Address() var vote *types.Vote @@ -228,17 +251,33 @@ func validatePrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound in if lockedBlockHash == nil { if cs.LockedRound != lockRound || cs.LockedBlock != nil { - panic(fmt.Sprintf("Expected to be locked on nil at round %d. Got locked at round %d with block %v", lockRound, cs.LockedRound, cs.LockedBlock)) + panic(fmt.Sprintf( + "Expected to be locked on nil at round %d. Got locked at round %d with block %v", + lockRound, + cs.LockedRound, + cs.LockedBlock)) } } else { if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) { - panic(fmt.Sprintf("Expected block to be locked on round %d, got %d. Got locked block %X, expected %X", lockRound, cs.LockedRound, cs.LockedBlock.Hash(), lockedBlockHash)) + panic(fmt.Sprintf( + "Expected block to be locked on round %d, got %d. Got locked block %X, expected %X", + lockRound, + cs.LockedRound, + cs.LockedBlock.Hash(), + lockedBlockHash)) } } } -func validatePrevoteAndPrecommit(t *testing.T, cs *ConsensusState, thisRound, lockRound int, privVal *validatorStub, votedBlockHash, lockedBlockHash []byte) { +func validatePrevoteAndPrecommit( + t *testing.T, + cs *ConsensusState, + thisRound, + lockRound int, + privVal *validatorStub, + votedBlockHash, + lockedBlockHash []byte) { // verify the prevote validatePrevote(t, cs, thisRound, privVal, votedBlockHash) // verify precommit @@ -273,12 +312,21 @@ func newConsensusState(state sm.State, pv types.PrivValidator, app abci.Applicat return newConsensusStateWithConfig(config, state, pv, app) } -func newConsensusStateWithConfig(thisConfig *cfg.Config, state sm.State, pv types.PrivValidator, app abci.Application) *ConsensusState { +func newConsensusStateWithConfig( + thisConfig *cfg.Config, + state sm.State, + pv types.PrivValidator, + app abci.Application) *ConsensusState { blockDB := dbm.NewMemDB() return newConsensusStateWithConfigAndBlockStore(thisConfig, state, pv, app, blockDB) } -func newConsensusStateWithConfigAndBlockStore(thisConfig *cfg.Config, state sm.State, pv types.PrivValidator, app abci.Application, blockDB dbm.DB) *ConsensusState { +func newConsensusStateWithConfigAndBlockStore( + thisConfig *cfg.Config, + state sm.State, + pv types.PrivValidator, + app abci.Application, + blockDB dbm.DB) *ConsensusState { // Get BlockStore blockStore := store.NewBlockStore(blockDB) @@ -597,7 +645,12 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou } // nPeers = nValidators + nNotValidator -func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerFunc func() TimeoutTicker, appFunc func(string) abci.Application) ([]*ConsensusState, *types.GenesisDoc, *cfg.Config, cleanupFunc) { +func randConsensusNetWithPeers( + nValidators, + nPeers int, + testName string, + tickerFunc func() TimeoutTicker, + appFunc func(string) abci.Application) ([]*ConsensusState, *types.GenesisDoc, *cfg.Config, cleanupFunc) { genDoc, privVals := randGenesisDoc(nValidators, false, testMinPower) css := make([]*ConsensusState, nPeers) logger := consensusLogger() @@ -631,7 +684,8 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF app := appFunc(path.Join(config.DBDir(), fmt.Sprintf("%s_%d", testName, i))) vals := types.TM2PB.ValidatorUpdates(state.Validators) if _, ok := app.(*kvstore.PersistentKVStoreApplication); ok { - state.Version.Consensus.App = kvstore.ProtocolVersion //simulate handshake, receive app version. If don't do this, replay test will fail + // simulate handshake, receive app version. If don't do this, replay test will fail + state.Version.Consensus.App = kvstore.ProtocolVersion } app.InitChain(abci.RequestInitChain{Validators: vals}) //sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index c1d4f69a7..30c522a75 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -99,7 +99,7 @@ func deliverTxsRange(cs *ConsensusState, start, end int) { for i := start; i < end; i++ { txBytes := make([]byte, 8) binary.BigEndian.PutUint64(txBytes, uint64(i)) - err := assertMempool(cs.txNotifier).CheckTx(txBytes, nil) + err := assertMempool(cs.txNotifier).CheckTx(txBytes, nil, mempl.TxInfo{}) if err != nil { panic(fmt.Sprintf("Error after CheckTx: %v", err)) } @@ -159,7 +159,7 @@ func TestMempoolRmBadTx(t *testing.T) { return } checkTxRespCh <- struct{}{} - }) + }, mempl.TxInfo{}) if err != nil { t.Errorf("Error after CheckTx: %v", err) return diff --git a/consensus/reactor.go b/consensus/reactor.go index a24981dec..6d4b61219 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -137,8 +137,9 @@ func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor { RecvMessageCapacity: maxMsgSize, }, { - ID: DataChannel, // maybe split between gossiping current block and catchup stuff - Priority: 10, // once we gossip the whole block there's nothing left to send until next height or round + ID: DataChannel, // maybe split between gossiping current block and catchup stuff + // once we gossip the whole block there's nothing left to send until next height or round + Priority: 10, SendQueueCapacity: 100, RecvBufferCapacity: 50 * 4096, RecvMessageCapacity: maxMsgSize, @@ -670,7 +671,11 @@ OUTER_LOOP: } } -func (conR *ConsensusReactor) gossipVotesForHeight(logger log.Logger, rs *cstypes.RoundState, prs *cstypes.PeerRoundState, ps *PeerState) bool { +func (conR *ConsensusReactor) gossipVotesForHeight( + logger log.Logger, + rs *cstypes.RoundState, + prs *cstypes.PeerRoundState, + ps *PeerState) bool { // If there are lastCommits to send... if prs.Step == cstypes.RoundStepNewHeight { @@ -1119,7 +1124,13 @@ func (ps *PeerState) ensureCatchupCommitRound(height int64, round int, numValida NOTE: This is wrong, 'round' could change. e.g. if orig round is not the same as block LastCommit round. if ps.CatchupCommitRound != -1 && ps.CatchupCommitRound != round { - panic(fmt.Sprintf("Conflicting CatchupCommitRound. Height: %v, Orig: %v, New: %v", height, ps.CatchupCommitRound, round)) + panic(fmt.Sprintf( + "Conflicting CatchupCommitRound. Height: %v, + Orig: %v, + New: %v", + height, + ps.CatchupCommitRound, + round)) } */ if ps.PRS.CatchupCommitRound == round { @@ -1211,7 +1222,11 @@ func (ps *PeerState) SetHasVote(vote *types.Vote) { } func (ps *PeerState) setHasVote(height int64, round int, type_ types.SignedMsgType, index int) { - logger := ps.logger.With("peerH/R", fmt.Sprintf("%d/%d", ps.PRS.Height, ps.PRS.Round), "H/R", fmt.Sprintf("%d/%d", height, round)) + logger := ps.logger.With( + "peerH/R", + fmt.Sprintf("%d/%d", ps.PRS.Height, ps.PRS.Round), + "H/R", + fmt.Sprintf("%d/%d", height, round)) logger.Debug("setHasVote", "type", type_, "index", index) // NOTE: some may be nil BitArrays -> no side effects. diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 1ebc91002..b0bd4c502 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -237,7 +237,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) // send a tx - if err := assertMempool(css[3].txNotifier).CheckTx([]byte{1, 2, 3}, nil); err != nil { + if err := assertMempool(css[3].txNotifier).CheckTx([]byte{1, 2, 3}, nil, mempl.TxInfo{}); err != nil { t.Error(err) } @@ -318,7 +318,11 @@ func TestReactorRecordsVotesAndBlockParts(t *testing.T) { func TestReactorVotingPowerChange(t *testing.T) { nVals := 4 logger := log.TestingLogger() - css, cleanup := randConsensusNet(nVals, "consensus_voting_power_changes_test", newMockTickerFunc(true), newPersistentKVStore) + css, cleanup := randConsensusNet( + nVals, + "consensus_voting_power_changes_test", + newMockTickerFunc(true), + newPersistentKVStore) defer cleanup() reactors, blocksSubs, eventBuses := startConsensusNet(t, css, nVals) defer stopConsensusNet(logger, reactors, eventBuses) @@ -349,7 +353,10 @@ func TestReactorVotingPowerChange(t *testing.T) { waitForAndValidateBlock(t, nVals, activeVals, blocksSubs, css) if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) + t.Fatalf( + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, + css[0].GetRoundState().LastValidators.TotalVotingPower()) } updateValidatorTx = kvstore.MakeValSetChangeTx(val1PubKeyABCI, 2) @@ -361,7 +368,10 @@ func TestReactorVotingPowerChange(t *testing.T) { waitForAndValidateBlock(t, nVals, activeVals, blocksSubs, css) if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) + t.Fatalf( + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, + css[0].GetRoundState().LastValidators.TotalVotingPower()) } updateValidatorTx = kvstore.MakeValSetChangeTx(val1PubKeyABCI, 26) @@ -373,14 +383,22 @@ func TestReactorVotingPowerChange(t *testing.T) { waitForAndValidateBlock(t, nVals, activeVals, blocksSubs, css) if css[0].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Fatalf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[0].GetRoundState().LastValidators.TotalVotingPower()) + t.Fatalf( + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, + css[0].GetRoundState().LastValidators.TotalVotingPower()) } } func TestReactorValidatorSetChanges(t *testing.T) { nPeers := 7 nVals := 4 - css, _, _, cleanup := randConsensusNetWithPeers(nVals, nPeers, "consensus_val_set_changes_test", newMockTickerFunc(true), newPersistentKVStoreWithPath) + css, _, _, cleanup := randConsensusNetWithPeers( + nVals, + nPeers, + "consensus_val_set_changes_test", + newMockTickerFunc(true), + newPersistentKVStoreWithPath) defer cleanup() logger := log.TestingLogger() @@ -441,7 +459,10 @@ func TestReactorValidatorSetChanges(t *testing.T) { waitForBlockWithUpdatedValsAndValidateIt(t, nPeers, activeVals, blocksSubs, css) if css[nVals].GetRoundState().LastValidators.TotalVotingPower() == previousTotalVotingPower { - t.Errorf("expected voting power to change (before: %d, after: %d)", previousTotalVotingPower, css[nVals].GetRoundState().LastValidators.TotalVotingPower()) + t.Errorf( + "expected voting power to change (before: %d, after: %d)", + previousTotalVotingPower, + css[nVals].GetRoundState().LastValidators.TotalVotingPower()) } //--------------------------------------------------------------------------- @@ -511,7 +532,7 @@ func waitForAndValidateBlock( err := validateBlock(newBlock, activeVals) assert.Nil(t, err) for _, tx := range txs { - err := assertMempool(css[j].txNotifier).CheckTx(tx, nil) + err := assertMempool(css[j].txNotifier).CheckTx(tx, nil, mempl.TxInfo{}) assert.Nil(t, err) } }, css) @@ -571,7 +592,10 @@ func waitForBlockWithUpdatedValsAndValidateIt( css[j].Logger.Debug("waitForBlockWithUpdatedValsAndValidateIt: Got block", "height", newBlock.Height) break LOOP } else { - css[j].Logger.Debug("waitForBlockWithUpdatedValsAndValidateIt: Got block with no new validators. Skipping", "height", newBlock.Height) + css[j].Logger.Debug( + "waitForBlockWithUpdatedValsAndValidateIt: Got block with no new validators. Skipping", + "height", + newBlock.Height) } } @@ -583,7 +607,10 @@ func waitForBlockWithUpdatedValsAndValidateIt( // expects high synchrony! func validateBlock(block *types.Block, activeVals map[string]struct{}) error { if block.LastCommit.Size() != len(activeVals) { - return fmt.Errorf("Commit size doesn't match number of active validators. Got %d, expected %d", block.LastCommit.Size(), len(activeVals)) + return fmt.Errorf( + "Commit size doesn't match number of active validators. Got %d, expected %d", + block.LastCommit.Size(), + len(activeVals)) } for _, vote := range block.LastCommit.Precommits { @@ -640,20 +667,20 @@ func capture() { // Ensure basic validation of structs is functioning func TestNewRoundStepMessageValidateBasic(t *testing.T) { - testCases := []struct { - testName string - messageHeight int64 - messageRound int - messageStep cstypes.RoundStepType - messageLastCommitRound int + testCases := []struct { // nolint: maligned expectErr bool + messageRound int + messageLastCommitRound int + messageHeight int64 + testName string + messageStep cstypes.RoundStepType }{ - {"Valid Message", 0, 0, 0x01, 1, false}, - {"Invalid Message", -1, 0, 0x01, 1, true}, - {"Invalid Message", 0, -1, 0x01, 1, true}, - {"Invalid Message", 0, 0, 0x00, 1, true}, - {"Invalid Message", 0, 0, 0x00, 0, true}, - {"Invalid Message", 1, 0, 0x01, 0, true}, + {false, 0, 0, 0, "Valid Message", 0x01}, + {true, -1, 0, 0, "Invalid Message", 0x01}, + {true, 0, 0, -1, "Invalid Message", 0x01}, + {true, 0, 0, 1, "Invalid Message", 0x00}, + {true, 0, 0, 1, "Invalid Message", 0x00}, + {true, 0, -2, 2, "Invalid Message", 0x01}, } for _, tc := range testCases { @@ -785,19 +812,19 @@ func TestHasVoteMessageValidateBasic(t *testing.T) { invalidSignedMsgType types.SignedMsgType = 0x03 ) - testCases := []struct { - testName string - messageHeight int64 - messageRound int - messageType types.SignedMsgType - messageIndex int + testCases := []struct { // nolint: maligned expectErr bool + messageRound int + messageIndex int + messageHeight int64 + testName string + messageType types.SignedMsgType }{ - {"Valid Message", 0, 0, validSignedMsgType, 0, false}, - {"Invalid Message", -1, 0, validSignedMsgType, 0, true}, - {"Invalid Message", 0, -1, validSignedMsgType, 0, true}, - {"Invalid Message", 0, 0, invalidSignedMsgType, 0, true}, - {"Invalid Message", 0, 0, validSignedMsgType, -1, true}, + {false, 0, 0, 0, "Valid Message", validSignedMsgType}, + {true, -1, 0, 0, "Invalid Message", validSignedMsgType}, + {true, 0, -1, 0, "Invalid Message", validSignedMsgType}, + {true, 0, 0, 0, "Invalid Message", invalidSignedMsgType}, + {true, 0, 0, -1, "Invalid Message", validSignedMsgType}, } for _, tc := range testCases { @@ -830,19 +857,19 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) { }, } - testCases := []struct { - testName string - messageHeight int64 + testCases := []struct { // nolint: maligned + expectErr bool messageRound int + messageHeight int64 + testName string messageType types.SignedMsgType messageBlockID types.BlockID - expectErr bool }{ - {"Valid Message", 0, 0, validSignedMsgType, validBlockID, false}, - {"Invalid Message", -1, 0, validSignedMsgType, validBlockID, true}, - {"Invalid Message", 0, -1, validSignedMsgType, validBlockID, true}, - {"Invalid Message", 0, 0, invalidSignedMsgType, validBlockID, true}, - {"Invalid Message", 0, 0, validSignedMsgType, invalidBlockID, true}, + {false, 0, 0, "Valid Message", validSignedMsgType, validBlockID}, + {true, -1, 0, "Invalid Message", validSignedMsgType, validBlockID}, + {true, 0, -1, "Invalid Message", validSignedMsgType, validBlockID}, + {true, 0, 0, "Invalid Message", invalidSignedMsgType, validBlockID}, + {true, 0, 0, "Invalid Message", validSignedMsgType, invalidBlockID}, } for _, tc := range testCases { @@ -861,7 +888,7 @@ func TestVoteSetMaj23MessageValidateBasic(t *testing.T) { } func TestVoteSetBitsMessageValidateBasic(t *testing.T) { - testCases := []struct { // nolint: maligned + testCases := []struct { malleateFn func(*VoteSetBitsMessage) expErr string }{ diff --git a/consensus/replay.go b/consensus/replay.go index 83c6b3d40..e5f28aa03 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -290,7 +290,14 @@ func (h *Handshaker) ReplayBlocks( ) ([]byte, error) { storeBlockHeight := h.store.Height() stateBlockHeight := state.LastBlockHeight - h.logger.Info("ABCI Replay Blocks", "appHeight", appBlockHeight, "storeHeight", storeBlockHeight, "stateHeight", stateBlockHeight) + h.logger.Info( + "ABCI Replay Blocks", + "appHeight", + appBlockHeight, + "storeHeight", + storeBlockHeight, + "stateHeight", + stateBlockHeight) // If appBlockHeight == 0 it means that we are at genesis and hence should send InitChain. if appBlockHeight == 0 { @@ -405,7 +412,12 @@ func (h *Handshaker) ReplayBlocks( appBlockHeight, storeBlockHeight, stateBlockHeight)) } -func (h *Handshaker) replayBlocks(state sm.State, proxyApp proxy.AppConns, appBlockHeight, storeBlockHeight int64, mutateState bool) ([]byte, error) { +func (h *Handshaker) replayBlocks( + state sm.State, + proxyApp proxy.AppConns, + appBlockHeight, + storeBlockHeight int64, + mutateState bool) ([]byte, error) { // App is further behind than it should be, so we need to replay blocks. // We replay all blocks from appBlockHeight+1. // diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 04d0f1eb5..b3ebf7340 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -23,6 +23,7 @@ import ( "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/log" + mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/mock" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" @@ -67,7 +68,12 @@ func startNewConsensusStateAndWaitForBlock(t *testing.T, consensusReplayConfig * logger := log.TestingLogger() state, _ := sm.LoadStateFromDBOrGenesisFile(stateDB, consensusReplayConfig.GenesisFile()) privValidator := loadPrivValidator(consensusReplayConfig) - cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) + cs := newConsensusStateWithConfigAndBlockStore( + consensusReplayConfig, + state, + privValidator, + kvstore.NewKVStoreApplication(), + blockDB) cs.SetLogger(logger) bytes, _ := ioutil.ReadFile(cs.config.WalFile()) @@ -99,7 +105,7 @@ func sendTxs(ctx context.Context, cs *ConsensusState) { return default: tx := []byte{byte(i)} - assertMempool(cs.txNotifier).CheckTx(tx, nil) + assertMempool(cs.txNotifier).CheckTx(tx, nil, mempl.TxInfo{}) i++ } } @@ -147,7 +153,12 @@ LOOP: stateDB := blockDB state, _ := sm.MakeGenesisStateFromFile(consensusReplayConfig.GenesisFile()) privValidator := loadPrivValidator(consensusReplayConfig) - cs := newConsensusStateWithConfigAndBlockStore(consensusReplayConfig, state, privValidator, kvstore.NewKVStoreApplication(), blockDB) + cs := newConsensusStateWithConfigAndBlockStore( + consensusReplayConfig, + state, + privValidator, + kvstore.NewKVStoreApplication(), + blockDB) cs.SetLogger(logger) // start sending transactions @@ -257,7 +268,9 @@ func (w *crashingWAL) WriteSync(m WALMessage) error { func (w *crashingWAL) FlushAndSync() error { return w.next.FlushAndSync() } -func (w *crashingWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { +func (w *crashingWAL) SearchForEndHeight( + height int64, + options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { return w.next.SearchForEndHeight(height, options) } @@ -297,7 +310,12 @@ var modes = []uint{0, 1, 2} func TestSimulateValidatorsChange(t *testing.T) { nPeers := 7 nVals := 4 - css, genDoc, config, cleanup := randConsensusNetWithPeers(nVals, nPeers, "replay_test", newMockTickerFunc(true), newPersistentKVStoreWithPath) + css, genDoc, config, cleanup := randConsensusNetWithPeers( + nVals, + nPeers, + "replay_test", + newMockTickerFunc(true), + newPersistentKVStoreWithPath) sim.Config = config sim.GenesisState, _ = sm.MakeGenesisState(genDoc) sim.CleanupFunc = cleanup @@ -327,7 +345,7 @@ func TestSimulateValidatorsChange(t *testing.T) { newValidatorPubKey1 := css[nVals].privValidator.GetPubKey() valPubKey1ABCI := types.TM2PB.PubKey(newValidatorPubKey1) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) - err := assertMempool(css[0].txNotifier).CheckTx(newValidatorTx1, nil) + err := assertMempool(css[0].txNotifier).CheckTx(newValidatorTx1, nil, mempl.TxInfo{}) assert.Nil(t, err) propBlock, _ := css[0].createProposalBlock() //changeProposer(t, cs1, vs2) propBlockParts := propBlock.MakePartSet(partSize) @@ -352,7 +370,7 @@ func TestSimulateValidatorsChange(t *testing.T) { updateValidatorPubKey1 := css[nVals].privValidator.GetPubKey() updatePubKey1ABCI := types.TM2PB.PubKey(updateValidatorPubKey1) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) - err = assertMempool(css[0].txNotifier).CheckTx(updateValidatorTx1, nil) + err = assertMempool(css[0].txNotifier).CheckTx(updateValidatorTx1, nil, mempl.TxInfo{}) assert.Nil(t, err) propBlock, _ = css[0].createProposalBlock() //changeProposer(t, cs1, vs2) propBlockParts = propBlock.MakePartSet(partSize) @@ -377,12 +395,12 @@ func TestSimulateValidatorsChange(t *testing.T) { newValidatorPubKey2 := css[nVals+1].privValidator.GetPubKey() newVal2ABCI := types.TM2PB.PubKey(newValidatorPubKey2) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx2, nil) + err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx2, nil, mempl.TxInfo{}) assert.Nil(t, err) newValidatorPubKey3 := css[nVals+2].privValidator.GetPubKey() newVal3ABCI := types.TM2PB.PubKey(newValidatorPubKey3) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) - err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx3, nil) + err = assertMempool(css[0].txNotifier).CheckTx(newValidatorTx3, nil, mempl.TxInfo{}) assert.Nil(t, err) propBlock, _ = css[0].createProposalBlock() //changeProposer(t, cs1, vs2) propBlockParts = propBlock.MakePartSet(partSize) @@ -410,7 +428,7 @@ func TestSimulateValidatorsChange(t *testing.T) { ensureNewProposal(proposalCh, height, round) removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) - err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx2, nil) + err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx2, nil, mempl.TxInfo{}) assert.Nil(t, err) rs = css[0].GetRoundState() @@ -440,7 +458,7 @@ func TestSimulateValidatorsChange(t *testing.T) { height++ incrementHeight(vss...) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) - err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx3, nil) + err = assertMempool(css[0].txNotifier).CheckTx(removeValidatorTx3, nil, mempl.TxInfo{}) assert.Nil(t, err) propBlock, _ = css[0].createProposalBlock() //changeProposer(t, cs1, vs2) propBlockParts = propBlock.MakePartSet(partSize) @@ -586,7 +604,8 @@ func tempWALWithData(data []byte) string { return walFile.Name() } -// Make some blocks. Start a fresh app and apply nBlocks blocks. Then restart the app and sync it up with the remaining blocks +// Make some blocks. Start a fresh app and apply nBlocks blocks. +// Then restart the app and sync it up with the remaining blocks func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uint, testValidatorsChange bool) { var chain []*types.Block var commits []*types.Commit @@ -632,7 +651,8 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin latestAppHash := state.AppHash // make a new client creator - kvstoreApp := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_a", nBlocks, mode))) + kvstoreApp := kvstore.NewPersistentKVStoreApplication( + filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_a", nBlocks, mode))) clientCreator2 := proxy.NewLocalClientCreator(kvstoreApp) if nBlocks > 0 { @@ -664,7 +684,10 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin // the app hash should be synced up if !bytes.Equal(latestAppHash, res.LastBlockAppHash) { - t.Fatalf("Expected app hashes to match after handshake/replay. got %X, expected %X", res.LastBlockAppHash, latestAppHash) + t.Fatalf( + "Expected app hashes to match after handshake/replay. got %X, expected %X", + res.LastBlockAppHash, + latestAppHash) } expectedBlocksToSync := numBlocks - nBlocks @@ -729,9 +752,17 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateDB dbm.DB, } -func buildTMStateFromChain(config *cfg.Config, stateDB dbm.DB, state sm.State, chain []*types.Block, nBlocks int, mode uint) sm.State { +func buildTMStateFromChain( + config *cfg.Config, + stateDB dbm.DB, + state sm.State, + chain []*types.Block, + nBlocks int, + mode uint) sm.State { // run the whole chain against this client to build up the tendermint state - clientCreator := proxy.NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))) + clientCreator := proxy.NewLocalClientCreator( + kvstore.NewPersistentKVStoreApplication( + filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))) proxyApp := proxy.NewAppConns(clientCreator) if err := proxyApp.Start(); err != nil { panic(err) @@ -854,7 +885,12 @@ func makeBlock(state sm.State, lastBlock *types.Block, lastBlockMeta *types.Bloc lastCommit := types.NewCommit(types.BlockID{}, nil) if height > 1 { - vote, _ := types.MakeVote(lastBlock.Header.Height, lastBlockMeta.BlockID, state.Validators, privVal, lastBlock.Header.ChainID) + vote, _ := types.MakeVote( + lastBlock.Header.Height, + lastBlockMeta.BlockID, + state.Validators, + privVal, + lastBlock.Header.ChainID) voteCommitSig := vote.CommitSig() lastCommit = types.NewCommit(lastBlockMeta.BlockID, []*types.CommitSig{voteCommitSig}) } @@ -995,7 +1031,10 @@ func readPieceFromWAL(msg *TimedWALMessage) interface{} { } // fresh state and mock store -func stateAndStore(config *cfg.Config, pubKey crypto.PubKey, appVersion version.Protocol) (dbm.DB, sm.State, *mockBlockStore) { +func stateAndStore( + config *cfg.Config, + pubKey crypto.PubKey, + appVersion version.Protocol) (dbm.DB, sm.State, *mockBlockStore) { stateDB := dbm.NewMemDB() state, _ := sm.MakeGenesisStateFromFile(config.GenesisFile()) state.Version.Consensus.App = appVersion diff --git a/consensus/state.go b/consensus/state.go index 110c2529c..2eedc8994 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -425,7 +425,11 @@ func (cs *ConsensusState) AddProposalBlockPart(height int64, round int, part *ty } // SetProposalAndBlock inputs the proposal and all block parts. -func (cs *ConsensusState) SetProposalAndBlock(proposal *types.Proposal, block *types.Block, parts *types.PartSet, peerID p2p.ID) error { +func (cs *ConsensusState) SetProposalAndBlock( + proposal *types.Proposal, + block *types.Block, + parts *types.PartSet, + peerID p2p.ID) error { if err := cs.SetProposal(proposal, peerID); err != nil { return err } @@ -511,7 +515,12 @@ func (cs *ConsensusState) updateToState(state sm.State) { // signal the new round step, because other services (eg. txNotifier) // depend on having an up-to-date peer state! if !cs.state.IsEmpty() && (state.LastBlockHeight <= cs.state.LastBlockHeight) { - cs.Logger.Info("Ignoring updateToState()", "newHeight", state.LastBlockHeight+1, "oldHeight", cs.state.LastBlockHeight+1) + cs.Logger.Info( + "Ignoring updateToState()", + "newHeight", + state.LastBlockHeight+1, + "oldHeight", + cs.state.LastBlockHeight+1) cs.newStep() return } @@ -682,7 +691,14 @@ func (cs *ConsensusState) handleMsg(mi msgInfo) { } if err != nil && msg.Round != cs.Round { - cs.Logger.Debug("Received block part from wrong round", "height", cs.Height, "csRound", cs.Round, "blockRound", msg.Round) + cs.Logger.Debug( + "Received block part from wrong round", + "height", + cs.Height, + "csRound", + cs.Round, + "blockRound", + msg.Round) err = nil } case *VoteMessage: @@ -794,7 +810,13 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) { logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { - logger.Debug(fmt.Sprintf("enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) + logger.Debug(fmt.Sprintf( + "enterNewRound(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + round, + cs.Height, + cs.Round, + cs.Step)) return } @@ -858,13 +880,20 @@ func (cs *ConsensusState) needProofBlock(height int64) bool { } // Enter (CreateEmptyBlocks): from enterNewRound(height,round) -// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ): after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval +// Enter (CreateEmptyBlocks, CreateEmptyBlocksInterval > 0 ): +// after enterNewRound(height,round), after timeout of CreateEmptyBlocksInterval // Enter (!CreateEmptyBlocks) : after enterNewRound(height,round), once txs are in the mempool func (cs *ConsensusState) enterPropose(height int64, round int) { logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPropose <= cs.Step) { - logger.Debug(fmt.Sprintf("enterPropose(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) + logger.Debug(fmt.Sprintf( + "enterPropose(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + round, + cs.Height, + cs.Round, + cs.Step)) return } logger.Info(fmt.Sprintf("enterPropose(%v/%v). Current: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) @@ -900,10 +929,18 @@ func (cs *ConsensusState) enterPropose(height int64, round int) { logger.Debug("This node is a validator") if cs.isProposer(address) { - logger.Info("enterPropose: Our turn to propose", "proposer", cs.Validators.GetProposer().Address, "privValidator", cs.privValidator) + logger.Info("enterPropose: Our turn to propose", + "proposer", + cs.Validators.GetProposer().Address, + "privValidator", + cs.privValidator) cs.decideProposal(height, round) } else { - logger.Info("enterPropose: Not our turn to propose", "proposer", cs.Validators.GetProposer().Address, "privValidator", cs.privValidator) + logger.Info("enterPropose: Not our turn to propose", + "proposer", + cs.Validators.GetProposer().Address, + "privValidator", + cs.privValidator) } } @@ -927,7 +964,8 @@ func (cs *ConsensusState) defaultDecideProposal(height int64, round int) { } } - // Flush the WAL. Otherwise, we may not recompute the same proposal to sign, and the privValidator will refuse to sign anything. + // Flush the WAL. Otherwise, we may not recompute the same proposal to sign, + // and the privValidator will refuse to sign anything. cs.wal.FlushAndSync() // Make proposal @@ -995,7 +1033,13 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts // Otherwise vote nil. func (cs *ConsensusState) enterPrevote(height int64, round int) { if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevote <= cs.Step) { - cs.Logger.Debug(fmt.Sprintf("enterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) + cs.Logger.Debug(fmt.Sprintf( + "enterPrevote(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + round, + cs.Height, + cs.Round, + cs.Step)) return } @@ -1052,7 +1096,13 @@ func (cs *ConsensusState) enterPrevoteWait(height int64, round int) { logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) { - logger.Debug(fmt.Sprintf("enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) + logger.Debug(fmt.Sprintf( + "enterPrevoteWait(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + round, + cs.Height, + cs.Round, + cs.Step)) return } if !cs.Votes.Prevotes(round).HasTwoThirdsAny() { @@ -1080,7 +1130,13 @@ func (cs *ConsensusState) enterPrecommit(height int64, round int) { logger := cs.Logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrecommit <= cs.Step) { - logger.Debug(fmt.Sprintf("enterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, round, cs.Height, cs.Round, cs.Step)) + logger.Debug(fmt.Sprintf( + "enterPrecommit(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + round, + cs.Height, + cs.Round, + cs.Step)) return } @@ -1204,7 +1260,13 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) { logger := cs.Logger.With("height", height, "commitRound", commitRound) if cs.Height != height || cstypes.RoundStepCommit <= cs.Step { - logger.Debug(fmt.Sprintf("enterCommit(%v/%v): Invalid args. Current step: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) + logger.Debug(fmt.Sprintf( + "enterCommit(%v/%v): Invalid args. Current step: %v/%v/%v", + height, + commitRound, + cs.Height, + cs.Round, + cs.Step)) return } logger.Info(fmt.Sprintf("enterCommit(%v/%v). Current: %v/%v/%v", height, commitRound, cs.Height, cs.Round, cs.Step)) @@ -1238,7 +1300,12 @@ func (cs *ConsensusState) enterCommit(height int64, commitRound int) { // If we don't have the block being committed, set up to get it. if !cs.ProposalBlock.HashesTo(blockID.Hash) { if !cs.ProposalBlockParts.HasHeader(blockID.PartsHeader) { - logger.Info("Commit is for a block we don't know about. Set ProposalBlock=nil", "proposal", cs.ProposalBlock.Hash(), "commit", blockID.Hash) + logger.Info( + "Commit is for a block we don't know about. Set ProposalBlock=nil", + "proposal", + cs.ProposalBlock.Hash(), + "commit", + blockID.Hash) // We're getting the wrong block. // Set up ProposalBlockParts and keep waiting. cs.ProposalBlock = nil @@ -1268,7 +1335,12 @@ func (cs *ConsensusState) tryFinalizeCommit(height int64) { if !cs.ProposalBlock.HashesTo(blockID.Hash) { // TODO: this happens every time if we're not a validator (ugly logs) // TODO: ^^ wait, why does it matter that we're a validator? - logger.Info("Attempt to finalize failed. We don't have the commit block.", "proposal-block", cs.ProposalBlock.Hash(), "commit-block", blockID.Hash) + logger.Info( + "Attempt to finalize failed. We don't have the commit block.", + "proposal-block", + cs.ProposalBlock.Hash(), + "commit-block", + blockID.Hash) return } @@ -1279,7 +1351,12 @@ func (cs *ConsensusState) tryFinalizeCommit(height int64) { // Increment height and goto cstypes.RoundStepNewHeight func (cs *ConsensusState) finalizeCommit(height int64) { if cs.Height != height || cs.Step != cstypes.RoundStepCommit { - cs.Logger.Debug(fmt.Sprintf("finalizeCommit(%v): Invalid args. Current step: %v/%v/%v", height, cs.Height, cs.Round, cs.Step)) + cs.Logger.Debug(fmt.Sprintf( + "finalizeCommit(%v): Invalid args. Current step: %v/%v/%v", + height, + cs.Height, + cs.Round, + cs.Step)) return } @@ -1334,7 +1411,8 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // restart). endMsg := EndHeightMessage{height} if err := cs.wal.WriteSync(endMsg); err != nil { // NOTE: fsync - panic(fmt.Sprintf("Failed to write %v msg to consensus wal due to %v. Check your FS and restart the node", endMsg, err)) + panic(fmt.Sprintf("Failed to write %v msg to consensus wal due to %v. Check your FS and restart the node", + endMsg, err)) } fail.Fail() // XXX @@ -1345,7 +1423,10 @@ func (cs *ConsensusState) finalizeCommit(height int64) { // Execute and commit the block, update and save the state, and update the mempool. // NOTE The block.AppHash wont reflect these txs until the next block. var err error - stateCopy, err = cs.blockExec.ApplyBlock(stateCopy, types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}, block) + stateCopy, err = cs.blockExec.ApplyBlock( + stateCopy, + types.BlockID{Hash: block.Hash(), PartsHeader: blockParts.Header()}, + block) if err != nil { cs.Logger.Error("Error on ApplyBlock. Did the application crash? Please restart tendermint", "err", err) err := cmn.Kill() @@ -1452,7 +1533,8 @@ func (cs *ConsensusState) defaultSetProposal(proposal *types.Proposal) error { } // NOTE: block is not necessarily valid. -// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit, once we have the full block. +// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit, +// once we have the full block. func (cs *ConsensusState) addProposalBlockPart(msg *BlockPartMessage, peerID p2p.ID) (added bool, err error) { height, round, part := msg.Height, msg.Round, msg.Part @@ -1534,7 +1616,11 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, err } else if voteErr, ok := err.(*types.ErrVoteConflictingVotes); ok { addr := cs.privValidator.GetPubKey().Address() if bytes.Equal(vote.ValidatorAddress, addr) { - cs.Logger.Error("Found conflicting vote from ourselves. Did you unsafe_reset a validator?", "height", vote.Height, "round", vote.Round, "type", vote.Type) + cs.Logger.Error( + "Found conflicting vote from ourselves. Did you unsafe_reset a validator?", + "height", vote.Height, + "round", vote.Round, + "type", vote.Type) return added, err } cs.evpool.AddEvidence(voteErr.DuplicateVoteEvidence) @@ -1543,7 +1629,8 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, err // Either // 1) bad peer OR // 2) not a bad peer? this can also err sometimes with "Unexpected step" OR - // 3) tmkms use with multiple validators connecting to a single tmkms instance (https://github.com/tendermint/tendermint/issues/3839). + // 3) tmkms use with multiple validators connecting to a single tmkms instance + // (https://github.com/tendermint/tendermint/issues/3839). cs.Logger.Info("Error attempting to add vote", "err", err) return added, ErrAddingVote } @@ -1553,8 +1640,15 @@ func (cs *ConsensusState) tryAddVote(vote *types.Vote, peerID p2p.ID) (bool, err //----------------------------------------------------------------------------- -func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error) { - cs.Logger.Debug("addVote", "voteHeight", vote.Height, "voteType", vote.Type, "valIndex", vote.ValidatorIndex, "csHeight", cs.Height) +func (cs *ConsensusState) addVote( + vote *types.Vote, + peerID p2p.ID) (added bool, err error) { + cs.Logger.Debug( + "addVote", + "voteHeight", vote.Height, + "voteType", vote.Type, + "valIndex", vote.ValidatorIndex, + "csHeight", cs.Height) // A precommit for the previous height? // These come in while we wait timeoutCommit @@ -1700,8 +1794,12 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerID p2p.ID) (added bool, return added, err } -func (cs *ConsensusState) signVote(type_ types.SignedMsgType, hash []byte, header types.PartSetHeader) (*types.Vote, error) { - // Flush the WAL. Otherwise, we may not recompute the same vote to sign, and the privValidator will refuse to sign anything. +func (cs *ConsensusState) signVote( + type_ types.SignedMsgType, + hash []byte, + header types.PartSetHeader) (*types.Vote, error) { + // Flush the WAL. Otherwise, we may not recompute the same vote to sign, + // and the privValidator will refuse to sign anything. cs.wal.FlushAndSync() addr := cs.privValidator.GetPubKey().Address() diff --git a/consensus/state_test.go b/consensus/state_test.go index 96547e796..4de8d3734 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -107,7 +107,10 @@ func TestStateProposerSelection2(t *testing.T) { addr := vss[(i+round)%len(vss)].GetPubKey().Address() correctProposer := addr if !bytes.Equal(prop.Address, correctProposer) { - panic(fmt.Sprintf("expected RoundState.Validators.GetProposer() to be validator %d. Got %X", (i+2)%len(vss), prop.Address)) + panic(fmt.Sprintf( + "expected RoundState.Validators.GetProposer() to be validator %d. Got %X", + (i+2)%len(vss), + prop.Address)) } rs := cs1.GetRoundState() @@ -432,7 +435,10 @@ func TestStateLockNoPOL(t *testing.T) { // now we're on a new round and are the proposer if !bytes.Equal(rs.ProposalBlock.Hash(), rs.LockedBlock.Hash()) { - panic(fmt.Sprintf("Expected proposal block to be locked block. Got %v, Expected %v", rs.ProposalBlock, rs.LockedBlock)) + panic(fmt.Sprintf( + "Expected proposal block to be locked block. Got %v, Expected %v", + rs.ProposalBlock, + rs.LockedBlock)) } ensurePrevote(voteCh, height, round) // prevote @@ -446,7 +452,12 @@ func TestStateLockNoPOL(t *testing.T) { validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal - signAddVotes(cs1, types.PrecommitType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) // NOTE: conflicting precommits at same height + signAddVotes( + cs1, + types.PrecommitType, + hash, + rs.ProposalBlock.MakePartSet(partSize).Header(), + vs2) // NOTE: conflicting precommits at same height ensurePrecommit(voteCh, height, round) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) @@ -486,7 +497,12 @@ func TestStateLockNoPOL(t *testing.T) { ensurePrecommit(voteCh, height, round) validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal - signAddVotes(cs1, types.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) // NOTE: conflicting precommits at same height + signAddVotes( + cs1, + types.PrecommitType, + propBlock.Hash(), + propBlock.MakePartSet(partSize).Header(), + vs2) // NOTE: conflicting precommits at same height ensurePrecommit(voteCh, height, round) } @@ -1330,7 +1346,10 @@ func TestStartNextHeightCorrectly(t *testing.T) { ensureNewTimeout(timeoutProposeCh, height+1, round, cs1.config.Propose(round).Nanoseconds()) rs = cs1.GetRoundState() - assert.False(t, rs.TriggeredTimeoutPrecommit, "triggeredTimeoutPrecommit should be false at the beginning of each round") + assert.False( + t, + rs.TriggeredTimeoutPrecommit, + "triggeredTimeoutPrecommit should be false at the beginning of each round") } func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { @@ -1382,7 +1401,10 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { ensureNewProposal(proposalCh, height+1, 0) rs = cs1.GetRoundState() - assert.False(t, rs.TriggeredTimeoutPrecommit, "triggeredTimeoutPrecommit should be false at the beginning of each height") + assert.False( + t, + rs.TriggeredTimeoutPrecommit, + "triggeredTimeoutPrecommit should be false at the beginning of each height") } //------------------------------------------------------------------------------------------ diff --git a/consensus/types/height_vote_set.go b/consensus/types/height_vote_set.go index 35c9a486d..cc8a23f2f 100644 --- a/consensus/types/height_vote_set.go +++ b/consensus/types/height_vote_set.go @@ -16,7 +16,8 @@ type RoundVoteSet struct { } var ( - GotVoteFromUnwantedRoundError = errors.New("Peer has sent a vote that does not match our round for more than one round") + GotVoteFromUnwantedRoundError = errors.New( + "Peer has sent a vote that does not match our round for more than one round") ) /* @@ -176,7 +177,11 @@ func (hvs *HeightVoteSet) getVoteSet(round int, type_ types.SignedMsgType) *type // NOTE: if there are too many peers, or too much peer churn, // this can cause memory issues. // TODO: implement ability to remove peers too -func (hvs *HeightVoteSet) SetPeerMaj23(round int, type_ types.SignedMsgType, peerID p2p.ID, blockID types.BlockID) error { +func (hvs *HeightVoteSet) SetPeerMaj23( + round int, + type_ types.SignedMsgType, + peerID p2p.ID, + blockID types.BlockID) error { hvs.mtx.Lock() defer hvs.mtx.Unlock() if !types.IsVoteTypeValid(type_) { diff --git a/consensus/types/peer_round_state.go b/consensus/types/peer_round_state.go index 16e292940..2eae65f5a 100644 --- a/consensus/types/peer_round_state.go +++ b/consensus/types/peer_round_state.go @@ -13,21 +13,31 @@ import ( // PeerRoundState contains the known state of a peer. // NOTE: Read-only when returned by PeerState.GetRoundState(). type PeerRoundState struct { - Height int64 `json:"height"` // Height peer is at - Round int `json:"round"` // Round peer is at, -1 if unknown. - Step RoundStepType `json:"step"` // Step peer is at - StartTime time.Time `json:"start_time"` // Estimated start of round 0 at this height - Proposal bool `json:"proposal"` // True if peer has proposal for this round + Height int64 `json:"height"` // Height peer is at + Round int `json:"round"` // Round peer is at, -1 if unknown. + Step RoundStepType `json:"step"` // Step peer is at + + // Estimated start of round 0 at this height + StartTime time.Time `json:"start_time"` + + // True if peer has proposal for this round + Proposal bool `json:"proposal"` ProposalBlockPartsHeader types.PartSetHeader `json:"proposal_block_parts_header"` // ProposalBlockParts *cmn.BitArray `json:"proposal_block_parts"` // ProposalPOLRound int `json:"proposal_pol_round"` // Proposal's POL round. -1 if none. - ProposalPOL *cmn.BitArray `json:"proposal_pol"` // nil until ProposalPOLMessage received. - Prevotes *cmn.BitArray `json:"prevotes"` // All votes peer has for this round - Precommits *cmn.BitArray `json:"precommits"` // All precommits peer has for this round - LastCommitRound int `json:"last_commit_round"` // Round of commit for last height. -1 if none. - LastCommit *cmn.BitArray `json:"last_commit"` // All commit precommits of commit for last height. - CatchupCommitRound int `json:"catchup_commit_round"` // Round that we have commit for. Not necessarily unique. -1 if none. - CatchupCommit *cmn.BitArray `json:"catchup_commit"` // All commit precommits peer has for this height & CatchupCommitRound + + // nil until ProposalPOLMessage received. + ProposalPOL *cmn.BitArray `json:"proposal_pol"` + Prevotes *cmn.BitArray `json:"prevotes"` // All votes peer has for this round + Precommits *cmn.BitArray `json:"precommits"` // All precommits peer has for this round + LastCommitRound int `json:"last_commit_round"` // Round of commit for last height. -1 if none. + LastCommit *cmn.BitArray `json:"last_commit"` // All commit precommits of commit for last height. + + // Round that we have commit for. Not necessarily unique. -1 if none. + CatchupCommitRound int `json:"catchup_commit_round"` + + // All commit precommits peer has for this height & CatchupCommitRound + CatchupCommit *cmn.BitArray `json:"catchup_commit"` } // String returns a string representation of the PeerRoundState diff --git a/consensus/types/round_state.go b/consensus/types/round_state.go index c4372e201..47c3f1fd7 100644 --- a/consensus/types/round_state.go +++ b/consensus/types/round_state.go @@ -65,21 +65,27 @@ func (rs RoundStepType) String() string { // NOTE: Not thread safe. Should only be manipulated by functions downstream // of the cs.receiveRoutine type RoundState struct { - Height int64 `json:"height"` // Height we are working on - Round int `json:"round"` - Step RoundStepType `json:"step"` - StartTime time.Time `json:"start_time"` - CommitTime time.Time `json:"commit_time"` // Subjective time when +2/3 precommits for Block at Round were found - Validators *types.ValidatorSet `json:"validators"` - Proposal *types.Proposal `json:"proposal"` - ProposalBlock *types.Block `json:"proposal_block"` - ProposalBlockParts *types.PartSet `json:"proposal_block_parts"` - LockedRound int `json:"locked_round"` - LockedBlock *types.Block `json:"locked_block"` - LockedBlockParts *types.PartSet `json:"locked_block_parts"` - ValidRound int `json:"valid_round"` // Last known round with POL for non-nil valid block. - ValidBlock *types.Block `json:"valid_block"` // Last known block of POL mentioned above. - ValidBlockParts *types.PartSet `json:"valid_block_parts"` // Last known block parts of POL metnioned above. + Height int64 `json:"height"` // Height we are working on + Round int `json:"round"` + Step RoundStepType `json:"step"` + StartTime time.Time `json:"start_time"` + + // Subjective time when +2/3 precommits for Block at Round were found + CommitTime time.Time `json:"commit_time"` + Validators *types.ValidatorSet `json:"validators"` + Proposal *types.Proposal `json:"proposal"` + ProposalBlock *types.Block `json:"proposal_block"` + ProposalBlockParts *types.PartSet `json:"proposal_block_parts"` + LockedRound int `json:"locked_round"` + LockedBlock *types.Block `json:"locked_block"` + LockedBlockParts *types.PartSet `json:"locked_block_parts"` + + // Last known round with POL for non-nil valid block. + ValidRound int `json:"valid_round"` + ValidBlock *types.Block `json:"valid_block"` // Last known block of POL mentioned above. + + // Last known block parts of POL metnioned above. + ValidBlockParts *types.PartSet `json:"valid_block_parts"` Votes *HeightVoteSet `json:"votes"` CommitRound int `json:"commit_round"` // LastCommit *types.VoteSet `json:"last_commit"` // Last precommits at Height-1 diff --git a/consensus/wal.go b/consensus/wal.go index f393955dc..166c95d9e 100644 --- a/consensus/wal.go +++ b/consensus/wal.go @@ -20,6 +20,7 @@ import ( const ( // amino overhead + time.Time + max consensus msg size + // TODO: Can we clarify better where 24 comes from precisely? maxMsgSizeBytes = maxMsgSize + 24 // how often the WAL should be sync'd during period sync'ing @@ -221,7 +222,9 @@ type WALSearchOptions struct { // Group reader will be nil if found equals false. // // CONTRACT: caller must close group reader. -func (wal *baseWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { +func (wal *baseWAL) SearchForEndHeight( + height int64, + options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { var ( msg *TimedWALMessage gr *auto.GroupReader @@ -365,7 +368,10 @@ func (dec *WALDecoder) Decode() (*TimedWALMessage, error) { length := binary.BigEndian.Uint32(b) if length > maxMsgSizeBytes { - return nil, DataCorruptionError{fmt.Errorf("length %d exceeded maximum possible value of %d bytes", length, maxMsgSizeBytes)} + return nil, DataCorruptionError{fmt.Errorf( + "length %d exceeded maximum possible value of %d bytes", + length, + maxMsgSizeBytes)} } data := make([]byte, length) diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go index 35b205778..6ceeb19b6 100644 --- a/consensus/wal_generator.go +++ b/consensus/wal_generator.go @@ -27,7 +27,8 @@ import ( // WALGenerateNBlocks generates a consensus WAL. It does this by spinning up a // stripped down version of node (proxy app, event bus, consensus state) with a // persistent kvstore application and special consensus wal instance -// (byteBufferWAL) and waits until numBlocks are created. If the node fails to produce given numBlocks, it returns an error. +// (byteBufferWAL) and waits until numBlocks are created. +// If the node fails to produce given numBlocks, it returns an error. func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { config := getConfig(t) @@ -199,7 +200,9 @@ func (w *byteBufferWAL) WriteSync(m WALMessage) error { func (w *byteBufferWAL) FlushAndSync() error { return nil } -func (w *byteBufferWAL) SearchForEndHeight(height int64, options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { +func (w *byteBufferWAL) SearchForEndHeight( + height int64, + options *WALSearchOptions) (rd io.ReadCloser, found bool, err error) { return nil, false, nil } diff --git a/crypto/README.md b/crypto/README.md index bb6631227..a77a7ab6c 100644 --- a/crypto/README.md +++ b/crypto/README.md @@ -14,7 +14,7 @@ If you want to decode bytes into one of the types, but don't care about the spec ## Binary encoding -For Binary encoding, please refer to the [Tendermint encoding spec](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md). +For Binary encoding, please refer to the [Tendermint encoding specification](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/encoding.md). ## JSON Encoding diff --git a/crypto/encoding/amino/amino.go b/crypto/encoding/amino/amino.go index f7be3a203..1aed88115 100644 --- a/crypto/encoding/amino/amino.go +++ b/crypto/encoding/amino/amino.go @@ -60,11 +60,19 @@ func RegisterAmino(cdc *amino.Codec) { secp256k1.PrivKeyAminoName, nil) } +// RegisterKeyType registers an external key type to allow decoding it from bytes +func RegisterKeyType(o interface{}, name string) { + cdc.RegisterConcrete(o, name, nil) + nameTable[reflect.TypeOf(o)] = name +} + +// PrivKeyFromBytes unmarshals private key bytes and returns a PrivKey func PrivKeyFromBytes(privKeyBytes []byte) (privKey crypto.PrivKey, err error) { err = cdc.UnmarshalBinaryBare(privKeyBytes, &privKey) return } +// PubKeyFromBytes unmarshals public key bytes and returns a PubKey func PubKeyFromBytes(pubKeyBytes []byte) (pubKey crypto.PubKey, err error) { err = cdc.UnmarshalBinaryBare(pubKeyBytes, &pubKey) return diff --git a/crypto/encoding/amino/encode_test.go b/crypto/encoding/amino/encode_test.go index d4e349454..e73478b54 100644 --- a/crypto/encoding/amino/encode_test.go +++ b/crypto/encoding/amino/encode_test.go @@ -2,10 +2,13 @@ package cryptoAmino import ( "os" + "reflect" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + amino "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/multisig" @@ -147,3 +150,75 @@ func TestPubkeyAminoName(t *testing.T) { } } } + +var _ crypto.PrivKey = testPriv{} +var _ crypto.PubKey = testPub{} +var testCdc = amino.NewCodec() + +type testPriv []byte + +func (privkey testPriv) PubKey() crypto.PubKey { return testPub{} } +func (privkey testPriv) Bytes() []byte { + return testCdc.MustMarshalBinaryBare(privkey) +} +func (privkey testPriv) Sign(msg []byte) ([]byte, error) { return []byte{}, nil } +func (privkey testPriv) Equals(other crypto.PrivKey) bool { return true } + +type testPub []byte + +func (key testPub) Address() crypto.Address { return crypto.Address{} } +func (key testPub) Bytes() []byte { + return testCdc.MustMarshalBinaryBare(key) +} +func (key testPub) VerifyBytes(msg []byte, sig []byte) bool { return true } +func (key testPub) Equals(other crypto.PubKey) bool { return true } + +var ( + privAminoName = "registerTest/Priv" + pubAminoName = "registerTest/Pub" +) + +func TestRegisterKeyType(t *testing.T) { + RegisterAmino(testCdc) + testCdc.RegisterConcrete(testPriv{}, privAminoName, nil) + testCdc.RegisterConcrete(testPub{}, pubAminoName, nil) + + pub := testPub{0x1} + priv := testPriv{0x2} + + // Check to make sure key cannot be decoded before registering + _, err := PrivKeyFromBytes(priv.Bytes()) + require.Error(t, err) + _, err = PubKeyFromBytes(pub.Bytes()) + require.Error(t, err) + + // Check that name is not registered + _, found := PubkeyAminoName(testCdc, pub) + require.False(t, found) + + // Register key types + RegisterKeyType(testPriv{}, privAminoName) + RegisterKeyType(testPub{}, pubAminoName) + + // Name should exist after registering + name, found := PubkeyAminoName(testCdc, pub) + require.True(t, found) + require.Equal(t, name, pubAminoName) + + // Decode keys using the encoded bytes from encoding with the other codec + decodedPriv, err := PrivKeyFromBytes(priv.Bytes()) + require.NoError(t, err) + require.Equal(t, priv, decodedPriv) + + decodedPub, err := PubKeyFromBytes(pub.Bytes()) + require.NoError(t, err) + require.Equal(t, pub, decodedPub) + + // Reset module codec after testing + cdc = amino.NewCodec() + nameTable = make(map[reflect.Type]string, 3) + RegisterAmino(cdc) + nameTable[reflect.TypeOf(ed25519.PubKeyEd25519{})] = ed25519.PubKeyAminoName + nameTable[reflect.TypeOf(secp256k1.PubKeySecp256k1{})] = secp256k1.PubKeyAminoName + nameTable[reflect.TypeOf(multisig.PubKeyMultisigThreshold{})] = multisig.PubKeyMultisigThresholdAminoRoute +} diff --git a/crypto/merkle/simple_map_test.go b/crypto/merkle/simple_map_test.go index 366d9f390..20868a782 100644 --- a/crypto/merkle/simple_map_test.go +++ b/crypto/merkle/simple_map_test.go @@ -16,11 +16,27 @@ func TestSimpleMap(t *testing.T) { {[]string{"key1"}, []string{"value1"}, "a44d3cc7daba1a4600b00a2434b30f8b970652169810d6dfa9fb1793a2189324"}, {[]string{"key1"}, []string{"value2"}, "0638e99b3445caec9d95c05e1a3fc1487b4ddec6a952ff337080360b0dcc078c"}, // swap order with 2 keys - {[]string{"key1", "key2"}, []string{"value1", "value2"}, "8fd19b19e7bb3f2b3ee0574027d8a5a4cec370464ea2db2fbfa5c7d35bb0cff3"}, - {[]string{"key2", "key1"}, []string{"value2", "value1"}, "8fd19b19e7bb3f2b3ee0574027d8a5a4cec370464ea2db2fbfa5c7d35bb0cff3"}, + { + []string{"key1", "key2"}, + []string{"value1", "value2"}, + "8fd19b19e7bb3f2b3ee0574027d8a5a4cec370464ea2db2fbfa5c7d35bb0cff3", + }, + { + []string{"key2", "key1"}, + []string{"value2", "value1"}, + "8fd19b19e7bb3f2b3ee0574027d8a5a4cec370464ea2db2fbfa5c7d35bb0cff3", + }, // swap order with 3 keys - {[]string{"key1", "key2", "key3"}, []string{"value1", "value2", "value3"}, "1dd674ec6782a0d586a903c9c63326a41cbe56b3bba33ed6ff5b527af6efb3dc"}, - {[]string{"key1", "key3", "key2"}, []string{"value1", "value3", "value2"}, "1dd674ec6782a0d586a903c9c63326a41cbe56b3bba33ed6ff5b527af6efb3dc"}, + { + []string{"key1", "key2", "key3"}, + []string{"value1", "value2", "value3"}, + "1dd674ec6782a0d586a903c9c63326a41cbe56b3bba33ed6ff5b527af6efb3dc", + }, + { + []string{"key1", "key3", "key2"}, + []string{"value1", "value3", "value2"}, + "1dd674ec6782a0d586a903c9c63326a41cbe56b3bba33ed6ff5b527af6efb3dc", + }, } for i, tc := range tests { db := newSimpleMap() diff --git a/crypto/merkle/simple_proof.go b/crypto/merkle/simple_proof.go index 93b6f9fea..79a4729eb 100644 --- a/crypto/merkle/simple_proof.go +++ b/crypto/merkle/simple_proof.go @@ -9,7 +9,10 @@ import ( ) const ( - maxAunts = 100 + // MaxAunts is the maximum number of aunts that can be included in a SimpleProof. + // This corresponds to a tree of size 2^100, which should be sufficient for all conceivable purposes. + // This maximum helps prevent Denial-of-Service attacks by limitting the size of the proofs. + MaxAunts = 100 ) // SimpleProof represents a simple Merkle proof. @@ -114,8 +117,8 @@ func (sp *SimpleProof) StringIndented(indent string) string { } // ValidateBasic performs basic validation. -// NOTE: - it expects LeafHash and Aunts of tmhash.Size size -// - it expects no more than 100 aunts +// NOTE: it expects the LeafHash and the elements of Aunts to be of size tmhash.Size, +// and it expects at most MaxAunts elements in Aunts. func (sp *SimpleProof) ValidateBasic() error { if sp.Total < 0 { return errors.New("negative Total") @@ -126,8 +129,8 @@ func (sp *SimpleProof) ValidateBasic() error { if len(sp.LeafHash) != tmhash.Size { return errors.Errorf("expected LeafHash size to be %d, got %d", tmhash.Size, len(sp.LeafHash)) } - if len(sp.Aunts) > maxAunts { - return errors.Errorf("expected no more than %d aunts, got %d", maxAunts, len(sp.Aunts)) + if len(sp.Aunts) > MaxAunts { + return errors.Errorf("expected no more than %d aunts, got %d", MaxAunts, len(sp.Aunts)) } for i, auntHash := range sp.Aunts { if len(auntHash) != tmhash.Size { diff --git a/crypto/merkle/simple_proof_test.go b/crypto/merkle/simple_proof_test.go index 1a517905b..68e6912fb 100644 --- a/crypto/merkle/simple_proof_test.go +++ b/crypto/merkle/simple_proof_test.go @@ -15,9 +15,12 @@ func TestSimpleProofValidateBasic(t *testing.T) { {"Good", func(sp *SimpleProof) {}, ""}, {"Negative Total", func(sp *SimpleProof) { sp.Total = -1 }, "negative Total"}, {"Negative Index", func(sp *SimpleProof) { sp.Index = -1 }, "negative Index"}, - {"Invalid LeafHash", func(sp *SimpleProof) { sp.LeafHash = make([]byte, 10) }, "expected LeafHash size to be 32, got 10"}, - {"Too many Aunts", func(sp *SimpleProof) { sp.Aunts = make([][]byte, maxAunts+1) }, "expected no more than 100 aunts, got 101"}, - {"Invalid Aunt", func(sp *SimpleProof) { sp.Aunts[0] = make([]byte, 10) }, "expected Aunts#0 size to be 32, got 10"}, + {"Invalid LeafHash", func(sp *SimpleProof) { sp.LeafHash = make([]byte, 10) }, + "expected LeafHash size to be 32, got 10"}, + {"Too many Aunts", func(sp *SimpleProof) { sp.Aunts = make([][]byte, MaxAunts+1) }, + "expected no more than 100 aunts, got 101"}, + {"Invalid Aunt", func(sp *SimpleProof) { sp.Aunts[0] = make([]byte, 10) }, + "expected Aunts#0 size to be 32, got 10"}, } for _, tc := range testCases { diff --git a/crypto/multisig/threshold_pubkey_test.go b/crypto/multisig/threshold_pubkey_test.go index d1d7e803c..a707c4b51 100644 --- a/crypto/multisig/threshold_pubkey_test.go +++ b/crypto/multisig/threshold_pubkey_test.go @@ -67,7 +67,11 @@ func TestThresholdMultisigValidCases(t *testing.T) { ) require.NoError( t, - multisignature.AddSignatureFromPubKey(tc.signatures[tc.signingIndices[tc.k]], tc.pubkeys[tc.signingIndices[tc.k]], tc.pubkeys), + multisignature.AddSignatureFromPubKey( + tc.signatures[tc.signingIndices[tc.k]], + tc.pubkeys[tc.signingIndices[tc.k]], + tc.pubkeys, + ), ) require.True( t, diff --git a/crypto/secp256k1/internal/secp256k1/curve.go b/crypto/secp256k1/internal/secp256k1/curve.go index df87200f2..7a2387365 100644 --- a/crypto/secp256k1/internal/secp256k1/curve.go +++ b/crypto/secp256k1/internal/secp256k1/curve.go @@ -41,7 +41,9 @@ import ( /* #include "libsecp256k1/include/secp256k1.h" -extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar); +extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, + const unsigned char *point, + const unsigned char *scalar); */ import "C" diff --git a/crypto/secp256k1/secp256k1_test.go b/crypto/secp256k1/secp256k1_test.go index aaf8f8112..a83cd0f5f 100644 --- a/crypto/secp256k1/secp256k1_test.go +++ b/crypto/secp256k1/secp256k1_test.go @@ -94,7 +94,11 @@ func TestGenPrivKeySecp256k1(t *testing.T) { secret []byte }{ {"empty secret", []byte{}}, - {"some long secret", []byte("We live in a society exquisitely dependent on science and technology, in which hardly anyone knows anything about science and technology.")}, + { + "some long secret", + []byte("We live in a society exquisitely dependent on science and technology, " + + "in which hardly anyone knows anything about science and technology."), + }, {"another seed used in cosmos tests #1", []byte{0}}, {"another seed used in cosmos tests #2", []byte("mySecret")}, {"another seed used in cosmos tests #3", []byte("")}, diff --git a/crypto/xchacha20poly1305/vector_test.go b/crypto/xchacha20poly1305/vector_test.go index 3001217f4..f1aa9d66d 100644 --- a/crypto/xchacha20poly1305/vector_test.go +++ b/crypto/xchacha20poly1305/vector_test.go @@ -94,10 +94,29 @@ var vectors = []struct { key, nonce, ad, plaintext, ciphertext []byte }{ { - []byte{0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f}, + []byte{ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, + 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + }, []byte{0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b}, []byte{0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7}, - []byte("Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."), - []byte{0x45, 0x3c, 0x06, 0x93, 0xa7, 0x40, 0x7f, 0x04, 0xff, 0x4c, 0x56, 0xae, 0xdb, 0x17, 0xa3, 0xc0, 0xa1, 0xaf, 0xff, 0x01, 0x17, 0x49, 0x30, 0xfc, 0x22, 0x28, 0x7c, 0x33, 0xdb, 0xcf, 0x0a, 0xc8, 0xb8, 0x9a, 0xd9, 0x29, 0x53, 0x0a, 0x1b, 0xb3, 0xab, 0x5e, 0x69, 0xf2, 0x4c, 0x7f, 0x60, 0x70, 0xc8, 0xf8, 0x40, 0xc9, 0xab, 0xb4, 0xf6, 0x9f, 0xbf, 0xc8, 0xa7, 0xff, 0x51, 0x26, 0xfa, 0xee, 0xbb, 0xb5, 0x58, 0x05, 0xee, 0x9c, 0x1c, 0xf2, 0xce, 0x5a, 0x57, 0x26, 0x32, 0x87, 0xae, 0xc5, 0x78, 0x0f, 0x04, 0xec, 0x32, 0x4c, 0x35, 0x14, 0x12, 0x2c, 0xfc, 0x32, 0x31, 0xfc, 0x1a, 0x8b, 0x71, 0x8a, 0x62, 0x86, 0x37, 0x30, 0xa2, 0x70, 0x2b, 0xb7, 0x63, 0x66, 0x11, 0x6b, 0xed, 0x09, 0xe0, 0xfd, 0x5c, 0x6d, 0x84, 0xb6, 0xb0, 0xc1, 0xab, 0xaf, 0x24, 0x9d, 0x5d, 0xd0, 0xf7, 0xf5, 0xa7, 0xea}, + []byte( + "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.", + ), + []byte{ + 0x45, 0x3c, 0x06, 0x93, 0xa7, 0x40, 0x7f, 0x04, 0xff, 0x4c, 0x56, + 0xae, 0xdb, 0x17, 0xa3, 0xc0, 0xa1, 0xaf, 0xff, 0x01, 0x17, 0x49, + 0x30, 0xfc, 0x22, 0x28, 0x7c, 0x33, 0xdb, 0xcf, 0x0a, 0xc8, 0xb8, + 0x9a, 0xd9, 0x29, 0x53, 0x0a, 0x1b, 0xb3, 0xab, 0x5e, 0x69, 0xf2, + 0x4c, 0x7f, 0x60, 0x70, 0xc8, 0xf8, 0x40, 0xc9, 0xab, 0xb4, 0xf6, + 0x9f, 0xbf, 0xc8, 0xa7, 0xff, 0x51, 0x26, 0xfa, 0xee, 0xbb, 0xb5, + 0x58, 0x05, 0xee, 0x9c, 0x1c, 0xf2, 0xce, 0x5a, 0x57, 0x26, 0x32, + 0x87, 0xae, 0xc5, 0x78, 0x0f, 0x04, 0xec, 0x32, 0x4c, 0x35, 0x14, + 0x12, 0x2c, 0xfc, 0x32, 0x31, 0xfc, 0x1a, 0x8b, 0x71, 0x8a, 0x62, + 0x86, 0x37, 0x30, 0xa2, 0x70, 0x2b, 0xb7, 0x63, 0x66, 0x11, 0x6b, + 0xed, 0x09, 0xe0, 0xfd, 0x5c, 0x6d, 0x84, 0xb6, 0xb0, 0xc1, 0xab, + 0xaf, 0x24, 0x9d, 0x5d, 0xd0, 0xf7, 0xf5, 0xa7, 0xea, + }, }, } diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 70b404c42..8ede2f8cc 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -1,141 +1,145 @@ module.exports = { - title: "Tendermint Documentation", - description: "Documentation for Tendermint Core.", - ga: "UA-51029217-1", - dest: "./dist/docs", - base: "/docs/", - markdown: { - lineNumbers: true - }, + theme: "cosmos", + // locales: { + // "/": { + // lang: "en-US" + // }, + // "/ru/": { + // lang: "ru" + // } + // }, + base: process.env.VUEPRESS_BASE, themeConfig: { - repo: "tendermint/tendermint", + docsRepo: "tendermint/tendermint", editLinks: true, docsDir: "docs", - docsBranch: "develop", - editLinkText: 'Edit this page on Github', - lastUpdated: true, - algolia: { - apiKey: '59f0e2deb984aa9cdf2b3a5fd24ac501', - indexName: 'tendermint', - debug: false + logo: "/logo.svg", + label: "core", + gutter: { + title: "Help & Support", + editLink: true, + chat: { + title: "Riot Chat", + text: "Chat with Tendermint developers on Riot Chat.", + url: "https://riot.im/app/#/room/#tendermint:matrix.org", + bg: "#222" + }, + forum: { + title: "Tendermint Forum", + text: "Join the Tendermint forum to learn more", + url: "https://forum.cosmos.network/c/tendermint", + bg: "#0B7E0B", + logo: "tendermint" + }, + github: { + title: "Found an Issue?", + text: "Help us improve this page by suggesting edits on GitHub." + } + }, + footer: { + logo: "/logo-bw.svg", + textLink: { + text: "tendermint.com", + url: "https://tendermint.com" + }, + services: [ + { + service: "medium", + url: "https://medium.com/@tendermint" + }, + { + service: "twitter", + url: "https://twitter.com/tendermint_team" + }, + { + service: "linkedin", + url: "https://www.linkedin.com/company/tendermint/" + }, + { + service: "reddit", + url: "https://reddit.com/r/cosmosnetwork" + }, + { + service: "telegram", + url: "https://t.me/cosmosproject" + }, + { + service: "youtube", + url: "https://www.youtube.com/c/CosmosProject" + } + ], + smallprint: + "The development of the Tendermint project is led primarily by Tendermint Inc., the for-profit entity which also maintains this website. Funding for this development comes primarily from the Interchain Foundation, a Swiss non-profit.", + links: [ + { + title: "Documentation", + children: [ + { + title: "Cosmos SDK", + url: "https://cosmos.network/docs" + }, + { + title: "Cosmos Hub", + url: "https://hub.cosmos.network/" + } + ] + }, + { + title: "Community", + children: [ + { + title: "Tendermint blog", + url: "https://medium.com/@tendermint" + }, + { + title: "Forum", + url: "https://forum.cosmos.network/c/tendermint" + }, + { + title: "Chat", + url: "https://riot.im/app/#/room/#tendermint:matrix.org" + } + ] + }, + { + title: "Contributing", + children: [ + { + title: "Contributing to the docs", + url: "https://github.com/tendermint/tendermint" + }, + { + title: "Source code on GitHub", + url: "https://github.com/tendermint/tendermint" + }, + { + title: "Careers at Tendermint", + url: "https://tendermint.com/careers" + } + ] + } + ] }, - nav: [ - { text: "Back to Tendermint", link: "https://tendermint.com" }, - { text: "RPC", link: "https://tendermint.com/rpc/" } - ], sidebar: [ { - title: "Introduction", - collapsable: false, + title: "Resources", children: [ - "/introduction/", - "/introduction/quick-start", - "/introduction/install", - "/introduction/what-is-tendermint" - ] - }, - { - title: "Guides", - collapsable: false, - children: [ - "/guides/go-built-in", - "/guides/go" - ] - }, - { - title: "Apps", - collapsable: false, - children: [ - "/app-dev/getting-started", - "/app-dev/abci-cli", - "/app-dev/app-architecture", - "/app-dev/app-development", - "/app-dev/subscribing-to-events-via-websocket", - "/app-dev/indexing-transactions", - "/spec/abci/abci", - "/app-dev/ecosystem" - ] - }, - { - title: "Tendermint Core", - collapsable: false, - children: [ - "/tendermint-core/", - "/tendermint-core/using-tendermint", - "/tendermint-core/configuration", - "/tendermint-core/rpc", - "/tendermint-core/running-in-production", - "/tendermint-core/fast-sync", - "/tendermint-core/how-to-read-logs", - "/tendermint-core/block-structure", - "/tendermint-core/light-client-protocol", - "/tendermint-core/metrics", - "/tendermint-core/secure-p2p", - "/tendermint-core/validators", - "/tendermint-core/mempool" - ] - }, - { - title: "Networks", - collapsable: false, - children: [ - "/networks/", - "/networks/docker-compose", - "/networks/terraform-and-ansible", - ] - }, - { - title: "Tools", - collapsable: false, - children: [ - "/tools/", - "/tools/benchmarking", - "/tools/monitoring", - "/tools/remote-signer-validation" - ] - }, - { - title: "Tendermint Spec", - collapsable: true, - children: [ - "/spec/", - "/spec/blockchain/blockchain", - "/spec/blockchain/encoding", - "/spec/blockchain/state", - "/spec/software/abci", - "/spec/consensus/bft-time", - "/spec/consensus/consensus", - "/spec/consensus/light-client", - "/spec/software/wal", - "/spec/p2p/config", - "/spec/p2p/connection", - "/spec/p2p/node", - "/spec/p2p/peer", - "/spec/reactors/block_sync/reactor", - "/spec/reactors/block_sync/impl", - "/spec/reactors/consensus/consensus", - "/spec/reactors/consensus/consensus-reactor", - "/spec/reactors/consensus/proposer-selection", - "/spec/reactors/evidence/reactor", - "/spec/reactors/mempool/concurrency", - "/spec/reactors/mempool/config", - "/spec/reactors/mempool/functionality", - "/spec/reactors/mempool/messages", - "/spec/reactors/mempool/reactor", - "/spec/reactors/pex/pex", - "/spec/reactors/pex/reactor", - ] - }, - { - title: "ABCI Spec", - collapsable: false, - children: [ - "/spec/abci/", - "/spec/abci/abci", - "/spec/abci/apps", - "/spec/abci/client-server" + { + title: "Developer Sessions", + path: "/DEV_SESSIONS.html" + }, + { + title: "RPC", + path: "/rpc/", + static: true + } ] } ] + }, + markdown: { + anchor: { + permalinkSymbol: "" + } } }; diff --git a/docs/.vuepress/dist/404.html b/docs/.vuepress/dist/404.html deleted file mode 100644 index 6249309b0..000000000 --- a/docs/.vuepress/dist/404.html +++ /dev/null @@ -1,17 +0,0 @@ - - -
- - -