lint markdown

This commit is contained in:
Callum
2020-11-20 14:43:34 +01:00
parent 5eae97045f
commit 41496117f2

View File

@@ -4,94 +4,108 @@
- 11-11-2020: Address both RPC and ABCI versioning
- 18-09-2018: Updates after working a bit on implementation
- ABCI Handshake needs to happen independently of starting the app conns so we can see the result
- Add question about ABCI protocol version
- ABCI Handshake needs to happen independently of starting the app conns so we
can see the result
- Add question about ABCI protocol version
- 16-08-2018: Updates after discussion with SDK team
- Remove signalling for next version from Header/ABCI
- Remove signalling for next version from Header/ABCI
- 03-08-2018: Updates from discussion with Jae:
- ProtocolVersion contains Block/AppVersion, not Current/Next
- signal upgrades to Tendermint using EndBlock fields
- don't restrict peer compatibility by version to simplify syncing old nodes
- ProtocolVersion contains Block/AppVersion, not Current/Next
- signal upgrades to Tendermint using EndBlock fields
- don't restrict peer compatibility by version to simplify syncing old nodes
- 28-07-2018: Updates from review
- split into two ADRs - one for protocol, one for chains
- include signalling for upgrades in header
- 16-07-2018: Initial draft - was originally joint ADR for protocol and chain versions
- split into two ADRs - one for protocol, one for chains
- include signalling for upgrades in header
- 16-07-2018: Initial draft - was originally joint ADR for protocol and chain
versions
## Context
This ADR focuses on software-agnostic protocol versions.
The Software Version is covered by SemVer and described elsewhere.
It is not relevant to the protocol description, suffice to say that if any protocol version
changes, the software version changes, but not necessarily vice versa.
It is not relevant to the protocol description, suffice to say that if any
protocol version changes, the software version changes, but not necessarily
vice versa.
Software version should be included in NodeInfo for convenience/diagnostics.
We need to version components of the blockchain that may be independently upgraded.
We need to do it in a way that is scalable and maintainable - we can't just litter
the code with conditionals. We need a versioning system that supports a range of
stakeholders throughout the lifespan of a blockchain.
We need to version components of the blockchain that may be independently
upgraded. We need to do it in a way that is scalable and maintainable - we can't
just litter the code with conditionals. We need a versioning system that
supports a range of stakeholders throughout the lifespan of a blockchain.
We also need to consider the lifespan of the application itself and be accommodating
to how it upgrades.
We also need to consider the lifespan of the application itself and be
accommodating to how it upgrades.
## Proposal
Ideally, each component of the software is independently versioned in a modular way and its easy to mix and match and upgrade.
Ideally, each component of the software is independently versioned in a modular
way and its easy to mix and match and upgrade.
We can consider the complete version of the protocol to contain the following sub-versions:
*BlockVersion*, *P2PVersion*, *AppVersion*. These versions reflect the major sub-components
of the software that are likely to evolve together, at different rates, and in different ways.
We can consider the complete version of the protocol to contain the following
sub-versions:
*BlockVersion*, *P2PVersion*, *AppVersion*
These versions reflect the major sub-components of the software that are likely
to evolve together, at different rates, and in different ways.
### What does each protocol version correspond to and how are they allowed to evolve
Each of BlockVersion, AppVersion, and P2PVersion is a monotonically increasing uint64.
Incrementing the version number indicates a change that is incompatible with the previous version.
Each of BlockVersion, AppVersion, and P2PVersion is a monotonically increasing
uint64. Incrementing the version number indicates a change that is incompatible
with the previous version.
#### BlockVersion
- This consists of all Tendermint data-structures (headers, votes, commits, txs,
responses, etc.). A complete list of data structures can be found in the
responses, etc.). A complete list of data structures can be found in the
[spec](https://github.com/tendermint/spec/blob/master/spec/core/data_structures.md)
#### P2PVersion
- All p2p and reactor messaging (messages, detectable behavior)
- It should be easy to determine the version of a peer from its first serialized message/s
- New versions must be compatible with at least one old version to allow gradual upgrades
- We need the peer/reactor protocols to take the versions of peers into account when sending messages so that we
don't send messages that the peer won't understand or won't expect.
- It should be easy to determine the version of a peer from its first serialized
message/s
- New versions must be compatible with at least one old version to allow gradual
upgrades
- We need the peer/reactor protocols to take the versions of peers into account
when sending messages so that we don't send messages that the peer won't
understand or won't expect.
#### AppVersion
- The ABCI state machine itself.
- Tendermint needs to know the version of the application to ensure that AppHash and Results are calculated in the same manner across the entire network.
- Tendermint needs to know the version of the application to ensure that AppHash
and Results are calculated in the same manner across the entire network.
In addition, the block version is the parent of two further sub versions: *RPCVersion* and *ABCIVersion*.
These are denoted using semantic versioning. Changing the block protocol will require either a new major
or minor release for each of these versions as the data structures they serve have changed,
however major and minor releases wouldn't necessarily mean a block protocol change.
In addition, the block version is the parent of two further sub versions:
*RPCVersion* and *ABCIVersion*.
These are denoted using semantic versioning. Changing the block protocol will
require either a new major or minor release for each of these versions as the
data structures they serve have changed, however major and minor releases
wouldn't necessarily mean a block protocol change.
#### RPCVersion
This covers all RPC endpoints and their respective requests and responses.
In the case of an introduction of a new interface with external users (i.e gRPC),
this would also fall under the RPCVersion. Minor changes could be adding new endpoints or
adding fields so long as these fields would not affect verification (in other words,
doesn't affect a hash).
This covers all RPC endpoints and their respective requests and responses.
In the case of an introduction of a new interface with external users (i.e gRPC),
this would also fall under the RPCVersion. Minor changes could be adding new
endpoints or adding fields so long as these fields would not affect verification
(in other words, doesn't affect a hash).
#### ABCIVersion
Refers to the entire ABCI Library and predominantly the application interface.
Similarly with RPCVersion, minor changes could be adding fields or calls
(so long as they are optional and not connected with the replication logic).
Because the application isn't concerned with verification logic or assessing hashes,
a block protocol version change does not necessarily imply a major version change.
Refers to the entire ABCI Library and predominantly the application interface.
Similarly with RPCVersion, minor changes could be adding fields or calls
(so long as they are optional and not connected with the replication logic).
Because the application isn't concerned with verification logic or assessing hashes,
a block protocol version change does not necessarily imply a major version change.
A minor version change could suffice.
### Where are versions located and how are they updated
To use these versions, we need to update the block Header, the p2p NodeInfo, the ABCI and add an RPC endpoint.
To use these versions, we need to update the block Header, the p2p NodeInfo, the
ABCI and add an RPC endpoint.
#### Header
@@ -109,7 +123,8 @@ Here, `Version.Block` defines the rules for the current block, while
the `AppHash` in the current block. Together they provide a complete description
of the consensus-critical protocol.
Since we have settled on a proto3 header, the ability to read the BlockVersion out of the serialized header is unanimous.
Since we have settled on a proto3 header, the ability to read the BlockVersion
out of the serialized header is unanimous.
Using a Version struct gives us more flexibility to add fields without breaking
the header.
@@ -118,7 +133,7 @@ the header.
NodeInfo should include a Version struct as its first field like:
```
```golang
type Version struct {
P2P uint64
Block uint64
@@ -129,28 +144,34 @@ type Version struct {
```
Note this effectively makes `Version.P2P` the first field in the NodeInfo, so it
should be easy to read this out of the serialized header if need be to facilitate an upgrade.
should be easy to read this out of the serialized header if need be to
facilitate an upgrade.
The `Version.Other` here should include additional information like the name of the software client and
it's SemVer version - this is for convenience only. Eg. `tendermint-core/v0.22.8`. It's a `[]string` so
it can include information about the version of Tendermint, of the app, of Tendermint libraries, etc.
The `Version.Other` here should include additional information like the name of
the software client and it's SemVer version - this is for convenience only.
Eg. `tendermint-core/v0.22.8`. It's a `[]string` so it can include information
about the version of Tendermint, of the app, of Tendermint libraries, etc.
Note NodeInfo is only exchanged after the authenticated encryption handshake to ensure that it's private.
Doing any version exchange before encrypting could be considered information leakage, though I'm not sure
how much that matters compared to being able to upgrade the protocol.
Note NodeInfo is only exchanged after the authenticated encryption handshake to
ensure that it's private. Doing any version exchange before encrypting could be
considered information leakage, though I'm not sure how much that matters
compared to being able to upgrade the protocol.
#### ABCI
Since the ABCI is responsible for keeping Tendermint and the App in sync, we need to communicate version information through it.
Since the ABCI is responsible for keeping Tendermint and the App in sync, we
need to communicate version information through it.
On startup, we use Info to perform a basic handshake. It should include all the version information so the node can check for compatibility.
This would also include tha ABCI version so applications using a socket connection can ensure they are using the correct version.
On startup, we use Info to perform a basic handshake. It should include all the
version information so the node can check for compatibility. This would also
include tha ABCI version so applications using a socket connection can ensure
they are using the correct version.
##### Info
RequestInfo should add support for protocol versions like:
```
```golang
message RequestInfo {
string abci_version
string version
@@ -161,7 +182,7 @@ message RequestInfo {
Similarly, ResponseInfo should return the versions:
```
```golang
message ResponseInfo {
string data
@@ -188,7 +209,7 @@ be communicated through EndBlock.
EndBlock already contains `ConsensusParams`. We can add version information to
the ConsensusParams as well:
```
```golang
message ConsensusParams {
BlockSize block_size
@@ -209,11 +230,11 @@ protocol version has changed, and the new `app_version` will be included in th
#### RPC
Clients can communicate the RPC version that they are able to parse in the request.
This can be either through the base URL path or in the header.
If the requested version is incompatible with the node's RPCVersion (i.e. different major versions)
then it will return a version error. If the client can support multiple RPC versions
then it can use the `/version` endpoint to ascertain the exact RPCVersion of the node.
Clients can communicate the RPC version that they are able to parse in the request.
This can be either through the base URL path or in the header.
If the requested version is incompatible with the node's RPCVersion (i.e. different major versions)
then it will return a version error. If the client can support multiple RPC versions
then it can use the `/version` endpoint to ascertain the exact RPCVersion of the node.
### Peer Compatibility