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.

513 lines
14 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "time"
  9. wire "github.com/tendermint/go-wire"
  10. "github.com/tendermint/go-wire/data"
  11. cmn "github.com/tendermint/tmlibs/common"
  12. "github.com/tendermint/tmlibs/merkle"
  13. )
  14. // Block defines the atomic unit of a Tendermint blockchain.
  15. // TODO: add Version byte
  16. type Block struct {
  17. *Header `json:"header"`
  18. *Data `json:"data"`
  19. Evidence EvidenceData `json:"evidence"`
  20. LastCommit *Commit `json:"last_commit"`
  21. }
  22. // MakeBlock returns a new block with an empty header, except what can be computed from itself.
  23. // It populates the same set of fields validated by ValidateBasic
  24. func MakeBlock(height int64, txs []Tx, commit *Commit) *Block {
  25. block := &Block{
  26. Header: &Header{
  27. Height: height,
  28. Time: time.Now(),
  29. NumTxs: int64(len(txs)),
  30. },
  31. LastCommit: commit,
  32. Data: &Data{
  33. Txs: txs,
  34. },
  35. }
  36. block.FillHeader()
  37. return block
  38. }
  39. // AddEvidence appends the given evidence to the block
  40. func (b *Block) AddEvidence(evidence []Evidence) {
  41. b.Evidence.Evidences = append(b.Evidence.Evidences, evidence...)
  42. }
  43. // ValidateBasic performs basic validation that doesn't involve state data.
  44. // It checks the internal consistency of the block.
  45. func (b *Block) ValidateBasic() error {
  46. newTxs := int64(len(b.Data.Txs))
  47. if b.NumTxs != newTxs {
  48. return fmt.Errorf("Wrong Block.Header.NumTxs. Expected %v, got %v", newTxs, b.NumTxs)
  49. }
  50. if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) {
  51. return fmt.Errorf("Wrong Block.Header.LastCommitHash. Expected %v, got %v", b.LastCommitHash, b.LastCommit.Hash())
  52. }
  53. if b.Header.Height != 1 {
  54. if err := b.LastCommit.ValidateBasic(); err != nil {
  55. return err
  56. }
  57. }
  58. if !bytes.Equal(b.DataHash, b.Data.Hash()) {
  59. return fmt.Errorf("Wrong Block.Header.DataHash. Expected %v, got %v", b.DataHash, b.Data.Hash())
  60. }
  61. if !bytes.Equal(b.EvidenceHash, b.Evidence.Hash()) {
  62. return errors.New(cmn.Fmt("Wrong Block.Header.EvidenceHash. Expected %v, got %v", b.EvidenceHash, b.Evidence.Hash()))
  63. }
  64. return nil
  65. }
  66. // FillHeader fills in any remaining header fields that are a function of the block data
  67. func (b *Block) FillHeader() {
  68. if b.LastCommitHash == nil {
  69. b.LastCommitHash = b.LastCommit.Hash()
  70. }
  71. if b.DataHash == nil {
  72. b.DataHash = b.Data.Hash()
  73. }
  74. if b.EvidenceHash == nil {
  75. b.EvidenceHash = b.Evidence.Hash()
  76. }
  77. }
  78. // Hash computes and returns the block hash.
  79. // If the block is incomplete, block hash is nil for safety.
  80. func (b *Block) Hash() data.Bytes {
  81. // fmt.Println(">>", b.Data)
  82. if b == nil || b.Header == nil || b.Data == nil || b.LastCommit == nil {
  83. return nil
  84. }
  85. b.FillHeader()
  86. return b.Header.Hash()
  87. }
  88. // MakePartSet returns a PartSet containing parts of a serialized block.
  89. // This is the form in which the block is gossipped to peers.
  90. func (b *Block) MakePartSet(partSize int) *PartSet {
  91. return NewPartSetFromData(wire.BinaryBytes(b), partSize)
  92. }
  93. // HashesTo is a convenience function that checks if a block hashes to the given argument.
  94. // A nil block never hashes to anything, and nothing hashes to a nil hash.
  95. func (b *Block) HashesTo(hash []byte) bool {
  96. if len(hash) == 0 {
  97. return false
  98. }
  99. if b == nil {
  100. return false
  101. }
  102. return bytes.Equal(b.Hash(), hash)
  103. }
  104. // String returns a string representation of the block
  105. func (b *Block) String() string {
  106. return b.StringIndented("")
  107. }
  108. // StringIndented returns a string representation of the block
  109. func (b *Block) StringIndented(indent string) string {
  110. if b == nil {
  111. return "nil-Block"
  112. }
  113. return fmt.Sprintf(`Block{
  114. %s %v
  115. %s %v
  116. %s %v
  117. %s %v
  118. %s}#%v`,
  119. indent, b.Header.StringIndented(indent+" "),
  120. indent, b.Data.StringIndented(indent+" "),
  121. indent, b.Evidence.StringIndented(indent+" "),
  122. indent, b.LastCommit.StringIndented(indent+" "),
  123. indent, b.Hash())
  124. }
  125. // StringShort returns a shortened string representation of the block
  126. func (b *Block) StringShort() string {
  127. if b == nil {
  128. return "nil-Block"
  129. } else {
  130. return fmt.Sprintf("Block#%v", b.Hash())
  131. }
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Header defines the structure of a Tendermint block header
  135. // TODO: limit header size
  136. // NOTE: changes to the Header should be duplicated in the abci Header
  137. type Header struct {
  138. // basic block info
  139. ChainID string `json:"chain_id"`
  140. Height int64 `json:"height"`
  141. Time time.Time `json:"time"`
  142. NumTxs int64 `json:"num_txs"`
  143. // prev block info
  144. LastBlockID BlockID `json:"last_block_id"`
  145. TotalTxs int64 `json:"total_txs"`
  146. // hashes of block data
  147. LastCommitHash data.Bytes `json:"last_commit_hash"` // commit from validators from the last block
  148. DataHash data.Bytes `json:"data_hash"` // transactions
  149. // hashes from the app output from the prev block
  150. ValidatorsHash data.Bytes `json:"validators_hash"` // validators for the current block
  151. ConsensusHash data.Bytes `json:"consensus_hash"` // consensus params for current block
  152. AppHash data.Bytes `json:"app_hash"` // state after txs from the previous block
  153. LastResultsHash data.Bytes `json:"last_results_hash"` // root hash of all results from the txs from the previous block
  154. // consensus info
  155. EvidenceHash data.Bytes `json:"evidence_hash"` // evidence included in the block
  156. }
  157. // Hash returns the hash of the header.
  158. // Returns nil if ValidatorHash is missing.
  159. func (h *Header) Hash() data.Bytes {
  160. if len(h.ValidatorsHash) == 0 {
  161. return nil
  162. }
  163. return merkle.SimpleHashFromMap(map[string]interface{}{
  164. "ChainID": h.ChainID,
  165. "Height": h.Height,
  166. "Time": h.Time,
  167. "NumTxs": h.NumTxs,
  168. "TotalTxs": h.TotalTxs,
  169. "LastBlockID": h.LastBlockID,
  170. "LastCommit": h.LastCommitHash,
  171. "Data": h.DataHash,
  172. "Validators": h.ValidatorsHash,
  173. "App": h.AppHash,
  174. "Consensus": h.ConsensusHash,
  175. "Results": h.LastResultsHash,
  176. "Evidence": h.EvidenceHash,
  177. })
  178. }
  179. // StringIndented returns a string representation of the header
  180. func (h *Header) StringIndented(indent string) string {
  181. if h == nil {
  182. return "nil-Header"
  183. }
  184. return fmt.Sprintf(`Header{
  185. %s ChainID: %v
  186. %s Height: %v
  187. %s Time: %v
  188. %s NumTxs: %v
  189. %s TotalTxs: %v
  190. %s LastBlockID: %v
  191. %s LastCommit: %v
  192. %s Data: %v
  193. %s Validators: %v
  194. %s App: %v
  195. %s Conensus: %v
  196. %s Results: %v
  197. %s Evidence: %v
  198. %s}#%v`,
  199. indent, h.ChainID,
  200. indent, h.Height,
  201. indent, h.Time,
  202. indent, h.NumTxs,
  203. indent, h.TotalTxs,
  204. indent, h.LastBlockID,
  205. indent, h.LastCommitHash,
  206. indent, h.DataHash,
  207. indent, h.ValidatorsHash,
  208. indent, h.AppHash,
  209. indent, h.ConsensusHash,
  210. indent, h.LastResultsHash,
  211. indent, h.EvidenceHash,
  212. indent, h.Hash())
  213. }
  214. //-------------------------------------
  215. // Commit contains the evidence that a block was committed by a set of validators.
  216. // NOTE: Commit is empty for height 1, but never nil.
  217. type Commit struct {
  218. // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order.
  219. // Any peer with a block can gossip precommits by index with a peer without recalculating the
  220. // active ValidatorSet.
  221. BlockID BlockID `json:"blockID"`
  222. Precommits []*Vote `json:"precommits"`
  223. // Volatile
  224. firstPrecommit *Vote
  225. hash data.Bytes
  226. bitArray *cmn.BitArray
  227. }
  228. // FirstPrecommit returns the first non-nil precommit in the commit
  229. func (commit *Commit) FirstPrecommit() *Vote {
  230. if len(commit.Precommits) == 0 {
  231. return nil
  232. }
  233. if commit.firstPrecommit != nil {
  234. return commit.firstPrecommit
  235. }
  236. for _, precommit := range commit.Precommits {
  237. if precommit != nil {
  238. commit.firstPrecommit = precommit
  239. return precommit
  240. }
  241. }
  242. return nil
  243. }
  244. // Height returns the height of the commit
  245. func (commit *Commit) Height() int64 {
  246. if len(commit.Precommits) == 0 {
  247. return 0
  248. }
  249. return commit.FirstPrecommit().Height
  250. }
  251. // Round returns the round of the commit
  252. func (commit *Commit) Round() int {
  253. if len(commit.Precommits) == 0 {
  254. return 0
  255. }
  256. return commit.FirstPrecommit().Round
  257. }
  258. // Type returns the vote type of the commit, which is always VoteTypePrecommit
  259. func (commit *Commit) Type() byte {
  260. return VoteTypePrecommit
  261. }
  262. // Size returns the number of votes in the commit
  263. func (commit *Commit) Size() int {
  264. if commit == nil {
  265. return 0
  266. }
  267. return len(commit.Precommits)
  268. }
  269. // BitArray returns a BitArray of which validators voted in this commit
  270. func (commit *Commit) BitArray() *cmn.BitArray {
  271. if commit.bitArray == nil {
  272. commit.bitArray = cmn.NewBitArray(len(commit.Precommits))
  273. for i, precommit := range commit.Precommits {
  274. // TODO: need to check the BlockID otherwise we could be counting conflicts,
  275. // not just the one with +2/3 !
  276. commit.bitArray.SetIndex(i, precommit != nil)
  277. }
  278. }
  279. return commit.bitArray
  280. }
  281. // GetByIndex returns the vote corresponding to a given validator index
  282. func (commit *Commit) GetByIndex(index int) *Vote {
  283. return commit.Precommits[index]
  284. }
  285. // IsCommit returns true if there is at least one vote
  286. func (commit *Commit) IsCommit() bool {
  287. return len(commit.Precommits) != 0
  288. }
  289. // ValidateBasic performs basic validation that doesn't involve state data.
  290. func (commit *Commit) ValidateBasic() error {
  291. if commit.BlockID.IsZero() {
  292. return errors.New("Commit cannot be for nil block")
  293. }
  294. if len(commit.Precommits) == 0 {
  295. return errors.New("No precommits in commit")
  296. }
  297. height, round := commit.Height(), commit.Round()
  298. // validate the precommits
  299. for _, precommit := range commit.Precommits {
  300. // It's OK for precommits to be missing.
  301. if precommit == nil {
  302. continue
  303. }
  304. // Ensure that all votes are precommits
  305. if precommit.Type != VoteTypePrecommit {
  306. return fmt.Errorf("Invalid commit vote. Expected precommit, got %v",
  307. precommit.Type)
  308. }
  309. // Ensure that all heights are the same
  310. if precommit.Height != height {
  311. return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v",
  312. height, precommit.Height)
  313. }
  314. // Ensure that all rounds are the same
  315. if precommit.Round != round {
  316. return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v",
  317. round, precommit.Round)
  318. }
  319. }
  320. return nil
  321. }
  322. // Hash returns the hash of the commit
  323. func (commit *Commit) Hash() data.Bytes {
  324. if commit.hash == nil {
  325. bs := make([]interface{}, len(commit.Precommits))
  326. for i, precommit := range commit.Precommits {
  327. bs[i] = precommit
  328. }
  329. commit.hash = merkle.SimpleHashFromBinaries(bs)
  330. }
  331. return commit.hash
  332. }
  333. // StringIndented returns a string representation of the commit
  334. func (commit *Commit) StringIndented(indent string) string {
  335. if commit == nil {
  336. return "nil-Commit"
  337. }
  338. precommitStrings := make([]string, len(commit.Precommits))
  339. for i, precommit := range commit.Precommits {
  340. precommitStrings[i] = precommit.String()
  341. }
  342. return fmt.Sprintf(`Commit{
  343. %s BlockID: %v
  344. %s Precommits: %v
  345. %s}#%v`,
  346. indent, commit.BlockID,
  347. indent, strings.Join(precommitStrings, "\n"+indent+" "),
  348. indent, commit.hash)
  349. }
  350. //-----------------------------------------------------------------------------
  351. // SignedHeader is a header along with the commits that prove it
  352. type SignedHeader struct {
  353. Header *Header `json:"header"`
  354. Commit *Commit `json:"commit"`
  355. }
  356. //-----------------------------------------------------------------------------
  357. // Data contains the set of transactions included in the block
  358. type Data struct {
  359. // Txs that will be applied by state @ block.Height+1.
  360. // NOTE: not all txs here are valid. We're just agreeing on the order first.
  361. // This means that block.AppHash does not include these txs.
  362. Txs Txs `json:"txs"`
  363. // Volatile
  364. hash data.Bytes
  365. }
  366. // Hash returns the hash of the data
  367. func (data *Data) Hash() data.Bytes {
  368. if data.hash == nil {
  369. data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs
  370. }
  371. return data.hash
  372. }
  373. // StringIndented returns a string representation of the transactions
  374. func (data *Data) StringIndented(indent string) string {
  375. if data == nil {
  376. return "nil-Data"
  377. }
  378. txStrings := make([]string, cmn.MinInt(len(data.Txs), 21))
  379. for i, tx := range data.Txs {
  380. if i == 20 {
  381. txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  382. break
  383. }
  384. txStrings[i] = fmt.Sprintf("Tx:%v", tx)
  385. }
  386. return fmt.Sprintf(`Data{
  387. %s %v
  388. %s}#%v`,
  389. indent, strings.Join(txStrings, "\n"+indent+" "),
  390. indent, data.hash)
  391. }
  392. //-----------------------------------------------------------------------------
  393. // EvidenceData contains any evidence of malicious wrong-doing by validators
  394. type EvidenceData struct {
  395. Evidences Evidences `json:"evidence"`
  396. // Volatile
  397. hash data.Bytes
  398. }
  399. // Hash returns the hash of the data.
  400. func (data *EvidenceData) Hash() data.Bytes {
  401. if data.hash == nil {
  402. data.hash = data.Evidences.Hash()
  403. }
  404. return data.hash
  405. }
  406. // StringIndented returns a string representation of the evidence.
  407. func (data *EvidenceData) StringIndented(indent string) string {
  408. if data == nil {
  409. return "nil-Evidence"
  410. }
  411. evStrings := make([]string, cmn.MinInt(len(data.Evidences), 21))
  412. for i, ev := range data.Evidences {
  413. if i == 20 {
  414. evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidences))
  415. break
  416. }
  417. evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
  418. }
  419. return fmt.Sprintf(`Data{
  420. %s %v
  421. %s}#%v`,
  422. indent, strings.Join(evStrings, "\n"+indent+" "),
  423. indent, data.hash)
  424. return ""
  425. }
  426. //--------------------------------------------------------------------------------
  427. // BlockID defines the unique ID of a block as its Hash and its PartSetHeader
  428. type BlockID struct {
  429. Hash data.Bytes `json:"hash"`
  430. PartsHeader PartSetHeader `json:"parts"`
  431. }
  432. // IsZero returns true if this is the BlockID for a nil-block
  433. func (blockID BlockID) IsZero() bool {
  434. return len(blockID.Hash) == 0 && blockID.PartsHeader.IsZero()
  435. }
  436. // Equals returns true if the BlockID matches the given BlockID
  437. func (blockID BlockID) Equals(other BlockID) bool {
  438. return bytes.Equal(blockID.Hash, other.Hash) &&
  439. blockID.PartsHeader.Equals(other.PartsHeader)
  440. }
  441. // Key returns a machine-readable string representation of the BlockID
  442. func (blockID BlockID) Key() string {
  443. return string(blockID.Hash) + string(wire.BinaryBytes(blockID.PartsHeader))
  444. }
  445. // WriteSignBytes writes the canonical bytes of the BlockID to the given writer for digital signing
  446. func (blockID BlockID) WriteSignBytes(w io.Writer, n *int, err *error) {
  447. if blockID.IsZero() {
  448. wire.WriteTo([]byte("null"), w, n, err)
  449. } else {
  450. wire.WriteJSON(CanonicalBlockID(blockID), w, n, err)
  451. }
  452. }
  453. // String returns a human readable string representation of the BlockID
  454. func (blockID BlockID) String() string {
  455. return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader)
  456. }