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 }