diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5f0e93dd0..176631644 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -18,11 +18,11 @@ - Blockchain Protocol - Data Storage - - [state] \#6541 Move pruneBlocks from consensus/state to state/execution. (@JayT106) + - [state] \#6541 Move pruneBlocks from consensus/state to state/execution. (@JayT106) - Tooling - - [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106) - - [metrics] \#9682 move state-syncing and block-syncing metrics to their respective packages (@cmwaters) + - [tools/tm-signer-harness] \#6498 Set OS home dir to instead of the hardcoded PATH. (@JayT106) + - [metrics] \#9682 move state-syncing and block-syncing metrics to their respective packages (@cmwaters) labels have moved from block_syncing -> blocksync_syncing and state_syncing -> statesync_syncing - [inspect] \#9655 Add a new `inspect` command for introspecting the state and block store of a crashed tendermint node. (@williambanfield) @@ -56,24 +56,24 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi ### BREAKING CHANGES - CLI/RPC/Config - - [config] \#9259 Rename the fastsync section and the fast_sync key blocksync and block_sync respectively + - [config] \#9259 Rename the fastsync section and the fast_sync key blocksync and block_sync respectively - Apps - - [abci/counter] \#6684 Delete counter example app - - [abci] \#5783 Make length delimiter encoding consistent (`uint64`) between ABCI and P2P wire-level protocols - - [abci] \#9145 Removes unused Response/Request `SetOption` from ABCI (@samricotta) - - [abci/params] \#9287 Deduplicate `ConsensusParams` and `BlockParams` so only `types` proto definitions are used (@cmwaters) - - Remove `TimeIotaMs` and use a hard-coded 1 millisecond value to ensure monotonically increasing block times. - - Rename `AppVersion` to `App` so as to not stutter. - - [types] \#9287 Reduce the use of protobuf types in core logic. (@cmwaters) - - `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams` have become native types. + - [abci/counter] \#6684 Delete counter example app + - [abci] \#5783 Make length delimiter encoding consistent (`uint64`) between ABCI and P2P wire-level protocols + - [abci] \#9145 Removes unused Response/Request `SetOption` from ABCI (@samricotta) + - [abci/params] \#9287 Deduplicate `ConsensusParams` and `BlockParams` so only `types` proto definitions are used (@cmwaters) + - Remove `TimeIotaMs` and use a hard-coded 1 millisecond value to ensure monotonically increasing block times. + - Rename `AppVersion` to `App` so as to not stutter. + - [types] \#9287 Reduce the use of protobuf types in core logic. (@cmwaters) + - `ConsensusParams`, `BlockParams`, `ValidatorParams`, `EvidenceParams`, `VersionParams` have become native types. They still utilize protobuf when being sent over the wire or written to disk. - - Moved `ValidateConsensusParams` inside (now native type) `ConsensusParams`, and renamed it to `ValidateBasic`. - - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. - - [abci] \#8216 Renamed `EvidenceType` to `MisbehaviorType` and `Evidence` to `Misbehavior` as a more accurate label of their contents. (@williambanfield, @sergio-mena) - - [abci] \#9122 Renamed `LastCommitInfo` to `CommitInfo` in preparation for vote extensions. (@cmwaters) - - [abci] \#8656, \#8901 Added cli commands for `PrepareProposal` and `ProcessProposal`. (@jmalicevic, @hvanz) - - [abci] \#6403 Change the `key` and `value` fields from `[]byte` to `string` in the `EventAttribute` type. (@alexanderbez) + - Moved `ValidateConsensusParams` inside (now native type) `ConsensusParams`, and renamed it to `ValidateBasic`. + - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. + - [abci] \#8216 Renamed `EvidenceType` to `MisbehaviorType` and `Evidence` to `Misbehavior` as a more accurate label of their contents. (@williambanfield, @sergio-mena) + - [abci] \#9122 Renamed `LastCommitInfo` to `CommitInfo` in preparation for vote extensions. (@cmwaters) + - [abci] \#8656, \#8901 Added cli commands for `PrepareProposal` and `ProcessProposal`. (@jmalicevic, @hvanz) + - [abci] \#6403 Change the `key` and `value` fields from `[]byte` to `string` in the `EventAttribute` type. (@alexanderbez) - P2P Protocol @@ -89,6 +89,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - [abci] \#9301 New ABCI methods `PrepareProposal` and `ProcessProposal` which give the app control over transactions proposed and allows for verification of proposed blocks. ### IMPROVEMENTS + - [crypto] \#9250 Update to use btcec v2 and the latest btcutil. (@wcsiu) - [cli] \#9171 add `--hard` flag to rollback command (and a boolean to the `RollbackState` method). This will rollback diff --git a/README.md b/README.md index ad3cadc2c..ced02ea7c 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ Currently supported versions include: - [Tendermint Core Blog](https://medium.com/tendermint/tagged/tendermint-core) - [Cosmos Blog](https://blog.cosmos.network/tendermint/home) -## Join us! +## Join us Tendermint Core is maintained by [Interchain GmbH](https://interchain.io). If you'd like to work full-time on Tendermint Core, diff --git a/RELEASES.md b/RELEASES.md index 3f8a9c721..d11043a84 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -50,6 +50,7 @@ the 0.38.x line. in order to do this). 3. Create and push the backport branch: + ```sh git checkout -b v0.38.x git push origin v0.38.x @@ -81,6 +82,7 @@ the 0.38.x line. * `docs.tendermint.com/main` -> `docs.tendermint.com/v0.38` Once you have updated all of the relevant documentation: + ```sh # Create and push the PR. git checkout -b update-docs-v038x @@ -113,7 +115,7 @@ create an alpha or beta version, or release candidate (RC) for our friends and partners to test out. We use git tags to create pre-releases, and we build them off of backport branches, for example: -- `v0.38.0-alpha.1` - The first alpha release of `v0.38.0`. Subsequent alpha +* `v0.38.0-alpha.1` - The first alpha release of `v0.38.0`. Subsequent alpha releases will be numbered `v0.38.0-alpha.2`, `v0.38.0-alpha.3`, etc. Alpha releases are to be considered the _most_ unstable of pre-releases, and @@ -121,14 +123,14 @@ off of backport branches, for example: adopters to start integrating and testing new functionality before we're done with QA. -- `v0.38.0-beta.1` - The first beta release of `v0.38.0`. Subsequent beta +* `v0.38.0-beta.1` - The first beta release of `v0.38.0`. Subsequent beta releases will be numbered `v0.38.0-beta.2`, `v0.38.0-beta.3`, etc. Beta releases can be considered more stable than alpha releases in that we will have QA'd them better than alpha releases, but there still may be minor breaking API changes if users have strong demands for such changes. -- `v0.38.0-rc1` - The first release candidate (RC) of `v0.38.0`. Subsequent RCs +* `v0.38.0-rc1` - The first release candidate (RC) of `v0.38.0`. Subsequent RCs will be numbered `v0.38.0-rc2`, `v0.38.0-rc3`, etc. RCs are considered more stable than beta releases in that we will have @@ -146,18 +148,18 @@ backport branch (see above). Otherwise: 1. Start from the backport branch (e.g. `v0.38.x`). 2. Run the integration tests and the E2E nightlies (which can be triggered from the GitHub UI; - e.g., https://github.com/tendermint/tendermint/actions/workflows/e2e-nightly-37x.yml). + e.g., ). 3. Prepare the pre-release documentation: - - Ensure that all relevant changes are in the `CHANGELOG_PENDING.md` file. + * Ensure that all relevant changes are in the `CHANGELOG_PENDING.md` file. This file's contents must only be included in the `CHANGELOG.md` when we cut final releases. - - Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes + * Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes or other upgrading flows. 4. Prepare the versioning: - - Bump TMVersionDefault version in `version.go` - - Bump P2P and block protocol versions in `version.go`, if necessary. + * Bump TMVersionDefault version in `version.go` + * Bump P2P and block protocol versions in `version.go`, if necessary. Check the changelog for breaking changes in these components. - - Bump ABCI protocol version in `version.go`, if necessary + * Bump ABCI protocol version in `version.go`, if necessary 5. Open a PR with these changes against the backport branch. 6. Once these changes have landed on the backport branch, be sure to pull them back down locally. 7. Once you have the changes locally, create the new tag, specifying a name and a tag "message": @@ -179,33 +181,33 @@ Before performing these steps, be sure the 1. Start on the backport branch (e.g. `v0.38.x`) 2. Run integration tests (`make test_integrations`) and the e2e nightlies. 3. Prepare the release: - - "Squash" changes from the changelog entries for the pre-releases into a + * "Squash" changes from the changelog entries for the pre-releases into a single entry, and add all changes included in `CHANGELOG_PENDING.md`. (Squashing includes both combining all entries, as well as removing or simplifying any intra-pre-release changes. It may also help to alphabetize the entries by package name.) - - Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for + * Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all PRs - - Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes + * Ensure that `UPGRADING.md` is up-to-date and includes notes on any breaking changes or other upgrading flows. - - Bump TMVersionDefault version in `version.go` - - Bump P2P and block protocol versions in `version.go`, if necessary - - Bump ABCI protocol version in `version.go`, if necessary + * Bump TMVersionDefault version in `version.go` + * Bump P2P and block protocol versions in `version.go`, if necessary + * Bump ABCI protocol version in `version.go`, if necessary 4. Open a PR with these changes against the backport branch. 5. Once these changes are on the backport branch, push a tag with prepared release details. This will trigger the actual release `v0.38.0`. - - `git tag -a v0.38.0 -m 'Release v0.38.0'` - - `git push origin v0.38.0` + * `git tag -a v0.38.0 -m 'Release v0.38.0'` + * `git push origin v0.38.0` 6. Make sure that `main` is updated with the latest `CHANGELOG.md`, `CHANGELOG_PENDING.md`, and `UPGRADING.md`. 7. Add the release to the documentation site generator config (see [DOCS\_README.md](./docs/DOCS_README.md) for more details). In summary: - - Start on branch `main`. - - Add a new line at the bottom of [`docs/versions`](./docs/versions) to + * Start on branch `main`. + * Add a new line at the bottom of [`docs/versions`](./docs/versions) to ensure the newest release is the default for the landing page. - - Add a new entry to `themeConfig.versions` in + * Add a new entry to `themeConfig.versions` in [`docs/.vuepress/config.js`](./docs/.vuepress/config.js) to include the release in the dropdown versions menu. - - Commit these changes to `main` and backport them into the backport + * Commit these changes to `main` and backport them into the backport branch for this release. ## Patch release @@ -222,21 +224,21 @@ To create a patch release: 1. Checkout the long-lived backport branch: `git checkout v0.38.x` 2. Run integration tests (`make test_integrations`) and the nightlies. 3. Check out a new branch and prepare the release: - - Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md` - - Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues - - Run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the GitHub aliases of external contributors to the top of the CHANGELOG. To lookup an alias from an email, try `bash ./scripts/authors.sh ` - - Reset the `CHANGELOG_PENDING.md` - - Bump the TMDefaultVersion in `version.go` - - Bump the ABCI version number, if necessary. + * Copy `CHANGELOG_PENDING.md` to top of `CHANGELOG.md` + * Run `python ./scripts/linkify_changelog.py CHANGELOG.md` to add links for all issues + * Run `bash ./scripts/authors.sh` to get a list of authors since the latest release, and add the GitHub aliases of external contributors to the top of the CHANGELOG. To lookup an alias from an email, try `bash ./scripts/authors.sh ` + * Reset the `CHANGELOG_PENDING.md` + * Bump the TMDefaultVersion in `version.go` + * Bump the ABCI version number, if necessary. (Note that ABCI follows semver, and that ABCI versions are the only versions which can change during patch releases, and only field additions are valid patch changes.) 4. Open a PR with these changes that will land them back on `v0.38.x` 5. Once this change has landed on the backport branch, make sure to pull it locally, then push a tag. - - `git tag -a v0.38.1 -m 'Release v0.38.1'` - - `git push origin v0.38.1` + * `git tag -a v0.38.1 -m 'Release v0.38.1'` + * `git push origin v0.38.1` 6. Create a pull request back to main with the CHANGELOG & version changes from the latest release. - - Remove all `R:patch` labels from the pull requests that were included in the release. - - Do not merge the backport branch into main. + * Remove all `R:patch` labels from the pull requests that were included in the release. + * Do not merge the backport branch into main. ## Minor Release Checklist diff --git a/abci/example/kvstore/README.md b/abci/example/kvstore/README.md index edc2c47a5..4a6e3a43d 100644 --- a/abci/example/kvstore/README.md +++ b/abci/example/kvstore/README.md @@ -4,7 +4,7 @@ There are two app's here: the KVStoreApplication and the PersistentKVStoreApplic ## KVStoreApplication -The KVStoreApplication is a simple merkle key-value store. +The KVStoreApplication is a simple merkle key-value store. Transactions of the form `key=value` are stored as key-value pairs in the tree. Transactions without an `=` sign set the value to the key. The app has no replay protection (other than what the mempool provides). @@ -27,4 +27,4 @@ Validator set changes are effected using the following transaction format: where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one). To remove a validator from the validator set, set power to `0`. -There is no sybil protection against new validators joining. +There is no sybil protection against new validators joining. diff --git a/consensus/README.md b/consensus/README.md index eb173d6ef..78acd9477 100644 --- a/consensus/README.md +++ b/consensus/README.md @@ -1,3 +1,3 @@ -# Consensus +# Consensus -See the [consensus spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus) for more information. \ No newline at end of file +See the [consensus spec](https://github.com/tendermint/tendermint/tree/main/spec/consensus) for more information. diff --git a/crypto/merkle/README.md b/crypto/merkle/README.md index 16b1abb58..7ef172f09 100644 --- a/crypto/merkle/README.md +++ b/crypto/merkle/README.md @@ -1,4 +1,4 @@ # Merkle Tree -For smaller static data structures that don't require immutable snapshots or mutability; +For smaller static data structures that don't require immutable snapshots or mutability; for instance the transactions and validation signatures of a block can be hashed using this simple merkle tree logic. diff --git a/docs/app-dev/abci-cli.md b/docs/app-dev/abci-cli.md index 50eecaac8..851def9b2 100644 --- a/docs/app-dev/abci-cli.md +++ b/docs/app-dev/abci-cli.md @@ -262,7 +262,7 @@ deployment, the role of sending messages is taken by Tendermint, which connects to the app using three separate connections, each with its own pattern of messages. -For examples of running an ABCI app with Tendermint, see the +For examples of running an ABCI app with Tendermint, see the [getting started guide](./getting-started.md). ## Bounties diff --git a/docs/app-dev/getting-started.md b/docs/app-dev/getting-started.md index 081ca8dc6..89977d41c 100644 --- a/docs/app-dev/getting-started.md +++ b/docs/app-dev/getting-started.md @@ -23,7 +23,7 @@ using Tendermint. The first apps we will work with are written in Go. To install them, you need to [install Go](https://golang.org/doc/install), put -`$GOPATH/bin` in your `$PATH` and enable go modules. If you use `bash`, +`$GOPATH/bin` in your `$PATH` and enable go modules. If you use `bash`, follow these instructions: ```bash diff --git a/docs/app-dev/indexing-transactions.md b/docs/app-dev/indexing-transactions.md index 0aba61583..7fea2cc90 100644 --- a/docs/app-dev/indexing-transactions.md +++ b/docs/app-dev/indexing-transactions.md @@ -84,7 +84,7 @@ the `psql` indexer type. Example: ```shell -$ psql ... -f state/indexer/sink/psql/schema.sql +psql ... -f state/indexer/sink/psql/schema.sql ``` ## Default Indexes diff --git a/docs/introduction/architecture.md b/docs/introduction/architecture.md index 3b70e7015..954ca2da7 100644 --- a/docs/introduction/architecture.md +++ b/docs/introduction/architecture.md @@ -39,7 +39,7 @@ When writing a p2p service, there are two primary responsibilities: The first responsibility is handled by the Switch: - Responsible for routing connections between peers -- Notably _only handles TCP connections_; RPC/HTTP is separate +- Notably *only handles TCP connections*; RPC/HTTP is separate - Is a dependency for every reactor; all reactors expose a function `setSwitch` - Holds onto channels (channels on the TCP connection--NOT Go channels) and uses them to route - Is a global object, with a global namespace for messages @@ -56,7 +56,7 @@ The second responsibility is handled by a combination of the PEX and the Address Here are some relevant facts about TCP: 1. All TCP connections have a "frame window size" which represents the packet size to the "confidence;" i.e., if you are sending packets along a new connection, you must start out with small packets. As the packets are received successfully, you can start to send larger and larger packets. (This curve is illustrated below.) This means that TCP connections are slow to spin up. -2. The syn/ack process also means that there's a high overhead for small, frequent messages +2. The syn/ack process also means that there's a high overhead for small, frequent messages 3. Sockets are represented by file descriptors. ![tcp](../imgs/tcp-window.png) @@ -114,7 +114,7 @@ Furthermore, all reactors expose: The `receive` method can be called many times by the mconnection. It has the same signature across all reactors. -The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the _transport_, a thin wrapper around TCP connections. +The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the *transport*, a thin wrapper around TCP connections. The following is an exhaustive (?) list of reactors: diff --git a/docs/introduction/what-is-tendermint.md b/docs/introduction/what-is-tendermint.md index a35d39f94..85083be28 100644 --- a/docs/introduction/what-is-tendermint.md +++ b/docs/introduction/what-is-tendermint.md @@ -22,7 +22,7 @@ reformalization of BFT in a more modern setting, with emphasis on peer-to-peer networking and cryptographic authentication. The name derives from the way transactions are batched in blocks, where each block contains a cryptographic hash of the previous one, forming a -chain. +chain. Tendermint consists of two chief technical components: a blockchain consensus engine and a generic application interface. The consensus @@ -55,7 +55,7 @@ atop a classical, non-BFT consensus algorithm. Zookeeper uses an algorithm called Zookeeper Atomic Broadcast, while etcd and consul use the Raft log replication algorithm. A typical cluster contains 3-5 machines, and can tolerate crash failures -in less than 1/2 of the machines (e.g., 1 out of 3 or 2 out of 5), +in less than 1/2 of the machines (e.g., 1 out of 3 or 2 out of 5), but even a single Byzantine fault can jeopardize the whole system. Each offering provides a slightly different implementation of a @@ -142,7 +142,7 @@ in design and suffers from "spaghetti code". Another problem with monolithic design is that it limits you to the language of the blockchain stack (or vice versa). In the case of Ethereum which supports a Turing-complete bytecode virtual-machine, it -limits you to languages that compile down to that bytecode; while the +limits you to languages that compile down to that bytecode; while the [list](https://github.com/pirapira/awesome-ethereum-virtual-machine#programming-languages-that-compile-into-evm) is growing, it is still very limited. @@ -156,7 +156,7 @@ protocol. [Tendermint Core](https://github.com/tendermint/tendermint), the "consensus engine", communicates with the application via a socket -protocol that satisfies the ABCI, the Tendermint Socket Protocol +protocol that satisfies the ABCI, the Tendermint Socket Protocol (TSP, or Teaspoon). To draw an analogy, lets talk about a well-known cryptocurrency, @@ -267,7 +267,7 @@ committed in a chain, with one block at each **height**. A block may fail to be committed, in which case the protocol moves to the next **round**, and a new validator gets to propose a block for that height. Two stages of voting are required to successfully commit a block; we -call them **pre-vote** and **pre-commit**. +call them **pre-vote** and **pre-commit**. There is a picture of a couple doing the polka because validators are doing something like a polka dance. When more than two-thirds of the diff --git a/docs/rfc/rfc-002-ipc-ecosystem.md b/docs/rfc/rfc-002-ipc-ecosystem.md index 8a15ae463..d3eba00be 100644 --- a/docs/rfc/rfc-002-ipc-ecosystem.md +++ b/docs/rfc/rfc-002-ipc-ecosystem.md @@ -332,11 +332,11 @@ some advantages over gRPC for our domain. Specifically: - We can still get the benefits of generated data types using protocol buffers, even without using gRPC: - - Protobuf defines a standard JSON encoding for all message types so + - Protobuf defines a standard JSON encoding for all message types so languages with protobuf support do not need to worry about type mapping oddities. - - Using JSON means that even languages _without_ good protobuf support can + - Using JSON means that even languages _without_ good protobuf support can implement the protocol with a bit more work, and I expect this situation to be rare. diff --git a/docs/rfc/rfc-003-performance-questions.md b/docs/rfc/rfc-003-performance-questions.md index cb1d986e8..fb4b582be 100644 --- a/docs/rfc/rfc-003-performance-questions.md +++ b/docs/rfc/rfc-003-performance-questions.md @@ -68,13 +68,13 @@ a series of metrics to the P2P layer to better understand the inefficiencies it The following metrics can help us understand the sources of latency in the Tendermint P2P stack: -* Number of messages sent and received per second -* Time of a message spent on the P2P layer send and receive queues +- Number of messages sent and received per second +- Time of a message spent on the P2P layer send and receive queues The following metrics exist and should be leveraged in addition to those added: -* Number of peers node's connected to -* Number of bytes per channel sent and received from each peer +- Number of peers node's connected to +- Number of bytes per channel sent and received from each peer ### Sync @@ -88,6 +88,7 @@ over a network so that we understand how much overhead Tendermint actually adds. The operation is likely to be _incredibly_ dependent on the environment in which the node is being run. The factors that will influence syncing include: + 1. Number of peers that a syncing node may fetch from. 2. Speed of the disk that a validator is writing to. 3. Speed of the network connection between the different peers that node is @@ -103,9 +104,9 @@ how much overhead Tendermint incurs. We should additionally add metrics to the blocksync operation to more clearly pinpoint slow operations. The following metrics should be added to the block syncing operation: -* Time to fetch and validate each block -* Time to execute a block -* Blocks sync'd per unit time +- Time to fetch and validate each block +- Time to execute a block +- Blocks sync'd per unit time ### Application @@ -146,7 +147,7 @@ usecase of Tendermint and do not necessarily need to be addressed at this time. ### RPC -#### Claim: The Query API is slow. +#### Claim: The Query API is slow The query API locks a mutex across the ABCI connections. This causes consensus to slow during queries, as ABCI is no longer able to make progress. This is known @@ -192,11 +193,11 @@ it takes for popular chains with many validators to gather all votes within a st Metrics that would improve visibility into this include: -* Amount of time for a node to gather votes in a step. -* Amount of time for a node to gather all block parts. -* Number of votes each node sends to gossip (i.e. not its own votes, but votes it is +- Amount of time for a node to gather votes in a step. +- Amount of time for a node to gather all block parts. +- Number of votes each node sends to gossip (i.e. not its own votes, but votes it is transmitting for a peer). -* Total number of votes each node sends to receives (A node may receive duplicate votes +- Total number of votes each node sends to receives (A node may receive duplicate votes so understanding how frequently this occurs will be valuable in evaluating the performance of the gossip system). @@ -261,17 +262,17 @@ event system. This has implications for the consensus system, which [publishes e To better understand the performance of the event system, we should add metrics to track the timing of event sends. The following metrics would be a good start for tracking this performance: -* Time in event send, labeled by Event Type -* Time in event receive, labeled by subscriber -* Event throughput, measured in events per unit time. +- Time in event send, labeled by Event Type +- Time in event receive, labeled by subscriber +- Event throughput, measured in events per unit time. ### References + [modular-hashing]: https://github.com/tendermint/tendermint/pull/6773 [issue-2186]: https://github.com/tendermint/tendermint/issues/2186 [issue-2187]: https://github.com/tendermint/tendermint/issues/2187 [rfc-002]: https://github.com/tendermint/tendermint/pull/6913 [adr-57]: https://github.com/tendermint/tendermint/blob/main/docs/architecture/adr-057-RPC.md -[issue-1319]: https://github.com/tendermint/tendermint/issues/1319 [abci-commit-description]: https://github.com/tendermint/tendermint/blob/main/spec/abci/abci++_methods.md#commit [abci-local-client-code]: https://github.com/tendermint/tendermint/blob/511bd3eb7f037855a793a27ff4c53c12f085b570/abci/client/local_client.go#L84 [hub-signature]: https://github.com/cosmos/gaia/blob/0ecb6ed8a244d835807f1ced49217d54a9ca2070/docs/resources/genesis.md#consensus-parameters diff --git a/docs/rfc/rfc-007-deterministic-proto-bytes.md b/docs/rfc/rfc-007-deterministic-proto-bytes.md index 0b55c2228..c1521753b 100644 --- a/docs/rfc/rfc-007-deterministic-proto-bytes.md +++ b/docs/rfc/rfc-007-deterministic-proto-bytes.md @@ -44,13 +44,13 @@ Proto allows fields to be encoded in any order and even be repeated. 3. Presence or absence of default values. -Types in proto have defined default values similar to Go's zero values. +Types in proto have defined default values similar to Go's zero values. Writing or omitting a default value are both legal ways of encoding a wire message. -4. Serialization of 'unknown' fields. +4. Serialization of 'unknown' fields. -Unknown fields can be present when a message is created by a binary with a newer -version of the proto that contains fields that the deserializer in a different +Unknown fields can be present when a message is created by a binary with a newer +version of the proto that contains fields that the deserializer in a different binary does not yet know about. Deserializers in binaries that do not know about the field will maintain the bytes of the unknown field but not place them into the deserialized structure. @@ -60,26 +60,26 @@ We have a few options to consider when producing this stable representation. #### Use only compliant serializers and constrain field usage -According to [Cosmos-SDK ADR-27][cosmos-sdk-adr-27], when message types obey a simple +According to [Cosmos-SDK ADR-27][cosmos-sdk-adr-27], when message types obey a simple set of rules, gogoproto produces a consistent byte representation of serialized messages. This seems promising, although more research is needed to guarantee gogoproto always -produces a consistent set of bytes on serialized messages. This would solve the problem +produces a consistent set of bytes on serialized messages. This would solve the problem within Tendermint as written in Go, but would require ensuring that there are similar serializers written in other languages that produce the same output as gogoproto. -#### Reorder serialized bytes to ensure determinism. +#### Reorder serialized bytes to ensure determinism The serialized form of a proto message can be transformed into a canonical representation by applying simple rules to the serialized bytes. Re-ordering the serialized bytes would allow Tendermint to produce a canonical byte representation without having to simultaneously maintain a custom proto marshaller. -This could be implemented as a function in many languages that performed the following +This could be implemented as a function in many languages that performed the following producing bytes to sign or hashing: 1. Does not add any of the data from unknown fields into the type to hash. -Tendermint should not run into a case where it needs to verify the integrity of +Tendermint should not run into a case where it needs to verify the integrity of data with unknown fields for the following reasons: The purpose of checking hash equality within Tendermint is to ensure that @@ -91,7 +91,7 @@ despite not understanding what their internal structure is. It's not clear what mean to verify that a block contains data that a process does not know about. The same reasoning applies for signature verification within Tendermint. Processes -verify that a digital signature signed over a set of bytes by locally reconstructing the +verify that a digital signature signed over a set of bytes by locally reconstructing the data structure that the digital signature signed using the process's local data. 2. Reordered all message fields to be in tag-sorted order. @@ -133,8 +133,6 @@ properly. ### References [proto-spec-encoding]: https://developers.google.com/protocol-buffers/docs/encoding -[spec-issue]: https://github.com/tendermint/tendermint/issues/5005 [cosmos-sdk-adr-27]: https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-027-deterministic-protobuf-serialization.md -[cer-proto-3]: https://github.com/regen-network/canonical-proto3 [wire-pb]: https://github.com/creachadair/wirepb diff --git a/docs/rfc/rfc-009-consensus-parameter-upgrades.md b/docs/rfc/rfc-009-consensus-parameter-upgrades.md index d5077840d..e89c4c1ab 100644 --- a/docs/rfc/rfc-009-consensus-parameter-upgrades.md +++ b/docs/rfc/rfc-009-consensus-parameter-upgrades.md @@ -66,7 +66,7 @@ have been updated until a height at which the parameters existed. #### Only Update HashedParams on Hash-Breaking Releases An alternate solution to never hashing defaults is to not update the hashed -parameters on non-hash-breaking releases. This means that when new consensus +parameters on non-hash-breaking releases. This means that when new consensus parameters are added to Tendermint, there may be a release that makes use of the parameters but does not verify that they are the same across all validators by referencing them in the hash. This seems reasonably safe given the fact that @@ -107,7 +107,7 @@ default values of the new parameters for a single height. As documented in the upcoming [ADR-74][adr-74], popular chains often simply use the default values. Additionally, great care is being taken to ensure that logic governed by upcoming -consensus parameters is not liveness-breaking. This means that, at worst-case, +consensus parameters is not liveness-breaking. This means that, at worst-case, chains will experience a single slow height while waiting for the new values to by applied. diff --git a/docs/rfc/rfc-011-delete-gas.md b/docs/rfc/rfc-011-delete-gas.md index a4e643ef2..854ed7395 100644 --- a/docs/rfc/rfc-011-delete-gas.md +++ b/docs/rfc/rfc-011-delete-gas.md @@ -156,7 +156,5 @@ gossiped along with the transaction. [cosmos-sdk-gas]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/gas-fees.md [cosmos-sdk-fees]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/tx-lifecycle.md#gas-and-fees [anoma-gas]: https://github.com/anoma/anoma/blob/6974fe1532a59db3574fc02e7f7e65d1216c1eb2/docs/src/specs/ledger.md#transaction-execution -[cosmos-sdk-fee]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/types/tx/tx.pb.go#L780-L794 -[issue-7750]: https://github.com/tendermint/tendermint/issues/7750 [reap-max-bytes-max-gas]: https://github.com/tendermint/tendermint/blob/1ac58469f32a98f1c0e2905ca1773d9eac7b7103/internal/mempool/types.go#L45 [add-mempool-error]: https://github.com/tendermint/tendermint/blob/205bfca66f6da1b2dded381efb9ad3792f9404cf/rpc/coretypes/responses.go#L239 diff --git a/docs/rfc/rfc-012-custom-indexing.md b/docs/rfc/rfc-012-custom-indexing.md index 64f9fc94b..489bcccc1 100644 --- a/docs/rfc/rfc-012-custom-indexing.md +++ b/docs/rfc/rfc-012-custom-indexing.md @@ -329,7 +329,7 @@ something like this (subject to refinement): - [KV transaction indexer][kv-index] - [Pluggable custom event indexing][i7135] (#7135) - [PostgreSQL event sink][psql] - - [PostgreSQL database][postgres] + - [PostgreSQL database][postgres] - [Query filter language][query] - [Stream events to postgres for indexing][i1161] (#1161) - [Unbuffered event subscription slow down the consensus][i7247] (#7247) @@ -346,7 +346,6 @@ something like this (subject to refinement): [kv-index]: https://github.com/tendermint/tendermint/blob/main/state/indexer/block/kv [postgres]: https://postgresql.org/ [psql]: https://github.com/tendermint/tendermint/tree/main/state/indexer/sink/psql -[psql]: https://github.com/tendermint/tendermint/tree/main/state/indexer/sink/psql [query]: https://pkg.go.dev/github.com/tendermint/tendermint/internal/pubsub/query/syntax [sdk]: https://github.com/cosmos/cosmos-sdk [tmdb]: https://pkg.go.dev/github.com/tendermint/tm-db#DB diff --git a/docs/rfc/rfc-015-abci++-tx-mutation.md b/docs/rfc/rfc-015-abci++-tx-mutation.md index 3c7854ed3..92d9ed668 100644 --- a/docs/rfc/rfc-015-abci++-tx-mutation.md +++ b/docs/rfc/rfc-015-abci++-tx-mutation.md @@ -77,7 +77,7 @@ from the mempool, so this would be a pretty straightforward change. Transaction replacement would would enable applications to aggregate or disaggregate transactions. For aggregation, a set of transactions that all related work, such as transferring -tokens between the same two accounts, could be replaced with a single transaction, +tokens between the same two accounts, could be replaced with a single transaction, i.e. one that transfers a single sum from one account to the other. Applications that make frequent use of aggregation may be able to achieve a higher throughput. Aggregation would decrease the space occupied by a single client-submitted transaction in the block, allowing @@ -189,7 +189,7 @@ it did not want executed. In this validation scheme, applications that allow replacement would check that each listed replaced transaction was correctly reflected in the replacement transaction. In order to perform such validation, the node would need to have the replaced transactions -locally. This could be accomplished one of a few ways: by querying the mempool, +locally. This could be accomplished one of a few ways: by querying the mempool, by adding an additional p2p gossip channel for transaction replacements, or by including the replaced transactions in the block. Replacement validation via mempool querying would require the node to have received all of the replaced transactions in the mempool which is far from @@ -255,7 +255,5 @@ power instead of immediately solving the problem for them. ### References [inclusion-proof]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/types/tx.go#L67 -[tx-serach-result]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/rpc/coretypes/responses.go#L267 -[tx-rpc-func]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/rpc/core/tx.go#L21 [tx-result-index]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/internal/state/indexer/tx/kv/kv.go#L90 [abci-event-type]: https://github.com/tendermint/tendermint/blob/0fcfaa4568cb700e27c954389c1fcd0b9e786332/abci/types/types.pb.go#L3168 diff --git a/docs/rfc/rfc-018-bls-agg-exploration.md b/docs/rfc/rfc-018-bls-agg-exploration.md index 70ca171a0..6de7510ab 100644 --- a/docs/rfc/rfc-018-bls-agg-exploration.md +++ b/docs/rfc/rfc-018-bls-agg-exploration.md @@ -16,29 +16,29 @@ become confusing quickly. Different sources appear to use slightly different meanings of each term and this can certainly add to the confusion. Below is a brief glossary that may be helpful in understanding the discussion that follows. -* **Short Signature**: A signature that does not vary in length with the +- **Short Signature**: A signature that does not vary in length with the number of signers. -* **Multi-Signature**: A signature generated over a single message +- **Multi-Signature**: A signature generated over a single message where, given the message and signature, a verifier is able to determine that all parties signed the message. May be short or may vary with the number of signers. -* **Aggregated Signature**: A _short_ signature generated over messages with +- **Aggregated Signature**: A _short_ signature generated over messages with possibly different content where, given the messages and signature, a verifier should be able to determine that all the parties signed the designated messages. -* **Threshold Signature**: A _short_ signature generated from multiple signers +- **Threshold Signature**: A _short_ signature generated from multiple signers where, given a message and the signature, a verifier is able to determine that a large enough share of the parties signed the message. The identities of the parties that contributed to the signature are not revealed. -* **BLS Signature**: An elliptic-curve pairing-based signature system that +- **BLS Signature**: An elliptic-curve pairing-based signature system that has some nice properties for short multi-signatures. May stand for -*Boneh-Lynn-Schacham* or *Barreto-Lynn-Scott* depending on the context. A +_Boneh-Lynn-Schacham_ or _Barreto-Lynn-Scott_ depending on the context. A BLS signature is type of signature scheme that is distinct from other forms of elliptic-curve signatures such as ECDSA and EdDSA. -* **Interactive**: Cryptographic scheme where parties need to perform one or +- **Interactive**: Cryptographic scheme where parties need to perform one or more request-response cycles to produce the cryptographic material. For example, an interactive signature scheme may require the signer and the verifier to cooperate to create and/or verify the signature, rather than a signature being created ahead of time. -* **Non-interactive**: Cryptographic scheme where parties do not need to +- **Non-interactive**: Cryptographic scheme where parties do not need to perform any request-response cycles to produce the cryptographic material. ### Brief notes on pairing-based elliptic-curve cryptography @@ -89,11 +89,11 @@ depth discussion, see the specific paper on BLS12-381, [Short signatures from BLS signatures have already gained traction within several popular projects. -* Algorand is working on an implementation. -* [Zcash][zcash-adoption] has adopted BLS12-381 into the protocol. -* [Ethereum 2.0][eth-2-adoption] has adopted BLS12-381 into the protocol. -* [Chia Network][chia-adoption] has adopted BLS for signing blocks. -* [Ostracon][line-ostracon-pr], a fork of Tendermint has adopted BLS for signing blocks. +- Algorand is working on an implementation. +- [Zcash][zcash-adoption] has adopted BLS12-381 into the protocol. +- [Ethereum 2.0][eth-2-adoption] has adopted BLS12-381 into the protocol. +- [Chia Network][chia-adoption] has adopted BLS for signing blocks. +- [Ostracon][line-ostracon-pr], a fork of Tendermint has adopted BLS for signing blocks. ### What systems may be affected by adding aggregated signatures? @@ -106,7 +106,7 @@ overhead. How costly this is is still subject to further investigation and performance testing. Even if vote signatures were aggregated before gossip, each validator would still -need to receive and verify vote extension data from each (individual) peer validator in +need to receive and verify vote extension data from each (individual) peer validator in order for consensus to proceed. That displaces any advantage gained by aggregating signatures across the vote message in the presence of vote extensions. #### Block Creation @@ -190,7 +190,7 @@ check an aggregated signature from 1024 validators versus our ed25519 library's #### Reduce Light-Client Verification Time -The light client aims to be a faster and lighter-weight way to verify that a +The light client aims to be a faster and lighter-weight way to verify that a block was voted on by a Tendermint network. The light client fetches Tendermint block headers and commit signatures, performing public key verification to ensure that the associated validator set signed the block. @@ -212,7 +212,7 @@ able to check if some singular validator's key signed the block. ##### Vote Gossip It is possible to aggregate subsets of signatures during voting, so that the -network need not gossip all *n* validator signatures to all *n* validators. +network need not gossip all _n_ validator signatures to all _n_ validators. Theoretically, subsets of the signatures could be aggregated during consensus and vote messages could carry those aggregated signatures. Implementing this would certainly increase the complexity of the gossip layer but could possibly @@ -243,12 +243,12 @@ possible for storing highly sensitive private key material. Below is a list of popular HSMs along with their support for BLS signatures. -* YubiKey - * [No support][yubi-key-bls-support] -* Amazon Cloud HSM - * [No support][cloud-hsm-support] -* Ledger - * [Lists support for the BLS12-381 curve][ledger-bls-announce] +- YubiKey + - [No support][yubi-key-bls-support] +- Amazon Cloud HSM + - [No support][cloud-hsm-support] +- Ledger + - [Lists support for the BLS12-381 curve][ledger-bls-announce] I cannot find support listed for Google Cloud, although perhaps it exists. @@ -261,7 +261,7 @@ reasonably unclear benefit. ### Can aggregated signatures be added as soft-upgrades? -In my estimation, yes. With the implementation of proposer-based timestamps, +In my estimation, yes. With the implementation of proposer-based timestamps, all validators now produce signatures on only one of two messages: 1. A [CanonicalVote][canonical-vote-proto] where the BlockID is the hash of the block or @@ -409,7 +409,7 @@ the block. ### Library Support -Libraries for BLS signature creation are limited in number, although active +Libraries for BLS signature creation are limited in number, although active development appears to be ongoing. Cryptographic algorithms are difficult to implement correctly and correctness issues are extremely serious and dangerous. No further exploration of BLS should be undertaken without strong assurance of @@ -422,7 +422,7 @@ and is supported by funds from the Ethereum foundation, adopting a new cryptogra library presents some serious risks. Namely, if the support for the library were to be discontinued, Tendermint may become saddled with the requirement of supporting a very complex piece of software or force a massive ecosystem-wide migration away -from BLS signatures. +from BLS signatures. This is one of the more serious reasons to avoid adopting BLS signatures at this time. There is no gold standard library. Some projects look promising, but no @@ -472,7 +472,7 @@ of re-aggregating the public key. Aggregation is _not_ constant time in the number of keys and instead grows linearly. When [benchmarked locally][blst-verify-bench-agg], blst public key aggregation of 128 keys took 2.43 milliseconds. This, along with the 1.5 milliseconds to verify a signature would raise light client signature -verification time to 3.9 milliseconds, a time above the previously mentioned +verification time to 3.9 milliseconds, a time above the previously mentioned batch verification time using our ed25519 library of 2.0 milliseconds. Schemes to cache aggregated subsets of keys could certainly cut this time down at the @@ -501,8 +501,8 @@ the associated protocols. ## Open Questions -* *Q*: Can you aggregate Ed25519 signatures in Tendermint? - * There is a suggested scheme in github issue [7892][suggested-ed25519-agg], +- _Q_: Can you aggregate Ed25519 signatures in Tendermint? + - There is a suggested scheme in github issue [7892][suggested-ed25519-agg], but additional rigor would be required to fully verify its correctness. ## Current Consideration @@ -523,9 +523,7 @@ standards develop. ### References -[line-ostracon-repo]: https://github.com/line/ostracon [line-ostracon-pr]: https://github.com/line/ostracon/pull/117 -[mit-BLS-lecture]: https://youtu.be/BFwc2XA8rSk?t=2521 [gcp-storage-pricing]: https://cloud.google.com/storage/pricing#north-america_2 [yubi-key-bls-support]: https://github.com/Yubico/yubihsm-shell/issues/66 [cloud-hsm-support]: https://docs.aws.amazon.com/cloudhsm/latest/userguide/pkcs11-key-types.html @@ -533,7 +531,6 @@ standards develop. [bls-ietf-terms]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-1.3 [bls-ietf-pop]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3 [multi-signatures-smaller-blockchains]: https://eprint.iacr.org/2018/483.pdf -[ibc-tendermint]: https://github.com/cosmos/ibc/tree/master/spec/client/ics-007-tendermint-client [zcash-adoption]: https://github.com/zcash/zcash/issues/2502 [chia-adoption]: https://github.com/Chia-Network/chia-blockchain#chia-blockchain [bls-ietf-ecdsa-compare]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-1.1 @@ -551,5 +548,4 @@ standards develop. [bls-weil-pairing]: https://www.iacr.org/archive/asiacrypt2001/22480516.pdf [summing-zero-paper]: https://eprint.iacr.org/2021/323.pdf [circl]: https://github.com/cloudflare/circl -[light-client-evidence]: https://github.com/tendermint/tendermint/blob/a6fd1fe20116d4b1f7e819cded81cece8e5c1ac7/types/evidence.go#L245 [suggested-ed25519-agg]: https://github.com/tendermint/tendermint/issues/7892 diff --git a/docs/rfc/rfc-021-socket-protocol.md b/docs/rfc/rfc-021-socket-protocol.md index 61e95f6cb..4b8fd2ab6 100644 --- a/docs/rfc/rfc-021-socket-protocol.md +++ b/docs/rfc/rfc-021-socket-protocol.md @@ -85,7 +85,7 @@ applications using it. In particular: the server that are not clearly documented anywhere, and it is very easy for small changes in both the client and the server to lead to tricky deadlocks, panics, race conditions, and slowdowns. As a recent example of this, see - https://github.com/tendermint/tendermint/pull/8581. + . These limitations are fixable, but one important question is whether it is worthwhile to fix them. We can add request and method identifiers, for @@ -190,28 +190,28 @@ design. - **Standardize on gRPC** - - ✅ Addresses existing performance and operational issues. - - ✅ Replaces custom code with a well-maintained widely-used library. - - ✅ Aligns with Cosmos SDK, which already uses gRPC extensively. - - ✅ Aligns with priv validator interface, for which the socket protocol is already deprecated for gRPC. - - ❓ Applications will be hard to implement in a language without gRPC support. - - ⛔ All users of the socket protocol have to migrate to gRPC, and we believe most current out-of-process applications use the socket protocol. + - ✅ Addresses existing performance and operational issues. + - ✅ Replaces custom code with a well-maintained widely-used library. + - ✅ Aligns with Cosmos SDK, which already uses gRPC extensively. + - ✅ Aligns with priv validator interface, for which the socket protocol is already deprecated for gRPC. + - ❓ Applications will be hard to implement in a language without gRPC support. + - ⛔ All users of the socket protocol have to migrate to gRPC, and we believe most current out-of-process applications use the socket protocol. - **Standardize on socket protocol** - - ✅ Less immediate impact for existing users (but see below). - - ✅ Simplifies ABCI API surface by removing gRPC. - - ❓ Users of the socket protocol will have a (smaller) migration. - - ❓ Potentially easier to implement for languages that do not have support. - - ⛔ Need to do all the work to fix the socket protocol (which will require existing users to update anyway later). - - ⛔ Ongoing maintenance burden for per-language server implementations. + - ✅ Less immediate impact for existing users (but see below). + - ✅ Simplifies ABCI API surface by removing gRPC. + - ❓ Users of the socket protocol will have a (smaller) migration. + - ❓ Potentially easier to implement for languages that do not have support. + - ⛔ Need to do all the work to fix the socket protocol (which will require existing users to update anyway later). + - ⛔ Ongoing maintenance burden for per-language server implementations. - **Keep both options** - - ✅ Less immediate impact for existing users (but see below). - - ❓ Users of the socket protocol will have a (smaller) migration. - - ⛔ Still need to do all the work to fix the socket protocol (which will require existing users to update anyway later). - - ⛔ Requires ongoing maintenance and support of both gRPC and socket protocol integrations. + - ✅ Less immediate impact for existing users (but see below). + - ❓ Users of the socket protocol will have a (smaller) migration. + - ⛔ Still need to do all the work to fix the socket protocol (which will require existing users to update anyway later). + - ⛔ Requires ongoing maintenance and support of both gRPC and socket protocol integrations. ## References diff --git a/docs/rfc/rfc-023-semi-permanent-testnet.md b/docs/rfc/rfc-023-semi-permanent-testnet.md index ddb31a908..7f5e68cd5 100644 --- a/docs/rfc/rfc-023-semi-permanent-testnet.md +++ b/docs/rfc/rfc-023-semi-permanent-testnet.md @@ -42,6 +42,7 @@ Once the decision has been made to run and operate a service, one of the next strategic questions is that of deploying said service. The author strongly holds the opinion that, when possible, a continuous delivery model offers the most compelling set of advantages: + - The code on a particular branch (likely `main` or `master`) is exactly what is, or what will very soon be, running in production - There are no manual steps involved in deploying -- other than merging your pull request, @@ -50,6 +51,7 @@ a continuous delivery model offers the most compelling set of advantages: In summary, if the tendermint authors build, maintain, and continuously deliver an application intended to serve as a long-lived testnet, they will be able to state with confidence: + - We operate the software in a production-like environment and we have observed it to be stable and performant to our requirements - We have discovered issues in production before any external parties have consumed our software, diff --git a/docs/rfc/rfc-024-block-structure-consolidation.md b/docs/rfc/rfc-024-block-structure-consolidation.md index c8cab17f5..91dec2d63 100644 --- a/docs/rfc/rfc-024-block-structure-consolidation.md +++ b/docs/rfc/rfc-024-block-structure-consolidation.md @@ -140,7 +140,7 @@ these are not its primary concern. ### Data to consider removing -This section proposes a list of data that could be completely removed from the +This section proposes a list of data that could be completely removed from the Merkle tree with no loss to the functionality of our consensus algorithm. Where the change is possible but would hamper external protocols or make @@ -241,7 +241,7 @@ only one header. validation. The light client uses this field to ensure that the validator set it fetched from a full node is correct. It can be sure of the correctness of the retrieved structure by hashing it and checking the hash against the `ValidatorsHash` -of the block it is verifying. Because a validator that the light client trusts +of the block it is verifying. Because a validator that the light client trusts signed over the `ValidatorsHash`, it can be certain of the validity of the structure. Without this check, phony validator sets could be handed to the light client and the code tricked into believing a different validator set was present @@ -268,7 +268,7 @@ of basic information about the chain. #### ProofOfLockRound -The *proof of lock round* is the round of consensus for a height in which the +The _proof of lock round_ is the round of consensus for a height in which the Tendermint algorithm observed a super majority of voting power on the network for a block. @@ -318,7 +318,7 @@ or unchanged from previous blocks_. For example, we propagate the `ValidatorAddr for each block in the `CommitSig` structure even when it never changed from a previous height. We could achieve a speed-up in many cases by communicating the hashes _first_ and letting peers request additional information when they do not -recognize the communicated hash. +recognize the communicated hash. For example, in the case of the `ValidatorAddress`es, the node would first communicate the `ValidatorsHash` of the block to its peers. The peers would @@ -353,12 +353,10 @@ this would not be light client breaking. ## References -[light-verify-trusting]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/validation.go#L124 [part-set-header]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/part_set.go#L94 [block-id]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/block.go#L1090 [psh-check]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/types/part_set.go#L116 [proposer-selection]: https://github.com/tendermint/tendermint/blob/208a15dadf01e4e493c187d8c04a55a61758c3cc/spec/consensus/proposer-selection.md -[chain-experiment]: https://github.com/williambanfield/tmtools/blob/master/hash-changes/RUN.txt [val-hash]: https://github.com/tendermint/tendermint/blob/29e5fbcc648510e4763bd0af0b461aed92c21f30/types/validator.go#L160 [proposer-check]: https://github.com/tendermint/tendermint/blob/29e5fbcc648510e4763bd0af0b461aed92c21f30/internal/state/validation.go#L102 [save-block]: https://github.com/tendermint/tendermint/blob/59f0236b845c83009bffa62ed44053b04370b8a9/internal/store/store.go#L490 diff --git a/docs/rfc/rfc-025-support-app-side-mempool.md b/docs/rfc/rfc-025-support-app-side-mempool.md index 6dfa83a0a..63dea8696 100644 --- a/docs/rfc/rfc-025-support-app-side-mempool.md +++ b/docs/rfc/rfc-025-support-app-side-mempool.md @@ -12,7 +12,7 @@ of the Tendermint mempool becomes much less clear. This RFC discusses possible changes that should be considered to Tendermint to better support applications that intend to use `PrepareProposal` to implement much more powerful transaction ordering and filtering functionality than Tendermint can provide. It proposes -scoping down the responsibilities of Tendermint to suit this new use case. +scoping down the responsibilities of Tendermint to suit this new use case. ## Background @@ -293,7 +293,6 @@ future designs are made in this area: ## References -[mempool-cache]:https://github.com/tendermint/tendermint/blob/c8302c5fcb7f1ffafdefc5014a26047df1d27c99/mempool/v1/mempool.go#L41 [cache-when-clear]:https://github.com/tendermint/tendermint/issues/7723 [update-remove-from-cache]:https://github.com/tendermint/tendermint/pull/233 [update-keep-in-cache]:https://github.com/tendermint/tendermint/issues/2855 diff --git a/docs/tendermint-core/block-sync.md b/docs/tendermint-core/block-sync.md index 4d55d52b8..d0e2e6ea7 100644 --- a/docs/tendermint-core/block-sync.md +++ b/docs/tendermint-core/block-sync.md @@ -3,6 +3,7 @@ order: 10 --- # Block Sync + *Formerly known as Fast Sync* In a proof of work blockchain, syncing with the chain is the same diff --git a/docs/tendermint-core/running-in-production.md b/docs/tendermint-core/running-in-production.md index 8da4b65a2..52ec4a9a7 100644 --- a/docs/tendermint-core/running-in-production.md +++ b/docs/tendermint-core/running-in-production.md @@ -220,8 +220,8 @@ Recovering from data corruption can be hard and time-consuming. Here are two app ./scripts/wal2json/wal2json "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal ``` -3) Search for a "CORRUPTED MESSAGE" line. -4) By looking at the previous message and the message after the corrupted one +3) Search for a "CORRUPTED MESSAGE" line. +4) By looking at the previous message and the message after the corrupted one and looking at the logs, try to rebuild the message. If the consequent messages are marked as corrupted too (this may happen if length header got corrupted or some writes did not make it to the WAL ~ truncation), @@ -232,7 +232,7 @@ Recovering from data corruption can be hard and time-consuming. Here are two app $EDITOR /tmp/corrupted_wal ``` -5) After editing, convert this file back into binary form by running: +5) After editing, convert this file back into binary form by running: ```sh ./scripts/json2wal/json2wal /tmp/corrupted_wal $TMHOME/data/cs.wal/wal diff --git a/docs/tendermint-core/state-sync.md b/docs/tendermint-core/state-sync.md index 8400a6ef9..0f477302e 100644 --- a/docs/tendermint-core/state-sync.md +++ b/docs/tendermint-core/state-sync.md @@ -4,41 +4,41 @@ order: 11 # State Sync -With block sync a node is downloading all of the data of an application from genesis and verifying it. -With state sync your node will download data related to the head or near the head of the chain and verify the data. -This leads to drastically shorter times for joining a network. +With block sync a node is downloading all of the data of an application from genesis and verifying it. +With state sync your node will download data related to the head or near the head of the chain and verify the data. +This leads to drastically shorter times for joining a network. ## Using State Sync State sync will continuously work in the background to supply nodes with chunked data when bootstrapping. -> NOTE: Before trying to use state sync, see if the application you are operating a node for supports it. +> NOTE: Before trying to use state sync, see if the application you are operating a node for supports it. Under the state sync section in `config.toml` you will find multiple settings that need to be configured in order for your node to use state sync. Lets breakdown the settings: - `enable`: Enable is to inform the node that you will be using state sync to bootstrap your node. -- `rpc_servers`: RPC servers are needed because state sync utilizes the light client for verification. - - 2 servers are required, more is always helpful. +- `rpc_servers`: RPC servers are needed because state sync utilizes the light client for verification. + - 2 servers are required, more is always helpful. - `temp_dir`: Temporary directory is store the chunks in the machines local storage, If nothing is set it will create a directory in `/tmp` -The next information you will need to acquire it through publicly exposed RPC's or a block explorer which you trust. +The next information you will need to acquire it through publicly exposed RPC's or a block explorer which you trust. - `trust_height`: Trusted height defines at which height your node should trust the chain. - `trust_hash`: Trusted hash is the hash in the `BlockID` corresponding to the trusted height. -- `trust_period`: Trust period is the period in which headers can be verified. +- `trust_period`: Trust period is the period in which headers can be verified. > :warning: This value should be significantly smaller than the unbonding period. If you are relying on publicly exposed RPC's to get the need information, you can use `curl`. -Example: +Example: ```bash curl -s https://233.123.0.140:26657/commit | jq "{height: .result.signed_header.header.height, hash: .result.signed_header.commit.block_id.hash}" ``` -The response will be: +The response will be: ```json { diff --git a/docs/tendermint-core/using-tendermint.md b/docs/tendermint-core/using-tendermint.md index 91421854d..36eca6300 100644 --- a/docs/tendermint-core/using-tendermint.md +++ b/docs/tendermint-core/using-tendermint.md @@ -47,8 +47,8 @@ definition](https://github.com/tendermint/tendermint/blob/main/types/genesis.go) - `chain_id`: ID of the blockchain. **This must be unique for every blockchain.** If your testnet blockchains do not have unique chain IDs, you will have a bad time. The ChainID must be less than 50 symbols. -- `initial_height`: Height at which Tendermint should begin at. If a blockchain is conducting a network upgrade, - starting from the stopped height brings uniqueness to previous heights. +- `initial_height`: Height at which Tendermint should begin at. If a blockchain is conducting a network upgrade, + starting from the stopped height brings uniqueness to previous heights. - `consensus_params` [spec](https://github.com/tendermint/tendermint/blob/main/spec/core/state.md#consensusparams) - `block` - `max_bytes`: Max block size, in bytes. diff --git a/docs/tutorials/go-built-in.md b/docs/tutorials/go-built-in.md index 3f38551cf..f979fa81c 100644 --- a/docs/tutorials/go-built-in.md +++ b/docs/tutorials/go-built-in.md @@ -13,10 +13,10 @@ experience with Tendermint Core. Tendermint Core is a service that provides a Byzantine Fault Tolerant consensus engine for state-machine replication. The replicated state-machine, or "application", can be written in any language that can send and receive protocol buffer messages in a client-server model. -Applications written in Go can also use Tendermint as a library and run the service in the same -process as the application. +Applications written in Go can also use Tendermint as a library and run the service in the same +process as the application. -By following along this tutorial you will create a Tendermint Core application called kvstore, +By following along this tutorial you will create a Tendermint Core application called kvstore, a (very) simple distributed BFT key-value store. The application will be written in Go and some understanding of the Go programming language is expected. @@ -30,15 +30,15 @@ We strongly advise against using unreleased commits for your development. ### Built-in app vs external app -On the one hand, to get maximum performance you can run your application in -the same process as the Tendermint Core, as long as your application is written in Go. +On the one hand, to get maximum performance you can run your application in +the same process as the Tendermint Core, as long as your application is written in Go. [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) is written -this way. +this way. This is the approach followed in this tutorial. -On the other hand, having a separate application might give you better security -guarantees as two processes would be communicating via established binary protocol. -Tendermint Core will not have access to application's state. +On the other hand, having a separate application might give you better security +guarantees as two processes would be communicating via established binary protocol. +Tendermint Core will not have access to application's state. If that is the way you wish to proceed, use the [Creating an application in Go](./go.md) guide instead of this one. @@ -90,7 +90,7 @@ go mod init kvstore go get github.com/tendermint/tendermint@latest ``` -After running the above commands you will see two generated files, `go.mod` and `go.sum`. +After running the above commands you will see two generated files, `go.mod` and `go.sum`. The go.mod file should look similar to: ```go @@ -114,11 +114,11 @@ go build ## 1.3 Writing a Tendermint Core application Tendermint Core communicates with the application through the Application -BlockChain Interface (ABCI). The messages exchanged through the interface are +BlockChain Interface (ABCI). The messages exchanged through the interface are defined in the ABCI [protobuf file](https://github.com/tendermint/tendermint/blob/main/proto/tendermint/abci/types.proto). -We begin by creating the basic scaffolding for an ABCI application by +We begin by creating the basic scaffolding for an ABCI application by creating a new type, `KVStoreApplication`, which implements the methods defined by the `abcitypes.Application` interface. @@ -203,7 +203,7 @@ to the project when you ran `go get`. If your IDE is not recognizing the types, go get github.com/tendermint/tendermint@latest ``` -Now go back to the `main.go` and modify the `main` function so it matches the following, +Now go back to the `main.go` and modify the `main` function so it matches the following, where an instance of the `KVStoreApplication` type is created. ```go @@ -221,17 +221,18 @@ and to start it along with the Tendermint Service. ### 1.3.1 Add a persistent data store + Our application will need to write its state out to persistent storage so that it can stop and start without losing all of its data. For this tutorial, we will use [BadgerDB](https://github.com/dgraph-io/badger), a -a fast embedded key-value store. +a fast embedded key-value store. First, add Badger as a dependency of your go module using the `go get` command: `go get github.com/dgraph-io/badger/v3` -Next, let's update the application and its constructor to receive a handle to the database, as follows: +Next, let's update the application and its constructor to receive a handle to the database, as follows: ```go type KVStoreApplication struct { @@ -246,7 +247,7 @@ func NewKVStoreApplication(db *badger.DB) *KVStoreApplication { } ``` -The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block +The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block is completed. Don't worry about it for now, we'll get to that later. Next, update the `import` stanza at the top to include the Badger library: @@ -265,7 +266,8 @@ Finally, update the `main.go` file to invoke the updated constructor: ``` ### 1.3.2 CheckTx -When Tendermint Core receives a new transaction from a client, or from another full node, Tendermint asks the application if + +When Tendermint Core receives a new transaction from a client, or from another full node, Tendermint asks the application if the transaction is acceptable, using the `CheckTx` method. Invalid transactions will not be shared with other nodes and will not become part of any blocks and, therefore, will not be executed by the application. @@ -295,17 +297,17 @@ func (app *KVStoreApplication) CheckTx(req abcitypes.RequestCheckTx) abcitypes.R } ``` -While this `CheckTx` is simple and only validates that the transaction is well-formed, +While this `CheckTx` is simple and only validates that the transaction is well-formed, it is very common for `CheckTx` to make more complex use of the state of an application. -For example, you may refuse to overwrite an existing value, or you can associate +For example, you may refuse to overwrite an existing value, or you can associate versions to the key/value pairs and allow the caller to specify a version to perform a conditional update. Depending on the checks and on the conditions violated, the function may return -different values, but any response with a non-zero code will be considered invalid -by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes -its validation checks. The specific value of the code is meaningless to Tendermint. -Non-zero codes are logged by Tendermint so applications can provide more specific +different values, but any response with a non-zero code will be considered invalid +by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes +its validation checks. The specific value of the code is meaningless to Tendermint. +Non-zero codes are logged by Tendermint so applications can provide more specific information on why the transaction was rejected. Note that `CheckTx` does not execute the transaction, it only verifies that that the transaction could be executed. We do not know yet if the rest of the network has agreed to accept this transaction into a block. @@ -334,7 +336,7 @@ receive a block. - `EndBlock` is called once to indicate to the application that no more transactions will be delivered to the application in within this block. -Note that, to implement these calls in our application we're going to make use of Badger's +Note that, to implement these calls in our application we're going to make use of Badger's transaction mechanism. We will always refer to these as Badger transactions, not to confuse them with the transactions included in the blocks delivered by Tendermint, the _application transactions_. @@ -372,26 +374,26 @@ func (app *KVStoreApplication) DeliverTx(req abcitypes.RequestDeliverTx) abcityp Note that we check the validity of the transaction _again_ during `DeliverTx`. Transactions are not guaranteed to be valid when they are delivered to an -application, even if they were valid when they were proposed. +application, even if they were valid when they were proposed. This can happen if the application state is used to determine transaction validity. Application state may have changed between the initial execution of `CheckTx` and the transaction delivery in `DeliverTx` in a way that rendered the transaction no longer valid. `EndBlock` is called to inform the application that the full block has been delivered -and give the application a chance to perform any other computation needed, before the +and give the application a chance to perform any other computation needed, before the effects of the transactions become permanent. -Note that `EndBlock` **cannot** yet commit the Badger transaction we were building +Note that `EndBlock` **cannot** yet commit the Badger transaction we were building in during `DeliverTx`. Since other methods, such as `Query`, rely on a consistent view of the application's -state, the application should only update its state by committing the Badger transactions +state, the application should only update its state by committing the Badger transactions when the full block has been delivered and the `Commit` method is invoked. -The `Commit` method tells the application to make permanent the effects of +The `Commit` method tells the application to make permanent the effects of the application transactions. Let's update the method to terminate the pending Badger transaction and -persist the resulting state: +persist the resulting state: ```go func (app *KVStoreApplication) Commit() abcitypes.ResponseCommit { @@ -416,10 +418,11 @@ import ( You may have noticed that the application we are writing will crash if it receives an unexpected error from the Badger database during the `DeliverTx` or `Commit` methods. -This is not an accident. If the application received an error from the database, there +This is not an accident. If the application received an error from the database, there is no deterministic way for it to make progress so the only safe option is to terminate. ### 1.3.4 Query + When a client tries to read some information from the `kvstore`, the request will be handled in the `Query` method. To do this, let's rewrite the `Query` method in `app.go`: @@ -454,11 +457,12 @@ Since it reads only committed data from the store, transactions that are part of that is being processed are not reflected in the query result. ### 1.3.5 PrepareProposal and ProcessProposal + `PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 to give the application more control over the construction and processing of transaction blocks. When Tendermint Core sees that valid transactions (validated through `CheckTx`) are available to be -included in blocks, it groups some of these transactions and then gives the application a chance +included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. The application is free to modify the group before returning from the call, as long as the resulting set @@ -476,7 +480,7 @@ func (app *KVStoreApplication) PrepareProposal(proposal abcitypes.RequestPrepare Once a proposed block is received by a node, the proposal is passed to the application to give its blessing before voting to accept the proposal. -This mechanism may be used for different reasons, for example to deal with blocks manipulated +This mechanism may be used for different reasons, for example to deal with blocks manipulated by malicious nodes, in which case the block should not be considered valid. The following code simply accepts all proposals: @@ -655,6 +659,7 @@ messages). Normally, you would use `SignerRemote` to connect to an external return nil, fmt.Errorf("failed to load node's key: %w", err) } ``` + Now we have everything set up to run the Tendermint node. We construct a node by passing it the configuration, the logger, a handle to our application and the genesis information: @@ -684,6 +689,7 @@ Finally, we start the node, i.e., the Tendermint Core service inside our applica node.Wait() }() ``` + The additional logic at the end of the file allows the program to catch SIGTERM. This means that the node can shut down gracefully when an operator tries to kill the program: ```go @@ -758,7 +764,8 @@ Open another terminal window and run the following curl command: ```bash curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"' ``` -If everything went well, you should see a response indicating which height the + +If everything went well, you should see a response indicating which height the transaction was included in the blockchain. Finally, let's make sure that transaction really was persisted by the application. @@ -779,7 +786,7 @@ The request returns a `json` object with a `key` and `value` field set. ``` Those values don't look like the `key` and `value` we sent to Tendermint. -What's going on here? +What's going on here? The response contains a `base64` encoded representation of the data we submitted. To get the original value out of this data, we can use the `base64` command line utility: diff --git a/docs/tutorials/go.md b/docs/tutorials/go.md index 5bd65aa16..df430962e 100644 --- a/docs/tutorials/go.md +++ b/docs/tutorials/go.md @@ -13,10 +13,10 @@ experience with Tendermint Core. Tendermint Core is a service that provides a Byzantine Fault Tolerant consensus engine for state-machine replication. The replicated state-machine, or "application", can be written in any language that can send and receive protocol buffer messages in a client-server model. -Applications written in Go can also use Tendermint as a library and run the service in the same -process as the application. +Applications written in Go can also use Tendermint as a library and run the service in the same +process as the application. -By following along this tutorial you will create a Tendermint Core application called kvstore, +By following along this tutorial you will create a Tendermint Core application called kvstore, a (very) simple distributed BFT key-value store. The application will be written in Go and some understanding of the Go programming language is expected. @@ -28,15 +28,16 @@ Note: Please use the latest released version of this guide and of Tendermint. We strongly advise against using unreleased commits for your development. ### Built-in app vs external app -On the one hand, to get maximum performance you can run your application in -the same process as the Tendermint Core, as long as your application is written in Go. + +On the one hand, to get maximum performance you can run your application in +the same process as the Tendermint Core, as long as your application is written in Go. [Cosmos SDK](https://github.com/cosmos/cosmos-sdk) is written -this way. +this way. If that is the way you wish to proceed, use the [Creating a built-in application in Go](./go-built-in.md) guide instead of this one. -On the other hand, having a separate application might give you better security -guarantees as two processes would be communicating via established binary protocol. -Tendermint Core will not have access to application's state. +On the other hand, having a separate application might give you better security +guarantees as two processes would be communicating via established binary protocol. +Tendermint Core will not have access to application's state. This is the approach followed in this tutorial. ## 1.1 Installing Go @@ -87,7 +88,7 @@ go mod init kvstore go get github.com/tendermint/tendermint@latest ``` -After running the above commands you will see two generated files, `go.mod` and `go.sum`. +After running the above commands you will see two generated files, `go.mod` and `go.sum`. The go.mod file should look similar to: ```go @@ -112,11 +113,11 @@ go build ## 1.3 Writing a Tendermint Core application Tendermint Core communicates with the application through the Application -BlockChain Interface (ABCI). The messages exchanged through the interface are +BlockChain Interface (ABCI). The messages exchanged through the interface are defined in the ABCI [protobuf file](https://github.com/tendermint/tendermint/blob/main/proto/tendermint/abci/types.proto). -We begin by creating the basic scaffolding for an ABCI application by +We begin by creating the basic scaffolding for an ABCI application by creating a new type, `KVStoreApplication`, which implements the methods defined by the `abcitypes.Application` interface. @@ -201,7 +202,7 @@ to the project when you ran `go get`. If your IDE is not recognizing the types, go get github.com/tendermint/tendermint@latest ``` -Now go back to the `main.go` and modify the `main` function so it matches the following, +Now go back to the `main.go` and modify the `main` function so it matches the following, where an instance of the `KVStoreApplication` type is created. @@ -220,17 +221,18 @@ and to start it along with the Tendermint Service. ### 1.3.1 Add a persistent data store + Our application will need to write its state out to persistent storage so that it can stop and start without losing all of its data. For this tutorial, we will use [BadgerDB](https://github.com/dgraph-io/badger), a -a fast embedded key-value store. +a fast embedded key-value store. First, add Badger as a dependency of your go module using the `go get` command: `go get github.com/dgraph-io/badger/v3` -Next, let's update the application and its constructor to receive a handle to the database, as follows: +Next, let's update the application and its constructor to receive a handle to the database, as follows: ```go type KVStoreApplication struct { @@ -245,7 +247,7 @@ func NewKVStoreApplication(db *badger.DB) *KVStoreApplication { } ``` -The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block +The `onGoingBlock` keeps track of the Badger transaction that will update the application's state when a block is completed. Don't worry about it for now, we'll get to that later. Next, update the `import` stanza at the top to include the Badger library: @@ -265,7 +267,8 @@ Finally, update the `main.go` file to invoke the updated constructor: ### 1.3.2 CheckTx -When Tendermint Core receives a new transaction from a client, Tendermint asks the application if + +When Tendermint Core receives a new transaction from a client, Tendermint asks the application if the transaction is acceptable, using the `CheckTx` method. In our application, a transaction is a string with the form `key=value`, indicating a key and value to write to the store. @@ -294,17 +297,17 @@ func (app *KVStoreApplication) CheckTx(req abcitypes.RequestCheckTx) abcitypes.R } ``` -While this `CheckTx` is simple and only validates that the transaction is well-formed, +While this `CheckTx` is simple and only validates that the transaction is well-formed, it is very common for `CheckTx` to make more complex use of the state of an application. -For example, you may refuse to overwrite an existing value, or you can associate +For example, you may refuse to overwrite an existing value, or you can associate versions to the key/value pairs and allow the caller to specify a version to perform a conditional update. Depending on the checks and on the conditions violated, the function may return -different values, but any response with a non-zero code will be considered invalid -by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes -its validation checks. The specific value of the code is meaningless to Tendermint. -Non-zero codes are logged by Tendermint so applications can provide more specific +different values, but any response with a non-zero code will be considered invalid +by Tendermint. Our `CheckTx` logic returns 0 to Tendermint when a transaction passes +its validation checks. The specific value of the code is meaningless to Tendermint. +Non-zero codes are logged by Tendermint so applications can provide more specific information on why the transaction was rejected. Note that `CheckTx` does not execute the transaction, it only verifies that that the transaction could be executed. We do not know yet if the rest of the network has agreed to accept this transaction into a block. @@ -333,7 +336,7 @@ receive a block. - `EndBlock` is called once to indicate to the application that no more transactions will be delivered to the application in within this block. -Note that, to implement these calls in our application we're going to make use of Badger's +Note that, to implement these calls in our application we're going to make use of Badger's transaction mechanism. We will always refer to these as Badger transactions, not to confuse them with the transactions included in the blocks delivered by Tendermint, the _application transactions_. @@ -371,26 +374,26 @@ func (app *KVStoreApplication) DeliverTx(req abcitypes.RequestDeliverTx) abcityp Note that we check the validity of the transaction _again_ during `DeliverTx`. Transactions are not guaranteed to be valid when they are delivered to an -application, even if they were valid when they were proposed. +application, even if they were valid when they were proposed. This can happen if the application state is used to determine transaction validity. Application state may have changed between the initial execution of `CheckTx` and the transaction delivery in `DeliverTx` in a way that rendered the transaction no longer valid. `EndBlock` is called to inform the application that the full block has been delivered -and give the application a chance to perform any other computation needed, before the +and give the application a chance to perform any other computation needed, before the effects of the transactions become permanent. -Note that `EndBlock` **cannot** yet commit the Badger transaction we were building +Note that `EndBlock` **cannot** yet commit the Badger transaction we were building in during `DeliverTx`. Since other methods, such as `Query`, rely on a consistent view of the application's -state, the application should only update its state by committing the Badger transactions +state, the application should only update its state by committing the Badger transactions when the full block has been delivered and the `Commit` method is invoked. -The `Commit` method tells the application to make permanent the effects of +The `Commit` method tells the application to make permanent the effects of the application transactions. Let's update the method to terminate the pending Badger transaction and -persist the resulting state: +persist the resulting state: ```go func (app *KVStoreApplication) Commit() abcitypes.ResponseCommit { @@ -415,10 +418,11 @@ import ( You may have noticed that the application we are writing will crash if it receives an unexpected error from the Badger database during the `DeliverTx` or `Commit` methods. -This is not an accident. If the application received an error from the database, there +This is not an accident. If the application received an error from the database, there is no deterministic way for it to make progress so the only safe option is to terminate. ### 1.3.4 Query + When a client tries to read some information from the `kvstore`, the request will be handled in the `Query` method. To do this, let's rewrite the `Query` method in `app.go`: @@ -453,11 +457,12 @@ Since it reads only committed data from the store, transactions that are part of that is being processed are not reflected in the query result. ### 1.3.5 PrepareProposal and ProcessProposal -`PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 + +`PrepareProposal` and `ProcessProposal` are methods introduced in Tendermint v0.37.0 to give the application more control over the construction and processing of transaction blocks. When Tendermint Core sees that valid transactions (validated through `CheckTx`) are available to be -included in blocks, it groups some of these transactions and then gives the application a chance +included in blocks, it groups some of these transactions and then gives the application a chance to modify the group by invoking `PrepareProposal`. The application is free to modify the group before returning from the call, as long as the resulting set @@ -475,7 +480,7 @@ func (app *KVStoreApplication) PrepareProposal(proposal abcitypes.RequestPrepare Once a proposed block is received by a node, the proposal is passed to the application to give its blessing before voting to accept the proposal. -This mechanism may be used for different reasons, for example to deal with blocks manipulated +This mechanism may be used for different reasons, for example to deal with blocks manipulated by malicious nodes, in which case the block should not be considered valid. The following code simply accepts all proposals: @@ -589,6 +594,7 @@ which connects to our server and send us transactions and other messages. signal.Notify(c, os.Interrupt, syscall.SIGTERM) <-c ``` + ## 1.5 Initializing and Running Our application is almost ready to run, but first we'll need to populate the Tendermint Core configuration files. @@ -631,8 +637,8 @@ I[2022-11-09|17:01:28.726] service start msg="Sta I[2022-11-09|17:01:28.726] Waiting for new connection... ``` -Then we need to start Tendermint Core service and point it to our application. -Open a new terminal window and cd to the same folder where the app is running. +Then we need to start Tendermint Core service and point it to our application. +Open a new terminal window and cd to the same folder where the app is running. Then execute the following command: ```bash @@ -672,7 +678,8 @@ Open another terminal window and run the following curl command: ```bash curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"' ``` -If everything went well, you should see a response indicating which height the + +If everything went well, you should see a response indicating which height the transaction was included in the blockchain. Finally, let's make sure that transaction really was persisted by the application. @@ -693,7 +700,7 @@ The request returns a `json` object with a `key` and `value` field set. ``` Those values don't look like the `key` and `value` we sent to Tendermint. -What's going on here? +What's going on here? The response contains a `base64` encoded representation of the data we submitted. To get the original value out of this data, we can use the `base64` command line utility: diff --git a/libs/events/README.md b/libs/events/README.md index 836e9c72e..aecef704b 100644 --- a/libs/events/README.md +++ b/libs/events/README.md @@ -24,7 +24,7 @@ Pub-Sub in go with event caching ### Package files -[event_cache.go](./event_cache.go) [events.go](./events.go) +[event_cache.go](./event_cache.go) [events.go](./events.go) ## Type [EventCache](./event_cache.go?s=116:179#L5) diff --git a/spec/abci/abci++_app_requirements.md b/spec/abci/abci++_app_requirements.md index 4d2dc7011..3fd312c03 100644 --- a/spec/abci/abci++_app_requirements.md +++ b/spec/abci/abci++_app_requirements.md @@ -128,10 +128,11 @@ As a general rule, `VerifyVoteExtension` SHOULD always accept the vote extension --> * Requirement 9 [*all*, no-side-effects]: *p*'s calls to `RequestPrepareProposal`, - `RequestProcessProposal`, + `RequestProcessProposal`, + --> at height *h* do not modify *sp,h-1*. @@ -366,7 +367,7 @@ For more information, see Section [State Sync](#state-sync). ### Transaction Results For each transaction within a block, the Application is expected to return a result within -[`ResponseDeliverTx`](./abci%2B%2B_methods.md#delivertx). +[`ResponseDeliverTx`](./abci%2B%2B_methods.md#delivertx). -We plan to extend this to allow applications to intervene at the moment a (precommit) vote is sent/received. -The applications could then require their validators to do more than just validating blocks through the `ExtendVote` +We plan to extend this to allow applications to intervene at the moment a (precommit) vote is sent/received. +The applications could then require their validators to do more than just validating blocks through the `ExtendVote` and `VerifyVoteExtension` methods. ## Method overview @@ -64,7 +64,7 @@ Methods can be classified into four categories: *consensus*, *mempool*, *info*, The first time a new blockchain is started, Tendermint calls `InitChain`. From then on, methods `BeginBlock`, `DeliverTx` and `EndBlock` are executed upon the decision of each block, resulting in an updated Application -state. One `DeliverTx` is called for each transaction in the block. The result is an updated application state. +state. One `DeliverTx` is called for each transaction in the block. The result is an updated application state. Cryptographic commitments to the results of `DeliverTx`, and an application-provided hash in `Commit` are included in the header of the next block. During the execution of an instance of consensus, which decides the block for a given height, and before method `BeginBlock` is called, methods `PrepareProposal` and `ProcessProposal`, may be called several times. See @@ -82,7 +82,7 @@ call sequences of these methods. been locked at Tendermint level. Tendermint gathers outstanding transactions from the mempool, generates a block header, and uses them to create a block to propose. Then, it calls `RequestPrepareProposal` with the newly created proposal, called *raw proposal*. The Application - can make changes to the raw proposal, such as modifying the set of transactions or the order + can make changes to the raw proposal, such as modifying the set of transactions or the order in which they appear, and returns the (potentially) modified proposal, called *prepared proposal* in the `ResponsePrepareProposal` call. The logic modifying the raw proposal can be non-deterministic. @@ -98,14 +98,14 @@ call sequences of these methods. the proposal is invalid (e.g., an invalid transaction); the Application can ignore the invalid part of the prepared proposal at block execution time. -- [**BeginBlock:**](./abci++_methods.md#beginblock) Is called exactly once after a block has been decided +- [**BeginBlock:**](./abci++_methods.md#beginblock) Is called exactly once after a block has been decided and executes once before all `DeliverTx` method calls. -- [**DeliverTx**](./abci++_methods.md#delivertx) Upon completion of `BeginBlock`, +- [**DeliverTx**](./abci++_methods.md#delivertx) Upon completion of `BeginBlock`, `DeliverTx` is called once for each of the transactions within the block. The application defines further checks to confirm their - validity - for example a key-value store might verify that the key does not already exist. Note that - even if a transaction does not pass the check in `DeliverTx`, it will still be part of the block as the + validity - for example a key-value store might verify that the key does not already exist. Note that + even if a transaction does not pass the check in `DeliverTx`, it will still be part of the block as the block has already been voted on (unlike with `CheckTx` which would dismiss such a transaction). The responses returned by `DeliverTx` are included in the header of the next block. @@ -232,7 +232,7 @@ to accommodate the long block execution time and non-proposer nodes might time out and prevote `nil`. The proposal, in this case, will probably be rejected and a new round will be necessary. -Operators will need to adjust the default value of *TimeoutPropose* in Tendermint's configuration file, +Operators will need to adjust the default value of *TimeoutPropose* in Tendermint's configuration file, in order to suit the needs of the particular application being deployed. ## Deterministic State-Machine Replication @@ -298,7 +298,7 @@ on them. All other fields in the `Response*` must be strictly deterministic. [↑ Back to Outline](#outline) -Methods `BeginBlock, DeliverTx` and `EndBlock ` include an `events` field in their +Methods `BeginBlock, DeliverTx` and `EndBlock` include an `events` field in their `Response*`. Applications may respond to this ABCI++ method with an event list for each executed transaction, and a general event list for the block itself. @@ -309,7 +309,7 @@ and instead exist to power subscriptions and queries of Tendermint state. An `Event` contains a `type` and a list of `EventAttributes`, which are key-value string pairs denoting metadata about what happened during the method's (or transaction's) execution. `Event` values can be used to index transactions and blocks according to what -happened during their execution. +happened during their execution. Each event has a `type` which is meant to categorize the event for a particular `Response*` or `Tx`. A `Response*` or `Tx` may contain multiple events with duplicate @@ -423,7 +423,7 @@ these codes reports errors related to the transaction it is attached to. However, `FinalizeBlock` does not return errors at the top level, so the same considerations on critical issues made for `Echo`, `Info`, and `InitChain` also apply here. ---> +--> The handling of non-zero response codes by Tendermint is described below. @@ -433,10 +433,10 @@ When Tendermint receives a `ResponseCheckTx` with a non-zero `Code`, the associa transaction will not be added to Tendermint's mempool or it will be removed if it is already included. -### `DeliverTx` +### `DeliverTx` -The `DeliverTx` ABCI method delivers transactions from Tendermint to the application. -When Tendermint receives a `ResponseDeliverTx` with a non-zero `Code`, the response code is logged. +The `DeliverTx` ABCI method delivers transactions from Tendermint to the application. +When Tendermint receives a `ResponseDeliverTx` with a non-zero `Code`, the response code is logged. The transaction was already included in a block, so the `Code` does not influence Tendermint consensus. +--> ## Server Implementations To use ABCI in your programming language of choice, there must be an ABCI diff --git a/spec/abci/abci++_methods.md b/spec/abci/abci++_methods.md index dfaba34b9..c45b0ae37 100644 --- a/spec/abci/abci++_methods.md +++ b/spec/abci/abci++_methods.md @@ -201,14 +201,14 @@ title: Methods * **Usage**: * [**Required**] The core method of the application. - * `DeliverTx` is called once for each transaction in the block. - * When `DeliverTx` is called, the application must execute the transaction deterministically - in full before returning control to Tendermint. + * `DeliverTx` is called once for each transaction in the block. + * When `DeliverTx` is called, the application must execute the transaction deterministically + in full before returning control to Tendermint. * Alternatively, the application can apply a candidate state corresponding to the same block previously executed via `PrepareProposal` or `ProcessProposal` any time between the calls to `BeginBlock`, the various calls to `DeliverTx` and `EndBlock`. * `ResponseDeliverTx.Code == 0` only if the transaction is fully valid. - + ### EndBlock @@ -238,7 +238,7 @@ title: Methods * `consensus_param_updates` returned for block `H` apply to the consensus params for block `H+1`. For more information on the consensus parameters, see the [application spec entry on consensus parameters](abci++_app_requirements.md#consensus-parameters). - * `validator_updates` and `consensus_param_updates` may be empty. In this case, Tendermint will keep the current values. + * `validator_updates` and `consensus_param_updates` may be empty. In this case, Tendermint will keep the current values. @@ -261,7 +261,7 @@ title: Methods * Signal the application to persist the application state. * Return an (optional) Merkle root hash of the application state * `ResponseCommit.Data` is included as the `Header.AppHash` in the next block - * It may be empty or hard-coded, but MUST be **deterministic** - it must not be a function of anything that did not come from the parameters of the execution calls (` BeginBlock/DeliverTx/EndBlock methods`) and the previous committed state. + * It may be empty or hard-coded, but MUST be **deterministic** - it must not be a function of anything that did not come from the parameters of the execution calls (`BeginBlock/DeliverTx/EndBlock methods`) and the previous committed state. * Later calls to `Query` can return proofs about the application state anchored in this Merkle root hash * Use `RetainHeight` with caution! If all nodes in the network remove historical @@ -453,11 +453,11 @@ title: Methods returned in `ResponsePrepareProposal.txs` . * As a result of executing the prepared proposal, the Application may produce block events or transaction events. The Application must keep those events until a block is decided. It will then forward the events to the `BeginBlock-DeliverTx-EndBlock` functions depending on where each event should be placed, thereby returning the events to Tendermint. - * Tendermint does NOT provide any additional validity checks (such as checking for duplicate + * Tendermint does NOT provide any additional validity checks (such as checking for duplicate transactions). * If Tendermint fails to validate the `ResponsePrepareProposal`, Tendermint will assume the Application is faulty and crash. @@ -897,7 +897,7 @@ Most of the data structures used in ABCI are shared [common data structures](../ * **Usage**: * Indicates whether a validator signed the last block, allowing for rewards based on validator availability. * This information is extracted from Tendermint's data structures in the local process. - * `vote_extension` is reserved for future use when vote extensions are added. Currently, this field is always set to `nil`. + * `vote_extension` is reserved for future use when vote extensions are added. Currently, this field is always set to `nil`. ### CommitInfo @@ -994,4 +994,4 @@ enum VerifyStatus { --> -[protobuf-timestamp]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp \ No newline at end of file +[protobuf-timestamp]: https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp diff --git a/spec/abci/abci++_tmint_expected_behavior.md b/spec/abci/abci++_tmint_expected_behavior.md index 849fb3fd9..74b73336d 100644 --- a/spec/abci/abci++_tmint_expected_behavior.md +++ b/spec/abci/abci++_tmint_expected_behavior.md @@ -23,12 +23,12 @@ what will happen during a block height _h_ in these frequent, benign conditions: * `VerifyVoteExtension` will be called exactly _n-1_ times at each validator process, where _n_ is the number of validators, and will always return _accept_ in its `Response*`; --> -* `BeginBlock` will be called exactly once at all processes, conveying the same prepared +* `BeginBlock` will be called exactly once at all processes, conveying the same prepared block header that all calls to `PrepareProposal` and `ProcessProposal` had previously reported for height _h_; and -* `DeliverTx` will be called exactly once for each transaction within the block. -* `EndBlock` will be called exactly once after `DeliverTx` has been executed for all transactions and marks - the end of processing for the block. +* `DeliverTx` will be called exactly once for each transaction within the block. +* `EndBlock` will be called exactly once after `DeliverTx` has been executed for all transactions and marks + the end of processing for the block. * `Commit` will finally be called exactly once at all processes at the end of height _h_. However, the Application logic must be ready to cope with any possible run of Tendermint for a given @@ -162,21 +162,23 @@ Let us now examine the grammar line by line, providing further details. >``` * For every round, if the local process is the proposer of the current round, Tendermint starts by - calling `PrepareProposal`, followed by `ProcessProposal`. + calling `PrepareProposal`, followed by `ProcessProposal`. + --> >```abnf >proposer = prepare-proposal process-proposal >``` * Also for every round, if the local process is _not_ the proposer of the current round, Tendermint - will call `ProcessProposal` at most once. + will call `ProcessProposal` at most once. . diff --git a/spec/light-client/attacks/isolate-attackers_002_reviewed.md b/spec/light-client/attacks/isolate-attackers_002_reviewed.md index 927c81bd6..8b430b8b6 100644 --- a/spec/light-client/attacks/isolate-attackers_002_reviewed.md +++ b/spec/light-client/attacks/isolate-attackers_002_reviewed.md @@ -197,7 +197,6 @@ For this fixed group membership, we have analyzed the attacks using the TLA+ spe [[detection]] The specification of the light client attack detection mechanism. -[[tendermint-accountability]]: TLA+ specification to check the types of attacks [tendermint-accountability]: https://github.com/tendermint/spec/blob/master/rust-spec/tendermint-accountability/README.md diff --git a/spec/light-client/detection/detection_001_reviewed.md b/spec/light-client/detection/detection_001_reviewed.md index bcd2c54bb..dfb67c9a8 100644 --- a/spec/light-client/detection/detection_001_reviewed.md +++ b/spec/light-client/detection/detection_001_reviewed.md @@ -771,13 +771,9 @@ Once a bogus block is recognized as such the secondary is removed. [supervisor]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/supervisor/supervisor.md -[block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md -[TMBC-FM-2THIRDS-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-fm-2thirds1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-sound-distr-poss-commit1 -[LCV-SEQ-SAFE-link]:https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#lcv-seq-safe1 [TMBC-VAL-CONTAINS-CORR-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification.md#tmbc-val-contains-corr1 diff --git a/spec/light-client/detection/detection_003_reviewed.md b/spec/light-client/detection/detection_003_reviewed.md index a300e403f..28d3104c7 100644 --- a/spec/light-client/detection/detection_003_reviewed.md +++ b/spec/light-client/detection/detection_003_reviewed.md @@ -807,7 +807,6 @@ Once a bogus block is recognized as such the secondary is removed. [supervisor]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/supervisor/supervisor_001_draft.md -[block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md [TMBC-FM-2THIRDS-link]: https://github.com/tendermint/spec/blob/master/rust-spec/lightclient/verification/verification_002_draft.md#tmbc-fm-2thirds1 diff --git a/spec/light-client/supervisor/supervisor_002_draft.md b/spec/light-client/supervisor/supervisor_002_draft.md index 3926b75ab..2649b3058 100644 --- a/spec/light-client/supervisor/supervisor_002_draft.md +++ b/spec/light-client/supervisor/supervisor_002_draft.md @@ -25,7 +25,7 @@ Types](https://github.com/tendermint/tendermint/blob/main/types/genesis.go). The light client is based on subjective initialization. It has to trust the initial data given to it by the user. It cannot perform any detection of an attack yet instead requires an initial point of trust. -There are three forms of initial data which are used to obtain the +There are three forms of initial data which are used to obtain the first trusted block: - A trusted block from a prior initialization diff --git a/spec/light-client/verification/verification_001_published.md b/spec/light-client/verification/verification_001_published.md index f446dda02..8cdae0acf 100644 --- a/spec/light-client/verification/verification_001_published.md +++ b/spec/light-client/verification/verification_001_published.md @@ -1152,7 +1152,6 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [block]: https://github.com/tendermint/spec/blob/d46cd7f573a2c6a2399fcab2cde981330aa63f37/spec/core/data_structures.md -[TMBC-HEADER-link]: #tmbc-header1 [TMBC-SEQ-link]: #tmbc-seq1 [TMBC-CorrFull-link]: #tmbc-corr-full1 [TMBC-Auth-Byz-link]: #tmbc-auth-byz1 @@ -1160,7 +1159,6 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [TMBC-FM-2THIRDS-link]: #tmbc-fm-2thirds1 [TMBC-VAL-CONTAINS-CORR-link]: #tmbc-val-contains-corr1 [TMBC-VAL-COMMIT-link]: #tmbc-val-commit1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: #tmbc-sound-distr-poss-commit1 [lightclient]: https://github.com/interchainio/tendermint-rs/blob/e2cb9aca0b95430fca2eac154edddc9588038982/docs/architecture/adr-002-lite-client.md [fork-detector]: https://github.com/tendermint/tendermint/tree/main/spec/light-client/detection @@ -1168,7 +1166,5 @@ func Main (primary PeerID, lightStore LightStore, targetHeight Height) [ibc-rs]:https://github.com/informalsystems/ibc-rs -[blockchain-validator-set]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md#validatorset -[fullnode-data-structures]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md [arXiv]: https://arxiv.org/abs/1807.04938 diff --git a/spec/light-client/verification/verification_002_draft.md b/spec/light-client/verification/verification_002_draft.md index 5082c5870..aaa9dc230 100644 --- a/spec/light-client/verification/verification_002_draft.md +++ b/spec/light-client/verification/verification_002_draft.md @@ -1045,7 +1045,6 @@ func Backwards (primary PeerID, root LightBlock, targetHeight Height) [TMBC-FM-2THIRDS-link]: #tmbc-fm-2thirds1 [TMBC-VAL-CONTAINS-CORR-link]: #tmbc-val-contains-corr1 [TMBC-VAL-COMMIT-link]: #tmbc-val-commit1 -[TMBC-SOUND-DISTR-POSS-COMMIT-link]: #tmbc-sound-distr-poss-commit1 [lightclient]: https://github.com/interchainio/tendermint-rs/blob/e2cb9aca0b95430fca2eac154edddc9588038982/docs/architecture/adr-002-lite-client.md [attack-detector]: https://github.com/tendermint/tendermint/blob/main/spec/light-client/detection/detection_001_reviewed.md @@ -1053,7 +1052,5 @@ func Backwards (primary PeerID, root LightBlock, targetHeight Height) [ibc-rs]:https://github.com/informalsystems/ibc-rs -[blockchain-validator-set]: https://github.com/tendermint/tendermint/blob/main/spec/blockchain/blockchain.md#data-structures -[fullnode-data-structures]: https://github.com/tendermint/tendermint/blob/main/spec/core/data_structures.md [arXiv]: https://arxiv.org/abs/1807.04938 diff --git a/spec/light-client/verification/verification_003_draft.md b/spec/light-client/verification/verification_003_draft.md index cd38e7e96..6ff8f6541 100644 --- a/spec/light-client/verification/verification_003_draft.md +++ b/spec/light-client/verification/verification_003_draft.md @@ -73,4 +73,4 @@ height int64, commit *Commit) error { return nil } -``` \ No newline at end of file +``` diff --git a/spec/p2p/messages/pex.md b/spec/p2p/messages/pex.md index 24215fd01..cab26ac2f 100644 --- a/spec/p2p/messages/pex.md +++ b/spec/p2p/messages/pex.md @@ -14,7 +14,7 @@ Pex has one channel. The channel identifier is listed below. ## Message Types -The current PEX service has two versions. The first uses IP/port pair but since the p2p stack is moving towards a transport agnostic approach, +The current PEX service has two versions. The first uses IP/port pair but since the p2p stack is moving towards a transport agnostic approach, node endpoints require a `Protocol` and `Path` hence the V2 version uses a [url](https://golang.org/pkg/net/url/#URL) instead. ### PexRequest diff --git a/spec/p2p/v0.34/README.md b/spec/p2p/v0.34/README.md index cfb132ce4..b87761326 100644 --- a/spec/p2p/v0.34/README.md +++ b/spec/p2p/v0.34/README.md @@ -40,30 +40,30 @@ which implements the following abstractions: that is, between local and remote instances of the Tendermint protocols; - [PEX Reactor](./pex.md): a reactor is the implementation of a protocol which exchanges messages through the p2p layer. The PEX reactor manages the [Address Book](./addressbook.md) and implements both the [PEX protocol](./pex-protocol.md) and the [Peer Manager](./peer_manager.md) role. - - [Peer Exchange protocol](./pex-protocol.md): enables nodes to exchange peer addresses, thus implementing a peer discovery service; - - [Address Book](./addressbook.md): stores discovered peer addresses and + - [Peer Exchange protocol](./pex-protocol.md): enables nodes to exchange peer addresses, thus implementing a peer discovery service; + - [Address Book](./addressbook.md): stores discovered peer addresses and quality metrics associated to peers with which the node has interacted; - - [Peer Manager](./peer_manager.md): defines when and to which peers a node + - [Peer Manager](./peer_manager.md): defines when and to which peers a node should dial, in order to establish outbound connections; - Finally, [Types](./types.md) and [Configuration](./configuration.md) provide a list of existing types and configuration parameters used by the p2p layer implementation. -## Further References +## Further References Existing documentation referring to the p2p layer: -- https://github.com/tendermint/tendermint/tree/main/spec/p2p: p2p-related +- : p2p-related configuration flags; overview of connections, peer instances, and reactors; overview of peer discovery and node types; peer identity, secure connections and peer authentication handshake. -- https://github.com/tendermint/tendermint/tree/main/spec/p2p/messages: message +- : message types and channel IDs of Block Sync, Mempool, Evidence, State Sync, PEX, and Consensus reactors. -- https://docs.tendermint.com/v0.34/tendermint-core: the p2p layer +- : the p2p layer configuration and operation is documented in several pages. This content is not necessarily up-to-date, some settings and concepts may refer to the release `v0.35`, that was [discontinued][v35postmorten]. -- https://github.com/tendermint/tendermint/tree/master/docs/tendermint-core/pex: +- : peer types, peer discovery, peer management overview, address book and peer ranking. This documentation refers to the release `v0.35`, that was [discontinued][v35postmorten]. diff --git a/spec/p2p/v0.34/addressbook.md b/spec/p2p/v0.34/addressbook.md index b51338121..8fd2cc3a2 100644 --- a/spec/p2p/v0.34/addressbook.md +++ b/spec/p2p/v0.34/addressbook.md @@ -203,6 +203,7 @@ number of addresses stored in the address book, but it should not be lower than --- nor greater than `250` (`maxGetSelection`). > The random selection is produced by: +> > - Retrieving all entries of the `addrLookup` map, which by definition are > returned in random order. > - Randomly shuffling the retrieved list, using the Fisher-Yates algorithm @@ -241,7 +242,7 @@ random order. ## Dial Attempts -The `MarkAttempt` method records a failed attempt to connect to an address. +The `MarkAttempt` method records a failed attempt to connect to an address. It is invoked by the Peer Manager when it fails dialing a peer, but the failure is not in the authentication step (`ErrSwitchAuthenticationFailure` error). diff --git a/spec/p2p/v0.34/configuration.md b/spec/p2p/v0.34/configuration.md index 1962f6ebc..929164772 100644 --- a/spec/p2p/v0.34/configuration.md +++ b/spec/p2p/v0.34/configuration.md @@ -1,12 +1,12 @@ # Tendermint p2p configuration -This document contains configurable parameters a node operator can use to tune the p2p behaviour. +This document contains configurable parameters a node operator can use to tune the p2p behaviour. | Parameter| Default| Description | | --- | --- | ---| | ListenAddress | "tcp://0.0.0.0:26656" | Address to listen for incoming connections (0.0.0.0:0 means any interface, any port) | | ExternalAddress | "" | Address to advertise to peers for them to dial | -| [Seeds](pex-protocol.md#seed-nodes) | empty | Comma separated list of seed nodes to connect to (ID@host:port )| +| [Seeds](pex-protocol.md#seed-nodes) | empty | Comma separated list of seed nodes to connect to (ID@host:port )| | [Persistent peers](peer_manager.md#persistent-peers) | empty | Comma separated list of nodes to keep persistent connections to (ID@host:port ) | | UPNP | false | UPNP port forwarding enabled | | [AddrBook](addressbook.md) | defaultAddrBookPath | Path do address book | @@ -33,19 +33,19 @@ These parameters can be set using the `$TMHOME/config/config.toml` file. A subse | --- | --- | ---| | Listen address| `p2p.laddr` | "tcp://0.0.0.0:26656" | | Seed nodes | `p2p.seeds` | `--p2p.seeds “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:4444”` | -| Persistent peers | `p2p.persistent_peers` | `--p2p.persistent_peers “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:26656”` | +| Persistent peers | `p2p.persistent_peers` | `--p2p.persistent_peers “id100000000000000000000000000000000@1.2.3.4:26656,id200000000000000000000000000000000@2.3.4.5:26656”` | | Unconditional peers | `p2p.unconditional_peer_ids` | `--p2p.unconditional_peer_ids “id100000000000000000000000000000000,id200000000000000000000000000000000”` | - | UPNP | `p2p.upnp` | `--p2p.upnp` | - | PexReactor | `p2p.pex` | `--p2p.pex` | + | UPNP | `p2p.upnp` | `--p2p.upnp` | + | PexReactor | `p2p.pex` | `--p2p.pex` | | Seed mode | `p2p.seed_mode` | `--p2p.seed_mode` | | Private peer ids | `p2p.private_peer_ids` | `--p2p.private_peer_ids “id100000000000000000000000000000000,id200000000000000000000000000000000”` | **Note on persistent peers** - + If `persistent_peers_max_dial_period` is set greater than zero, the pause between each dial to each persistent peer will not exceed `persistent_peers_max_dial_period` during exponential backoff and we keep trying again without giving up. If `seeds` and `persistent_peers` intersect, the user will be warned that seeds may auto-close connections -and that the node may not be able to keep the connection persistent. \ No newline at end of file +and that the node may not be able to keep the connection persistent. diff --git a/spec/p2p/v0.34/peer_manager.md b/spec/p2p/v0.34/peer_manager.md index 00051ed0e..ba2e75ef3 100644 --- a/spec/p2p/v0.34/peer_manager.md +++ b/spec/p2p/v0.34/peer_manager.md @@ -10,7 +10,7 @@ but a role that is played by the [PEX reactor](./pex.md). The `ensurePeersRoutine` is a persistent routine intended to ensure that a node is connected to `MaxNumOutboundPeers` outbound peers. This routine is continuously executed by regular nodes, i.e. nodes not -operating in seed mode, as part of the PEX reactor implementation. +operating in seed mode, as part of the PEX reactor implementation. The logic defining when the node should dial peers, for selecting peers to dial and for actually dialing them is implemented in the `ensurePeers` method. @@ -70,7 +70,7 @@ They are contacted by a node when, after an invocation of the `ensurePeers` method, no suitable peer address to dial is retrieved from the address book (e.g., because it is empty). -Once a connection with a seed node is established, the node immediately +Once a connection with a seed node is established, the node immediately [sends a PEX request](./pex-protocol.md#Requesting-Addresses) to it, as it is added as an outbound peer. When the corresponding PEX response is received, the addresses provided by the @@ -137,7 +137,7 @@ A peer can be in the following states: - Connected peers: peers that a node has successfully dialed, added as outbound peers. - [Bad peers](addressbook.md#bad-peers): peers marked as bad in the address book due to exhibited [misbehavior](pex-protocol.md#misbehavior). - Peers can be reinstated after being marked as bad. + Peers can be reinstated after being marked as bad. ## Pending of documentation diff --git a/spec/p2p/v0.34/pex-protocol.md b/spec/p2p/v0.34/pex-protocol.md index 6497e1385..d4d7fc089 100644 --- a/spec/p2p/v0.34/pex-protocol.md +++ b/spec/p2p/v0.34/pex-protocol.md @@ -85,7 +85,7 @@ This leads the peer to be disconnected and [marked as a bad peer](addressbook.md When a node receives a `PexRequest` message from a peer, it replies with a `PexAddrs` message. -This message encodes a [random selection of peer addresses](./addressbook.md#random-selection) +This message encodes a [random selection of peer addresses](./addressbook.md#random-selection) retrieved from the address book. Sending a PEX response to a peer is implemented by the `SendAddrs` method of diff --git a/spec/p2p/v0.34/pex.md b/spec/p2p/v0.34/pex.md index f976cc83b..945969f84 100644 --- a/spec/p2p/v0.34/pex.md +++ b/spec/p2p/v0.34/pex.md @@ -93,7 +93,7 @@ trustworthy than outbound peers. The `RemovePeer` method, from the `Reactor` interface, removes a peer from the PEX protocol. -The peer's ID is removed from the tables tracking PEX requests +The peer's ID is removed from the tables tracking PEX requests [sent](./pex-protocol.md#misbehavior) but not yet replied and PEX requests [received](./pex-protocol.md#misbehavior-1). @@ -105,7 +105,7 @@ handles a message received by the PEX protocol. A node receives two type of messages as part of the PEX protocol: - `PexRequest`: a request for addresses received from a peer, handled as - described [here](./pex-protocol.md#providing-addresses) + described [here](./pex-protocol.md#providing-addresses) - `PexAddrs`: a list of addresses received from a peer, as a reponse to a PEX - request sent by the node, as described [here](./pex-protocol.md#responses) + request sent by the node, as described [here](./pex-protocol.md#responses) diff --git a/spec/p2p/v0.34/switch.md b/spec/p2p/v0.34/switch.md index 54a0f63c2..dd2833a4b 100644 --- a/spec/p2p/v0.34/switch.md +++ b/spec/p2p/v0.34/switch.md @@ -47,7 +47,7 @@ this same `DialPeerWithAddress` method for dialing peers. ### Manual operation The `DialPeersAsync` method receives a list of peer addresses (strings) -and dials all of them in parallel. +and dials all of them in parallel. It is invoked in two situations: - In the [setup](https://github.com/tendermint/tendermint/blob/29c5a062d23aaef653f11195db55c45cd9e02715/node/node.go#L985) of a node, to establish connections with every configured @@ -61,7 +61,7 @@ In case of parsing errors, the method returns. An exception is made for DNS resolution `ErrNetAddressLookup` errors, which do not interrupt the procedure. As the peer addresses provided to this method are typically not known by the node, -contrarily to the addressed dialed using the `DialPeerWithAddress` method, +contrarily to the addressed dialed using the `DialPeerWithAddress` method, they are added to the node's address book, which is persisted to disk. The switch dials the provided peers in parallel. @@ -173,7 +173,7 @@ precisely, not providing to the switch any "reason" for that. In both cases the `Peer` instance is stopped, the peer is removed from all registered reactors, and finally from the list of connected peers. -> Issue https://github.com/tendermint/tendermint/issues/3338 is mentioned in +> Issue is mentioned in > the internal `stopAndRemovePeer` method explaining why removing the peer from > the list of connected peers is the last action taken. @@ -232,6 +232,7 @@ The return value (a boolean) of these calls are redirected to a channel that is returned by the method. > TODO: detail where this method is invoked: +> > - By the consensus protocol, in `broadcastNewRoundStepMessage`, > `broadcastNewValidBlockMessage`, and `broadcastHasVoteMessage` > - By the state sync protocol diff --git a/spec/p2p/v0.34/transport.md b/spec/p2p/v0.34/transport.md index 9bb486a3d..e072bfe6f 100644 --- a/spec/p2p/v0.34/transport.md +++ b/spec/p2p/v0.34/transport.md @@ -71,7 +71,7 @@ as well any error returned in this process are added to a queue of accepted conn This queue is consumed by the `Accept` method. > Handling accepted connection asynchronously was introduced due to this issue: -> https://github.com/tendermint/tendermint/issues/2047 +> ## Connection Filtering diff --git a/spec/p2p/v0.34/types.md b/spec/p2p/v0.34/types.md index ba43980ee..88cdcafb3 100644 --- a/spec/p2p/v0.34/types.md +++ b/spec/p2p/v0.34/types.md @@ -48,7 +48,7 @@ but currently is not produced outside tests. `ErrTransportClosed` is produced by the [transport](#transportgo) and handled by the [switch](#switchgo). -`ErrNetAddressNoID`, `ErrNetAddressInvalid`, and `ErrNetAddressLookup` +`ErrNetAddressNoID`, `ErrNetAddressInvalid`, and `ErrNetAddressLookup` are parsing a string to create an instance of `NetAddress`. It can be returned in the setup of the [switch](#switchgo) and of the [PEX reactor](#pex_reactorgo), @@ -92,7 +92,7 @@ It is implemented by `DefaultNodeInfo` type. The [switch](#switchgo) stores the local `NodeInfo`. -The `NodeInfo` of connected peers is produced by the +The `NodeInfo` of connected peers is produced by the [transport](#transportgo) during the handshake, and stored in [`Peer`](#peergo) instances. ### `peer.go` @@ -236,4 +236,4 @@ Not imported by any other Tendermint source file. This package implementation was taken from "taipei-torrent". -It is used by the `probe-upnp` command of the Tendermint binary. +It is used by the `probe-upnp` command of the Tendermint binary. diff --git a/test/e2e/README.md b/test/e2e/README.md index ed411440b..11e019f5f 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -155,9 +155,9 @@ Docker does not enable IPv6 by default. To do so, enter the following in It is also possible to run a simple benchmark on a testnet. This is done through the `benchmark` command. This manages the entire process: setting up the environment, starting the test net, waiting for a considerable amount of blocks to be used (currently 100), and then returning the following metrics from the sample of the blockchain: -- Average time to produce a block -- Standard deviation of producing a block -- Minimum and maximum time to produce a block +* Average time to produce a block +* Standard deviation of producing a block +* Minimum and maximum time to produce a block ## Running Individual Nodes