github.com/onflow/flow-go@v0.33.17/ledger/common/testutils/testutils.go (about) 1 package testutils 2 3 import ( 4 crand "crypto/rand" 5 "encoding/binary" 6 "encoding/hex" 7 "fmt" 8 "math/rand" 9 10 l "github.com/onflow/flow-go/ledger" 11 "github.com/onflow/flow-go/ledger/common/hash" 12 "github.com/onflow/flow-go/ledger/common/utils" 13 ) 14 15 // TrieUpdateFixture returns a trie update fixture 16 func TrieUpdateFixture(n int, minPayloadByteSize int, maxPayloadByteSize int) *l.TrieUpdate { 17 return &l.TrieUpdate{ 18 RootHash: RootHashFixture(), 19 Paths: RandomPaths(n), 20 Payloads: RandomPayloads(n, minPayloadByteSize, maxPayloadByteSize), 21 } 22 } 23 24 // QueryFixture returns a query fixture 25 func QueryFixture() *l.Query { 26 scBytes, _ := hex.DecodeString("6a7a565add94fb36069d79e8725c221cd1e5740742501ef014ea6db999fd98ad") 27 var sc l.State 28 copy(sc[:], scBytes) 29 k1p1 := l.NewKeyPart(uint16(1), []byte("1")) 30 k1p2 := l.NewKeyPart(uint16(22), []byte("2")) 31 k1 := l.NewKey([]l.KeyPart{k1p1, k1p2}) 32 33 k2p1 := l.NewKeyPart(uint16(1), []byte("3")) 34 k2p2 := l.NewKeyPart(uint16(22), []byte("4")) 35 k2 := l.NewKey([]l.KeyPart{k2p1, k2p2}) 36 37 u, _ := l.NewQuery(sc, []l.Key{k1, k2}) 38 return u 39 } 40 41 // LightPayload returns a payload with 2 byte key and 2 byte value 42 func LightPayload(key uint16, value uint16) *l.Payload { 43 k := l.Key{KeyParts: []l.KeyPart{{Type: 0, Value: utils.Uint16ToBinary(key)}}} 44 v := l.Value(utils.Uint16ToBinary(value)) 45 return l.NewPayload(k, v) 46 } 47 48 // LightPayload8 returns a payload with 1 byte key and 1 byte value 49 func LightPayload8(key uint8, value uint8) *l.Payload { 50 k := l.Key{KeyParts: []l.KeyPart{{Type: 0, Value: []byte{key}}}} 51 v := l.Value([]byte{value}) 52 return l.NewPayload(k, v) 53 } 54 55 // PathByUint8 returns a path (32 bytes) given a uint8 56 func PathByUint8(inp uint8) l.Path { 57 var b l.Path 58 b[0] = inp 59 return b 60 } 61 62 // PathByUint16 returns a path (32 bytes) given a uint16 (big endian) 63 func PathByUint16(inp uint16) l.Path { 64 var b l.Path 65 binary.BigEndian.PutUint16(b[:], inp) 66 return b 67 } 68 69 // PathByUint16LeftPadded returns a path (32 bytes) given a uint16 (left padded big endian) 70 func PathByUint16LeftPadded(inp uint16) l.Path { 71 var b l.Path 72 binary.BigEndian.PutUint16(b[30:], inp) 73 return b 74 } 75 76 // KeyPartFixture returns a key part fixture 77 func KeyPartFixture(typ uint16, val string) l.KeyPart { 78 kp1t := typ 79 kp1v := []byte(val) 80 return l.NewKeyPart(kp1t, kp1v) 81 } 82 83 // UpdateFixture returns an update fixture 84 func UpdateFixture() *l.Update { 85 scBytes, _ := hex.DecodeString("6a7a565add94fb36069d79e8725c221cd1e5740742501ef014ea6db999fd98ad") 86 var sc l.State 87 copy(sc[:], scBytes) 88 k1p1 := l.NewKeyPart(uint16(1), []byte("1")) 89 k1p2 := l.NewKeyPart(uint16(22), []byte("2")) 90 k1 := l.NewKey([]l.KeyPart{k1p1, k1p2}) 91 v1 := l.Value([]byte{'A'}) 92 93 k2p1 := l.NewKeyPart(uint16(1), []byte("3")) 94 k2p2 := l.NewKeyPart(uint16(22), []byte("4")) 95 k2 := l.NewKey([]l.KeyPart{k2p1, k2p2}) 96 v2 := l.Value([]byte{'B'}) 97 98 u, _ := l.NewUpdate(sc, []l.Key{k1, k2}, []l.Value{v1, v2}) 99 return u 100 } 101 102 // RootHashFixture returns a root hash fixture 103 func RootHashFixture() l.RootHash { 104 rootBytes, _ := hex.DecodeString("6a7a565add94fb36069d79e8725c221cd1e5740742501ef014ea6db999fd98ad") 105 var root l.RootHash 106 copy(root[:], rootBytes) 107 return root 108 } 109 110 // TrieProofFixture returns a trie proof fixture 111 func TrieProofFixture() (*l.TrieProof, l.State) { 112 p := l.NewTrieProof() 113 p.Path = PathByUint16(330) 114 p.Payload = LightPayload8('A', 'A') 115 p.Inclusion = true 116 p.Flags = []byte{byte(130), byte(0)} 117 p.Interims = make([]hash.Hash, 0) 118 interim1Bytes, _ := hex.DecodeString("accb0399dd2b3a7a48618b2376f5e61d822e0c7736b044c364a05c2904a2f315") 119 interim2Bytes, _ := hex.DecodeString("f3fba426a2f01c342304e3ca7796c3980c62c625f7fd43105ad5afd92b165542") 120 var interim1, interim2 hash.Hash 121 copy(interim1[:], interim1Bytes) 122 copy(interim2[:], interim2Bytes) 123 p.Interims = append(p.Interims, interim1) 124 p.Interims = append(p.Interims, interim2) 125 p.Steps = uint8(7) 126 scBytes, _ := hex.DecodeString("4a9f3a15d7257b624b645955576f62edcceff5e125f49585cdf077d9f37c7ac0") 127 var sc l.State 128 copy(sc[:], scBytes) 129 return p, sc 130 } 131 132 // TrieBatchProofFixture returns a trie batch proof fixture 133 func TrieBatchProofFixture() (*l.TrieBatchProof, l.State) { 134 p, s := TrieProofFixture() 135 bp := l.NewTrieBatchProof() 136 bp.Proofs = append(bp.Proofs, p) 137 bp.Proofs = append(bp.Proofs, p) 138 return bp, s 139 } 140 141 // RandomPathsRandLen generate m random paths. 142 // the number of paths, m, is also randomly selected from the range [1, maxN] 143 func RandomPathsRandLen(maxN int) []l.Path { 144 numberOfPaths := rand.Intn(maxN) + 1 145 return RandomPaths(numberOfPaths) 146 } 147 148 // RandomPaths generates n random (no repetition) 149 func RandomPaths(n int) []l.Path { 150 paths := make([]l.Path, 0, n) 151 alreadySelectPaths := make(map[l.Path]bool) 152 i := 0 153 for i < n { 154 var path l.Path 155 _, err := crand.Read(path[:]) 156 if err != nil { 157 panic("randomness failed") 158 } 159 // deduplicate 160 if _, found := alreadySelectPaths[path]; !found { 161 paths = append(paths, path) 162 alreadySelectPaths[path] = true 163 i++ 164 } 165 } 166 return paths 167 } 168 169 // RandomPayload returns a random payload 170 func RandomPayload(minByteSize int, maxByteSize int) *l.Payload { 171 keyByteSize := minByteSize + rand.Intn(maxByteSize-minByteSize) 172 keydata := make([]byte, keyByteSize) 173 _, err := crand.Read(keydata) 174 if err != nil { 175 panic("randomness failed") 176 } 177 key := l.Key{KeyParts: []l.KeyPart{{Type: 0, Value: keydata}}} 178 valueByteSize := minByteSize + rand.Intn(maxByteSize-minByteSize) 179 valuedata := make([]byte, valueByteSize) 180 _, err = crand.Read(valuedata) 181 if err != nil { 182 panic("random generation failed") 183 } 184 value := l.Value(valuedata) 185 return l.NewPayload(key, value) 186 } 187 188 // RandomPayloads returns n random payloads 189 func RandomPayloads(n int, minByteSize int, maxByteSize int) []*l.Payload { 190 res := make([]*l.Payload, 0) 191 for i := 0; i < n; i++ { 192 res = append(res, RandomPayload(minByteSize, maxByteSize)) 193 } 194 return res 195 } 196 197 // RandomValues returns n random values with variable sizes (minByteSize <= size < maxByteSize) 198 func RandomValues(n int, minByteSize, maxByteSize int) []l.Value { 199 if minByteSize > maxByteSize { 200 panic("minByteSize cannot be smaller then maxByteSize") 201 } 202 values := make([]l.Value, 0) 203 for i := 0; i < n; i++ { 204 var byteSize = maxByteSize 205 if minByteSize < maxByteSize { 206 byteSize = minByteSize + rand.Intn(maxByteSize-minByteSize) 207 } 208 value := make([]byte, byteSize) 209 _, err := crand.Read(value) 210 if err != nil { 211 panic("random generation failed") 212 } 213 values = append(values, value) 214 } 215 return values 216 } 217 218 // RandomUniqueKeys generates n random keys (each with m random key parts) 219 func RandomUniqueKeys(n, m, minByteSize, maxByteSize int) []l.Key { 220 if minByteSize > maxByteSize { 221 panic("minByteSize cannot be smaller then maxByteSize") 222 } 223 keys := make([]l.Key, 0) 224 alreadySelectKeys := make(map[string]bool) 225 i := 0 226 for i < n { 227 keyParts := make([]l.KeyPart, 0) 228 for j := 0; j < m; j++ { 229 byteSize := maxByteSize 230 if minByteSize < maxByteSize { 231 byteSize = minByteSize + rand.Intn(maxByteSize-minByteSize) 232 } 233 keyPartData := make([]byte, byteSize) 234 _, err := crand.Read(keyPartData) 235 if err != nil { 236 panic("random generation failed") 237 } 238 keyParts = append(keyParts, l.NewKeyPart(uint16(j), keyPartData)) 239 } 240 key := l.NewKey(keyParts) 241 242 // deduplicate 243 if _, found := alreadySelectKeys[key.String()]; !found { 244 keys = append(keys, key) 245 alreadySelectKeys[key.String()] = true 246 i++ 247 } else { 248 fmt.Println("Already existing") 249 } 250 } 251 return keys 252 }