@@ -23,6 +23,7 @@ import (
2323 "errors"
2424 "fmt"
2525 "hash"
26+ "io"
2627 "math/big"
2728 "math/rand"
2829 "reflect"
@@ -292,8 +293,9 @@ func TestRandomCases(t *testing.T) {
292293 {op : 1 , key : common .Hex2Bytes ("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268" ), value : common .Hex2Bytes ("" )}, // step 24
293294 {op : 1 , key : common .Hex2Bytes ("fd" ), value : common .Hex2Bytes ("" )}, // step 25
294295 }
295- runRandTest (rt )
296-
296+ if err := runRandTest (rt ); err != nil {
297+ t .Fatal (err )
298+ }
297299}
298300
299301// randTest performs random trie operations.
@@ -319,36 +321,53 @@ const (
319321)
320322
321323func (randTest ) Generate (r * rand.Rand , size int ) reflect.Value {
324+ var finishedFn = func () bool {
325+ size --
326+ return size > 0
327+ }
328+ return reflect .ValueOf (generateSteps (finishedFn , r ))
329+ }
330+
331+ func generateSteps (finished func () bool , r io.Reader ) randTest {
322332 var allKeys [][]byte
333+ var one = []byte {0 }
323334 genKey := func () []byte {
324- if len (allKeys ) < 2 || r .Intn (100 ) < 10 {
335+ r .Read (one )
336+ if len (allKeys ) < 2 || one [0 ]% 100 > 90 {
325337 // new key
326- key := make ([]byte , r .Intn (50 ))
338+ size := one [0 ] % 50
339+ key := make ([]byte , size )
327340 r .Read (key )
328341 allKeys = append (allKeys , key )
329342 return key
330343 }
331344 // use existing key
332- return allKeys [r .Intn (len (allKeys ))]
345+ idx := int (one [0 ]) % len (allKeys )
346+ return allKeys [idx ]
333347 }
334-
335348 var steps randTest
336- for i := 0 ; i < size ; i ++ {
337- step := randTestStep {op : r .Intn (opMax )}
349+ for ! finished () {
350+ r .Read (one )
351+ step := randTestStep {op : int (one [0 ]) % opMax }
338352 switch step .op {
339353 case opUpdate :
340354 step .key = genKey ()
341355 step .value = make ([]byte , 8 )
342- binary .BigEndian .PutUint64 (step .value , uint64 (i ))
356+ binary .BigEndian .PutUint64 (step .value , uint64 (len ( steps ) ))
343357 case opGet , opDelete :
344358 step .key = genKey ()
345359 }
346360 steps = append (steps , step )
347361 }
348- return reflect . ValueOf ( steps )
362+ return steps
349363}
350364
351- func runRandTest (rt randTest ) bool {
365+ // runRandTestBool coerces error to boolean, for use in quick.Check
366+ func runRandTestBool (rt randTest ) bool {
367+ return runRandTest (rt ) == nil
368+ }
369+
370+ func runRandTest (rt randTest ) error {
352371 triedb := NewDatabase (memorydb .New ())
353372
354373 tr , _ := New (common.Hash {}, triedb )
@@ -378,12 +397,12 @@ func runRandTest(rt randTest) bool {
378397 hash , err := tr .Commit (nil )
379398 if err != nil {
380399 rt [i ].err = err
381- return false
400+ return err
382401 }
383402 newtr , err := New (hash , triedb )
384403 if err != nil {
385404 rt [i ].err = err
386- return false
405+ return err
387406 }
388407 tr = newtr
389408 case opItercheckhash :
@@ -398,14 +417,14 @@ func runRandTest(rt randTest) bool {
398417 }
399418 // Abort the test on error.
400419 if rt [i ].err != nil {
401- return false
420+ return rt [ i ]. err
402421 }
403422 }
404- return true
423+ return nil
405424}
406425
407426func TestRandom (t * testing.T ) {
408- if err := quick .Check (runRandTest , nil ); err != nil {
427+ if err := quick .Check (runRandTestBool , nil ); err != nil {
409428 if cerr , ok := err .(* quick.CheckError ); ok {
410429 t .Fatalf ("random test iteration %d failed: %s" , cerr .Count , spew .Sdump (cerr .In ))
411430 }
@@ -841,3 +860,17 @@ func TestDecodeNode(t *testing.T) {
841860 decodeNode (hash , elems )
842861 }
843862}
863+
864+ func FuzzTrie (f * testing.F ) {
865+ f .Fuzz (func (t * testing.T , data []byte ) {
866+ var steps = 500
867+ var input = bytes .NewReader (data )
868+ var finishedFn = func () bool {
869+ steps --
870+ return steps < 0 || input .Len () == 0
871+ }
872+ if err := runRandTest (generateSteps (finishedFn , input )); err != nil {
873+ t .Fatal (err )
874+ }
875+ })
876+ }
0 commit comments