github.com/Finschia/finschia-sdk@v0.48.1/store/internal/proofs/helpers.go (about)

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