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  }