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.

342 lines
7.9 KiB

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