github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/store/internal/maps/maps.go (about)

     1  package maps
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/kv"
     7  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/merkle"
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/tmhash"
     9  	merkle2 "github.com/fibonacci-chain/fbc/libs/tendermint/proto/crypto/merkle"
    10  )
    11  
    12  // merkleMap defines a merkle-ized tree from a map. Leave values are treated as
    13  // hash(key) | hash(value). Leaves are sorted before Merkle hashing.
    14  type merkleMap struct {
    15  	kvs    kv.Pairs
    16  	sorted bool
    17  }
    18  
    19  func newMerkleMap() *merkleMap {
    20  	return &merkleMap{
    21  		kvs:    kv.Pairs{},
    22  		sorted: false,
    23  	}
    24  }
    25  
    26  // Set creates a kv.Pair from the provided key and value. The value is hashed prior
    27  // to creating a kv.Pair. The created kv.Pair is appended to the MerkleMap's slice
    28  // of kv.Pairs. Whenever called, the MerkleMap must be resorted.
    29  func (sm *merkleMap) set(key string, value []byte) {
    30  	byteKey := []byte(key)
    31  	assertValidKey(byteKey)
    32  
    33  	sm.sorted = false
    34  
    35  	// The value is hashed, so you can check for equality with a cached value (say)
    36  	// and make a determination to fetch or not.
    37  	vhash := tmhash.Sum(value)
    38  
    39  	sm.kvs.Pairs = append(sm.kvs.Pairs, kv.Pair{
    40  		Key:   byteKey,
    41  		Value: vhash,
    42  	})
    43  }
    44  
    45  // Hash returns the merkle root of items sorted by key. Note, it is unstable.
    46  func (sm *merkleMap) hash() []byte {
    47  	sm.sort()
    48  	return hashKVPairs(sm.kvs)
    49  }
    50  
    51  func (sm *merkleMap) sort() {
    52  	if sm.sorted {
    53  		return
    54  	}
    55  
    56  	sm.kvs.Sort()
    57  	sm.sorted = true
    58  }
    59  
    60  // hashKVPairs hashes a kvPair and creates a merkle tree where the leaves are
    61  // byte slices.
    62  func hashKVPairs(kvs kv.Pairs) []byte {
    63  	kvsH := make([][]byte, len(kvs.Pairs))
    64  	for i, kvp := range kvs.Pairs {
    65  		kvsH[i] = KVPair(kvp).Bytes()
    66  	}
    67  
    68  	return merkle.HashFromByteSlices(kvsH)
    69  }
    70  
    71  // ---------------------------------------------
    72  
    73  // Merkle tree from a map.
    74  // Leaves are `hash(key) | hash(value)`.
    75  // Leaves are sorted before Merkle hashing.
    76  type simpleMap struct {
    77  	Kvs    kv.Pairs
    78  	sorted bool
    79  }
    80  
    81  func newSimpleMap() *simpleMap {
    82  	return &simpleMap{
    83  		Kvs:    kv.Pairs{},
    84  		sorted: false,
    85  	}
    86  }
    87  
    88  // Set creates a kv pair of the key and the hash of the value,
    89  // and then appends it to SimpleMap's kv pairs.
    90  func (sm *simpleMap) Set(key string, value []byte) {
    91  	byteKey := []byte(key)
    92  	assertValidKey(byteKey)
    93  	sm.sorted = false
    94  
    95  	// The value is hashed, so you can
    96  	// check for equality with a cached value (say)
    97  	// and make a determination to fetch or not.
    98  	vhash := tmhash.Sum(value)
    99  
   100  	sm.Kvs.Pairs = append(sm.Kvs.Pairs, kv.Pair{
   101  		Key:   byteKey,
   102  		Value: vhash,
   103  	})
   104  }
   105  
   106  // Hash Merkle root hash of items sorted by key
   107  // (UNSTABLE: and by value too if duplicate key).
   108  func (sm *simpleMap) Hash() []byte {
   109  	sm.Sort()
   110  	return hashKVPairs(sm.Kvs)
   111  }
   112  
   113  func (sm *simpleMap) Sort() {
   114  	if sm.sorted {
   115  		return
   116  	}
   117  	sm.Kvs.Sort()
   118  	sm.sorted = true
   119  }
   120  
   121  // Returns a copy of sorted KVPairs.
   122  // NOTE these contain the hashed key and value.
   123  func (sm *simpleMap) KVPairs() kv.Pairs {
   124  	sm.Sort()
   125  	kvs := kv.Pairs{
   126  		Pairs: make([]kv.Pair, len(sm.Kvs.Pairs)),
   127  	}
   128  
   129  	copy(kvs.Pairs, sm.Kvs.Pairs)
   130  	return kvs
   131  }
   132  
   133  //----------------------------------------
   134  
   135  // A local extension to KVPair that can be hashed.
   136  // Key and value are length prefixed and concatenated,
   137  // then hashed.
   138  type KVPair kv.Pair
   139  
   140  // NewKVPair takes in a key and value and creates a kv.Pair
   141  // wrapped in the local extension KVPair
   142  func NewKVPair(key, value []byte) KVPair {
   143  	return KVPair(kv.Pair{
   144  		Key:   key,
   145  		Value: value,
   146  	})
   147  }
   148  
   149  // Bytes returns key || value, with both the
   150  // key and value length prefixed.
   151  func (kv KVPair) Bytes() []byte {
   152  	// In the worst case:
   153  	// * 8 bytes to Uvarint encode the length of the key
   154  	// * 8 bytes to Uvarint encode the length of the value
   155  	// So preallocate for the worst case, which will in total
   156  	// be a maximum of 14 bytes wasted, if len(key)=1, len(value)=1,
   157  	// but that's going to rare.
   158  	buf := make([]byte, 8+len(kv.Key)+8+len(kv.Value))
   159  
   160  	// Encode the key, prefixed with its length.
   161  	nlk := binary.PutUvarint(buf, uint64(len(kv.Key)))
   162  	nk := copy(buf[nlk:], kv.Key)
   163  
   164  	// Encode the value, prefixing with its length.
   165  	nlv := binary.PutUvarint(buf[nlk+nk:], uint64(len(kv.Value)))
   166  	nv := copy(buf[nlk+nk+nlv:], kv.Value)
   167  
   168  	return buf[:nlk+nk+nlv+nv]
   169  }
   170  
   171  // HashFromMap computes a merkle tree from sorted map and returns the merkle
   172  // root.
   173  func HashFromMap(m map[string][]byte) []byte {
   174  	mm := newMerkleMap()
   175  	for k, v := range m {
   176  		mm.set(k, v)
   177  	}
   178  
   179  	return mm.hash()
   180  }
   181  
   182  // ProofsFromMap generates proofs from a map. The keys/values of the map will be used as the keys/values
   183  // in the underlying key-value pairs.
   184  // The keys are sorted before the proofs are computed.
   185  func ProofsFromMap(m map[string][]byte) ([]byte, map[string]*merkle2.SimpleProof, []string) {
   186  	sm := newSimpleMap()
   187  	for k, v := range m {
   188  		sm.Set(k, v)
   189  	}
   190  
   191  	sm.Sort()
   192  	kvs := sm.Kvs
   193  	kvsBytes := make([][]byte, len(kvs.Pairs))
   194  	for i, kvp := range kvs.Pairs {
   195  		kvsBytes[i] = KVPair(kvp).Bytes()
   196  	}
   197  
   198  	rootHash, proofList := merkle.ProofsFromByteSlices(kvsBytes)
   199  	proofs := make(map[string]*merkle2.SimpleProof)
   200  	keys := make([]string, len(proofList))
   201  
   202  	for i, kvp := range kvs.Pairs {
   203  		proofs[string(kvp.Key)] = proofList[i].ToProto()
   204  		keys[i] = string(kvp.Key)
   205  	}
   206  
   207  	return rootHash, proofs, keys
   208  }
   209  
   210  func assertValidKey(key []byte) {
   211  	if len(key) == 0 {
   212  		panic("key is nil")
   213  	}
   214  }