From 41496117f2f3d8cb6f1d53e0848d36aabcf65a8d Mon Sep 17 00:00:00 2001 From: Callum Date: Fri, 20 Nov 2020 14:43:34 +0100 Subject: [PATCH] lint markdown --- .../architecture/adr-016-protocol-versions.md | 149 ++++++++++-------- 1 file changed, 85 insertions(+), 64 deletions(-) diff --git a/docs/architecture/adr-016-protocol-versions.md b/docs/architecture/adr-016-protocol-versions.md index 90066259e..fc8bcb76a 100644 --- a/docs/architecture/adr-016-protocol-versions.md +++ b/docs/architecture/adr-016-protocol-versions.md @@ -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