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.

577 lines
16 KiB

10 years ago
10 years ago
6 years ago
10 years ago
10 years ago
6 years ago
6 years ago
7 years ago
10 years ago
9 years ago
7 years ago
7 years ago
10 years ago
7 years ago
6 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. ConsensusHash cmn.HexBytes `json:"consensus_hash"` // consensus params for current block
  177. AppHash cmn.HexBytes `json:"app_hash"` // state after txs from the previous block
  178. LastResultsHash cmn.HexBytes `json:"last_results_hash"` // root hash of all results from the txs from the previous block
  179. // consensus info
  180. EvidenceHash cmn.HexBytes `json:"evidence_hash"` // evidence included in the block
  181. }
  182. // Hash returns the hash of the header.
  183. // Returns nil if ValidatorHash is missing,
  184. // since a Header is not valid unless there is
  185. // a ValidatorsHash (corresponding to the validator set).
  186. func (h *Header) Hash() cmn.HexBytes {
  187. if h == nil || len(h.ValidatorsHash) == 0 {
  188. return nil
  189. }
  190. return merkle.SimpleHashFromMap(map[string]merkle.Hasher{
  191. "ChainID": aminoHasher(h.ChainID),
  192. "Height": aminoHasher(h.Height),
  193. "Time": aminoHasher(h.Time),
  194. "NumTxs": aminoHasher(h.NumTxs),
  195. "TotalTxs": aminoHasher(h.TotalTxs),
  196. "LastBlockID": aminoHasher(h.LastBlockID),
  197. "LastCommit": aminoHasher(h.LastCommitHash),
  198. "Data": aminoHasher(h.DataHash),
  199. "Validators": aminoHasher(h.ValidatorsHash),
  200. "App": aminoHasher(h.AppHash),
  201. "Consensus": aminoHasher(h.ConsensusHash),
  202. "Results": aminoHasher(h.LastResultsHash),
  203. "Evidence": aminoHasher(h.EvidenceHash),
  204. })
  205. }
  206. // StringIndented returns a string representation of the header
  207. func (h *Header) StringIndented(indent string) string {
  208. if h == nil {
  209. return "nil-Header"
  210. }
  211. return fmt.Sprintf(`Header{
  212. %s ChainID: %v
  213. %s Height: %v
  214. %s Time: %v
  215. %s NumTxs: %v
  216. %s TotalTxs: %v
  217. %s LastBlockID: %v
  218. %s LastCommit: %v
  219. %s Data: %v
  220. %s Validators: %v
  221. %s App: %v
  222. %s Consensus: %v
  223. %s Results: %v
  224. %s Evidence: %v
  225. %s}#%v`,
  226. indent, h.ChainID,
  227. indent, h.Height,
  228. indent, h.Time,
  229. indent, h.NumTxs,
  230. indent, h.TotalTxs,
  231. indent, h.LastBlockID,
  232. indent, h.LastCommitHash,
  233. indent, h.DataHash,
  234. indent, h.ValidatorsHash,
  235. indent, h.AppHash,
  236. indent, h.ConsensusHash,
  237. indent, h.LastResultsHash,
  238. indent, h.EvidenceHash,
  239. indent, h.Hash())
  240. }
  241. //-------------------------------------
  242. // Commit contains the evidence that a block was committed by a set of validators.
  243. // NOTE: Commit is empty for height 1, but never nil.
  244. type Commit struct {
  245. // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order.
  246. // Any peer with a block can gossip precommits by index with a peer without recalculating the
  247. // active ValidatorSet.
  248. BlockID BlockID `json:"block_id"`
  249. Precommits []*Vote `json:"precommits"`
  250. // Volatile
  251. firstPrecommit *Vote
  252. hash cmn.HexBytes
  253. bitArray *cmn.BitArray
  254. }
  255. // FirstPrecommit returns the first non-nil precommit in the commit.
  256. // If all precommits are nil, it returns an empty precommit with height 0.
  257. func (commit *Commit) FirstPrecommit() *Vote {
  258. if len(commit.Precommits) == 0 {
  259. return nil
  260. }
  261. if commit.firstPrecommit != nil {
  262. return commit.firstPrecommit
  263. }
  264. for _, precommit := range commit.Precommits {
  265. if precommit != nil {
  266. commit.firstPrecommit = precommit
  267. return precommit
  268. }
  269. }
  270. return &Vote{
  271. Type: VoteTypePrecommit,
  272. }
  273. }
  274. // Height returns the height of the commit
  275. func (commit *Commit) Height() int64 {
  276. if len(commit.Precommits) == 0 {
  277. return 0
  278. }
  279. return commit.FirstPrecommit().Height
  280. }
  281. // Round returns the round of the commit
  282. func (commit *Commit) Round() int {
  283. if len(commit.Precommits) == 0 {
  284. return 0
  285. }
  286. return commit.FirstPrecommit().Round
  287. }
  288. // Type returns the vote type of the commit, which is always VoteTypePrecommit
  289. func (commit *Commit) Type() byte {
  290. return VoteTypePrecommit
  291. }
  292. // Size returns the number of votes in the commit
  293. func (commit *Commit) Size() int {
  294. if commit == nil {
  295. return 0
  296. }
  297. return len(commit.Precommits)
  298. }
  299. // BitArray returns a BitArray of which validators voted in this commit
  300. func (commit *Commit) BitArray() *cmn.BitArray {
  301. if commit.bitArray == nil {
  302. commit.bitArray = cmn.NewBitArray(len(commit.Precommits))
  303. for i, precommit := range commit.Precommits {
  304. // TODO: need to check the BlockID otherwise we could be counting conflicts,
  305. // not just the one with +2/3 !
  306. commit.bitArray.SetIndex(i, precommit != nil)
  307. }
  308. }
  309. return commit.bitArray
  310. }
  311. // GetByIndex returns the vote corresponding to a given validator index
  312. func (commit *Commit) GetByIndex(index int) *Vote {
  313. return commit.Precommits[index]
  314. }
  315. // IsCommit returns true if there is at least one vote
  316. func (commit *Commit) IsCommit() bool {
  317. return len(commit.Precommits) != 0
  318. }
  319. // ValidateBasic performs basic validation that doesn't involve state data.
  320. func (commit *Commit) ValidateBasic() error {
  321. if commit.BlockID.IsZero() {
  322. return errors.New("Commit cannot be for nil block")
  323. }
  324. if len(commit.Precommits) == 0 {
  325. return errors.New("No precommits in commit")
  326. }
  327. height, round := commit.Height(), commit.Round()
  328. // validate the precommits
  329. for _, precommit := range commit.Precommits {
  330. // It's OK for precommits to be missing.
  331. if precommit == nil {
  332. continue
  333. }
  334. // Ensure that all votes are precommits
  335. if precommit.Type != VoteTypePrecommit {
  336. return fmt.Errorf("Invalid commit vote. Expected precommit, got %v",
  337. precommit.Type)
  338. }
  339. // Ensure that all heights are the same
  340. if precommit.Height != height {
  341. return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v",
  342. height, precommit.Height)
  343. }
  344. // Ensure that all rounds are the same
  345. if precommit.Round != round {
  346. return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v",
  347. round, precommit.Round)
  348. }
  349. }
  350. return nil
  351. }
  352. // Hash returns the hash of the commit
  353. func (commit *Commit) Hash() cmn.HexBytes {
  354. if commit == nil {
  355. return nil
  356. }
  357. if commit.hash == nil {
  358. bs := make([]merkle.Hasher, len(commit.Precommits))
  359. for i, precommit := range commit.Precommits {
  360. bs[i] = aminoHasher(precommit)
  361. }
  362. commit.hash = merkle.SimpleHashFromHashers(bs)
  363. }
  364. return commit.hash
  365. }
  366. // StringIndented returns a string representation of the commit
  367. func (commit *Commit) StringIndented(indent string) string {
  368. if commit == nil {
  369. return "nil-Commit"
  370. }
  371. precommitStrings := make([]string, len(commit.Precommits))
  372. for i, precommit := range commit.Precommits {
  373. precommitStrings[i] = precommit.String()
  374. }
  375. return fmt.Sprintf(`Commit{
  376. %s BlockID: %v
  377. %s Precommits: %v
  378. %s}#%v`,
  379. indent, commit.BlockID,
  380. indent, strings.Join(precommitStrings, "\n"+indent+" "),
  381. indent, commit.hash)
  382. }
  383. //-----------------------------------------------------------------------------
  384. // SignedHeader is a header along with the commits that prove it
  385. type SignedHeader struct {
  386. Header *Header `json:"header"`
  387. Commit *Commit `json:"commit"`
  388. }
  389. //-----------------------------------------------------------------------------
  390. // Data contains the set of transactions included in the block
  391. type Data struct {
  392. // Txs that will be applied by state @ block.Height+1.
  393. // NOTE: not all txs here are valid. We're just agreeing on the order first.
  394. // This means that block.AppHash does not include these txs.
  395. Txs Txs `json:"txs"`
  396. // Volatile
  397. hash cmn.HexBytes
  398. }
  399. // Hash returns the hash of the data
  400. func (data *Data) Hash() cmn.HexBytes {
  401. if data == nil {
  402. return (Txs{}).Hash()
  403. }
  404. if data.hash == nil {
  405. data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs
  406. }
  407. return data.hash
  408. }
  409. // StringIndented returns a string representation of the transactions
  410. func (data *Data) StringIndented(indent string) string {
  411. if data == nil {
  412. return "nil-Data"
  413. }
  414. txStrings := make([]string, cmn.MinInt(len(data.Txs), 21))
  415. for i, tx := range data.Txs {
  416. if i == 20 {
  417. txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  418. break
  419. }
  420. txStrings[i] = fmt.Sprintf("%X (%d bytes)", tx.Hash(), len(tx))
  421. }
  422. return fmt.Sprintf(`Data{
  423. %s %v
  424. %s}#%v`,
  425. indent, strings.Join(txStrings, "\n"+indent+" "),
  426. indent, data.hash)
  427. }
  428. //-----------------------------------------------------------------------------
  429. // EvidenceData contains any evidence of malicious wrong-doing by validators
  430. type EvidenceData struct {
  431. Evidence EvidenceList `json:"evidence"`
  432. // Volatile
  433. hash cmn.HexBytes
  434. }
  435. // Hash returns the hash of the data.
  436. func (data *EvidenceData) Hash() cmn.HexBytes {
  437. if data.hash == nil {
  438. data.hash = data.Evidence.Hash()
  439. }
  440. return data.hash
  441. }
  442. // StringIndented returns a string representation of the evidence.
  443. func (data *EvidenceData) StringIndented(indent string) string {
  444. if data == nil {
  445. return "nil-Evidence"
  446. }
  447. evStrings := make([]string, cmn.MinInt(len(data.Evidence), 21))
  448. for i, ev := range data.Evidence {
  449. if i == 20 {
  450. evStrings[i] = fmt.Sprintf("... (%v total)", len(data.Evidence))
  451. break
  452. }
  453. evStrings[i] = fmt.Sprintf("Evidence:%v", ev)
  454. }
  455. return fmt.Sprintf(`EvidenceData{
  456. %s %v
  457. %s}#%v`,
  458. indent, strings.Join(evStrings, "\n"+indent+" "),
  459. indent, data.hash)
  460. return ""
  461. }
  462. //--------------------------------------------------------------------------------
  463. // BlockID defines the unique ID of a block as its Hash and its PartSetHeader
  464. type BlockID struct {
  465. Hash cmn.HexBytes `json:"hash"`
  466. PartsHeader PartSetHeader `json:"parts"`
  467. }
  468. // IsZero returns true if this is the BlockID for a nil-block
  469. func (blockID BlockID) IsZero() bool {
  470. return len(blockID.Hash) == 0 && blockID.PartsHeader.IsZero()
  471. }
  472. // Equals returns true if the BlockID matches the given BlockID
  473. func (blockID BlockID) Equals(other BlockID) bool {
  474. return bytes.Equal(blockID.Hash, other.Hash) &&
  475. blockID.PartsHeader.Equals(other.PartsHeader)
  476. }
  477. // Key returns a machine-readable string representation of the BlockID
  478. func (blockID BlockID) Key() string {
  479. bz, err := cdc.MarshalBinaryBare(blockID.PartsHeader)
  480. if err != nil {
  481. panic(err)
  482. }
  483. return string(blockID.Hash) + string(bz)
  484. }
  485. // String returns a human readable string representation of the BlockID
  486. func (blockID BlockID) String() string {
  487. return fmt.Sprintf(`%v:%v`, blockID.Hash, blockID.PartsHeader)
  488. }
  489. //-------------------------------------------------------
  490. type hasher struct {
  491. item interface{}
  492. }
  493. func (h hasher) Hash() []byte {
  494. hasher := tmhash.New()
  495. if h.item != nil && !cmn.IsTypedNil(h.item) && !cmn.IsEmpty(h.item) {
  496. bz, err := cdc.MarshalBinaryBare(h.item)
  497. if err != nil {
  498. panic(err)
  499. }
  500. _, err = hasher.Write(bz)
  501. if err != nil {
  502. panic(err)
  503. }
  504. }
  505. return hasher.Sum(nil)
  506. }
  507. func aminoHash(item interface{}) []byte {
  508. h := hasher{item}
  509. return h.Hash()
  510. }
  511. func aminoHasher(item interface{}) merkle.Hasher {
  512. return hasher{item}
  513. }