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.

61 lines
1.9 KiB

  1. # `tendermint/block`
  2. ## Block
  3. TODO: document
  4. ### Header
  5. ### Validation
  6. ### Data
  7. ## PartSet
  8. PartSet is used to split a byteslice of data into parts (pieces) for transmission.
  9. By splitting data into smaller parts and computing a Merkle root hash on the list,
  10. you can verify that a part is legitimately part of the complete data, and the
  11. part can be forwarded to other peers before all the parts are known. In short,
  12. it's a fast way to propagate a large file over a gossip network.
  13. PartSet was inspired by the LibSwift project.
  14. Usage:
  15. ```Go
  16. data := RandBytes(2 << 20) // Something large
  17. partSet := NewPartSetFromData(data)
  18. partSet.Total() // Total number of 4KB parts
  19. partSet.Count() // Equal to the Total, since we already have all the parts
  20. partSet.Hash() // The Merkle root hash
  21. partSet.BitArray() // A BitArray of partSet.Total() 1's
  22. header := partSet.Header() // Send this to the peer
  23. header.Total // Total number of parts
  24. header.Hash // The merkle root hash
  25. // Now we'll reconstruct the data from the parts
  26. partSet2 := NewPartSetFromHeader(header)
  27. partSet2.Total() // Same total as partSet.Total()
  28. partSet2.Count() // Zero, since this PartSet doesn't have any parts yet.
  29. partSet2.Hash() // Same hash as in partSet.Hash()
  30. partSet2.BitArray() // A BitArray of partSet.Total() 0's
  31. // In a gossip network the parts would arrive in arbitrary order, perhaps
  32. // in response to explicit requests for parts, or optimistically in response
  33. // to the receiving peer's partSet.BitArray().
  34. for !partSet2.IsComplete() {
  35. part := receivePartFromGossipNetwork()
  36. added, err := partSet2.AddPart(part)
  37. if err != nil {
  38. // A wrong part,
  39. // the merkle trail does not hash to partSet2.Hash()
  40. } else if !added {
  41. // A duplicate part already received
  42. }
  43. }
  44. data2, _ := ioutil.ReadAll(partSet2.GetReader())
  45. bytes.Equal(data, data2) // true
  46. ```