@@ -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