prysm-pulse/fuzz/block_fuzz.go
Preston Van Loon 07e7e030d9
Update PubSub and include topic filter (#7496)
* Update pubsub and fix topicIDs

* WIP filter

* Add suggested code from @bidlocode

* add tests and fix bugs

* more tests

* Wait until state initialized to accept pubsub filtering

* rename for clarity and clarify comment

* fix test builds

* Autofix issues in 2 files

Resolved issues in the following files via DeepSource Autofix:
1. beacon-chain/p2p/pubsub_filter.go
2. beacon-chain/p2p/pubsub_filter_test.go

* @nisdas pr feedback

* pr feedback and fuzz fix

* Update beacon-chain/p2p/pubsub_filter.go

* Must have protocol suffix

* Must have protocol suffix

* gofmt

* rm test, fix panic

* Fix tests

* Add isInitialized check

* Add a few more tests for better coverage

* cache fork digest, make pubsub filter part of the p2p service

* rename service

* gofmt

* Add comment

* fix

Co-authored-by: deepsource-autofix[bot] <62050782+deepsource-autofix[bot]@users.noreply.github.com>
Co-authored-by: Nishant Das <nishdas93@gmail.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-10-16 07:05:40 +00:00

199 lines
4.7 KiB
Go

// +build libfuzzer
package fuzz
import (
"bytes"
"context"
"encoding/hex"
"io/ioutil"
"os"
"path"
"github.com/libp2p/go-libp2p-core/peer"
pubsub "github.com/libp2p/go-libp2p-pubsub"
pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain/testing"
"github.com/prysmaticlabs/prysm/beacon-chain/cache"
"github.com/prysmaticlabs/prysm/beacon-chain/core/state"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/forkchoice/protoarray"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/voluntaryexits"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
p2pt "github.com/prysmaticlabs/prysm/beacon-chain/p2p/testing"
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stategen"
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/sirupsen/logrus"
)
const topic = p2p.BlockSubnetTopicFormat
var db1 db.Database
var ssc *cache.StateSummaryCache
var dbPath = path.Join(os.TempDir(), "fuzz_beacondb", randomHex(6))
func randomHex(n int) string {
bytes := make([]byte, n)
if _, err := rand.NewGenerator().Read(bytes); err != nil {
panic(err)
}
return hex.EncodeToString(bytes)
}
func init() {
featureconfig.Init(&featureconfig.Flags{SkipBLSVerify: true})
logrus.SetLevel(logrus.PanicLevel)
logrus.SetOutput(ioutil.Discard)
ssc = cache.NewStateSummaryCache()
var err error
db1, err = db.NewDB(dbPath, ssc)
if err != nil {
panic(err)
}
}
func setupDB() {
if err := db1.ClearDB(); err != nil {
_ = err
}
ctx := context.Background()
s := testutil.NewBeaconState()
b := testutil.NewBeaconBlock()
if err := db1.SaveBlock(ctx, b); err != nil {
panic(err)
}
br, err := ssz.HashTreeRoot(b)
if err != nil {
panic(err)
}
if err := db1.SaveState(ctx, s, br); err != nil {
panic(err)
}
if err := db1.SaveGenesisBlockRoot(ctx, br); err != nil {
panic(err)
}
}
type fakeChecker struct{}
func (fakeChecker) Syncing() bool {
return false
}
func (fakeChecker) Status() error {
return nil
}
func (fakeChecker) Resync() error {
return nil
}
// BeaconFuzzBlock runs full processing of beacon block against a given state.
func BeaconFuzzBlock(b []byte) {
params.UseMainnetConfig()
input := &InputBlockWithPrestate{}
if err := input.UnmarshalSSZ(b); err != nil {
return
}
st, err := stateTrie.InitializeFromProtoUnsafe(input.State)
if err != nil {
return
}
setupDB()
p2p := p2pt.NewFuzzTestP2P()
sgen := stategen.New(db1, ssc)
sn := &testing.MockStateNotifier{}
bn := &testing.MockBlockNotifier{}
an := &testing.MockOperationNotifier{}
ap := attestations.NewPool()
ep := voluntaryexits.NewPool()
sp := slashings.NewPool()
ops, err := attestations.NewService(context.Background(), &attestations.Config{Pool: ap})
if err != nil {
panic(err)
}
chain, err := blockchain.NewService(context.Background(), &blockchain.Config{
ChainStartFetcher: nil,
BeaconDB: db1,
DepositCache: nil,
AttPool: ap,
ExitPool: ep,
SlashingPool: sp,
P2p: p2p,
StateNotifier: sn,
ForkChoiceStore: protoarray.New(0, 0, [32]byte{}),
OpsService: ops,
StateGen: sgen,
})
if err != nil {
panic(err)
}
chain.Start()
s := sync.NewRegularSyncFuzz(&sync.Config{
DB: db1,
P2P: p2p,
Chain: chain,
InitialSync: fakeChecker{},
StateNotifier: sn,
BlockNotifier: bn,
AttestationNotifier: an,
AttPool: ap,
ExitPool: ep,
SlashingPool: sp,
StateSummaryCache: ssc,
StateGen: sgen,
})
if err := s.InitCaches(); err != nil {
panic(err)
}
buf := new(bytes.Buffer)
_, err = p2p.Encoding().EncodeGossip(buf, input.Block)
if err != nil {
panic(err)
}
ctx := context.Background()
pid := peer.ID("fuzz")
msg := &pubsub.Message{
Message: &pubsub_pb.Message{
Data: buf.Bytes(),
Topic: func() *string {
tpc := topic
return &tpc
}(),
},
}
if res := s.FuzzValidateBeaconBlockPubSub(ctx, pid, msg); res != pubsub.ValidationAccept {
return
}
if err := s.FuzzBeaconBlockSubscriber(ctx, msg); err != nil {
_ = err
}
if _, err := state.ProcessBlock(ctx, st, input.Block); err != nil {
_ = err
}
}