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.

370 lines
9.4 KiB

10 years ago
10 years ago
10 years ago
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. "strings"
  7. "time"
  8. . "github.com/tendermint/go-common"
  9. "github.com/tendermint/go-merkle"
  10. "github.com/tendermint/go-wire"
  11. )
  12. const MaxBlockSize = 22020096 // 21MB TODO make it configurable
  13. type Block struct {
  14. *Header `json:"header"`
  15. *Data `json:"data"`
  16. LastValidation *Validation `json:"last_validation"`
  17. }
  18. // Basic validation that doesn't involve state data.
  19. func (b *Block) ValidateBasic(chainID string, lastBlockHeight int, lastBlockHash []byte,
  20. lastBlockParts PartSetHeader, lastBlockTime time.Time, appHash []byte) error {
  21. if b.ChainID != chainID {
  22. return errors.New(Fmt("Wrong Block.Header.ChainID. Expected %v, got %v", chainID, b.ChainID))
  23. }
  24. if b.Height != lastBlockHeight+1 {
  25. return errors.New(Fmt("Wrong Block.Header.Height. Expected %v, got %v", lastBlockHeight+1, b.Height))
  26. }
  27. /* TODO: Determine bounds for Time
  28. See blockchain/reactor "stopSyncingDurationMinutes"
  29. if !b.Time.After(lastBlockTime) {
  30. return errors.New("Invalid Block.Header.Time")
  31. }
  32. */
  33. // TODO: validate Fees
  34. if b.NumTxs != len(b.Data.Txs) {
  35. return errors.New(Fmt("Wrong Block.Header.NumTxs. Expected %v, got %v", len(b.Data.Txs), b.NumTxs))
  36. }
  37. if !bytes.Equal(b.LastBlockHash, lastBlockHash) {
  38. return errors.New(Fmt("Wrong Block.Header.LastBlockHash. Expected %X, got %X", lastBlockHash, b.LastBlockHash))
  39. }
  40. if !b.LastBlockParts.Equals(lastBlockParts) {
  41. return errors.New(Fmt("Wrong Block.Header.LastBlockParts. Expected %v, got %v", lastBlockParts, b.LastBlockParts))
  42. }
  43. if !bytes.Equal(b.LastValidationHash, b.LastValidation.Hash()) {
  44. return errors.New(Fmt("Wrong Block.Header.LastValidationHash. Expected %X, got %X", b.LastValidationHash, b.LastValidation.Hash()))
  45. }
  46. if b.Header.Height != 1 {
  47. if err := b.LastValidation.ValidateBasic(); err != nil {
  48. return err
  49. }
  50. }
  51. if !bytes.Equal(b.DataHash, b.Data.Hash()) {
  52. return errors.New(Fmt("Wrong Block.Header.DataHash. Expected %X, got %X", b.DataHash, b.Data.Hash()))
  53. }
  54. if !bytes.Equal(b.AppHash, appHash) {
  55. return errors.New(Fmt("Wrong Block.Header.AppHash. Expected %X, got %X", appHash, b.AppHash))
  56. }
  57. // NOTE: the AppHash and ValidatorsHash are validated later.
  58. return nil
  59. }
  60. func (b *Block) FillHeader() {
  61. if b.LastValidationHash == nil {
  62. b.LastValidationHash = b.LastValidation.Hash()
  63. }
  64. if b.DataHash == nil {
  65. b.DataHash = b.Data.Hash()
  66. }
  67. }
  68. // Computes and returns the block hash.
  69. // If the block is incomplete, block hash is nil for safety.
  70. func (b *Block) Hash() []byte {
  71. if b.Header == nil || b.Data == nil || b.LastValidation == nil {
  72. return nil
  73. }
  74. b.FillHeader()
  75. return b.Header.Hash()
  76. }
  77. func (b *Block) MakePartSet() *PartSet {
  78. return NewPartSetFromData(wire.BinaryBytes(b))
  79. }
  80. // Convenience.
  81. // A nil block never hashes to anything.
  82. // Nothing hashes to a nil hash.
  83. func (b *Block) HashesTo(hash []byte) bool {
  84. if len(hash) == 0 {
  85. return false
  86. }
  87. if b == nil {
  88. return false
  89. }
  90. return bytes.Equal(b.Hash(), hash)
  91. }
  92. func (b *Block) String() string {
  93. return b.StringIndented("")
  94. }
  95. func (b *Block) StringIndented(indent string) string {
  96. if b == nil {
  97. return "nil-Block"
  98. }
  99. return fmt.Sprintf(`Block{
  100. %s %v
  101. %s %v
  102. %s %v
  103. %s}#%X`,
  104. indent, b.Header.StringIndented(indent+" "),
  105. indent, b.Data.StringIndented(indent+" "),
  106. indent, b.LastValidation.StringIndented(indent+" "),
  107. indent, b.Hash())
  108. }
  109. func (b *Block) StringShort() string {
  110. if b == nil {
  111. return "nil-Block"
  112. } else {
  113. return fmt.Sprintf("Block#%X", b.Hash())
  114. }
  115. }
  116. //-----------------------------------------------------------------------------
  117. type Header struct {
  118. ChainID string `json:"chain_id"`
  119. Height int `json:"height"`
  120. Time time.Time `json:"time"`
  121. Fees int64 `json:"fees"`
  122. NumTxs int `json:"num_txs"`
  123. LastBlockHash []byte `json:"last_block_hash"`
  124. LastBlockParts PartSetHeader `json:"last_block_parts"`
  125. LastValidationHash []byte `json:"last_validation_hash"`
  126. DataHash []byte `json:"data_hash"`
  127. ValidatorsHash []byte `json:"validators_hash"`
  128. AppHash []byte `json:"app_hash"` // state merkle root of txs from the previous block
  129. }
  130. // NOTE: hash is nil if required fields are missing.
  131. func (h *Header) Hash() []byte {
  132. if len(h.ValidatorsHash) == 0 {
  133. return nil
  134. }
  135. return merkle.SimpleHashFromMap(map[string]interface{}{
  136. "ChainID": h.ChainID,
  137. "Height": h.Height,
  138. "Time": h.Time,
  139. "Fees": h.Fees,
  140. "NumTxs": h.NumTxs,
  141. "LastBlock": h.LastBlockHash,
  142. "LastBlockParts": h.LastBlockParts,
  143. "LastValidation": h.LastValidationHash,
  144. "Data": h.DataHash,
  145. "Validators": h.ValidatorsHash,
  146. "App": h.AppHash,
  147. })
  148. }
  149. func (h *Header) StringIndented(indent string) string {
  150. if h == nil {
  151. return "nil-Header"
  152. }
  153. return fmt.Sprintf(`Header{
  154. %s ChainID: %v
  155. %s Height: %v
  156. %s Time: %v
  157. %s Fees: %v
  158. %s NumTxs: %v
  159. %s LastBlock: %X
  160. %s LastBlockParts: %v
  161. %s LastValidation: %X
  162. %s Data: %X
  163. %s Validators: %X
  164. %s App: %X
  165. %s}#%X`,
  166. indent, h.ChainID,
  167. indent, h.Height,
  168. indent, h.Time,
  169. indent, h.Fees,
  170. indent, h.NumTxs,
  171. indent, h.LastBlockHash,
  172. indent, h.LastBlockParts,
  173. indent, h.LastValidationHash,
  174. indent, h.DataHash,
  175. indent, h.ValidatorsHash,
  176. indent, h.AppHash,
  177. indent, h.Hash())
  178. }
  179. //-------------------------------------
  180. // NOTE: Validation is empty for height 1, but never nil.
  181. type Validation struct {
  182. // NOTE: The Precommits are in order of address to preserve the bonded ValidatorSet order.
  183. // Any peer with a block can gossip precommits by index with a peer without recalculating the
  184. // active ValidatorSet.
  185. Precommits []*Vote `json:"precommits"`
  186. // Volatile
  187. firstPrecommit *Vote
  188. hash []byte
  189. bitArray *BitArray
  190. }
  191. func (v *Validation) FirstPrecommit() *Vote {
  192. if len(v.Precommits) == 0 {
  193. return nil
  194. }
  195. if v.firstPrecommit != nil {
  196. return v.firstPrecommit
  197. }
  198. for _, precommit := range v.Precommits {
  199. if precommit != nil {
  200. v.firstPrecommit = precommit
  201. return precommit
  202. }
  203. }
  204. return nil
  205. }
  206. func (v *Validation) Height() int {
  207. if len(v.Precommits) == 0 {
  208. return 0
  209. }
  210. return v.FirstPrecommit().Height
  211. }
  212. func (v *Validation) Round() int {
  213. if len(v.Precommits) == 0 {
  214. return 0
  215. }
  216. return v.FirstPrecommit().Round
  217. }
  218. func (v *Validation) Type() byte {
  219. return VoteTypePrecommit
  220. }
  221. func (v *Validation) Size() int {
  222. if v == nil {
  223. return 0
  224. }
  225. return len(v.Precommits)
  226. }
  227. func (v *Validation) BitArray() *BitArray {
  228. if v.bitArray == nil {
  229. v.bitArray = NewBitArray(len(v.Precommits))
  230. for i, precommit := range v.Precommits {
  231. v.bitArray.SetIndex(i, precommit != nil)
  232. }
  233. }
  234. return v.bitArray
  235. }
  236. func (v *Validation) GetByIndex(index int) *Vote {
  237. return v.Precommits[index]
  238. }
  239. func (v *Validation) IsCommit() bool {
  240. if len(v.Precommits) == 0 {
  241. return false
  242. }
  243. return true
  244. }
  245. func (v *Validation) ValidateBasic() error {
  246. if len(v.Precommits) == 0 {
  247. return errors.New("No precommits in validation")
  248. }
  249. height, round := v.Height(), v.Round()
  250. for _, precommit := range v.Precommits {
  251. // It's OK for precommits to be missing.
  252. if precommit == nil {
  253. continue
  254. }
  255. // Ensure that all votes are precommits
  256. if precommit.Type != VoteTypePrecommit {
  257. return fmt.Errorf("Invalid validation vote. Expected precommit, got %v",
  258. precommit.Type)
  259. }
  260. // Ensure that all heights are the same
  261. if precommit.Height != height {
  262. return fmt.Errorf("Invalid validation precommit height. Expected %v, got %v",
  263. height, precommit.Height)
  264. }
  265. // Ensure that all rounds are the same
  266. if precommit.Round != round {
  267. return fmt.Errorf("Invalid validation precommit round. Expected %v, got %v",
  268. round, precommit.Round)
  269. }
  270. }
  271. return nil
  272. }
  273. func (v *Validation) Hash() []byte {
  274. if v.hash == nil {
  275. bs := make([]interface{}, len(v.Precommits))
  276. for i, precommit := range v.Precommits {
  277. bs[i] = precommit
  278. }
  279. v.hash = merkle.SimpleHashFromBinaries(bs)
  280. }
  281. return v.hash
  282. }
  283. func (v *Validation) StringIndented(indent string) string {
  284. if v == nil {
  285. return "nil-Validation"
  286. }
  287. precommitStrings := make([]string, len(v.Precommits))
  288. for i, precommit := range v.Precommits {
  289. precommitStrings[i] = precommit.String()
  290. }
  291. return fmt.Sprintf(`Validation{
  292. %s Precommits: %v
  293. %s}#%X`,
  294. indent, strings.Join(precommitStrings, "\n"+indent+" "),
  295. indent, v.hash)
  296. }
  297. //-----------------------------------------------------------------------------
  298. type Data struct {
  299. // Txs that will be applied by state @ block.Height+1.
  300. // NOTE: not all txs here are valid. We're just agreeing on the order first.
  301. // This means that block.AppHash does not include these txs.
  302. Txs []Tx `json:"txs"`
  303. // Volatile
  304. hash []byte
  305. }
  306. func (data *Data) Hash() []byte {
  307. if data.hash == nil {
  308. txs := make([]interface{}, len(data.Txs))
  309. for i, tx := range data.Txs {
  310. txs[i] = tx
  311. }
  312. data.hash = merkle.SimpleHashFromBinaries(txs) // NOTE: leaves are TxIDs.
  313. }
  314. return data.hash
  315. }
  316. func (data *Data) StringIndented(indent string) string {
  317. if data == nil {
  318. return "nil-Data"
  319. }
  320. txStrings := make([]string, MinInt(len(data.Txs), 21))
  321. for i, tx := range data.Txs {
  322. if i == 20 {
  323. txStrings[i] = fmt.Sprintf("... (%v total)", len(data.Txs))
  324. break
  325. }
  326. txStrings[i] = fmt.Sprintf("Tx:%v", tx)
  327. }
  328. return fmt.Sprintf(`Data{
  329. %s %v
  330. %s}#%X`,
  331. indent, strings.Join(txStrings, "\n"+indent+" "),
  332. indent, data.hash)
  333. }