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