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

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