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.

276 lines
5.9 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
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 blocks
  2. import (
  3. "bytes"
  4. "crypto/sha256"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "strings"
  9. "time"
  10. . "github.com/tendermint/tendermint/binary"
  11. . "github.com/tendermint/tendermint/config"
  12. "github.com/tendermint/tendermint/merkle"
  13. )
  14. type Block struct {
  15. Header
  16. Validation
  17. Data
  18. // Volatile
  19. hash []byte
  20. }
  21. func ReadBlock(r io.Reader, n *int64, err *error) *Block {
  22. return &Block{
  23. Header: ReadHeader(r, n, err),
  24. Validation: ReadValidation(r, n, err),
  25. Data: ReadData(r, n, err),
  26. }
  27. }
  28. func (b *Block) WriteTo(w io.Writer) (n int64, err error) {
  29. WriteBinary(w, &b.Header, &n, &err)
  30. WriteBinary(w, &b.Validation, &n, &err)
  31. WriteBinary(w, &b.Data, &n, &err)
  32. return
  33. }
  34. // Basic validation that doesn't involve state data.
  35. func (b *Block) ValidateBasic(lastBlockHeight uint32, lastBlockHash []byte,
  36. lastBlockParts PartSetHeader, lastBlockTime time.Time) error {
  37. if b.Network != Config.Network {
  38. return errors.New("Invalid block network")
  39. }
  40. if b.Height != lastBlockHeight+1 {
  41. return errors.New("Invalid block height")
  42. }
  43. if !bytes.Equal(b.LastBlockHash, lastBlockHash) {
  44. return errors.New("Invalid block hash")
  45. }
  46. if !b.LastBlockParts.Equals(lastBlockParts) {
  47. return errors.New("Invalid block parts header")
  48. }
  49. if !b.Time.After(lastBlockTime) {
  50. return errors.New("Invalid block time")
  51. }
  52. // XXX more validation
  53. return nil
  54. }
  55. func (b *Block) Hash() []byte {
  56. if b.hash == nil {
  57. hashes := [][]byte{
  58. b.Header.Hash(),
  59. b.Validation.Hash(),
  60. b.Data.Hash(),
  61. }
  62. // Merkle hash from sub-hashes.
  63. b.hash = merkle.HashFromHashes(hashes)
  64. }
  65. return b.hash
  66. }
  67. // Convenience.
  68. // A nil block never hashes to anything.
  69. // Nothing hashes to a nil hash.
  70. func (b *Block) HashesTo(hash []byte) bool {
  71. if len(hash) == 0 {
  72. return false
  73. }
  74. if b == nil {
  75. return false
  76. }
  77. return bytes.Equal(b.Hash(), hash)
  78. }
  79. func (b *Block) String() string {
  80. return b.StringWithIndent("")
  81. }
  82. func (b *Block) StringWithIndent(indent string) string {
  83. return fmt.Sprintf(`Block{
  84. %s %v
  85. %s %v
  86. %s %v
  87. %s}#%X`,
  88. indent, b.Header.StringWithIndent(indent+" "),
  89. indent, b.Validation.StringWithIndent(indent+" "),
  90. indent, b.Data.StringWithIndent(indent+" "),
  91. indent, b.hash)
  92. }
  93. func (b *Block) Description() string {
  94. if b == nil {
  95. return "nil-Block"
  96. } else {
  97. return fmt.Sprintf("Block#%X", b.Hash())
  98. }
  99. }
  100. //-----------------------------------------------------------------------------
  101. type Header struct {
  102. Network string
  103. Height uint32
  104. Time time.Time
  105. Fees uint64
  106. LastBlockHash []byte
  107. LastBlockParts PartSetHeader
  108. StateHash []byte
  109. // Volatile
  110. hash []byte
  111. }
  112. func ReadHeader(r io.Reader, n *int64, err *error) (h Header) {
  113. if *err != nil {
  114. return Header{}
  115. }
  116. return Header{
  117. Network: ReadString(r, n, err),
  118. Height: ReadUInt32(r, n, err),
  119. Time: ReadTime(r, n, err),
  120. Fees: ReadUInt64(r, n, err),
  121. LastBlockHash: ReadByteSlice(r, n, err),
  122. LastBlockParts: ReadPartSetHeader(r, n, err),
  123. StateHash: ReadByteSlice(r, n, err),
  124. }
  125. }
  126. func (h *Header) WriteTo(w io.Writer) (n int64, err error) {
  127. WriteString(w, h.Network, &n, &err)
  128. WriteUInt32(w, h.Height, &n, &err)
  129. WriteTime(w, h.Time, &n, &err)
  130. WriteUInt64(w, h.Fees, &n, &err)
  131. WriteByteSlice(w, h.LastBlockHash, &n, &err)
  132. WriteBinary(w, h.LastBlockParts, &n, &err)
  133. WriteByteSlice(w, h.StateHash, &n, &err)
  134. return
  135. }
  136. func (h *Header) Hash() []byte {
  137. if h.hash == nil {
  138. hasher := sha256.New()
  139. _, err := h.WriteTo(hasher)
  140. if err != nil {
  141. panic(err)
  142. }
  143. h.hash = hasher.Sum(nil)
  144. }
  145. return h.hash
  146. }
  147. func (h *Header) StringWithIndent(indent string) string {
  148. return fmt.Sprintf(`Header{
  149. %s Network: %v
  150. %s Height: %v
  151. %s Time: %v
  152. %s Fees: %v
  153. %s LastBlockHash: %X
  154. %s LastBlockParts: %v
  155. %s StateHash: %X
  156. %s}#%X`,
  157. indent, h.Network,
  158. indent, h.Height,
  159. indent, h.Time,
  160. indent, h.Fees,
  161. indent, h.LastBlockHash,
  162. indent, h.LastBlockParts,
  163. indent, h.StateHash,
  164. indent, h.hash)
  165. }
  166. //-----------------------------------------------------------------------------
  167. type Validation struct {
  168. Commits []RoundSignature
  169. // Volatile
  170. hash []byte
  171. }
  172. func ReadValidation(r io.Reader, n *int64, err *error) Validation {
  173. return Validation{
  174. Commits: ReadRoundSignatures(r, n, err),
  175. }
  176. }
  177. func (v *Validation) WriteTo(w io.Writer) (n int64, err error) {
  178. WriteRoundSignatures(w, v.Commits, &n, &err)
  179. return
  180. }
  181. func (v *Validation) Hash() []byte {
  182. if v.hash == nil {
  183. bs := make([]Binary, len(v.Commits))
  184. for i, commit := range v.Commits {
  185. bs[i] = Binary(commit)
  186. }
  187. v.hash = merkle.HashFromBinaries(bs)
  188. }
  189. return v.hash
  190. }
  191. func (v *Validation) StringWithIndent(indent string) string {
  192. commitStrings := make([]string, len(v.Commits))
  193. for i, commit := range v.Commits {
  194. commitStrings[i] = commit.String()
  195. }
  196. return fmt.Sprintf(`Validation{
  197. %s %v
  198. %s}#%X`,
  199. indent, strings.Join(commitStrings, "\n"+indent+" "),
  200. indent, v.hash)
  201. }
  202. //-----------------------------------------------------------------------------
  203. type Data struct {
  204. Txs []Tx
  205. // Volatile
  206. hash []byte
  207. }
  208. func ReadData(r io.Reader, n *int64, err *error) Data {
  209. numTxs := ReadUInt32(r, n, err)
  210. txs := make([]Tx, 0, numTxs)
  211. for i := uint32(0); i < numTxs; i++ {
  212. txs = append(txs, ReadTx(r, n, err))
  213. }
  214. return Data{Txs: txs}
  215. }
  216. func (data *Data) WriteTo(w io.Writer) (n int64, err error) {
  217. WriteUInt32(w, uint32(len(data.Txs)), &n, &err)
  218. for _, tx := range data.Txs {
  219. WriteBinary(w, tx, &n, &err)
  220. }
  221. return
  222. }
  223. func (data *Data) Hash() []byte {
  224. if data.hash == nil {
  225. bs := make([]Binary, len(data.Txs))
  226. for i, tx := range data.Txs {
  227. bs[i] = Binary(tx)
  228. }
  229. data.hash = merkle.HashFromBinaries(bs)
  230. }
  231. return data.hash
  232. }
  233. func (data *Data) StringWithIndent(indent string) string {
  234. txStrings := make([]string, len(data.Txs))
  235. for i, tx := range data.Txs {
  236. txStrings[i] = tx.String()
  237. }
  238. return fmt.Sprintf(`Data{
  239. %s %v
  240. %s}#%X`,
  241. indent, strings.Join(txStrings, "\n"+indent+" "),
  242. indent, data.hash)
  243. }