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.

437 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. - `Vote`
  8. - `BlockID`
  9. - `Signature`
  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. ## Header
  23. A block header contains metadata about the block and about the consensus, as well as commitments to
  24. the data in the current block, the previous block, and the results returned by the application:
  25. ```go
  26. type Header struct {
  27. // block metadata
  28. Version string // Version string
  29. ChainID string // ID of the chain
  30. Height int64 // Current block height
  31. Time int64 // UNIX time, in millisconds
  32. // current block
  33. NumTxs int64 // Number of txs in this block
  34. TxHash []byte // SimpleMerkle of the block.Txs
  35. LastCommitHash []byte // SimpleMerkle of the block.LastCommit
  36. // previous block
  37. TotalTxs int64 // prevBlock.TotalTxs + block.NumTxs
  38. LastBlockID BlockID // BlockID of prevBlock
  39. // application
  40. ResultsHash []byte // SimpleMerkle of []abci.Result from prevBlock
  41. AppHash []byte // Arbitrary state digest
  42. ValidatorsHash []byte // SimpleMerkle of the current ValidatorSet
  43. NextValidatorsHash []byte // SimpleMerkle of the next ValidatorSet
  44. ConsensusParamsHash []byte // SimpleMerkle of the ConsensusParams
  45. // consensus
  46. EvidenceHash []byte // SimpleMerkle of []Evidence
  47. ProposerAddress []byte // Address of the original proposer of the block
  48. }
  49. ```
  50. Further details on each of these fields is described below.
  51. ## BlockID
  52. The `BlockID` contains two distinct Merkle roots of the block.
  53. The first, used as the block's main hash, is the Merkle root
  54. of all the fields in the header. The second, used for secure gossipping of
  55. the block during consensus, is the Merkle root of the complete serialized block
  56. cut into parts. The `BlockID` includes these two hashes, as well as the number of
  57. parts.
  58. ```go
  59. type BlockID struct {
  60. Hash []byte
  61. Parts PartsHeader
  62. }
  63. type PartsHeader struct {
  64. Hash []byte
  65. Total int32
  66. }
  67. ```
  68. ## Vote
  69. A vote is a signed message from a validator for a particular block.
  70. The vote includes information about the validator signing it.
  71. ```go
  72. type Vote struct {
  73. Timestamp int64
  74. Address []byte
  75. Index int
  76. Height int64
  77. Round int
  78. Type int8
  79. BlockID BlockID
  80. Signature Signature
  81. }
  82. ```
  83. There are two types of votes:
  84. a *prevote* has `vote.Type == 1` and
  85. a *precommit* has `vote.Type == 2`.
  86. ## Signature
  87. Tendermint allows for multiple signature schemes to be used by prepending a single type-byte
  88. to the signature bytes. Different signatures may also come with fixed or variable lengths.
  89. Currently, Tendermint supports Ed25519 and Secp256k1.
  90. ### ED25519
  91. An ED25519 signature has `Type == 0x1`. It looks like:
  92. ```go
  93. // Implements Signature
  94. type Ed25519Signature struct {
  95. Type int8 = 0x1
  96. Signature [64]byte
  97. }
  98. ```
  99. where `Signature` is the 64 byte signature.
  100. ### Secp256k1
  101. A `Secp256k1` signature has `Type == 0x2`. It looks like:
  102. ```go
  103. // Implements Signature
  104. type Secp256k1Signature struct {
  105. Type int8 = 0x2
  106. Signature []byte
  107. }
  108. ```
  109. where `Signature` is the DER encoded signature, ie:
  110. ```hex
  111. 0x30 <length of whole message> <0x02> <length of R> <R> 0x2 <length of S> <S>.
  112. ```
  113. ## Evidence
  114. TODO
  115. ## Validation
  116. Here we describe the validation rules for every element in a block.
  117. Blocks which do not satisfy these rules are considered invalid.
  118. We abuse notation by using something that looks like Go, supplemented with English.
  119. A statement such as `x == y` is an assertion - if it fails, the item is invalid.
  120. We refer to certain globally available objects:
  121. `block` is the block under consideration,
  122. `prevBlock` is the `block` at the previous height,
  123. and `state` keeps track of the validator set, the consensus parameters
  124. and other results from the application. At the point when `block` is the block under consideration,
  125. the current version of the `state` corresponds to the state
  126. after executing transactions from the `prevBlock`.
  127. Elements of an object are accessed as expected,
  128. ie. `block.Header`.
  129. See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`.
  130. ### Header
  131. A Header is valid if its corresponding fields are valid.
  132. ### Version
  133. Arbitrary string.
  134. ### ChainID
  135. Arbitrary constant string.
  136. ### Height
  137. ```go
  138. block.Header.Height > 0
  139. block.Header.Height == prevBlock.Header.Height + 1
  140. ```
  141. The height is an incrementing integer. The first block has `block.Header.Height == 1`.
  142. ### Time
  143. The median of the timestamps of the valid votes in the block.LastCommit.
  144. Corresponds to the number of nanoseconds, with millisecond resolution, since January 1, 1970.
  145. Note: the timestamp of a vote must be greater by at least one millisecond than that of the
  146. block being voted on.
  147. ### NumTxs
  148. ```go
  149. block.Header.NumTxs == len(block.Txs)
  150. ```
  151. Number of transactions included in the block.
  152. ### TxHash
  153. ```go
  154. block.Header.TxHash == SimpleMerkleRoot(block.Txs)
  155. ```
  156. Simple Merkle root of the transactions in the block.
  157. ### LastCommitHash
  158. ```go
  159. block.Header.LastCommitHash == SimpleMerkleRoot(block.LastCommit)
  160. ```
  161. Simple Merkle root of the votes included in the block.
  162. These are the votes that committed the previous block.
  163. The first block has `block.Header.LastCommitHash == []byte{}`
  164. ### TotalTxs
  165. ```go
  166. block.Header.TotalTxs == prevBlock.Header.TotalTxs + block.Header.NumTxs
  167. ```
  168. The cumulative sum of all transactions included in this blockchain.
  169. The first block has `block.Header.TotalTxs = block.Header.NumberTxs`.
  170. ### LastBlockID
  171. LastBlockID is the previous block's BlockID:
  172. ```go
  173. prevBlockParts := MakeParts(prevBlock, state.LastConsensusParams.BlockGossip.BlockPartSize)
  174. block.Header.LastBlockID == BlockID {
  175. Hash: SimpleMerkleRoot(prevBlock.Header),
  176. PartsHeader{
  177. Hash: SimpleMerkleRoot(prevBlockParts),
  178. Total: len(prevBlockParts),
  179. },
  180. }
  181. ```
  182. Note: it depends on the ConsensusParams,
  183. which are held in the `state` and may be updated by the application.
  184. The first block has `block.Header.LastBlockID == BlockID{}`.
  185. ### ResultsHash
  186. ```go
  187. block.ResultsHash == SimpleMerkleRoot(state.LastResults)
  188. ```
  189. Simple Merkle root of the results of the transactions in the previous block.
  190. The first block has `block.Header.ResultsHash == []byte{}`.
  191. ### AppHash
  192. ```go
  193. block.AppHash == state.AppHash
  194. ```
  195. Arbitrary byte array returned by the application after executing and commiting the previous block.
  196. The first block has `block.Header.AppHash == []byte{}`.
  197. ### ValidatorsHash
  198. ```go
  199. block.ValidatorsHash == SimpleMerkleRoot(state.Validators)
  200. ```
  201. Simple Merkle root of the current validator set that is committing the block.
  202. This can be used to validate the `LastCommit` included in the next block.
  203. ### NextValidatorsHash
  204. ```go
  205. block.NextValidatorsHash == SimpleMerkleRoot(state.NextValidators)
  206. ```
  207. Simple Merkle root of the next validator set that will be the validator set that commits the next block.
  208. Modifications to the validator set are defined by the application.
  209. ### ConsensusParamsHash
  210. ```go
  211. block.ConsensusParamsHash == SimpleMerkleRoot(state.ConsensusParams)
  212. ```
  213. Simple Merkle root of the consensus parameters.
  214. May be updated by the application.
  215. ### ProposerAddress
  216. ```go
  217. block.Header.ProposerAddress in state.Validators
  218. ```
  219. Address of the original proposer of the block. Must be a current validator.
  220. NOTE: we also need to track the round.
  221. ## EvidenceHash
  222. ```go
  223. block.EvidenceHash == SimpleMerkleRoot(block.Evidence)
  224. ```
  225. Simple Merkle root of the evidence of Byzantine behaviour included in this block.
  226. ## Txs
  227. Arbitrary length array of arbitrary length byte-arrays.
  228. ## LastCommit
  229. The first height is an exception - it requires the LastCommit to be empty:
  230. ```go
  231. if block.Header.Height == 1 {
  232. len(b.LastCommit) == 0
  233. }
  234. ```
  235. Otherwise, we require:
  236. ```go
  237. len(block.LastCommit) == len(state.LastValidators)
  238. talliedVotingPower := 0
  239. for i, vote := range block.LastCommit{
  240. if vote == nil{
  241. continue
  242. }
  243. vote.Type == 2
  244. vote.Height == block.LastCommit.Height()
  245. vote.Round == block.LastCommit.Round()
  246. vote.BlockID == block.LastBlockID
  247. val := state.LastValidators[i]
  248. vote.Verify(block.ChainID, val.PubKey) == true
  249. talliedVotingPower += val.VotingPower
  250. }
  251. talliedVotingPower > (2/3) * TotalVotingPower(state.LastValidators)
  252. ```
  253. Includes one (possibly nil) vote for every current validator.
  254. Non-nil votes must be Precommits.
  255. All votes must be for the same height and round.
  256. All votes must be for the previous block.
  257. All votes must have a valid signature from the corresponding validator.
  258. The sum total of the voting power of the validators that voted
  259. must be greater than 2/3 of the total voting power of the complete validator set.
  260. ### Vote
  261. A vote is a signed message broadcast in the consensus for a particular block at a particular height and round.
  262. When stored in the blockchain or propagated over the network, votes are encoded in TMBIN.
  263. For signing, votes are encoded in JSON, and the ChainID is included, in the form of the `CanonicalSignBytes`.
  264. We define a method `Verify` that returns `true` if the signature verifies against the pubkey for the CanonicalSignBytes
  265. using the given ChainID:
  266. ```go
  267. func (v Vote) Verify(chainID string, pubKey PubKey) bool {
  268. return pubKey.Verify(v.Signature, CanonicalSignBytes(chainID, v))
  269. }
  270. ```
  271. where `pubKey.Verify` performs the appropriate digital signature verification of the `pubKey`
  272. against the given signature and message bytes.
  273. ## Evidence
  274. There is currently only one kind of evidence:
  275. ```
  276. // amino: "tendermint/DuplicateVoteEvidence"
  277. type DuplicateVoteEvidence struct {
  278. PubKey crypto.PubKey
  279. VoteA *Vote
  280. VoteB *Vote
  281. }
  282. ```
  283. DuplicateVoteEvidence `ev` is valid if
  284. - `ev.VoteA` and `ev.VoteB` can be verified with `ev.PubKey`
  285. - `ev.VoteA` and `ev.VoteB` have the same `Height, Round, Address, Index, Type`
  286. - `ev.VoteA.BlockID != ev.VoteB.BlockID`
  287. - `(block.Height - ev.VoteA.Height) < MAX_EVIDENCE_AGE`
  288. # Execution
  289. Once a block is validated, it can be executed against the state.
  290. The state follows this recursive equation:
  291. ```go
  292. state(1) = InitialState
  293. state(h+1) <- Execute(state(h), ABCIApp, block(h))
  294. ```
  295. where `InitialState` includes the initial consensus parameters and validator set,
  296. and `ABCIApp` is an ABCI application that can return results and changes to the validator
  297. set (TODO). Execute is defined as:
  298. ```go
  299. Execute(s State, app ABCIApp, block Block) State {
  300. // Fuction ApplyBlock executes block of transactions against the app and returns the new root hash of the app state,
  301. // modifications to the validator set and the changes of the consensus parameters.
  302. AppHash, ValidatorChanges, ConsensusParamChanges := app.ApplyBlock(block)
  303. return State{
  304. LastResults: abciResponses.DeliverTxResults,
  305. AppHash: AppHash,
  306. LastValidators: state.Validators,
  307. Validators: state.NextValidators,
  308. NextValidators: UpdateValidators(state.NextValidators, ValidatorChanges),
  309. ConsensusParams: UpdateConsensusParams(state.ConsensusParams, ConsensusParamChanges),
  310. }
  311. }
  312. ```