github.com/tendermint/tmlibs@v0.9.0/merkle/simple_tree.go (about)

     1  /*
     2  Computes a deterministic minimal height merkle tree hash.
     3  If the number of items is not a power of two, some leaves
     4  will be at different levels. Tries to keep both sides of
     5  the tree the same size, but the left may be one greater.
     6  
     7  Use this for short deterministic trees, such as the validator list.
     8  For larger datasets, use IAVLTree.
     9  
    10                          *
    11                         / \
    12                       /     \
    13                     /         \
    14                   /             \
    15                  *               *
    16                 / \             / \
    17                /   \           /   \
    18               /     \         /     \
    19              *       *       *       h6
    20             / \     / \     / \
    21            h0  h1  h2  h3  h4  h5
    22  
    23  */
    24  
    25  package merkle
    26  
    27  import (
    28  	"github.com/tendermint/tmlibs/merkle/tmhash"
    29  )
    30  
    31  func SimpleHashFromTwoHashes(left []byte, right []byte) []byte {
    32  	var hasher = tmhash.New()
    33  	err := encodeByteSlice(hasher, left)
    34  	if err != nil {
    35  		panic(err)
    36  	}
    37  	err = encodeByteSlice(hasher, right)
    38  	if err != nil {
    39  		panic(err)
    40  	}
    41  	return hasher.Sum(nil)
    42  }
    43  
    44  func SimpleHashFromHashes(hashes [][]byte) []byte {
    45  	// Recursive impl.
    46  	switch len(hashes) {
    47  	case 0:
    48  		return nil
    49  	case 1:
    50  		return hashes[0]
    51  	default:
    52  		left := SimpleHashFromHashes(hashes[:(len(hashes)+1)/2])
    53  		right := SimpleHashFromHashes(hashes[(len(hashes)+1)/2:])
    54  		return SimpleHashFromTwoHashes(left, right)
    55  	}
    56  }
    57  
    58  // NOTE: Do not implement this, use SimpleHashFromByteslices instead.
    59  // type Byteser interface { Bytes() []byte }
    60  // func SimpleHashFromBytesers(items []Byteser) []byte { ... }
    61  
    62  func SimpleHashFromByteslices(bzs [][]byte) []byte {
    63  	hashes := make([][]byte, len(bzs))
    64  	for i, bz := range bzs {
    65  		hashes[i] = SimpleHashFromBytes(bz)
    66  	}
    67  	return SimpleHashFromHashes(hashes)
    68  }
    69  
    70  func SimpleHashFromBytes(bz []byte) []byte {
    71  	hasher := tmhash.New()
    72  	hasher.Write(bz)
    73  	return hasher.Sum(nil)
    74  }
    75  
    76  func SimpleHashFromHashers(items []Hasher) []byte {
    77  	hashes := make([][]byte, len(items))
    78  	for i, item := range items {
    79  		hash := item.Hash()
    80  		hashes[i] = hash
    81  	}
    82  	return SimpleHashFromHashes(hashes)
    83  }
    84  
    85  func SimpleHashFromMap(m map[string]Hasher) []byte {
    86  	sm := NewSimpleMap()
    87  	for k, v := range m {
    88  		sm.Set(k, v)
    89  	}
    90  	return sm.Hash()
    91  }