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.

640 lines
18 KiB

10 years ago
10 years ago
7 years ago
10 years ago
10 years ago
7 years ago
7 years ago
7 years ago
10 years ago
10 years ago
7 years ago
7 years ago
11 years ago
7 years ago
7 years ago
7 years ago
7 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "sync"
  8. "time"
  9. "github.com/tendermint/tendermint/crypto/merkle"
  10. "github.com/tendermint/tendermint/crypto/tmhash"
  11. cmn "github.com/tendermint/tendermint/libs/common"
  12. )
  13. // Block defines the atomic unit of a Tendermint blockchain.
  14. // TODO: add Version byte
  15. type Block struct {
  16. mtx sync.Mutex
  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, evidence []Evidence) *Block {
  25. block := &Block{
  26. Header: Header{
  27. Height: height,
  28. Time: time.Now(),
  29. NumTxs: int64(len(txs)),
  30. },
  31. Data: Data{
  32. Txs: txs,
  33. },
  34. Evidence: EvidenceData{Evidence: evidence},
  35. LastCommit: commit,
  36. }
  37. block.fillHeader()
  38. return block
  39. }
  40. // ValidateBasic performs basic validation that doesn't involve state data.
  41. // It checks the internal consistency of the block.
  42. func (b *Block) ValidateBasic() error {
  43. if b == nil {
  44. return errors.New("Nil blocks are invalid")
  45. }
  46. b.mtx.Lock()
  47. defer b.mtx.Unlock()
  48. newTxs := int64(len(b.Data.Txs))
  49. if b.NumTxs != newTxs {
  50. return fmt.Errorf("Wrong Block.Header.NumTxs. Expected %v, got %v", newTxs, b.NumTxs)
  51. }
  52. if !bytes.Equal(b.LastCommitHash, b.LastCommit.Hash()) {
  53. return fmt.Errorf("Wrong Block.Header.LastCommitHash. Expected %v, got %v", b.LastCommitHash, b.LastCommit.Hash())
  54. }
  55. if b.Header.Height != 1 {
  56. if err := b.LastCommit.ValidateBasic(); err != nil {
  57. return err
  58. }
  59. }
  60. if !bytes.Equal(b.DataHash, b.Data.Hash()) {
  61. return fmt.Errorf("Wrong Block.Header.DataHash. Expected %v, got %v", b.DataHash, b.Data.Hash())
  62. }
  63. if !bytes.Equal(b.EvidenceHash, b.Evidence.Hash()) {
  64. return errors.New(cmn.Fmt("Wrong Block.Header.EvidenceHash. Expected %v, got %v", b.EvidenceHash, b.Evidence.Hash()))
  65. }
  66. return nil
  67. }
  68. // fillHeader fills in any remaining header fields that are a function of the block data
  69. func (b *Block) fillHeader() {
  70. if b.LastCommitHash == nil {
  71. b.LastCommitHash = b.LastCommit.Hash()
  72. }
  73. if b.DataHash == nil {
  74. b.DataHash = b.Data.Hash()
  75. }
  76. if b.EvidenceHash == nil {
  77. b.EvidenceHash = b.Evidence.Hash()
  78. }
  79. }
  80. // Hash computes and returns the block hash.
  81. // If the block is incomplete, block hash is nil for safety.
  82. func (b *Block) Hash() cmn.HexBytes {
  83. if b == nil {
  84. return nil
  85. }
  86. b.mtx.Lock()
  87. defer b.mtx.Unlock()
  88. if b == nil || b.LastCommit == nil {
  89. return nil
  90. }
  91. b.fillHeader()
  92. return b.Header.Hash()
  93. }
  94. // MakePartSet returns a PartSet containing parts of a serialized block.
  95. // This is the form in which the block is gossipped to peers.
  96. // CONTRACT: partSize is greater than zero.
  97. func (b *Block) MakePartSet(partSize int) *PartSet {
  98. if b == nil {
  99. return nil
  100. }
  101. b.mtx.Lock()
  102. defer b.mtx.Unlock()
  103. // We prefix the byte length, so that unmarshaling
  104. // can easily happen via a reader.
  105. bz, err := cdc.MarshalBinary(b)
  106. if err != nil {
  107. panic(err)
  108. }
  109. return NewPartSetFromData(bz, partSize)
  110. }
  111. // HashesTo is a convenience function that checks if a block hashes to the given argument.
  112. // Returns false if the block is nil or the hash is empty.
  113. func (b *Block) HashesTo(hash []byte) bool {
  114. if len(hash) == 0 {
  115. return false
  116. }
  117. if b == nil {
  118. return false
  119. }
  120. return bytes.Equal(b.Hash(), hash)
  121. }
  122. // Size returns size of the block in bytes.
  123. func (b *Block) Size() int {
  124. bz, err := cdc.MarshalBinaryBare(b)
  125. if err != nil {
  126. return 0
  127. }
  128. return len(bz)
  129. }
  130. // String returns a string representation of the block
  131. func (b *Block) String() string {
  132. return b.StringIndented("")
  133. }
  134. // StringIndented returns a string representation of the block
  135. func (b *Block) StringIndented(indent string) string {
  136. if b == nil {
  137. return "nil-Block"
  138. }
  139. return fmt.Sprintf(`Block{
  140. %s %v
  141. %s %v
  142. %s %v
  143. %s %v
  144. %s}#%v`,
  145. indent, b.Header.StringIndented(indent+" "),
  146. indent, b.Data.StringIndented(indent+" "),
  147. indent, b.Evidence.StringIndented(indent+" "),
  148. indent, b.LastCommit.StringIndented(indent+" "),
  149. indent, b.Hash())
  150. }
  151. // StringShort returns a shortened string representation of the block
  152. func (b *Block) StringShort() string {
  153. if b == nil {
  154. return "nil-Block"
  155. }
  156. return fmt.Sprintf("Block#%v", b.Hash())
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Header defines the structure of a Tendermint block header
  160. // TODO: limit header size
  161. // NOTE: changes to the Header should be duplicated in the abci Header
  162. type Header struct {
  163. // basic block info
  164. ChainID string `json:"chain_id"`
  165. Height int64 `json:"height"`
  166. Time time.Time `json:"time"`
  167. NumTxs int64 `json:"num_txs"`
  168. // prev block info
  169. LastBlockID BlockID `json:"last_block_id"`
  170. TotalTxs int64 `json:"total_txs"`
  171. // hashes of block data
  172. LastCommitHash cmn.HexBytes `json:"last_commit_hash"` // commit from validators from the last block
  173. DataHash cmn.HexBytes `json:"data_hash"` // transactions
  174. // hashes from the app output from the prev block
  175. ValidatorsHash cmn.HexBytes `json:"validators_hash"` // validators for the current block
  176. NextValidatorsHash cmn.HexBytes `json:"next_validators_hash"` // validators for the next block
  177. ConsensusHash cmn.HexBytes `json:"consensus_hash"` // consensus params for current block
  178. AppHash cmn.HexBytes `json:"app_hash"` // state after txs from the previous block
  179. LastResultsHash cmn.HexBytes `json:"last_results_hash"` // root hash of all results from the txs from the previous block
  180. // consensus info
  181. EvidenceHash cmn.HexBytes `json:"evidence_hash"` // evidence included in the block
  182. }
  183. // Hash returns the hash of the header.
  184. // Returns nil if ValidatorHash is missing,
  185. // since a Header is not valid unless there is
  186. // a ValidatorsHash (corresponding to the validator set).
  187. func (h *Header) Hash() cmn.HexBytes {
  188. if h == nil || len(h.ValidatorsHash) == 0 {
  189. return nil
  190. }
  191. return merkle.SimpleHashFromMap(map[string]merkle.Hasher{
  192. "ChainID": aminoHasher(h.ChainID),
  193. "Height": aminoHasher(h.Height),
  194. "Time": aminoHasher(h.Time),
  195. "NumTxs": aminoHasher(h.NumTxs),
  196. "TotalTxs": aminoHasher(h.TotalTxs),
  197. "LastBlockID": aminoHasher(h.LastBlockID),
  198. "LastCommit": aminoHasher(h.LastCommitHash),
  199. "Data": aminoHasher(h.DataHash),
  200. "Validators": aminoHasher(h.ValidatorsHash),
  201. "NextValidators": aminoHasher(h.NextValidatorsHash),
  202. "App": aminoHasher(h.AppHash),
  203. "Consensus": aminoHasher(h.ConsensusHash),
  204. "Results": aminoHasher(h.LastResultsHash),
  205. "Evidence": aminoHasher(h.EvidenceHash),
  206. })
  207. }
  208. // StringIndented returns a string representation of the header
  209. func (h *Header) StringIndented(indent string) string {
  210. if h == nil {
  211. return "nil-Header"
  212. }
  213. return fmt.Sprintf(`Header{
  214. %s ChainID: %v
  215. %s Height: %v
  216. %s Time: %v
  217. %s NumTxs: %v
  218. %s TotalTxs: %v
  219. %s LastBlockID: %v
  220. %s LastCommit: %v
  221. %s Data: %v
  222. %s Validators: %v
  223. %s NextValidators: %v
  224. %s App: %v
  225. %s Consensus: %v
  226. %s Results: %v
  227. %s Evidence: %v
  228. %s}#%v`,
  229. indent, h.ChainID,
  230. indent, h.Height,
  231. indent, h.Time,
  232. indent, h.NumTxs,
  233. indent, h.TotalTxs,
  234. indent, h.LastBlockID,
  235. indent, h.LastCommitHash,
  236. indent, h.DataHash,
  237. indent, h.ValidatorsHash,
  238. indent, h.NextValidatorsHash,
  239. indent, h.AppHash,
  240. indent, h.ConsensusHash,
  241. indent, h.LastResultsHash,
  242. indent, h.EvidenceHash,
  243. indent, h.Hash())
  244. }
  245. //-------------------------------------
  246. // Commit contains the evidence that a block was committed by a set of validators.
  247. // NOTE: Commit is empty for height 1, but never nil.
  248. type Commit struct {
  249. // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order.
  250. // Any peer with a block can gossip precommits by index with a peer without recalculating the
  251. // active ValidatorSet.
  252. BlockID BlockID `json:"block_id"`
  253. Precommits []*Vote `json:"precommits"`
  254. // Volatile
  255. firstPrecommit *Vote
  256. hash cmn.HexBytes
  257. bitArray *cmn.BitArray
  258. }
  259. // FirstPrecommit returns the first non-nil precommit in the commit.
  260. // If all precommits are nil, it returns an empty precommit with height 0.
  261. func (commit *Commit) FirstPrecommit() *Vote {
  262. if len(commit.Precommits) == 0 {
  263. return nil
  264. }
  265. if commit.firstPrecommit != nil {
  266. return commit.firstPrecommit
  267. }
  268. for _, precommit := range commit.Precommits {
  269. if precommit != nil {
  270. commit.firstPrecommit = precommit
  271. return precommit
  272. }
  273. }
  274. return &Vote{
  275. Type: VoteTypePrecommit,
  276. }
  277. }
  278. // Height returns the height of the commit
  279. func (commit *Commit) Height() int64 {
  280. if len(commit.Precommits) == 0 {
  281. return 0
  282. }
  283. return commit.FirstPrecommit().Height
  284. }
  285. // Round returns the round of the commit
  286. func (commit *Commit) Round() int {
  287. if len(commit.Precommits) == 0 {
  288. return 0
  289. }
  290. return commit.FirstPrecommit().Round
  291. }
  292. // Type returns the vote type of the commit, which is always VoteTypePrecommit
  293. func (commit *Commit) Type() byte {
  294. return VoteTypePrecommit
  295. }
  296. // Size returns the number of votes in the commit
  297. func (commit *Commit) Size() int {
  298. if commit == nil {
  299. return 0
  300. }
  301. return len(commit.Precommits)
  302. }
  303. // BitArray returns a BitArray of which validators voted in this commit
  304. func (commit *Commit) BitArray() *cmn.BitArray {
  305. if commit.bitArray == nil {
  306. commit.bitArray = cmn.NewBitArray(len(commit.Precommits))
  307. for i, precommit := range commit.Precommits {
  308. // TODO: need to check the BlockID otherwise we could be counting conflicts,
  309. // not just the one with +2/3 !
  310. commit.bitArray.SetIndex(i, precommit != nil)
  311. }
  312. }
  313. return commit.bitArray
  314. }
  315. // GetByIndex returns the vote corresponding to a given validator index
  316. func (commit *Commit) GetByIndex(index int) *Vote {
  317. return commit.Precommits[index]
  318. }
  319. // IsCommit returns true if there is at least one vote
  320. func (commit *Commit) IsCommit() bool {
  321. return len(commit.Precommits) != 0
  322. }
  323. // ValidateBasic performs basic validation that doesn't involve state data.
  324. // Does not actually check the cryptographic signatures.
  325. func (commit *Commit) ValidateBasic() error {
  326. if commit.BlockID.IsZero() {
  327. return errors.New("Commit cannot be for nil block")
  328. }
  329. if len(commit.Precommits) == 0 {
  330. return errors.New("No precommits in commit")
  331. }
  332. height, round := commit.Height(), commit.Round()
  333. // Validate the precommits.
  334. for _, precommit := range commit.Precommits {
  335. // It's OK for precommits to be missing.
  336. if precommit == nil {
  337. continue
  338. }
  339. // Ensure that all votes are precommits.
  340. if precommit.Type != VoteTypePrecommit {
  341. return fmt.Errorf("Invalid commit vote. Expected precommit, got %v",
  342. precommit.Type)
  343. }
  344. // Ensure that all heights are the same.
  345. if precommit.Height != height {
  346. return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v",
  347. height, precommit.Height)
  348. }
  349. // Ensure that all rounds are the same.
  350. if precommit.Round != round {
  351. return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v",
  352. round, precommit.Round)
  353. }
  354. }
  355. return nil
  356. }
  357. // Hash returns the hash of the commit
  358. func (commit *Commit) Hash() cmn.HexBytes {
  359. if commit == nil {
  360. return nil
  361. }
  362. if commit.hash == nil {
  363. bs := make([]merkle.Hasher, len(commit.Precommits))
  364. for i, precommit := range commit.Precommits {
  365. bs[i] = aminoHasher(precommit)
  366. }
  367. commit.hash = merkle.SimpleHashFromHashers(bs)
  368. }
  369. return commit.hash
  370. }
  371. // StringIndented returns a string representation of the commit
  372. func (commit *Commit) StringIndented(indent string) string {
  373. if commit == nil {
  374. return "nil-Commit"
  375. }
  376. precommitStrings := make([]string, len(commit.Precommits))
  377. for i, precommit := range commit.Precommits {
  378. precommitStrings[i] = precommit.String()
  379. }
  380. return fmt.Sprintf(`Commit{
  381. %s BlockID: %v
  382. %s Precommits:
  383. %s %v
  384. %s}#%v`,
  385. indent, commit.BlockID,
  386. indent,
  387. indent, strings.Join(precommitStrings, "\n"+indent+" "),
  388. indent, commit.hash)
  389. }
  390. //-----------------------------------------------------------------------------
  391. // SignedHeader is a header along with the commits that prove it.
  392. type SignedHeader struct {
  393. *Header `json:"header"`
  394. Commit *Commit `json:"commit"`
  395. }
  396. // ValidateBasic does basic consistency checks and makes sure the header
  397. // and commit are consistent.
  398. //
  399. // NOTE: This does not actually check the cryptographic signatures. Make
  400. // sure to use a Verifier to validate the signatures actually provide a
  401. // significantly strong proof for this header's validity.
  402. func (sh SignedHeader) ValidateBasic(chainID string) error {
  403. // Make sure the header is consistent with the commit.
  404. if sh.Header == nil {
  405. return errors.New("SignedHeader missing header.")
  406. }
  407. if sh.Commit == nil {
  408. return errors.New("SignedHeader missing commit (precommit votes).")
  409. }
  410. // Check ChainID.
  411. if sh.ChainID != chainID {
  412. return fmt.Errorf("Header belongs to another chain '%s' not '%s'",
  413. sh.ChainID, chainID)
  414. }
  415. // Check Height.
  416. if sh.Commit.Height() != sh.Height {
  417. return fmt.Errorf("SignedHeader header and commit height mismatch: %v vs %v",
  418. sh.Height, sh.Commit.Height())
  419. }
  420. // Check Hash.
  421. hhash := sh.Hash()
  422. chash := sh.Commit.BlockID.Hash
  423. if !bytes.Equal(hhash, chash) {
  424. return fmt.Errorf("SignedHeader commit signs block %X, header is block %X",
  425. chash, hhash)
  426. }
  427. // ValidateBasic on the Commit.
  428. err := sh.Commit.ValidateBasic()
  429. if err != nil {
  430. return cmn.ErrorWrap(err, "commit.ValidateBasic failed during SignedHeader.ValidateBasic")
  431. }
  432. return nil
  433. }
  434. func (sh SignedHeader) String() string {
  435. return sh.StringIndented("")
  436. }
  437. // StringIndented returns a string representation of the SignedHeader.
  438. func (sh SignedHeader) StringIndented(indent string) string {
  439. return fmt.Sprintf(`SignedHeader{
  440. %s %v
  441. %s %v
  442. %s}`,
  443. indent, sh.Header.StringIndented(indent+" "),
  444. indent, sh.Commit.StringIndented(indent+" "),
  445. indent)
  446. return ""
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Data contains the set of transactions included in the block
  450. type Data struct {
  451. // Txs that will be applied by state @ block.Height+1.
  452. // NOTE: not all txs here are valid. We're just agreeing on the order first.
  453. // This means that block.AppHash does not include these txs.
  454. Txs Txs `json:"txs"`
  455. // Volatile
  456. hash cmn.HexBytes
  457. }
  458. // Hash returns the hash of the data
  459. func (data *Data) Hash() cmn.HexBytes {
  460. if data == nil {
  461. return (Txs{}).Hash()
  462. }
  463. if data.hash == nil {
  464. data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs
  465. }
  466. return data.hash
  467. }
  468. // StringIndented returns a string representation of the transactions
  469. func (data *Data) StringIndented(indent string) string {
  470. if data == nil {
  471. return "nil-Data"
  472. }
  473. txStrings := make([]string, cmn.MinInt(len(data.Txs), 21))
  474. for i, tx := range data.Txs {
  475. if i == 20 {
  476. txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  477. break
  478. }
  479. txStrings[i] = fmt.Sprintf("%X (%d bytes)", tx.Hash(), len(tx))
  480. }
  481. return fmt.Sprintf(`Data{
  482. %s %v
  483. %s}#%v`,
  484. indent, strings.Join(txStrings, "\n"+indent+" "),
  485. indent, data.hash)
  486. }
  487. //-----------------------------------------------------------------------------
  488. // EvidenceData contains any evidence of malicious wrong-doing by validators
  489. type EvidenceData struct {
  490. Evidence EvidenceList `json:"evidence"`
  491. // Volatile
  492. hash cmn.HexBytes
  493. }
  494. // Hash returns the hash of the data.
  495. func (data *EvidenceData) Hash() cmn.HexBytes {
  496. if data.hash == nil {
  497. data.hash = data.Evidence.Hash()
  498. }
  499. return data.hash
  500. }
  501. // StringIndented returns a string representation of the evidence.
  502. func (data *EvidenceData) StringIndented(indent string) string {
  503. if data == nil {
  504. return "nil-Evidence"
  505. }
  506. evStrings := make([]string, cmn.MinInt(len(data.Evidence), 21))
  507. for i, ev := range data.Evidence {
  508. if i == 20 {
  509. evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidence))
  510. break
  511. }
  512. evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
  513. }
  514. return fmt.Sprintf(`EvidenceData{
  515. %s %v
  516. %s}#%v`,
  517. indent, strings.Join(evStrings, "\n"+indent+" "),
  518. indent, data.hash)
  519. return ""
  520. }
  521. //--------------------------------------------------------------------------------
  522. // BlockID defines the unique ID of a block as its Hash and its PartSetHeader
  523. type BlockID struct {
  524. Hash cmn.HexBytes `json:"hash"`
  525. PartsHeader PartSetHeader `json:"parts"`
  526. }
  527. // IsZero returns true if this is the BlockID for a nil-block
  528. func (blockID BlockID) IsZero() bool {
  529. return len(blockID.Hash) == 0 && blockID.PartsHeader.IsZero()
  530. }
  531. // Equals returns true if the BlockID matches the given BlockID
  532. func (blockID BlockID) Equals(other BlockID) bool {
  533. return bytes.Equal(blockID.Hash, other.Hash) &&
  534. blockID.PartsHeader.Equals(other.PartsHeader)
  535. }
  536. // Key returns a machine-readable string representation of the BlockID
  537. func (blockID BlockID) Key() string {
  538. bz, err := cdc.MarshalBinaryBare(blockID.PartsHeader)
  539. if err != nil {
  540. panic(err)
  541. }
  542. return string(blockID.Hash) + string(bz)
  543. }
  544. // String returns a human readable string representation of the BlockID
  545. func (blockID BlockID) String() string {
  546. return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader)
  547. }
  548. //-------------------------------------------------------
  549. type hasher struct {
  550. item interface{}
  551. }
  552. func (h hasher) Hash() []byte {
  553. hasher := tmhash.New()
  554. if h.item != nil && !cmn.IsTypedNil(h.item) && !cmn.IsEmpty(h.item) {
  555. bz, err := cdc.MarshalBinaryBare(h.item)
  556. if err != nil {
  557. panic(err)
  558. }
  559. _, err = hasher.Write(bz)
  560. if err != nil {
  561. panic(err)
  562. }
  563. }
  564. return hasher.Sum(nil)
  565. }
  566. func aminoHash(item interface{}) []byte {
  567. h := hasher{item}
  568. return h.Hash()
  569. }
  570. func aminoHasher(item interface{}) merkle.Hasher {
  571. return hasher{item}
  572. }