You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
7.1 KiB

  1. # Tendermint Consensus
  2. Tendermint consensus is a distributed protocol executed by validator processes to agree on
  3. the next block to be added to the Tendermint blockchain. The protocol proceeds in rounds, where
  4. each round is a try to reach agreement on the next block. A round starts by having a dedicated
  5. process (called proposer) suggesting to other processes what should be the next block with
  6. the `ProposalMessage`.
  7. The processes respond by voting for a block with `VoteMessage` (there are two kinds of vote messages, prevote
  8. and precommit votes). Note that a proposal message is just a suggestion what the next block should be; a
  9. validator might vote with a `VoteMessage` for a different block. If in some round, enough number
  10. of processes vote for the same block, then this block is committed and later added to the blockchain.
  11. `ProposalMessage` and `VoteMessage` are signed by the private key of the validator.
  12. The internals of the protocol and how it ensures safety and liveness properties are
  13. explained [here](https://github.com/tendermint/spec).
  14. For efficiency reasons, validators in Tendermint consensus protocol do not agree directly on the block
  15. as the block size is big, i.e., they don't embed the block inside `Proposal` and `VoteMessage`. Instead, they
  16. reach agreement on the `BlockID` (see `BlockID` definition in [Blockchain](blockchain.md) section)
  17. that uniquely identifies each block. The block itself is disseminated to validator processes using
  18. peer-to-peer gossiping protocol. It starts by having a proposer first splitting a block into a
  19. number of block parts, that are then gossiped between processes using `BlockPartMessage`.
  20. Validators in Tendermint communicate by peer-to-peer gossiping protocol. Each validator is connected
  21. only to a subset of processes called peers. By the gossiping protocol, a validator send to its peers
  22. all needed information (`ProposalMessage`, `VoteMessage` and `BlockPartMessage`) so they can
  23. reach agreement on some block, and also obtain the content of the chosen block (block parts). As part of
  24. the gossiping protocol, processes also send auxiliary messages that inform peers about the
  25. executed steps of the core consensus algorithm (`NewRoundStepMessage` and `CommitStepMessage`), and
  26. also messages that inform peers what votes the process has seen (`HasVoteMessage`,
  27. `VoteSetMaj23Message` and `VoteSetBitsMessage`). These messages are then used in the gossiping protocol
  28. to determine what messages a process should send to its peers.
  29. We now describe the content of each message exchanged during Tendermint consensus protocol.
  30. ## ProposalMessage
  31. ProposalMessage is sent when a new block is proposed. It is a suggestion of what the
  32. next block in the blockchain should be.
  33. ```
  34. type ProposalMessage struct {
  35. Proposal Proposal
  36. }
  37. ```
  38. ### Proposal
  39. Proposal contains height and round for which this proposal is made, BlockID as a unique identifier of proposed
  40. block, timestamp, and two fields (POLRound and POLBlockID) that are needed for termination of the consensus.
  41. The message is signed by the validator private key.
  42. ```
  43. type Proposal struct {
  44. Height int64
  45. Round int
  46. Timestamp Time
  47. BlockID BlockID
  48. POLRound int
  49. POLBlockID BlockID
  50. Signature Signature
  51. }
  52. ```
  53. NOTE: In the current version of the Tendermint, the consensus value in proposal is represented with
  54. PartSetHeader, and with BlockID in vote message. It should be aligned as suggested in this spec as
  55. BlockID contains PartSetHeader.
  56. ## VoteMessage
  57. VoteMessage is sent to vote for some block (or to inform others that a process does not vote in the current round).
  58. Vote is defined in [Blockchain](blockchain.md) section and contains validator's information (validator address
  59. and index), height and round for which the vote is sent, vote type, blockID if process vote for some
  60. block (`nil` otherwise) and a timestamp when the vote is sent. The message is signed by the validator private key.
  61. ```
  62. type VoteMessage struct {
  63. Vote Vote
  64. }
  65. ```
  66. ## BlockPartMessage
  67. BlockPartMessage is sent when gossipping a piece of the proposed block. It contains height, round
  68. and the block part.
  69. ```
  70. type BlockPartMessage struct {
  71. Height int64
  72. Round int
  73. Part Part
  74. }
  75. ```
  76. ## ProposalHeartbeatMessage
  77. ProposalHeartbeatMessage is sent to signal that a node is alive and waiting for transactions
  78. to be able to create a next block proposal.
  79. ```
  80. type ProposalHeartbeatMessage struct {
  81. Heartbeat Heartbeat
  82. }
  83. ```
  84. ### Heartbeat
  85. Heartbeat contains validator information (address and index),
  86. height, round and sequence number. It is signed by the private key of the validator.
  87. ```
  88. type Heartbeat struct {
  89. ValidatorAddress []byte
  90. ValidatorIndex int
  91. Height int64
  92. Round int
  93. Sequence int
  94. Signature Signature
  95. }
  96. ```
  97. ## NewRoundStepMessage
  98. NewRoundStepMessage is sent for every step transition during the core consensus algorithm execution. It is
  99. used in the gossip part of the Tendermint protocol to inform peers about a current height/round/step
  100. a process is in.
  101. ```
  102. type NewRoundStepMessage struct {
  103. Height int64
  104. Round int
  105. Step RoundStepType
  106. SecondsSinceStartTime int
  107. LastCommitRound int
  108. }
  109. ```
  110. ## CommitStepMessage
  111. CommitStepMessage is sent when an agreement on some block is reached. It contains height for which agreement
  112. is reached, block parts header that describes the decided block and is used to obtain all block parts,
  113. and a bit array of the block parts a process currently has, so its peers can know what parts
  114. it is missing so they can send them.
  115. ```
  116. type CommitStepMessage struct {
  117. Height int64
  118. BlockID BlockID
  119. BlockParts BitArray
  120. }
  121. ```
  122. TODO: We use BlockID instead of BlockPartsHeader (in current implementation) for symmetry.
  123. ## ProposalPOLMessage
  124. ProposalPOLMessage is sent when a previous block is re-proposed.
  125. It is used to inform peers in what round the process learned for this block (ProposalPOLRound),
  126. and what prevotes for the re-proposed block the process has.
  127. ```
  128. type ProposalPOLMessage struct {
  129. Height int64
  130. ProposalPOLRound int
  131. ProposalPOL BitArray
  132. }
  133. ```
  134. ## HasVoteMessage
  135. HasVoteMessage is sent to indicate that a particular vote has been received. It contains height,
  136. round, vote type and the index of the validator that is the originator of the corresponding vote.
  137. ```
  138. type HasVoteMessage struct {
  139. Height int64
  140. Round int
  141. Type byte
  142. Index int
  143. }
  144. ```
  145. ## VoteSetMaj23Message
  146. VoteSetMaj23Message is sent to indicate that a process has seen +2/3 votes for some BlockID.
  147. It contains height, round, vote type and the BlockID.
  148. ```
  149. type VoteSetMaj23Message struct {
  150. Height int64
  151. Round int
  152. Type byte
  153. BlockID BlockID
  154. }
  155. ```
  156. ## VoteSetBitsMessage
  157. VoteSetBitsMessage is sent to communicate the bit-array of votes a process has seen for a given
  158. BlockID. It contains height, round, vote type, BlockID and a bit array of
  159. the votes a process has.
  160. ```
  161. type VoteSetBitsMessage struct {
  162. Height int64
  163. Round int
  164. Type byte
  165. BlockID BlockID
  166. Votes BitArray
  167. }
  168. ```