* Changed the spec text to agreed VoteExtension solution
* Revert "Removed protobufs related to vote extensions"
This reverts commit 4566f1e302.
* Changes to ABCI protocol buffers
* Update spec/core/data_structures.md
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
* Update spec/core/data_structures.md
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
* Fix dangling link in ABCI++ readme
* Addressed comments
Co-authored-by: M. J. Fromberger <fromberger@interchain.io>
| hash | bytes | The block header's hash of the block to propose. Present for convenience (can be derived from the block header). | 1 |
| hash | bytes | The block header's hash of the block to propose. Present for convenience (can be derived from the block header). | 1 |
| header | [Header](../core/data_structures.md#header) | The header of the block to propose. | 2 |
| header | [Header](../core/data_structures.md#header) | The header of the block to propose. | 2 |
| txs | repeated bytes | Preliminary list of transactions that have been picked as part of the block to propose. | 3 |
| txs | repeated bytes | Preliminary list of transactions that have been picked as part of the block to propose. | 3 |
| last_commit_info | [LastCommitInfo](#lastcommitinfo) | Info about the last commit, including the round, the validator list, and which ones signed the last block. | 4 |
| local_last_commit | [ExtendedCommitInfo](#extendedcommitinfo) | Info about the last commit, obtained locally from Tendermint's data structures. | 4 |
| byzantine_validators | repeated [Evidence](#evidence) | List of evidence of validators that acted maliciously. | 5 |
| byzantine_validators | repeated [Evidence](#evidence) | List of evidence of validators that acted maliciously. | 5 |
| max_tx_bytes | int64 | Currently configured maximum size in bytes taken by the modified transactions. | 6 |
| max_tx_bytes | int64 | Currently configured maximum size in bytes taken by the modified transactions. | 6 |
>**TODO**: Add the changes needed in LastCommitInfo for vote extensions
>**TODO**: DISCUSS: We need to make clear whether a proposer is also running the logic of a non-proposer node (in particular "ProcessProposal")
From the App's perspective, they'll probably skip ProcessProposal
* **Response**:
* **Response**:
| Name | Type | Description | Field Number |
| Name | Type | Description | Field Number |
@ -340,7 +335,7 @@ From the App's perspective, they'll probably skip ProcessProposal
for blocks `H+1`, and `H+2`. Heights following a validator update are affected in the following way:
for blocks `H+1`, and `H+2`. Heights following a validator update are affected in the following way:
* `H`: `NextValidatorsHash` includes the new `validator_updates` value.
* `H`: `NextValidatorsHash` includes the new `validator_updates` value.
* `H+1`: The validator set change takes effect and `ValidatorsHash` is updated.
* `H+1`: The validator set change takes effect and `ValidatorsHash` is updated.
* `H+2`: `last_commit_info`is changed to include the altered validator set.
* `H+2`: `local_last_commit` now includes the altered validator set.
* `ResponseFinalizeBlock.consensus_param_updates` returned for block `H` apply to the consensus
* `ResponseFinalizeBlock.consensus_param_updates` returned for block `H` apply to the consensus
params for block `H+1` even if the change is agreed in block `H`.
params for block `H+1` even if the change is agreed in block `H`.
For more information on the consensus parameters,
For more information on the consensus parameters,
@ -414,7 +409,7 @@ Note that, if _p_ has a non-`nil` _validValue_, Tendermint will use it as propos
| hash | bytes | The block header's hash of the proposed block. Present for convenience (can be derived from the block header). | 1 |
| hash | bytes | The block header's hash of the proposed block. Present for convenience (can be derived from the block header). | 1 |
| txs | repeated bytes | List of transactions that have been picked as part of the proposed block. | 3 |
| txs | repeated bytes | List of transactions that have been picked as part of the proposed block. | 3 |
| last_commit_info | [LastCommitInfo](#lastcommitinfo) | Info about the last commit, including the round , the validator list, and which ones signed the last block. | 4 |
| proposed_last_commit | [CommitInfo](#commitinfo) | Info about the last commit, obtained from the information in the proposed block. | 4 |
| byzantine_validators | repeated [Evidence](#evidence) | List of evidence of validators that acted maliciously. | 5 |
| byzantine_validators | repeated [Evidence](#evidence) | List of evidence of validators that acted maliciously. | 5 |
* **Response**:
* **Response**:
@ -495,18 +490,17 @@ When a validator _p_ enters Tendermint consensus round _r_, height _h_, in which
| vote_extension | bytes | Optional information signed by by Tendermint. | 1 |
* **Usage**:
* **Usage**:
* Both `ResponseExtendVote.app_signed` and `ResponseExtendVote.tendermint_signed` are optional information that will
be attached to the Precommit message.
* `ResponseExtendVote.vote_extension` is optional information that, if present, will be signed by Tendermint and
attached to the Precommit message.
* `RequestExtendVote.hash` corresponds to the hash of a proposed block that was made available to the application
* `RequestExtendVote.hash` corresponds to the hash of a proposed block that was made available to the application
in a previous call to `ProcessProposal` or `PrepareProposal` for the current height.
in a previous call to `ProcessProposal` or `PrepareProposal` for the current height.
* `ResponseExtendVote.app_signed` and `ResponseExtendVote.tendermint_signed` will always be attached to a non-`nil`
Precommit message. If Tendermint is to precommit `nil`, it will not call `RequestExtendVote`.
* `ResponseExtendVote.vote_extension` will only be attached to a non-`nil` Precommit message. If Tendermint is to
precommit `nil`, it will not call `RequestExtendVote`.
* The Application logic that creates the extension can be non-deterministic.
* The Application logic that creates the extension can be non-deterministic.
#### When does Tendermint call it?
#### When does Tendermint call it?
@ -520,11 +514,18 @@ then _p_'s Tendermint locks _v_ and sends a Precommit message in the following
1. _p_'s Tendermint sets _lockedValue_ and _validValue_ to _v_, and sets _lockedRound_ and _validRound_ to _r_
1. _p_'s Tendermint sets _lockedValue_ and _validValue_ to _v_, and sets _lockedRound_ and _validRound_ to _r_
2. _p_'s Tendermint calls `RequestExtendVote` with _id(v)_ (`RequestExtendVote.hash`). The call is synchronous.
2. _p_'s Tendermint calls `RequestExtendVote` with _id(v)_ (`RequestExtendVote.hash`). The call is synchronous.
3. The Application returns an array of bytes, `ResponseExtendVote.extension`, which is not interpreted by Tendermint.
4. _p_'s Tendermint includes `ResponseExtendVote.extension` as a new field in the Precommit message.
5. _p_'s Tendermint signs and broadcasts the Precommit message.
In the cases when _p_'s Tendermint is to broadcast `precommit nil` messages (either _2f+1_`prevote nil` messages received, or _timeoutPrevote_ triggered), _p_'s Tendermint does **not** call `RequestExtendVote` and will include an empty byte array as vote extension in the `precommit nil` message.
3. The Application optionally returns an array of bytes, `ResponseExtendVote.extension`, which is not interpreted by Tendermint.
4. _p_'s Tendermint includes `ResponseExtendVote.extension` in a field of type [CanonicalVoteExtension](#canonicalvoteextension),
it then populates the other fields in [CanonicalVoteExtension](#canonicalvoteextension), and signs the populated
data structure.
5. _p_'s Tendermint constructs and signs the [CanonicalVote](../core/data_structures.md#canonicalvote) structure.
6. _p_'s Tendermint constructs the Precommit message (i.e. [Vote](../core/data_structures.md#vote) structure)
using [CanonicalVoteExtension](#canonicalvoteextension) and [CanonicalVote](../core/data_structures.md#canonicalvote).
7. _p_'s Tendermint broadcasts the Precommit message.
In the cases when _p_'s Tendermint is to broadcast `precommit nil` messages (either _2f+1_`prevote nil` messages received,
or _timeoutPrevote_ triggered), _p_'s Tendermint does **not** call `RequestExtendVote` and will not include
a [CanonicalVoteExtension](#canonicalvoteextension) field in the `precommit nil` message.
### VerifyVoteExtension
### VerifyVoteExtension
@ -534,11 +535,10 @@ In the cases when _p_'s Tendermint is to broadcast `precommit nil` messages (eit
| txs | repeated bytes | List of transactions committed as part of the block. | 3 |
| last_commit_info | [LastCommitInfo](#lastcommitinfo) | Info about the last commit, including the round, and the list of validators and which ones signed the last block. | 4 |
| byzantine_validators | repeated [Evidence](#evidence) | List of evidence of validators that acted maliciously. | 5 |
| round | int32 | Commit round. Reflects the total amount of rounds it took to come to consensus for the current block. | 1 |
| votes | repeated [VoteInfo](#voteinfo) | List of validators addresses in the last validator set with their voting power and whether or not they signed a vote. | 2 |
| round | int32 | Commit round. Reflects the round at which the block proposer decided in the previous height. | 1 |
| votes | repeated [ExtendedVoteInfo](#extendedvoteinfo) | List of validators' addresses in the last validator set with their voting information, including vote extensions. | 2 |
### ExecTxResult
### ExecTxResult
@ -843,3 +860,23 @@ Most of the data structures used in ABCI are shared [common data structures](../
This section describes what the Application can expect from Tendermint.
This section describes what the Application can expect from Tendermint.
The Tendermint consensus algorithm is designed to protect safety under any network conditions, as long as
The Tendermint consensus algorithm is designed to protect safety under any network conditions, as long as
less than 1/3 of validators' voting power is byzantine. Most of the time, though, the network will behave synchronously and there will be no byzantine process. In these frequent, benign conditions:
less than 1/3 of validators' voting power is byzantine. Most of the time, though, the network will behave
synchronously and there will be no byzantine process. In these frequent, benign conditions:
* Tendermint will decide in round 0;
* Tendermint will decide in round 0;
* `PrepareProposal` will be called exactly once at the proposer process of round 0, height _h_;
* `PrepareProposal` will be called exactly once at the proposer process of round 0, height _h_;
A vote is a signed message from a validator for a particular block.
A vote is a signed message from a validator for a particular block.
The vote includes information about the validator signing it. When stored in the blockchain or propagated over the network, votes are encoded in Protobuf.
The vote includes information about the validator signing it. When stored in the blockchain or propagated over the network, votes are encoded in Protobuf.
| Type | [SignedMsgType](#signedmsgtype) | Either prevote or precommit. [SignedMsgType](#signedmsgtype) | A Vote is valid if its corresponding fields are included in the enum [signedMsgType](#signedmsgtype) |
| Height | uint64 | Height for which this vote was created for | Must be > 0 |
| Round | int32 | Round that the commit corresponds to. | Must be > 0 |
| BlockID | [BlockID](#blockid) | The blockID of the corresponding block. | [BlockID](#blockid) |
| Timestamp | [Time](#Time) | Timestamp represents the time at which a validator signed. | [Time](#time) |
| ValidatorAddress | slice of bytes (`[]byte`) | Address of the validator | Length must be equal to 20 |
| ValidatorIndex | int32 | Index at a specific block height that corresponds to the Index of the validator in the set. | must be > 0 |
| Signature | slice of bytes (`[]byte`) | Signature by the validator if they participated in consensus for the associated bock. | Length of signature must be > 0 and <64|
The vote extension is not part of the [`CanonicalVote`](#canonicalvote).
| Type | [SignedMsgType](#signedmsgtype) | Either prevote or precommit. [SignedMsgType](#signedmsgtype) | A Vote is valid if its corresponding fields are included in the enum [signedMsgType](#signedmsgtype) |
| Height | uint64 | Height for which this vote was created. | Must be > 0 |
| Round | int32 | Round that the commit corresponds to. | Must be > 0 |
| BlockID | [BlockID](#blockid) | The blockID of the corresponding block. | [BlockID](#blockid) |
| Timestamp | [Time](#Time) | The time at which a validator signed. | [Time](#time) |
| ValidatorAddress | slice of bytes (`[]byte`) | Address of the validator | Length must be equal to 20 |
| ValidatorIndex | int32 | Index at a specific block height that corresponds to the Index of the validator in the set. | must be > 0 |
| Signature | slice of bytes (`[]byte`) | Signature by the validator if they participated in consensus for the associated bock. | Length of signature must be > 0 and <64|
| Extension | slice of bytes (`[]byte`) | The vote extension provided by the Application. Only valid for precommit messages. | Length must be 0 if Type != `SIGNED_MSG_TYPE_PRECOMMIT` |
| ExtensionSignature | slice of bytes (`[]byte`) | Signature by the validator if they participated in consensus for the associated bock. | Length must be 0 if Type != `SIGNED_MSG_TYPE_PRECOMMIT`; else length must be > 0 and <64|