# `tendermint/block` ## Block TODO: document ### Header ### Validation ### Data ## PartSet PartSet is used to split a byteslice of data into parts (pieces) for transmission. By splitting data into smaller parts and computing a Merkle root hash on the list, you can verify that a part is legitimately part of the complete data, and the part can be forwarded to other peers before all the parts are known. In short, it's a fast way to propagate a large file over a gossip network. PartSet was inspired by the LibSwift project. Usage: ```Go data := RandBytes(2 << 20) // Something large partSet := NewPartSetFromData(data) partSet.Total() // Total number of 4KB parts partSet.Count() // Equal to the Total, since we already have all the parts partSet.Hash() // The Merkle root hash partSet.BitArray() // A BitArray of partSet.Total() 1's header := partSet.Header() // Send this to the peer header.Total // Total number of parts header.Hash // The merkle root hash // Now we'll reconstruct the data from the parts partSet2 := NewPartSetFromHeader(header) partSet2.Total() // Same total as partSet.Total() partSet2.Count() // Zero, since this PartSet doesn't have any parts yet. partSet2.Hash() // Same hash as in partSet.Hash() partSet2.BitArray() // A BitArray of partSet.Total() 0's // In a gossip network the parts would arrive in arbitrary order, perhaps // in response to explicit requests for parts, or optimistically in response // to the receiving peer's partSet.BitArray(). for !partSet2.IsComplete() { part := receivePartFromGossipNetwork() added, err := partSet2.AddPart(part) if err != nil { // A wrong part, // the merkle trail does not hash to partSet2.Hash() } else if !added { // A duplicate part already received } } data2, _ := ioutil.ReadAll(partSet2.GetReader()) bytes.Equal(data, data2) // true ```