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
10 years ago
10 years ago
11 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. if b == nil || b.Header == nil || b.Data == nil || b.LastCommit == nil {
  82. return nil
  83. }
  84. b.FillHeader()
  85. return b.Header.Hash()
  86. }
  87. // MakePartSet returns a PartSet containing parts of a serialized block.
  88. // This is the form in which the block is gossipped to peers.
  89. func (b *Block) MakePartSet(partSize int) *PartSet {
  90. return NewPartSetFromData(wire.BinaryBytes(b), partSize)
  91. }
  92. // HashesTo is a convenience function that checks if a block hashes to the given argument.
  93. // A nil block never hashes to anything, and nothing hashes to a nil hash.
  94. func (b *Block) HashesTo(hash []byte) bool {
  95. if len(hash) == 0 {
  96. return false
  97. }
  98. if b == nil {
  99. return false
  100. }
  101. return bytes.Equal(b.Hash(), hash)
  102. }
  103. // String returns a string representation of the block
  104. func (b *Block) String() string {
  105. return b.StringIndented("")
  106. }
  107. // StringIndented returns a string representation of the block
  108. func (b *Block) StringIndented(indent string) string {
  109. if b == nil {
  110. return "nil-Block"
  111. }
  112. return fmt.Sprintf(`Block{
  113. %s %v
  114. %s %v
  115. %s %v
  116. %s %v
  117. %s}#%v`,
  118. indent, b.Header.StringIndented(indent+" "),
  119. indent, b.Data.StringIndented(indent+" "),
  120. indent, b.Evidence.StringIndented(indent+" "),
  121. indent, b.LastCommit.StringIndented(indent+" "),
  122. indent, b.Hash())
  123. }
  124. // StringShort returns a shortened string representation of the block
  125. func (b *Block) StringShort() string {
  126. if b == nil {
  127. return "nil-Block"
  128. } else {
  129. return fmt.Sprintf("Block#%v", b.Hash())
  130. }
  131. }
  132. //-----------------------------------------------------------------------------
  133. // Header defines the structure of a Tendermint block header
  134. // TODO: limit header size
  135. // NOTE: changes to the Header should be duplicated in the abci Header
  136. type Header struct {
  137. // basic block info
  138. ChainID string `json:"chain_id"`
  139. Height int64 `json:"height"`
  140. Time time.Time `json:"time"`
  141. NumTxs int64 `json:"num_txs"`
  142. // prev block info
  143. LastBlockID BlockID `json:"last_block_id"`
  144. TotalTxs int64 `json:"total_txs"`
  145. // hashes of block data
  146. LastCommitHash data.Bytes `json:"last_commit_hash"` // commit from validators from the last block
  147. DataHash data.Bytes `json:"data_hash"` // transactions
  148. // hashes from the app output from the prev block
  149. ValidatorsHash data.Bytes `json:"validators_hash"` // validators for the current block
  150. ConsensusHash data.Bytes `json:"consensus_hash"` // consensus params for current block
  151. AppHash data.Bytes `json:"app_hash"` // state after txs from the previous block
  152. LastResultsHash data.Bytes `json:"last_results_hash"` // root hash of all results from the txs from the previous block
  153. // consensus info
  154. EvidenceHash data.Bytes `json:"evidence_hash"` // evidence included in the block
  155. }
  156. // Hash returns the hash of the header.
  157. // Returns nil if ValidatorHash is missing.
  158. func (h *Header) Hash() data.Bytes {
  159. if len(h.ValidatorsHash) == 0 {
  160. return nil
  161. }
  162. return merkle.SimpleHashFromMap(map[string]interface{}{
  163. "ChainID": h.ChainID,
  164. "Height": h.Height,
  165. "Time": h.Time,
  166. "NumTxs": h.NumTxs,
  167. "TotalTxs": h.TotalTxs,
  168. "LastBlockID": h.LastBlockID,
  169. "LastCommit": h.LastCommitHash,
  170. "Data": h.DataHash,
  171. "Validators": h.ValidatorsHash,
  172. "App": h.AppHash,
  173. "Consensus": h.ConsensusHash,
  174. "Results": h.LastResultsHash,
  175. "Evidence": h.EvidenceHash,
  176. })
  177. }
  178. // StringIndented returns a string representation of the header
  179. func (h *Header) StringIndented(indent string) string {
  180. if h == nil {
  181. return "nil-Header"
  182. }
  183. return fmt.Sprintf(`Header{
  184. %s ChainID: %v
  185. %s Height: %v
  186. %s Time: %v
  187. %s NumTxs: %v
  188. %s TotalTxs: %v
  189. %s LastBlockID: %v
  190. %s LastCommit: %v
  191. %s Data: %v
  192. %s Validators: %v
  193. %s App: %v
  194. %s Conensus: %v
  195. %s Results: %v
  196. %s Evidence: %v
  197. %s}#%v`,
  198. indent, h.ChainID,
  199. indent, h.Height,
  200. indent, h.Time,
  201. indent, h.NumTxs,
  202. indent, h.TotalTxs,
  203. indent, h.LastBlockID,
  204. indent, h.LastCommitHash,
  205. indent, h.DataHash,
  206. indent, h.ValidatorsHash,
  207. indent, h.AppHash,
  208. indent, h.ConsensusHash,
  209. indent, h.LastResultsHash,
  210. indent, h.EvidenceHash,
  211. indent, h.Hash())
  212. }
  213. //-------------------------------------
  214. // Commit contains the evidence that a block was committed by a set of validators.
  215. // NOTE: Commit is empty for height 1, but never nil.
  216. type Commit struct {
  217. // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order.
  218. // Any peer with a block can gossip precommits by index with a peer without recalculating the
  219. // active ValidatorSet.
  220. BlockID BlockID `json:"blockID"`
  221. Precommits []*Vote `json:"precommits"`
  222. // Volatile
  223. firstPrecommit *Vote
  224. hash data.Bytes
  225. bitArray *cmn.BitArray
  226. }
  227. // FirstPrecommit returns the first non-nil precommit in the commit
  228. func (commit *Commit) FirstPrecommit() *Vote {
  229. if len(commit.Precommits) == 0 {
  230. return nil
  231. }
  232. if commit.firstPrecommit != nil {
  233. return commit.firstPrecommit
  234. }
  235. for _, precommit := range commit.Precommits {
  236. if precommit != nil {
  237. commit.firstPrecommit = precommit
  238. return precommit
  239. }
  240. }
  241. return nil
  242. }
  243. // Height returns the height of the commit
  244. func (commit *Commit) Height() int64 {
  245. if len(commit.Precommits) == 0 {
  246. return 0
  247. }
  248. return commit.FirstPrecommit().Height
  249. }
  250. // Round returns the round of the commit
  251. func (commit *Commit) Round() int {
  252. if len(commit.Precommits) == 0 {
  253. return 0
  254. }
  255. return commit.FirstPrecommit().Round
  256. }
  257. // Type returns the vote type of the commit, which is always VoteTypePrecommit
  258. func (commit *Commit) Type() byte {
  259. return VoteTypePrecommit
  260. }
  261. // Size returns the number of votes in the commit
  262. func (commit *Commit) Size() int {
  263. if commit == nil {
  264. return 0
  265. }
  266. return len(commit.Precommits)
  267. }
  268. // BitArray returns a BitArray of which validators voted in this commit
  269. func (commit *Commit) BitArray() *cmn.BitArray {
  270. if commit.bitArray == nil {
  271. commit.bitArray = cmn.NewBitArray(len(commit.Precommits))
  272. for i, precommit := range commit.Precommits {
  273. // TODO: need to check the BlockID otherwise we could be counting conflicts,
  274. // not just the one with +2/3 !
  275. commit.bitArray.SetIndex(i, precommit != nil)
  276. }
  277. }
  278. return commit.bitArray
  279. }
  280. // GetByIndex returns the vote corresponding to a given validator index
  281. func (commit *Commit) GetByIndex(index int) *Vote {
  282. return commit.Precommits[index]
  283. }
  284. // IsCommit returns true if there is at least one vote
  285. func (commit *Commit) IsCommit() bool {
  286. return len(commit.Precommits) != 0
  287. }
  288. // ValidateBasic performs basic validation that doesn't involve state data.
  289. func (commit *Commit) ValidateBasic() error {
  290. if commit.BlockID.IsZero() {
  291. return errors.New("Commit cannot be for nil block")
  292. }
  293. if len(commit.Precommits) == 0 {
  294. return errors.New("No precommits in commit")
  295. }
  296. height, round := commit.Height(), commit.Round()
  297. // validate the precommits
  298. for _, precommit := range commit.Precommits {
  299. // It's OK for precommits to be missing.
  300. if precommit == nil {
  301. continue
  302. }
  303. // Ensure that all votes are precommits
  304. if precommit.Type != VoteTypePrecommit {
  305. return fmt.Errorf("Invalid commit vote. Expected precommit, got %v",
  306. precommit.Type)
  307. }
  308. // Ensure that all heights are the same
  309. if precommit.Height != height {
  310. return fmt.Errorf("Invalid commit precommit height. Expected %v, got %v",
  311. height, precommit.Height)
  312. }
  313. // Ensure that all rounds are the same
  314. if precommit.Round != round {
  315. return fmt.Errorf("Invalid commit precommit round. Expected %v, got %v",
  316. round, precommit.Round)
  317. }
  318. }
  319. return nil
  320. }
  321. // Hash returns the hash of the commit
  322. func (commit *Commit) Hash() data.Bytes {
  323. if commit.hash == nil {
  324. bs := make([]interface{}, len(commit.Precommits))
  325. for i, precommit := range commit.Precommits {
  326. bs[i] = precommit
  327. }
  328. commit.hash = merkle.SimpleHashFromBinaries(bs)
  329. }
  330. return commit.hash
  331. }
  332. // StringIndented returns a string representation of the commit
  333. func (commit *Commit) StringIndented(indent string) string {
  334. if commit == nil {
  335. return "nil-Commit"
  336. }
  337. precommitStrings := make([]string, len(commit.Precommits))
  338. for i, precommit := range commit.Precommits {
  339. precommitStrings[i] = precommit.String()
  340. }
  341. return fmt.Sprintf(`Commit{
  342. %s BlockID: %v
  343. %s Precommits: %v
  344. %s}#%v`,
  345. indent, commit.BlockID,
  346. indent, strings.Join(precommitStrings, "\n"+indent+" "),
  347. indent, commit.hash)
  348. }
  349. //-----------------------------------------------------------------------------
  350. // SignedHeader is a header along with the commits that prove it
  351. type SignedHeader struct {
  352. Header *Header `json:"header"`
  353. Commit *Commit `json:"commit"`
  354. }
  355. //-----------------------------------------------------------------------------
  356. // Data contains the set of transactions included in the block
  357. type Data struct {
  358. // Txs that will be applied by state @ block.Height+1.
  359. // NOTE: not all txs here are valid. We're just agreeing on the order first.
  360. // This means that block.AppHash does not include these txs.
  361. Txs Txs `json:"txs"`
  362. // Volatile
  363. hash data.Bytes
  364. }
  365. // Hash returns the hash of the data
  366. func (data *Data) Hash() data.Bytes {
  367. if data.hash == nil {
  368. data.hash = data.Txs.Hash() // NOTE: leaves of merkle tree are TxIDs
  369. }
  370. return data.hash
  371. }
  372. // StringIndented returns a string representation of the transactions
  373. func (data *Data) StringIndented(indent string) string {
  374. if data == nil {
  375. return "nil-Data"
  376. }
  377. txStrings := make([]string, cmn.MinInt(len(data.Txs), 21))
  378. for i, tx := range data.Txs {
  379. if i == 20 {
  380. txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  381. break
  382. }
  383. txStrings[i] = fmt.Sprintf("Tx:%v", tx)
  384. }
  385. return fmt.Sprintf(`Data{
  386. %s %v
  387. %s}#%v`,
  388. indent, strings.Join(txStrings, "\n"+indent+" "),
  389. indent, data.hash)
  390. }
  391. //-----------------------------------------------------------------------------
  392. // EvidenceData contains any evidence of malicious wrong-doing by validators
  393. type EvidenceData struct {
  394. // TODO: FIXME
  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. }