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.

281 lines
6.2 KiB

11 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
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
10 years ago
11 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/config"
  13. "github.com/tendermint/tendermint/merkle"
  14. )
  15. type Block struct {
  16. *Header
  17. *Validation
  18. *Data
  19. }
  20. // Basic validation that doesn't involve state data.
  21. func (b *Block) ValidateBasic(lastBlockHeight uint, lastBlockHash []byte,
  22. lastBlockParts PartSetHeader, lastBlockTime time.Time) error {
  23. if b.Network != config.App().GetString("Network") {
  24. return errors.New("Wrong Block.Header.Network")
  25. }
  26. if b.Height != lastBlockHeight+1 {
  27. return errors.New("Wrong Block.Header.Height")
  28. }
  29. if b.NumTxs != uint(len(b.Data.Txs)) {
  30. return errors.New("Wrong Block.Header.NumTxs")
  31. }
  32. if !bytes.Equal(b.LastBlockHash, lastBlockHash) {
  33. return errors.New("Wrong Block.Header.LastBlockHash")
  34. }
  35. if !b.LastBlockParts.Equals(lastBlockParts) {
  36. return errors.New("Wrong Block.Header.LastBlockParts")
  37. }
  38. /* TODO: Determine bounds.
  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.Validation.ValidateBasic(); err != nil {
  45. return err
  46. }
  47. }
  48. // XXX more validation
  49. return nil
  50. }
  51. func (b *Block) Hash() []byte {
  52. if b.Header == nil || b.Validation == nil || b.Data == nil {
  53. return nil
  54. }
  55. hashes := [][]byte{
  56. b.Header.Hash(),
  57. b.Validation.Hash(),
  58. b.Data.Hash(),
  59. }
  60. // Merkle hash from sub-hashes.
  61. return merkle.HashFromHashes(hashes)
  62. }
  63. // Convenience.
  64. // A nil block never hashes to anything.
  65. // Nothing hashes to a nil hash.
  66. func (b *Block) HashesTo(hash []byte) bool {
  67. if len(hash) == 0 {
  68. return false
  69. }
  70. if b == nil {
  71. return false
  72. }
  73. return bytes.Equal(b.Hash(), hash)
  74. }
  75. func (b *Block) String() string {
  76. return b.StringIndented("")
  77. }
  78. func (b *Block) StringIndented(indent string) string {
  79. if b == nil {
  80. return "nil-Block"
  81. }
  82. return fmt.Sprintf(`Block{
  83. %s %v
  84. %s %v
  85. %s %v
  86. %s}#%X`,
  87. indent, b.Header.StringIndented(indent+" "),
  88. indent, b.Validation.StringIndented(indent+" "),
  89. indent, b.Data.StringIndented(indent+" "),
  90. indent, b.Hash())
  91. }
  92. func (b *Block) StringShort() string {
  93. if b == nil {
  94. return "nil-Block"
  95. } else {
  96. return fmt.Sprintf("Block#%X", b.Hash())
  97. }
  98. }
  99. //-----------------------------------------------------------------------------
  100. type Header struct {
  101. Network string
  102. Height uint
  103. Time time.Time
  104. Fees uint64
  105. NumTxs uint
  106. LastBlockHash []byte
  107. LastBlockParts PartSetHeader
  108. StateHash []byte
  109. }
  110. func (h *Header) Hash() []byte {
  111. buf := new(bytes.Buffer)
  112. hasher, n, err := sha256.New(), new(int64), new(error)
  113. binary.WriteBinary(h, buf, n, err)
  114. if *err != nil {
  115. panic(err)
  116. }
  117. hasher.Write(buf.Bytes())
  118. hash := hasher.Sum(nil)
  119. return hash
  120. }
  121. func (h *Header) StringIndented(indent string) string {
  122. if h == nil {
  123. return "nil-Header"
  124. }
  125. return fmt.Sprintf(`Header{
  126. %s Network: %v
  127. %s Height: %v
  128. %s Time: %v
  129. %s Fees: %v
  130. %s NumTxs: %v
  131. %s LastBlockHash: %X
  132. %s LastBlockParts: %v
  133. %s StateHash: %X
  134. %s}#%X`,
  135. indent, h.Network,
  136. indent, h.Height,
  137. indent, h.Time,
  138. indent, h.Fees,
  139. indent, h.NumTxs,
  140. indent, h.LastBlockHash,
  141. indent, h.LastBlockParts,
  142. indent, h.StateHash,
  143. indent, h.Hash())
  144. }
  145. //-----------------------------------------------------------------------------
  146. type Commit struct {
  147. Address []byte
  148. Round uint
  149. Signature account.SignatureEd25519
  150. }
  151. func (commit Commit) IsZero() bool {
  152. return commit.Round == 0 && commit.Signature.IsZero()
  153. }
  154. func (commit Commit) String() string {
  155. return fmt.Sprintf("Commit{A:%X R:%v %X}", commit.Address, commit.Round, Fingerprint(commit.Signature))
  156. }
  157. //-------------------------------------
  158. // NOTE: The Commits are in order of address to preserve the bonded ValidatorSet order.
  159. // Any peer with a block can gossip commits by index with a peer without recalculating the
  160. // active ValidatorSet.
  161. type Validation struct {
  162. Commits []Commit // Commits (or nil) of all active validators in address order.
  163. // Volatile
  164. hash []byte
  165. bitArray BitArray
  166. }
  167. func (v *Validation) ValidateBasic() error {
  168. if len(v.Commits) == 0 {
  169. return errors.New("No commits in validation")
  170. }
  171. lastAddress := []byte{}
  172. for i := 0; i < len(v.Commits); i++ {
  173. commit := v.Commits[i]
  174. if commit.IsZero() {
  175. if len(commit.Address) > 0 {
  176. return errors.New("Zero commits should not have an address")
  177. }
  178. } else {
  179. if len(commit.Address) == 0 {
  180. return errors.New("Nonzero commits should have an address")
  181. }
  182. if len(lastAddress) > 0 && bytes.Compare(lastAddress, commit.Address) != -1 {
  183. return errors.New("Invalid commit order")
  184. }
  185. lastAddress = commit.Address
  186. }
  187. }
  188. return nil
  189. }
  190. func (v *Validation) Hash() []byte {
  191. if v.hash == nil {
  192. bs := make([]interface{}, len(v.Commits))
  193. for i, commit := range v.Commits {
  194. bs[i] = commit
  195. }
  196. v.hash = merkle.HashFromBinaries(bs)
  197. }
  198. return v.hash
  199. }
  200. func (v *Validation) StringIndented(indent string) string {
  201. if v == nil {
  202. return "nil-Validation"
  203. }
  204. commitStrings := make([]string, len(v.Commits))
  205. for i, commit := range v.Commits {
  206. commitStrings[i] = commit.String()
  207. }
  208. return fmt.Sprintf(`Validation{
  209. %s %v
  210. %s}#%X`,
  211. indent, strings.Join(commitStrings, "\n"+indent+" "),
  212. indent, v.hash)
  213. }
  214. func (v *Validation) BitArray() BitArray {
  215. if v.bitArray.IsZero() {
  216. v.bitArray = NewBitArray(uint(len(v.Commits)))
  217. for i, commit := range v.Commits {
  218. v.bitArray.SetIndex(uint(i), !commit.IsZero())
  219. }
  220. }
  221. return v.bitArray
  222. }
  223. //-----------------------------------------------------------------------------
  224. type Data struct {
  225. Txs []Tx
  226. // Volatile
  227. hash []byte
  228. }
  229. func (data *Data) Hash() []byte {
  230. if data.hash == nil {
  231. bs := make([]interface{}, len(data.Txs))
  232. for i, tx := range data.Txs {
  233. bs[i] = tx
  234. }
  235. data.hash = merkle.HashFromBinaries(bs)
  236. }
  237. return data.hash
  238. }
  239. func (data *Data) StringIndented(indent string) string {
  240. if data == nil {
  241. return "nil-Data"
  242. }
  243. txStrings := make([]string, len(data.Txs))
  244. for i, tx := range data.Txs {
  245. txStrings[i] = fmt.Sprintf("Tx:%v", tx)
  246. }
  247. return fmt.Sprintf(`Data{
  248. %s %v
  249. %s}#%X`,
  250. indent, strings.Join(txStrings, "\n"+indent+" "),
  251. indent, data.hash)
  252. }