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.

206 lines
8.8 KiB

  1. # Block Structure
  2. The tendermint consensus engine records all agreements by a
  3. supermajority of nodes into a blockchain, which is replicated among all
  4. nodes. This blockchain is accessible via various rpc endpoints, mainly
  5. `/block?height=` to get the full block, as well as
  6. `/blockchain?minHeight=_&maxHeight=_` to get a list of headers. But what
  7. exactly is stored in these blocks?
  8. ## Block
  9. A
  10. [Block](https://godoc.org/github.com/tendermint/tendermint/types#Block)
  11. contains:
  12. - a [Header](#header) contains merkle hashes for various chain states
  13. - the
  14. [Data](https://godoc.org/github.com/tendermint/tendermint/types#Data)
  15. is all transactions which are to be processed
  16. - the [LastCommit](#commit) > 2/3 signatures for the last block
  17. The signatures returned along with block `H` are those validating block
  18. `H-1`. This can be a little confusing, but we must also consider that
  19. the `Header` also contains the `LastCommitHash`. It would be impossible
  20. for a Header to include the commits that sign it, as it would cause an
  21. infinite loop here. But when we get block `H`, we find
  22. `Header.LastCommitHash`, which must match the hash of `LastCommit`.
  23. ## Header
  24. The
  25. [Header](https://godoc.org/github.com/tendermint/tendermint/types#Header)
  26. contains lots of information (follow link for up-to-date info). Notably,
  27. it maintains the `Height`, the `LastBlockID` (to make it a chain), and
  28. hashes of the data, the app state, and the validator set. This is
  29. important as the only item that is signed by the validators is the
  30. `Header`, and all other data must be validated against one of the merkle
  31. hashes in the `Header`.
  32. The `DataHash` can provide a nice check on the
  33. [Data](https://godoc.org/github.com/tendermint/tendermint/types#Data)
  34. returned in this same block. If you are subscribed to new blocks, via
  35. tendermint RPC, in order to display or process the new transactions you
  36. should at least validate that the `DataHash` is valid. If it is
  37. important to verify autheniticity, you must wait for the `LastCommit`
  38. from the next block to make sure the block header (including `DataHash`)
  39. was properly signed.
  40. The `ValidatorHash` contains a hash of the current
  41. [Validators](https://godoc.org/github.com/tendermint/tendermint/types#Validator).
  42. Tracking all changes in the validator set is complex, but a client can
  43. quickly compare this hash with the [hash of the currently known
  44. validators](https://godoc.org/github.com/tendermint/tendermint/types#ValidatorSet.Hash)
  45. to see if there have been changes.
  46. The `AppHash` serves as the basis for validating any merkle proofs that
  47. come from the ABCI application. It represents the state of the actual
  48. application, rather that the state of the blockchain itself. This means
  49. it's necessary in order to perform any business logic, such as verifying
  50. an account balance.
  51. **Note** After the transactions are committed to a block, they still
  52. need to be processed in a separate step, which happens between the
  53. blocks. If you find a given transaction in the block at height `H`, the
  54. effects of running that transaction will be first visible in the
  55. `AppHash` from the block header at height `H+1`.
  56. Like the `LastCommit` issue, this is a requirement of the immutability
  57. of the block chain, as the application only applies transactions _after_
  58. they are commited to the chain.
  59. ## Commit
  60. The
  61. [Commit](https://godoc.org/github.com/tendermint/tendermint/types#Commit)
  62. contains a set of
  63. [Votes](https://godoc.org/github.com/tendermint/tendermint/types#Vote)
  64. that were made by the validator set to reach consensus on this block.
  65. This is the key to the security in any PoS system, and actually no data
  66. that cannot be traced back to a block header with a valid set of Votes
  67. can be trusted. Thus, getting the Commit data and verifying the votes is
  68. extremely important.
  69. As mentioned above, in order to find the `precommit votes` for block
  70. header `H`, we need to query block `H+1`. Then we need to check the
  71. votes, make sure they really are for that block, and properly formatted.
  72. Much of this code is implemented in Go in the
  73. [light-client](https://github.com/tendermint/light-client) package. If
  74. you look at the code, you will notice that we need to provide the
  75. `chainID` of the blockchain in order to properly calculate the votes.
  76. This is to protect anyone from swapping votes between chains to fake (or
  77. frame) a validator. Also note that this `chainID` is in the
  78. `genesis.json` from _Tendermint_, not the `genesis.json` from the
  79. basecoin app ([that is a different
  80. chainID...](https://github.com/cosmos/cosmos-sdk/issues/32)).
  81. Once we have those votes, and we calculated the proper [sign
  82. bytes](https://godoc.org/github.com/tendermint/tendermint/types#Vote.WriteSignBytes)
  83. using the chainID and a [nice helper
  84. function](https://godoc.org/github.com/tendermint/tendermint/types#SignBytes),
  85. we can verify them. The light client is responsible for maintaining a
  86. set of validators that we trust. Each vote only stores the validators
  87. `Address`, as well as the `Signature`. Assuming we have a local copy of
  88. the trusted validator set, we can look up the `Public Key` of the
  89. validator given its `Address`, then verify that the `Signature` matches
  90. the `SignBytes` and `Public Key`. Then we sum up the total voting power
  91. of all validators, whose votes fulfilled all these stringent
  92. requirements. If the total number of voting power for a single block is
  93. greater than 2/3 of all voting power, then we can finally trust the
  94. block header, the AppHash, and the proof we got from the ABCI
  95. application.
  96. ### Vote Sign Bytes
  97. The `sign-bytes` of a vote is produced by taking a
  98. [stable-json](https://github.com/substack/json-stable-stringify)-like
  99. deterministic JSON [wire](./wire-protocol.html) encoding of the vote
  100. (excluding the `Signature` field), and wrapping it with
  101. `{"chain_id":"my_chain","vote":...}`.
  102. For example, a precommit vote might have the following `sign-bytes`:
  103. ```
  104. {"chain_id":"my_chain","vote":{"block_hash":"611801F57B4CE378DF1A3FFF1216656E89209A99","block_parts_header":{"hash":"B46697379DBE0774CC2C3B656083F07CA7E0F9CE","total":123},"height":1234,"round":1,"type":2}}
  105. ```
  106. ## Block Hash
  107. The [block
  108. hash](https://godoc.org/github.com/tendermint/tendermint/types#Block.Hash)
  109. is the [Simple Tree hash](./merkle.html#simple-tree-with-dictionaries)
  110. of the fields of the block `Header` encoded as a list of `KVPair`s.
  111. ## Transaction
  112. A transaction is any sequence of bytes. It is up to your ABCI
  113. application to accept or reject transactions.
  114. ## BlockID
  115. Many of these data structures refer to the
  116. [BlockID](https://godoc.org/github.com/tendermint/tendermint/types#BlockID),
  117. which is the `BlockHash` (hash of the block header, also referred to by
  118. the next block) along with the `PartSetHeader`. The `PartSetHeader` is
  119. explained below and is used internally to orchestrate the p2p
  120. propogation. For clients, it is basically opaque bytes, but they must
  121. match for all votes.
  122. ## PartSetHeader
  123. The
  124. [PartSetHeader](https://godoc.org/github.com/tendermint/tendermint/types#PartSetHeader)
  125. contains the total number of pieces in a
  126. [PartSet](https://godoc.org/github.com/tendermint/tendermint/types#PartSet),
  127. and the Merkle root hash of those pieces.
  128. ## PartSet
  129. PartSet is used to split a byteslice of data into parts (pieces) for
  130. transmission. By splitting data into smaller parts and computing a
  131. Merkle root hash on the list, you can verify that a part is legitimately
  132. part of the complete data, and the part can be forwarded to other peers
  133. before all the parts are known. In short, it's a fast way to securely
  134. propagate a large chunk of data (like a block) over a gossip network.
  135. PartSet was inspired by the LibSwift project.
  136. Usage:
  137. ```
  138. data := RandBytes(2 << 20) // Something large
  139. partSet := NewPartSetFromData(data)
  140. partSet.Total() // Total number of 4KB parts
  141. partSet.Count() // Equal to the Total, since we already have all the parts
  142. partSet.Hash() // The Merkle root hash
  143. partSet.BitArray() // A BitArray of partSet.Total() 1's
  144. header := partSet.Header() // Send this to the peer
  145. header.Total // Total number of parts
  146. header.Hash // The merkle root hash
  147. // Now we'll reconstruct the data from the parts
  148. partSet2 := NewPartSetFromHeader(header)
  149. partSet2.Total() // Same total as partSet.Total()
  150. partSet2.Count() // Zero, since this PartSet doesn't have any parts yet.
  151. partSet2.Hash() // Same hash as in partSet.Hash()
  152. partSet2.BitArray() // A BitArray of partSet.Total() 0's
  153. // In a gossip network the parts would arrive in arbitrary order, perhaps
  154. // in response to explicit requests for parts, or optimistically in response
  155. // to the receiving peer's partSet.BitArray().
  156. for !partSet2.IsComplete() {
  157. part := receivePartFromGossipNetwork()
  158. added, err := partSet2.AddPart(part)
  159. if err != nil {
  160. // A wrong part,
  161. // the merkle trail does not hash to partSet2.Hash()
  162. } else if !added {
  163. // A duplicate part already received
  164. }
  165. }
  166. data2, _ := ioutil.ReadAll(partSet2.GetReader())
  167. bytes.Equal(data, data2) // true
  168. ```