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

     1  package proofs
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/internal/maps"
     7  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/rand"
     8  	"github.com/fibonacci-chain/fbc/libs/tendermint/proto/crypto/merkle"
     9  )
    10  
    11  // SimpleResult contains a merkle.SimpleProof along with all data needed to build the confio/proof
    12  type SimpleResult struct {
    13  	Key      []byte
    14  	Value    []byte
    15  	Proof    *merkle.SimpleProof
    16  	RootHash []byte
    17  }
    18  
    19  // GenerateRangeProof makes a tree of size and returns a range proof for one random element
    20  //
    21  // returns a range proof and the root hash of the tree
    22  func GenerateRangeProof(size int, loc Where) *SimpleResult {
    23  	data := BuildMap(size)
    24  	root, proofs, allkeys := maps.ProofsFromMap(data)
    25  
    26  	key := GetKey(allkeys, loc)
    27  	proof := proofs[key]
    28  
    29  	res := &SimpleResult{
    30  		Key:      []byte(key),
    31  		Value:    toValue(key),
    32  		Proof:    proof,
    33  		RootHash: root,
    34  	}
    35  	return res
    36  }
    37  
    38  // Where selects a location for a key - Left, Right, or Middle
    39  type Where int
    40  
    41  const (
    42  	Left Where = iota
    43  	Right
    44  	Middle
    45  )
    46  
    47  func SortedKeys(data map[string][]byte) []string {
    48  	keys := make([]string, len(data))
    49  	i := 0
    50  	for k := range data {
    51  		keys[i] = k
    52  		i++
    53  	}
    54  	sort.Strings(keys)
    55  	return keys
    56  }
    57  
    58  func CalcRoot(data map[string][]byte) []byte {
    59  	root, _, _ := maps.ProofsFromMap(data)
    60  	return root
    61  }
    62  
    63  // GetKey this returns a key, on Left/Right/Middle
    64  func GetKey(allkeys []string, loc Where) string {
    65  	if loc == Left {
    66  		return allkeys[0]
    67  	}
    68  	if loc == Right {
    69  		return allkeys[len(allkeys)-1]
    70  	}
    71  	// select a random index between 1 and allkeys-2
    72  	idx := rand.Int()%(len(allkeys)-2) + 1
    73  	return allkeys[idx]
    74  }
    75  
    76  // GetNonKey returns a missing key - Left of all, Right of all, or in the Middle
    77  func GetNonKey(allkeys []string, loc Where) string {
    78  	if loc == Left {
    79  		return string([]byte{1, 1, 1, 1})
    80  	}
    81  	if loc == Right {
    82  		return string([]byte{0xff, 0xff, 0xff, 0xff})
    83  	}
    84  	// otherwise, next to an existing key (copy before mod)
    85  	key := GetKey(allkeys, loc)
    86  	key = key[:len(key)-2] + string([]byte{255, 255})
    87  	return key
    88  }
    89  
    90  func toValue(key string) []byte {
    91  	return []byte("value_for_" + key)
    92  }
    93  
    94  // BuildMap creates random key/values and stores in a map,
    95  // returns a list of all keys in sorted order
    96  func BuildMap(size int) map[string][]byte {
    97  	data := make(map[string][]byte)
    98  	// insert lots of info and store the bytes
    99  	for i := 0; i < size; i++ {
   100  		key := rand.Str(20)
   101  		data[key] = toValue(key)
   102  	}
   103  	return data
   104  }