From 1262e73806284e45892a8b18b0b286f97ccaa6bb Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 26 Sep 2022 23:56:07 +0800 Subject: [PATCH] Author a sibling block in case best block's slot is same as current slot (#2827) While authoring a block in a given slot S, it could happen that best block was also authored in the slot S by some other author. In this case, we can't create a new block as a child of best block, because then we would have a chain where slot numbers don't increase. In such scenario, we author a sibling block to best block. That is we author a block as a child of best block's parent. After authoring such a block, we would have two blocks with same parent, same block number and same slot. This would create a fork, but that would eventually get resolved. --- dot/services.go | 1 + dot/types/authority.go | 4 +- lib/babe/babe.go | 47 +++++- lib/babe/babe_integration_test.go | 235 ++++++++++++++++++++++++----- lib/babe/build_integration_test.go | 45 +----- lib/babe/errors.go | 1 + lib/babe/helpers_test.go | 123 +++++++++++++++ lib/babe/mocks/network.go | 75 +++++++++ lib/babe/mocks_generate_test.go | 6 + 9 files changed, 454 insertions(+), 83 deletions(-) create mode 100644 lib/babe/mocks/network.go create mode 100644 lib/babe/mocks_generate_test.go diff --git a/dot/services.go b/dot/services.go index 23688eec83..5674fe753f 100644 --- a/dot/services.go +++ b/dot/services.go @@ -175,6 +175,7 @@ func (nb nodeBuilder) createBABEService(cfg *Config, st *state.Service, ks keyst cs *core.Service, telemetryMailer telemetry.Client) (babe.ServiceIFace, error) { return nb.createBABEServiceWithBuilder(cfg, st, ks, cs, telemetryMailer, babe.Builder{}) } + func (nodeBuilder) createBABEServiceWithBuilder(cfg *Config, st *state.Service, ks keystore.Keystore, cs *core.Service, telemetryMailer telemetry.Client, newBabeService ServiceBuilder) (babe. ServiceIFace, error) { diff --git a/dot/types/authority.go b/dot/types/authority.go index a75f6437df..2dff7a4434 100644 --- a/dot/types/authority.go +++ b/dot/types/authority.go @@ -16,7 +16,9 @@ import ( // Authority struct to hold authority data type Authority struct { - Key crypto.PublicKey + Key crypto.PublicKey + // Weight exists for potential improvements in the protocol and could + // have a use-case in the future. In polkadot all authorities have the weight = 1. Weight uint64 } diff --git a/lib/babe/babe.go b/lib/babe/babe.go index 929e77315b..1b615f6265 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -454,32 +454,65 @@ func (b *Service) handleEpoch(epoch uint64) (next uint64, err error) { return next, nil } -func (b *Service) handleSlot(epoch, slotNum uint64, - authorityIndex uint32, - preRuntimeDigest *types.PreRuntimeDigest, -) error { +func (b *Service) getParentForBlockAuthoring(slotNum uint64) (*types.Header, error) { parentHeader, err := b.blockState.BestBlockHeader() if err != nil { - return err + return nil, fmt.Errorf("could not get best block header: %w", err) } if parentHeader == nil { - return errNilParentHeader + return nil, errNilParentHeader + } + + atGenesisBlock := b.blockState.GenesisHash().Equal(parentHeader.Hash()) + if !atGenesisBlock { + bestBlockSlotNum, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) + if err != nil { + return nil, fmt.Errorf("could not get slot for block: %w", err) + } + + if bestBlockSlotNum > slotNum { + return nil, fmt.Errorf("%w: best block slot number is %d and got slot number %d", + errLaggingSlot, bestBlockSlotNum, slotNum) + } + + if bestBlockSlotNum == slotNum { + // pick parent of best block instead to handle slot + newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) + if err != nil { + return nil, fmt.Errorf("could not get header: %w", err) + } + if newParentHeader == nil { + return nil, fmt.Errorf("%w: for block hash %s", errNilParentHeader, parentHeader.ParentHash) + } + parentHeader = newParentHeader + } } // there is a chance that the best block header may change in the course of building the block, // so let's copy it first. parent, err := parentHeader.DeepCopy() if err != nil { - return err + return nil, fmt.Errorf("could not create deep copy of parent header: %w", err) } + return parent, nil +} + +func (b *Service) handleSlot(epoch, slotNum uint64, + authorityIndex uint32, + preRuntimeDigest *types.PreRuntimeDigest, +) error { currentSlot := Slot{ start: time.Now(), duration: b.constants.slotDuration, number: slotNum, } + parent, err := b.getParentForBlockAuthoring(slotNum) + if err != nil { + return fmt.Errorf("could not get parent for claiming slot %d: %w", slotNum, err) + } b.storageState.Lock() defer b.storageState.Unlock() diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index 5b9f30cc1b..6096916f24 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -6,7 +6,6 @@ package babe import ( - "path/filepath" "testing" "time" @@ -15,16 +14,16 @@ import ( "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/babe/mocks" + "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/trie" - "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" "github.com/golang/mock/gomock" - mock "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -79,37 +78,32 @@ func createTestService(t *testing.T, cfg ServiceConfig) *Service { cfg.Telemetry = telemetryMock - if cfg.TransactionState == nil { - cfg.TransactionState = state.NewTransactionState(telemetryMock) - } - testDatadirPath := t.TempDir() require.NoError(t, err) var dbSrv *state.Service - if cfg.BlockState == nil || cfg.StorageState == nil || cfg.EpochState == nil { - config := state.Config{ - Path: testDatadirPath, - LogLevel: log.Info, - Telemetry: telemetryMock, - } - dbSrv = state.NewService(config) - dbSrv.UseMemDB() + config := state.Config{ + Path: testDatadirPath, + LogLevel: log.Info, + Telemetry: telemetryMock, + } + dbSrv = state.NewService(config) + dbSrv.UseMemDB() - err = dbSrv.Initialise(&gen, &genHeader, &genTrie) - require.NoError(t, err) + err = dbSrv.Initialise(&gen, &genHeader, &genTrie) + require.NoError(t, err) - err = dbSrv.Start() - require.NoError(t, err) + err = dbSrv.Start() + require.NoError(t, err) - t.Cleanup(func() { - _ = dbSrv.Stop() - }) + t.Cleanup(func() { + _ = dbSrv.Stop() + }) - cfg.BlockState = dbSrv.Block - cfg.StorageState = dbSrv.Storage - cfg.EpochState = dbSrv.Epoch - } + cfg.BlockState = dbSrv.Block + cfg.StorageState = dbSrv.Storage + cfg.EpochState = dbSrv.Epoch + cfg.TransactionState = dbSrv.Transaction var rtCfg wasmer.Config rtCfg.Storage = rtstorage.NewTrieState(&genTrie) @@ -119,12 +113,7 @@ func createTestService(t *testing.T, cfg ServiceConfig) *Service { require.NoError(t, err) nodeStorage := runtime.NodeStorage{} - if dbSrv != nil { - nodeStorage.BaseDB = dbSrv.Base - } else { - nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) - require.NoError(t, err) - } + nodeStorage.BaseDB = dbSrv.Base rtCfg.NodeStorage = nodeStorage rt, err := wasmer.NewRuntimeFromGenesis(rtCfg) @@ -135,6 +124,26 @@ func createTestService(t *testing.T, cfg ServiceConfig) *Service { cfg.LogLvl = defaultTestLogLvl babeService, err := NewService(&cfg) require.NoError(t, err) + + if cfg.BlockImportHandler == nil { + mockNetwork := mocks.NewMockNetwork(ctrl) + mockNetwork.EXPECT().GossipMessage(gomock.Any()).AnyTimes() + + coreConfig := core.Config{ + BlockState: dbSrv.Block, + EpochState: dbSrv.Epoch, + StorageState: storageState, + TransactionState: dbSrv.Transaction, + Runtime: rt, + Keystore: rtCfg.Keystore, + Network: mockNetwork, + CodeSubstitutedState: dbSrv.Base, + CodeSubstitutes: make(map[common.Hash]string), + } + + babeService.blockImportHandler = NewTestService(t, &coreConfig) + } + return babeService } @@ -256,8 +265,7 @@ func TestService_GetAuthorityIndex(t *testing.T) { } func TestStartAndStop(t *testing.T) { - serviceConfig := ServiceConfig{} - bs := createTestService(t, serviceConfig) + bs := createTestService(t, ServiceConfig{}) err := bs.Start() require.NoError(t, err) err = bs.Stop() @@ -265,8 +273,7 @@ func TestStartAndStop(t *testing.T) { } func TestService_PauseAndResume(t *testing.T) { - serviceConfig := ServiceConfig{} - bs := createTestService(t, serviceConfig) + bs := createTestService(t, ServiceConfig{}) err := bs.Start() require.NoError(t, err) time.Sleep(time.Second) @@ -292,3 +299,159 @@ func TestService_PauseAndResume(t *testing.T) { err = bs.Stop() require.NoError(t, err) } + +func TestService_HandleSlotWithLaggingSlot(t *testing.T) { + cfg := ServiceConfig{ + Authority: true, + Lead: true, + } + babeService := createTestService(t, cfg) + + err := babeService.Start() + require.NoError(t, err) + defer func() { + err = babeService.Stop() + require.NoError(t, err) + }() + + // add a block + parentHash := babeService.blockState.GenesisHash() + rt, err := babeService.blockState.GetRuntime(nil) + require.NoError(t, err) + + epochData, err := babeService.initiateEpoch(testEpochIndex) + require.NoError(t, err) + + ext := runtime.NewTestExtrinsic(t, rt, parentHash, parentHash, 0, "System.remark", []byte{0xab, 0xcd}) + block := createTestBlock(t, babeService, emptyHeader, [][]byte{common.MustHexToBytes(ext)}, + 1, testEpochIndex, epochData) + + babeService.blockState.AddBlock(block) + time.Sleep(babeService.constants.slotDuration) + + header, err := babeService.blockState.BestBlockHeader() + require.NoError(t, err) + + bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(header.Hash()) + require.NoError(t, err) + + slotnum := uint64(1) + slot := Slot{ + start: time.Now(), + duration: time.Second, + number: slotnum, + } + preRuntimeDigest, err := types.NewBabePrimaryPreDigest( + 0, slot.number, + [sr25519.VRFOutputLength]byte{}, + [sr25519.VRFProofLength]byte{}, + ).ToPreRuntimeDigest() + + require.NoError(t, err) + + err = babeService.handleSlot( + babeService.epochHandler.epochNumber, + bestBlockSlotNum-1, + babeService.epochHandler.epochData.authorityIndex, + preRuntimeDigest) + + require.ErrorIs(t, err, errLaggingSlot) +} + +func TestService_HandleSlotWithSameSlot(t *testing.T) { + alice := keyring.Alice().(*sr25519.Keypair) + bob := keyring.Bob().(*sr25519.Keypair) + + // Create babe service for alice + cfgAlice := ServiceConfig{ + Authority: true, + Lead: true, + Keypair: alice, + AuthData: []types.Authority{ + { + Key: alice.Public().(*sr25519.PublicKey), + Weight: 1, + }, + { + Key: bob.Public().(*sr25519.PublicKey), + Weight: 1, + }, + }, + } + + // Create babe service for bob + cfgBob := ServiceConfig{ + Authority: true, + Lead: true, + Keypair: bob, + AuthData: []types.Authority{ + { + Key: alice.Public().(*sr25519.PublicKey), + Weight: 1, + }, + { + Key: bob.Public().(*sr25519.PublicKey), + Weight: 1, + }, + }, + } + + babeServiceBob := createTestService(t, cfgBob) + + err := babeServiceBob.Start() + require.NoError(t, err) + defer func() { + _ = babeServiceBob.Stop() + }() + + // wait till bob creates a block + time.Sleep(babeServiceBob.constants.slotDuration) + require.NoError(t, err) + + block, err := babeServiceBob.blockState.GetBlockByNumber(1) + require.NoError(t, err) + + err = babeServiceBob.Stop() + require.NoError(t, err) + + time.Sleep(babeServiceBob.constants.slotDuration) + + babeServiceAlice := createTestService(t, cfgAlice) + + // Add block created by Bob to Alice + err = babeServiceAlice.blockState.AddBlock(block) + require.NoError(t, err) + + time.Sleep(babeServiceBob.constants.slotDuration) + + bestBlockHeader, err := babeServiceAlice.blockState.BestBlockHeader() + require.NoError(t, err) + require.Equal(t, block.Header.Hash(), bestBlockHeader.Hash()) + + // If the slot we are claiming is the same as the slot of the best block header, test that we can + // still claim the slot without error. + bestBlockSlotNum, err := babeServiceAlice.blockState.GetSlotForBlock(bestBlockHeader.Hash()) + require.NoError(t, err) + + slot := Slot{ + start: time.Now(), + duration: time.Second, + number: bestBlockSlotNum, + } + preRuntimeDigest, err := types.NewBabePrimaryPreDigest( + 0, slot.number, + [sr25519.VRFOutputLength]byte{}, + [sr25519.VRFProofLength]byte{}, + ).ToPreRuntimeDigest() + require.NoError(t, err) + + // slot gets occupied even if it has been occupied by a block + // authored by someone else + err = babeServiceAlice.handleSlot( + testEpochIndex, + bestBlockSlotNum, + 0, + preRuntimeDigest) + require.NoError(t, err) + +} diff --git a/lib/babe/build_integration_test.go b/lib/babe/build_integration_test.go index f1ac699221..94e98b16f6 100644 --- a/lib/babe/build_integration_test.go +++ b/lib/babe/build_integration_test.go @@ -10,14 +10,12 @@ import ( "testing" "time" - "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/transaction" "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/golang/mock/gomock" cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" "github.com/centrifuge/go-substrate-rpc-client/v4/signature" @@ -59,7 +57,8 @@ func createTestBlock(t *testing.T, babeService *Service, parent *types.Header, exts [][]byte, slotNumber, epoch uint64, epochData *epochData) *types.Block { for _, ext := range exts { vtx := transaction.NewValidTransaction(ext, &transaction.Validity{}) - _, _ = babeService.transactionState.Push(vtx) + _, err := babeService.transactionState.Push(vtx) + require.NoError(t, err) } duration, err := time.ParseDuration("1s") @@ -87,15 +86,7 @@ func createTestBlock(t *testing.T, babeService *Service, parent *types.Header, // TODO: add test against latest dev runtime // See https://github.com/ChainSafe/gossamer/issues/2704 func TestBuildBlock_ok(t *testing.T) { - ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - cfg := ServiceConfig{ - TransactionState: state.NewTransactionState(telemetryMock), - } - - babeService := createTestService(t, cfg) + babeService := createTestService(t, ServiceConfig{}) parentHash := babeService.blockState.GenesisHash() rt, err := babeService.blockState.GetRuntime(nil) @@ -127,15 +118,7 @@ func TestBuildBlock_ok(t *testing.T) { // TODO: add test against latest dev runtime // See https://github.com/ChainSafe/gossamer/issues/2704 func TestApplyExtrinsic(t *testing.T) { - ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - cfg := ServiceConfig{ - TransactionState: state.NewTransactionState(telemetryMock), - } - - babeService := createTestService(t, cfg) + babeService := createTestService(t, ServiceConfig{}) const authorityIndex = 0 duration, err := time.ParseDuration("1s") @@ -222,15 +205,7 @@ func TestApplyExtrinsic(t *testing.T) { // TODO: add test against latest dev runtime // See https://github.com/ChainSafe/gossamer/issues/2704 func TestBuildAndApplyExtrinsic(t *testing.T) { - ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - cfg := ServiceConfig{ - TransactionState: state.NewTransactionState(telemetryMock), - } - - babeService := createTestService(t, cfg) + babeService := createTestService(t, ServiceConfig{}) parentHash := common.MustHexToHash("0x35a28a7dbaf0ba07d1485b0f3da7757e3880509edc8c31d0850cb6dd6219361d") header, err := types.NewHeader(parentHash, common.Hash{}, common.Hash{}, 1, types.NewDigest()) @@ -302,15 +277,7 @@ func TestBuildAndApplyExtrinsic(t *testing.T) { func TestBuildBlock_failing(t *testing.T) { t.Skip() - ctrl := gomock.NewController(t) - telemetryMock := NewMockClient(ctrl) - telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() - - cfg := ServiceConfig{ - TransactionState: state.NewTransactionState(telemetryMock), - } - - babeService := createTestService(t, cfg) + babeService := createTestService(t, ServiceConfig{}) // see https://github.com/noot/substrate/blob/add-blob/core/test-runtime/src/system.rs#L468 // add a valid transaction diff --git a/lib/babe/errors.go b/lib/babe/errors.go index 463832ba0f..e666d80717 100644 --- a/lib/babe/errors.go +++ b/lib/babe/errors.go @@ -71,6 +71,7 @@ var ( errInvalidSlotTechnique = errors.New("invalid slot claiming technique") errNoBABEAuthorityKeyProvided = errors.New("cannot create BABE service as authority; no keypair provided") errLastDigestItemNotSeal = errors.New("last digest item is not seal") + errLaggingSlot = errors.New("current slot is smaller than slot of best block") other Other invalidCustom InvalidCustom diff --git a/lib/babe/helpers_test.go b/lib/babe/helpers_test.go index 37ae424e4d..24b07449ff 100644 --- a/lib/babe/helpers_test.go +++ b/lib/babe/helpers_test.go @@ -4,17 +4,140 @@ package babe import ( + "path/filepath" "testing" + "github.com/ChainSafe/gossamer/dot/core" + "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/genesis" + "github.com/ChainSafe/gossamer/lib/keystore" + "github.com/ChainSafe/gossamer/lib/runtime" + rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) +// NewTestService creates a new test core service +func NewTestService(t *testing.T, cfg *core.Config) *core.Service { + t.Helper() + ctrl := gomock.NewController(t) + + if cfg == nil { + cfg = &core.Config{} + } + + if cfg.Keystore == nil { + cfg.Keystore = keystore.NewGlobalKeystore() + kp, err := sr25519.GenerateKeypair() + if err != nil { + t.Fatal(err) + } + err = cfg.Keystore.Acco.Insert(kp) + require.NoError(t, err) + } + + cfg.LogLvl = 3 + + var stateSrvc *state.Service + testDatadirPath := t.TempDir() + + gen, genesisTrie, genesisHeader := newTestGenesisWithTrieAndHeader(t) + + if cfg.BlockState == nil || cfg.StorageState == nil || + cfg.TransactionState == nil || cfg.EpochState == nil || + cfg.CodeSubstitutedState == nil { + telemetryMock := NewMockClient(ctrl) + telemetryMock.EXPECT().SendMessage(gomock.Any()).AnyTimes() + + config := state.Config{ + Path: testDatadirPath, + LogLevel: log.Info, + Telemetry: telemetryMock, + } + + stateSrvc = state.NewService(config) + stateSrvc.UseMemDB() + + err := stateSrvc.Initialise(&gen, &genesisHeader, &genesisTrie) + require.NoError(t, err) + + err = stateSrvc.Start() + require.NoError(t, err) + } + + if cfg.BlockState == nil { + cfg.BlockState = stateSrvc.Block + } + + if cfg.StorageState == nil { + cfg.StorageState = stateSrvc.Storage + } + + if cfg.TransactionState == nil { + cfg.TransactionState = stateSrvc.Transaction + } + + if cfg.EpochState == nil { + cfg.EpochState = stateSrvc.Epoch + } + + if cfg.CodeSubstitutedState == nil { + cfg.CodeSubstitutedState = stateSrvc.Base + } + + if cfg.Runtime == nil { + var rtCfg wasmer.Config + + rtCfg.Storage = rtstorage.NewTrieState(&genesisTrie) + + var err error + rtCfg.CodeHash, err = cfg.StorageState.LoadCodeHash(nil) + require.NoError(t, err) + + nodeStorage := runtime.NodeStorage{} + + if stateSrvc != nil { + nodeStorage.BaseDB = stateSrvc.Base + } else { + nodeStorage.BaseDB, err = utils.SetupDatabase(filepath.Join(testDatadirPath, "offline_storage"), false) + require.NoError(t, err) + } + + rtCfg.NodeStorage = nodeStorage + + cfg.Runtime, err = wasmer.NewRuntimeFromGenesis(rtCfg) + require.NoError(t, err) + } + cfg.BlockState.StoreRuntime(cfg.BlockState.BestBlockHash(), cfg.Runtime) + + if cfg.CodeSubstitutes == nil { + cfg.CodeSubstitutes = make(map[common.Hash]string) + + genesisData, err := cfg.CodeSubstitutedState.(*state.BaseState).LoadGenesisData() + require.NoError(t, err) + + for k, v := range genesisData.CodeSubstitutes { + cfg.CodeSubstitutes[common.MustHexToHash(k)] = v + } + } + + if cfg.CodeSubstitutedState == nil { + cfg.CodeSubstitutedState = stateSrvc.Base + } + + s, err := core.NewService(cfg) + require.NoError(t, err) + + return s +} + // newDevGenesisWithTrieAndHeader generates test dev genesis, genesis trie and genesis header func newDevGenesisWithTrieAndHeader(t *testing.T) ( gen genesis.Genesis, genesisTrie trie.Trie, genesisHeader types.Header) { diff --git a/lib/babe/mocks/network.go b/lib/babe/mocks/network.go new file mode 100644 index 0000000000..1f1314e3cb --- /dev/null +++ b/lib/babe/mocks/network.go @@ -0,0 +1,75 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ChainSafe/gossamer/dot/core (interfaces: Network) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + network "github.com/ChainSafe/gossamer/dot/network" + peerset "github.com/ChainSafe/gossamer/dot/peerset" + gomock "github.com/golang/mock/gomock" + peer "github.com/libp2p/go-libp2p-core/peer" +) + +// MockNetwork is a mock of Network interface. +type MockNetwork struct { + ctrl *gomock.Controller + recorder *MockNetworkMockRecorder +} + +// MockNetworkMockRecorder is the mock recorder for MockNetwork. +type MockNetworkMockRecorder struct { + mock *MockNetwork +} + +// NewMockNetwork creates a new mock instance. +func NewMockNetwork(ctrl *gomock.Controller) *MockNetwork { + mock := &MockNetwork{ctrl: ctrl} + mock.recorder = &MockNetworkMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockNetwork) EXPECT() *MockNetworkMockRecorder { + return m.recorder +} + +// GossipMessage mocks base method. +func (m *MockNetwork) GossipMessage(arg0 network.NotificationsMessage) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "GossipMessage", arg0) +} + +// GossipMessage indicates an expected call of GossipMessage. +func (mr *MockNetworkMockRecorder) GossipMessage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GossipMessage", reflect.TypeOf((*MockNetwork)(nil).GossipMessage), arg0) +} + +// IsSynced mocks base method. +func (m *MockNetwork) IsSynced() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsSynced") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsSynced indicates an expected call of IsSynced. +func (mr *MockNetworkMockRecorder) IsSynced() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSynced", reflect.TypeOf((*MockNetwork)(nil).IsSynced)) +} + +// ReportPeer mocks base method. +func (m *MockNetwork) ReportPeer(arg0 peerset.ReputationChange, arg1 peer.ID) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReportPeer", arg0, arg1) +} + +// ReportPeer indicates an expected call of ReportPeer. +func (mr *MockNetworkMockRecorder) ReportPeer(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportPeer", reflect.TypeOf((*MockNetwork)(nil).ReportPeer), arg0, arg1) +} diff --git a/lib/babe/mocks_generate_test.go b/lib/babe/mocks_generate_test.go new file mode 100644 index 0000000000..f392cf6f6f --- /dev/null +++ b/lib/babe/mocks_generate_test.go @@ -0,0 +1,6 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package babe + +//go:generate mockgen -destination=mocks/network.go -package=mocks github.com/ChainSafe/gossamer/dot/core Network