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.

429 lines
12 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. # Tendermint Blockchain
  2. Here we describe the data structures in the Tendermint blockchain and the rules for validating them.
  3. ## Data Structures
  4. The Tendermint blockchains consists of a short list of basic data types:
  5. - `Block`
  6. - `Header`
  7. - `BlockID`
  8. - `Time`
  9. - `Vote`
  10. - `Evidence`
  11. ## Block
  12. A block consists of a header, a list of transactions, a list of votes (the commit),
  13. and a list of evidence of malfeasance (ie. signing conflicting votes).
  14. ```go
  15. type Block struct {
  16. Header Header
  17. Txs [][]byte
  18. LastCommit []Vote
  19. Evidence []Evidence
  20. }
  21. ```
  22. The signatures returned along with block `X` are those validating block
  23. `X-1`. This can be a little confusing, but consider that
  24. the `Header` also contains the `LastCommitHash`. It would be impossible
  25. for a Header to include the commits that sign it, as it would cause an
  26. infinite loop here. But when we get block `X`, we find
  27. `Header.LastCommitHash`, which must match the hash of `LastCommit`.
  28. ## Header
  29. A block header contains metadata about the block and about the consensus, as well as commitments to
  30. the data in the current block, the previous block, and the results returned by the application:
  31. ```go
  32. type Header struct {
  33. // basic block info
  34. ChainID string
  35. Height int64
  36. Time time.Time
  37. NumTxs int64
  38. TotalTxs int64
  39. // prev block info
  40. LastBlockID BlockID
  41. // hashes of block data
  42. LastCommitHash []byte // commit from validators from the last block
  43. DataHash []byte // Merkle root of transactions
  44. // hashes from the app output from the prev block
  45. ValidatorsHash []byte // validators for the current block
  46. NextValidatorsHash []byte // validators for the next block
  47. ConsensusHash []byte // consensus params for current block
  48. AppHash []byte // state after txs from the previous block
  49. LastResultsHash []byte // root hash of all results from the txs from the previous block
  50. // consensus info
  51. EvidenceHash []byte // evidence included in the block
  52. ProposerAddress []byte // original proposer of the block
  53. ```
  54. Further details on each of these fields is described below.
  55. ## BlockID
  56. The `BlockID` contains two distinct Merkle roots of the block.
  57. The first, used as the block's main hash, is the Merkle root
  58. of all the fields in the header. The second, used for secure gossipping of
  59. the block during consensus, is the Merkle root of the complete serialized block
  60. cut into parts. The `BlockID` includes these two hashes, as well as the number of
  61. parts.
  62. ```go
  63. type BlockID struct {
  64. Hash []byte
  65. Parts PartsHeader
  66. }
  67. type PartsHeader struct {
  68. Hash []byte
  69. Total int32
  70. }
  71. ```
  72. ## Time
  73. Tendermint uses the
  74. [Google.Protobuf.WellKnownTypes.Timestamp](https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/timestamp)
  75. format, which uses two integers, one for Seconds and for Nanoseconds.
  76. TODO: clarify exact format and reconcile [this
  77. comment](https://github.com/tendermint/tendermint/blob/892b170818cd3be4cd3f919d72dde1ad60c28bbb/types/proto3/block.proto#L43).
  78. ## Vote
  79. A vote is a signed message from a validator for a particular block.
  80. The vote includes information about the validator signing it.
  81. ```go
  82. type Vote struct {
  83. ValidatorAddress []byte
  84. ValidatorIndex int
  85. Height int64
  86. Round int
  87. Timestamp Time
  88. Type int8
  89. BlockID BlockID
  90. Signature []byte
  91. }
  92. ```
  93. There are two types of votes:
  94. a _prevote_ has `vote.Type == 1` and
  95. a _precommit_ has `vote.Type == 2`.
  96. ## Signature
  97. Signatures in Tendermint are raw bytes representing the underlying signature.
  98. The only signature scheme currently supported for Tendermint validators is
  99. ED25519. The signature is the raw 64-byte ED25519 signature.
  100. ## Evidence
  101. Forthcoming, see [this issue](https://github.com/tendermint/tendermint/issues/2329)
  102. ## Validation
  103. Here we describe the validation rules for every element in a block.
  104. Blocks which do not satisfy these rules are considered invalid.
  105. We abuse notation by using something that looks like Go, supplemented with English.
  106. A statement such as `x == y` is an assertion - if it fails, the item is invalid.
  107. We refer to certain globally available objects:
  108. `block` is the block under consideration,
  109. `prevBlock` is the `block` at the previous height,
  110. and `state` keeps track of the validator set, the consensus parameters
  111. and other results from the application. At the point when `block` is the block under consideration,
  112. the current version of the `state` corresponds to the state
  113. after executing transactions from the `prevBlock`.
  114. Elements of an object are accessed as expected,
  115. ie. `block.Header`.
  116. See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`.
  117. ### Header
  118. A Header is valid if its corresponding fields are valid.
  119. ### Version
  120. Arbitrary string.
  121. ### ChainID
  122. Arbitrary constant string.
  123. ### Height
  124. ```go
  125. block.Header.Height > 0
  126. block.Header.Height == prevBlock.Header.Height + 1
  127. ```
  128. The height is an incrementing integer. The first block has `block.Header.Height == 1`.
  129. ### Time
  130. The median of the timestamps of the valid votes in the block.LastCommit.
  131. Corresponds to the number of nanoseconds, with millisecond resolution, since January 1, 1970.
  132. Note: the timestamp of a vote must be greater by at least one millisecond than that of the
  133. block being voted on.
  134. ### NumTxs
  135. ```go
  136. block.Header.NumTxs == len(block.Txs)
  137. ```
  138. Number of transactions included in the block.
  139. ### TxHash
  140. ```go
  141. block.Header.TxHash == SimpleMerkleRoot(block.Txs)
  142. ```
  143. Simple Merkle root of the transactions in the block.
  144. ### LastCommitHash
  145. ```go
  146. block.Header.LastCommitHash == SimpleMerkleRoot(block.LastCommit)
  147. ```
  148. Simple Merkle root of the votes included in the block.
  149. These are the votes that committed the previous block.
  150. The first block has `block.Header.LastCommitHash == []byte{}`
  151. ### DataHash
  152. The `DataHash` can provide a nice check on the
  153. [Data](https://godoc.org/github.com/tendermint/tendermint/types#Data)
  154. returned in this same block. If you are subscribed to new blocks, via
  155. tendermint RPC, in order to display or process the new transactions you
  156. should at least validate that the `DataHash` is valid. If it is
  157. important to verify autheniticity, you must wait for the `LastCommit`
  158. from the next block to make sure the block header (including `DataHash`)
  159. was properly signed.
  160. ### TotalTxs
  161. ```go
  162. block.Header.TotalTxs == prevBlock.Header.TotalTxs + block.Header.NumTxs
  163. ```
  164. The cumulative sum of all transactions included in this blockchain.
  165. The first block has `block.Header.TotalTxs = block.Header.NumberTxs`.
  166. ### LastBlockID
  167. LastBlockID is the previous block's BlockID:
  168. ```go
  169. prevBlockParts := MakeParts(prevBlock, state.LastConsensusParams.BlockGossip.BlockPartSize)
  170. block.Header.LastBlockID == BlockID {
  171. Hash: SimpleMerkleRoot(prevBlock.Header),
  172. PartsHeader{
  173. Hash: SimpleMerkleRoot(prevBlockParts),
  174. Total: len(prevBlockParts),
  175. },
  176. }
  177. ```
  178. Note: it depends on the ConsensusParams,
  179. which are held in the `state` and may be updated by the application.
  180. The first block has `block.Header.LastBlockID == BlockID{}`.
  181. ### ResultsHash
  182. ```go
  183. block.ResultsHash == SimpleMerkleRoot(state.LastResults)
  184. ```
  185. Simple Merkle root of the results of the transactions in the previous block.
  186. The first block has `block.Header.ResultsHash == []byte{}`.
  187. ### AppHash
  188. ```go
  189. block.AppHash == state.AppHash
  190. ```
  191. Arbitrary byte array returned by the application after executing and commiting the previous block. It serves as the basis for validating any merkle proofs that comes from the ABCI application and represents the state of the actual application rather than the state of the blockchain itself.
  192. The first block has `block.Header.AppHash == []byte{}`.
  193. ### ValidatorsHash
  194. ```go
  195. block.ValidatorsHash == SimpleMerkleRoot(state.Validators)
  196. ```
  197. Simple Merkle root of the current validator set that is committing the block.
  198. This can be used to validate the `LastCommit` included in the next block.
  199. ### NextValidatorsHash
  200. ```go
  201. block.NextValidatorsHash == SimpleMerkleRoot(state.NextValidators)
  202. ```
  203. Simple Merkle root of the next validator set that will be the validator set that commits the next block.
  204. Modifications to the validator set are defined by the application.
  205. ### ConsensusParamsHash
  206. ```go
  207. block.ConsensusParamsHash == SimpleMerkleRoot(state.ConsensusParams)
  208. ```
  209. Simple Merkle root of the consensus parameters.
  210. May be updated by the application.
  211. ### ProposerAddress
  212. ```go
  213. block.Header.ProposerAddress in state.Validators
  214. ```
  215. Address of the original proposer of the block. Must be a current validator.
  216. NOTE: we also need to track the round.
  217. ## EvidenceHash
  218. ```go
  219. block.EvidenceHash == SimpleMerkleRoot(block.Evidence)
  220. ```
  221. Simple Merkle root of the evidence of Byzantine behaviour included in this block.
  222. ## Txs
  223. Arbitrary length array of arbitrary length byte-arrays.
  224. ## LastCommit
  225. The first height is an exception - it requires the LastCommit to be empty:
  226. ```go
  227. if block.Header.Height == 1 {
  228. len(b.LastCommit) == 0
  229. }
  230. ```
  231. Otherwise, we require:
  232. ```go
  233. len(block.LastCommit) == len(state.LastValidators)
  234. talliedVotingPower := 0
  235. for i, vote := range block.LastCommit{
  236. if vote == nil{
  237. continue
  238. }
  239. vote.Type == 2
  240. vote.Height == block.LastCommit.Height()
  241. vote.Round == block.LastCommit.Round()
  242. vote.BlockID == block.LastBlockID
  243. val := state.LastValidators[i]
  244. vote.Verify(block.ChainID, val.PubKey) == true
  245. talliedVotingPower += val.VotingPower
  246. }
  247. talliedVotingPower > (2/3) * TotalVotingPower(state.LastValidators)
  248. ```
  249. Includes one (possibly nil) vote for every current validator.
  250. Non-nil votes must be Precommits.
  251. All votes must be for the same height and round.
  252. All votes must be for the previous block.
  253. All votes must have a valid signature from the corresponding validator.
  254. The sum total of the voting power of the validators that voted
  255. must be greater than 2/3 of the total voting power of the complete validator set.
  256. ### Vote
  257. A vote is a signed message broadcast in the consensus for a particular block at a particular height and round.
  258. When stored in the blockchain or propagated over the network, votes are encoded in TMBIN.
  259. For signing, votes are encoded in JSON, and the ChainID is included, in the form of the `CanonicalSignBytes`.
  260. We define a method `Verify` that returns `true` if the signature verifies against the pubkey for the CanonicalSignBytes
  261. using the given ChainID:
  262. ```go
  263. func (v Vote) Verify(chainID string, pubKey PubKey) bool {
  264. return pubKey.Verify(v.Signature, CanonicalSignBytes(chainID, v))
  265. }
  266. ```
  267. where `pubKey.Verify` performs the appropriate digital signature verification of the `pubKey`
  268. against the given signature and message bytes.
  269. ## Evidence
  270. There is currently only one kind of evidence:
  271. ```
  272. // amino: "tendermint/DuplicateVoteEvidence"
  273. type DuplicateVoteEvidence struct {
  274. PubKey crypto.PubKey
  275. VoteA *Vote
  276. VoteB *Vote
  277. }
  278. ```
  279. DuplicateVoteEvidence `ev` is valid if
  280. - `ev.VoteA` and `ev.VoteB` can be verified with `ev.PubKey`
  281. - `ev.VoteA` and `ev.VoteB` have the same `Height, Round, Address, Index, Type`
  282. - `ev.VoteA.BlockID != ev.VoteB.BlockID`
  283. - `(block.Height - ev.VoteA.Height) < MAX_EVIDENCE_AGE`
  284. # Execution
  285. Once a block is validated, it can be executed against the state.
  286. The state follows this recursive equation:
  287. ```go
  288. state(1) = InitialState
  289. state(h+1) <- Execute(state(h), ABCIApp, block(h))
  290. ```
  291. where `InitialState` includes the initial consensus parameters and validator set,
  292. and `ABCIApp` is an ABCI application that can return results and changes to the validator
  293. set (TODO). Execute is defined as:
  294. ```go
  295. Execute(s State, app ABCIApp, block Block) State {
  296. // Fuction ApplyBlock executes block of transactions against the app and returns the new root hash of the app state,
  297. // modifications to the validator set and the changes of the consensus parameters.
  298. AppHash, ValidatorChanges, ConsensusParamChanges := app.ApplyBlock(block)
  299. return State{
  300. LastResults: abciResponses.DeliverTxResults,
  301. AppHash: AppHash,
  302. LastValidators: state.Validators,
  303. Validators: state.NextValidators,
  304. NextValidators: UpdateValidators(state.NextValidators, ValidatorChanges),
  305. ConsensusParams: UpdateConsensusParams(state.ConsensusParams, ConsensusParamChanges),
  306. }
  307. }
  308. ```