github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/handler_fuzz.go (about)

     1  //go:build gofuzz
     2  // +build gofuzz
     3  
     4  package gossip
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"math/rand"
    10  	"sync"
    11  
    12  	_ "github.com/dvyukov/go-fuzz/go-fuzz-defs"
    13  	"github.com/unicornultrafoundation/go-helios/utils/cachescale"
    14  	"github.com/unicornultrafoundation/go-u2u/core/types"
    15  	"github.com/unicornultrafoundation/go-u2u/p2p"
    16  	"github.com/unicornultrafoundation/go-u2u/p2p/enode"
    17  
    18  	"github.com/unicornultrafoundation/go-u2u/evmcore"
    19  	"github.com/unicornultrafoundation/go-u2u/integration/makefakegenesis"
    20  	"github.com/unicornultrafoundation/go-u2u/native"
    21  	"github.com/unicornultrafoundation/go-u2u/u2u"
    22  	"github.com/unicornultrafoundation/go-u2u/utils"
    23  	"github.com/unicornultrafoundation/go-u2u/utils/signers/gsignercache"
    24  )
    25  
    26  const (
    27  	fuzzHot      int = 1  // if the fuzzer should increase priority of the given input during subsequent fuzzing;
    28  	fuzzCold     int = -1 // if the input must not be added to corpus even if gives new coverage;
    29  	fuzzNoMatter int = 0  // otherwise.
    30  )
    31  
    32  var (
    33  	fuzzedHandler *handler
    34  )
    35  
    36  func FuzzHandler(data []byte) int {
    37  	var err error
    38  	if fuzzedHandler == nil {
    39  		fuzzedHandler, err = makeFuzzedHandler()
    40  		if err != nil {
    41  			panic(err)
    42  		}
    43  	}
    44  
    45  	msg, err := newFuzzMsg(data)
    46  	if err != nil {
    47  		return fuzzCold
    48  	}
    49  	input := &fuzzMsgReadWriter{msg}
    50  	other := &peer{
    51  		version: ProtocolVersion,
    52  		Peer:    p2p.NewPeer(randomID(), "fake-node-1", []p2p.Cap{}),
    53  		rw:      input,
    54  	}
    55  
    56  	err = fuzzedHandler.handleMsg(other)
    57  	if err != nil {
    58  		return fuzzNoMatter
    59  	}
    60  
    61  	return fuzzHot
    62  }
    63  
    64  func makeFuzzedHandler() (h *handler, err error) {
    65  	const (
    66  		genesisStakers = 3
    67  		genesisBalance = 1e18
    68  		genesisStake   = 2 * 4e6
    69  	)
    70  
    71  	genStore := makefakegenesis.FakeGenesisStore(genesisStakers, utils.ToU2U(genesisBalance), utils.ToU2U(genesisStake))
    72  	genesis := genStore.Genesis()
    73  
    74  	config := DefaultConfig(cachescale.Identity)
    75  	store := NewMemStore()
    76  	_, err = store.ApplyGenesis(genesis)
    77  	if err != nil {
    78  		return
    79  	}
    80  
    81  	var (
    82  		network             = u2u.FakeNetRules()
    83  		heavyCheckReader    HeavyCheckReader
    84  		gasPowerCheckReader GasPowerCheckReader
    85  		// TODO: init
    86  	)
    87  
    88  	mu := new(sync.RWMutex)
    89  	feed := new(ServiceFeed)
    90  	net := store.GetRules()
    91  	txSigner := gsignercache.Wrap(types.LatestSignerForChainID(net.EvmChainConfig().ChainID))
    92  	checkers := makeCheckers(config.HeavyCheck, txSigner, &heavyCheckReader, &gasPowerCheckReader, store)
    93  
    94  	txpool := evmcore.NewTxPool(evmcore.DefaultTxPoolConfig, network.EvmChainConfig(), &EvmStateReader{
    95  		ServiceFeed: feed,
    96  		store:       store,
    97  	})
    98  
    99  	h, err = newHandler(
   100  		handlerConfig{
   101  			config:   config,
   102  			notifier: feed,
   103  			txpool:   txpool,
   104  			engineMu: mu,
   105  			checkers: checkers,
   106  			s:        store,
   107  			process: processCallback{
   108  				Event: func(event *native.EventPayload) error {
   109  					return nil
   110  				},
   111  			},
   112  		})
   113  	if err != nil {
   114  		return
   115  	}
   116  
   117  	h.Start(3)
   118  	return
   119  }
   120  
   121  func randomID() (id enode.ID) {
   122  	for i := range id {
   123  		id[i] = byte(rand.Intn(255))
   124  	}
   125  	return id
   126  }
   127  
   128  type fuzzMsgReadWriter struct {
   129  	msg *p2p.Msg
   130  }
   131  
   132  func newFuzzMsg(data []byte) (*p2p.Msg, error) {
   133  	if len(data) < 1 {
   134  		return nil, errors.New("empty data")
   135  	}
   136  
   137  	var (
   138  		codes = []uint64{
   139  			HandshakeMsg,
   140  			EvmTxsMsg,
   141  			ProgressMsg,
   142  			NewEventIDsMsg,
   143  			GetEventsMsg,
   144  			EventsMsg,
   145  			RequestEventsStream,
   146  			EventsStreamResponse,
   147  		}
   148  		code = codes[int(data[0])%len(codes)]
   149  	)
   150  	data = data[1:]
   151  
   152  	return &p2p.Msg{
   153  		Code:    code,
   154  		Size:    uint32(len(data)),
   155  		Payload: bytes.NewReader(data),
   156  	}, nil
   157  }
   158  
   159  func (rw *fuzzMsgReadWriter) ReadMsg() (p2p.Msg, error) {
   160  	return *rw.msg, nil
   161  }
   162  
   163  func (rw *fuzzMsgReadWriter) WriteMsg(p2p.Msg) error {
   164  	return nil
   165  }