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.

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