diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 77fc2b13ec..bfdc5b6d84 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -38,8 +38,8 @@ import ( "github.com/stretchr/testify/require" ) -func addTestBlocksToState(t *testing.T, depth int, blockState BlockState) []*types.Header { - return addTestBlocksToStateWithParent(t, blockState.BestBlockHash(), depth, blockState) +func addTestBlocksToState(t *testing.T, depth int, blockState BlockState) { + _ = addTestBlocksToStateWithParent(t, blockState.BestBlockHash(), depth, blockState) } func addTestBlocksToStateWithParent(t *testing.T, previousHash common.Hash, depth int, blockState BlockState) []*types.Header { diff --git a/dot/digest/digest.go b/dot/digest/digest.go index 76b7f31bb4..c81ad9c02c 100644 --- a/dot/digest/digest.go +++ b/dot/digest/digest.go @@ -424,7 +424,7 @@ func newGrandpaChange(raw []*types.GrandpaAuthoritiesRaw, delay uint32, currBloc }, nil } -func (h *Handler) handleBABEOnDisabled(d *types.ConsensusDigest, header *types.Header) error { +func (h *Handler) handleBABEOnDisabled(d *types.ConsensusDigest, _ *types.Header) error { od := &types.BABEOnDisabled{} dec, err := scale.Decode(d.Data[1:], od) if err != nil { @@ -433,13 +433,6 @@ func (h *Handler) handleBABEOnDisabled(d *types.ConsensusDigest, header *types.H od = dec.(*types.BABEOnDisabled) logger.Debug("handling BABEOnDisabled", "data", od) - - // err = h.verifier.SetOnDisabled(od.ID, header) - // if err != nil { - // return err - // } - - // h.babe.SetOnDisabled(od.ID) return nil } diff --git a/dot/node.go b/dot/node.go index 87839f74e8..ee3d22d861 100644 --- a/dot/node.go +++ b/dot/node.go @@ -272,7 +272,6 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node, if err != nil { return nil, err } - nodeSrvcs = append(nodeSrvcs, bp) // create GRANDPA service @@ -291,7 +290,7 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node, // Core Service // create core service and append core service to node services - coreSrvc, err := createCoreService(cfg, bp, ver, rt, ks, stateSrvc, networkSrvc) + coreSrvc, err := createCoreService(cfg, bp, rt, ks, stateSrvc, networkSrvc) if err != nil { return nil, fmt.Errorf("failed to create core service: %s", err) } diff --git a/dot/node_test.go b/dot/node_test.go index 29d331470b..b152781a16 100644 --- a/dot/node_test.go +++ b/dot/node_test.go @@ -188,7 +188,9 @@ func TestStartNode(t *testing.T) { require.NoError(t, err) go func() { - time.Sleep(time.Second) + // TODO: need to wait until all services are started so that wg.Add is called, otherwise + // will call wg.Done before the counter is at 1 + time.Sleep(time.Second * 15) node.Stop() }() diff --git a/dot/services.go b/dot/services.go index 354bbb9035..80ec019d33 100644 --- a/dot/services.go +++ b/dot/services.go @@ -213,7 +213,7 @@ func createBABEService(cfg *Config, rt runtime.Instance, st *state.Service, ks k // Core Service // createCoreService creates the core service from the provided core configuration -func createCoreService(cfg *Config, bp core.BlockProducer, verifier *babe.VerificationManager, rt runtime.Instance, ks *keystore.GlobalKeystore, stateSrvc *state.Service, net *network.Service) (*core.Service, error) { +func createCoreService(cfg *Config, bp core.BlockProducer, rt runtime.Instance, ks *keystore.GlobalKeystore, stateSrvc *state.Service, net *network.Service) (*core.Service, error) { logger.Debug( "creating core service...", "authority", cfg.Core.Roles == types.AuthorityRole, diff --git a/dot/services_test.go b/dot/services_test.go index 2a6746d186..c05e4b48c6 100644 --- a/dot/services_test.go +++ b/dot/services_test.go @@ -85,7 +85,7 @@ func TestCreateCoreService(t *testing.T) { rt, err := createRuntime(cfg, stateSrvc, ks, networkSrvc) require.NoError(t, err) - coreSrvc, err := createCoreService(cfg, nil, nil, rt, ks, stateSrvc, networkSrvc) + coreSrvc, err := createCoreService(cfg, nil, rt, ks, stateSrvc, networkSrvc) require.Nil(t, err) require.NotNil(t, coreSrvc) } @@ -196,7 +196,7 @@ func TestCreateRPCService(t *testing.T) { rt, err := createRuntime(cfg, stateSrvc, ks, networkSrvc) require.NoError(t, err) - coreSrvc, err := createCoreService(cfg, nil, nil, rt, ks, stateSrvc, networkSrvc) + coreSrvc, err := createCoreService(cfg, nil, rt, ks, stateSrvc, networkSrvc) require.Nil(t, err) sysSrvc, err := createSystemService(&cfg.System, stateSrvc) @@ -233,7 +233,10 @@ func TestCreateBABEService(t *testing.T) { rt, err := createRuntime(cfg, stateSrvc, ks, &network.Service{}) require.NoError(t, err) - bs, err := createBABEService(cfg, rt, stateSrvc, ks.Babe) + dh, err := createDigestHandler(stateSrvc) + require.NoError(t, err) + + bs, err := createBABEService(cfg, rt, stateSrvc, ks.Babe, dh) require.NoError(t, err) require.NotNil(t, bs) } @@ -265,7 +268,7 @@ func TestCreateGrandpaService(t *testing.T) { rt, err := createRuntime(cfg, stateSrvc, ks, &network.Service{}) require.NoError(t, err) - dh, err := createDigestHandler(stateSrvc, nil, nil) + dh, err := createDigestHandler(stateSrvc) require.NoError(t, err) gs, err := createGRANDPAService(cfg, rt, stateSrvc, dh, ks.Gran, &network.Service{}) @@ -317,7 +320,7 @@ func TestNewWebSocketServer(t *testing.T) { rt, err := createRuntime(cfg, stateSrvc, ks, networkSrvc) require.NoError(t, err) - coreSrvc, err := createCoreService(cfg, nil, nil, rt, ks, stateSrvc, networkSrvc) + coreSrvc, err := createCoreService(cfg, nil, rt, ks, stateSrvc, networkSrvc) require.Nil(t, err) sysSrvc, err := createSystemService(&cfg.System, stateSrvc) diff --git a/dot/state/base_test.go b/dot/state/base_test.go index a6aee30313..3d7648f281 100644 --- a/dot/state/base_test.go +++ b/dot/state/base_test.go @@ -112,3 +112,16 @@ func TestStoreAndLoadBestBlockHash(t *testing.T) { require.NoError(t, err) require.Equal(t, hash, res) } + +func TestLoadStoreEpochLength(t *testing.T) { + db := NewInMemoryDB(t) + base := NewBaseState(db) + + length := uint64(2222) + err := base.storeEpochLength(length) + require.NoError(t, err) + + ret, err := base.loadEpochLength() + require.NoError(t, err) + require.Equal(t, length, ret) +} diff --git a/dot/state/block.go b/dot/state/block.go index 2e6346dc38..655621509a 100644 --- a/dot/state/block.go +++ b/dot/state/block.go @@ -421,7 +421,10 @@ func (bs *BlockState) SetFinalizedHash(hash common.Hash, round, setID uint64) er // if nothing was previously finalised, set the first slot of the network to the // slot number of block 1, which is now being set as final if bs.lastFinalised.Equal(bs.genesisHash) && !hash.Equal(bs.genesisHash) { - bs.setFirstSlotOnFinalisation() + err := bs.setFirstSlotOnFinalisation() + if err != nil { + return err + } } go bs.notifyFinalized(hash, round, setID) diff --git a/dot/state/epoch.go b/dot/state/epoch.go index f018223bc5..a8c5361632 100644 --- a/dot/state/epoch.go +++ b/dot/state/epoch.go @@ -155,10 +155,12 @@ func NewEpochState(db chaindb.Database, blockState *BlockState) (*EpochState, er }, nil } +// GetEpochLength returns the length of an epoch in slots func (s *EpochState) GetEpochLength() (uint64, error) { return s.baseState.loadEpochLength() } +// GetSlotDuration returns the duration of a slot func (s *EpochState) GetSlotDuration() (time.Duration, error) { d, err := s.baseState.loadSlotDuration() if err != nil { @@ -298,6 +300,7 @@ func (s *EpochState) GetConfigData(epoch uint64) (*types.ConfigData, error) { return info.(*types.ConfigData), nil } +// GetLatestConfigData returns the most recently set ConfigData func (s *EpochState) GetLatestConfigData() (*types.ConfigData, error) { b, err := s.db.Get(latestConfigDataKey) if err != nil { diff --git a/dot/state/epoch_test.go b/dot/state/epoch_test.go index fb4fca3614..e188e17085 100644 --- a/dot/state/epoch_test.go +++ b/dot/state/epoch_test.go @@ -42,17 +42,6 @@ func newEpochStateFromGenesis(t *testing.T) *EpochState { return s } -func TestLoadStoreEpochLength(t *testing.T) { - db := NewInMemoryDB(t) - length := uint64(2222) - err := storeEpochLength(db, length) - require.NoError(t, err) - - ret, err := loadEpochLength(db) - require.NoError(t, err) - require.Equal(t, length, ret) -} - func TestNewEpochStateFromGenesis(t *testing.T) { _ = newEpochStateFromGenesis(t) } diff --git a/lib/babe/babe.go b/lib/babe/babe.go index ebf7fe5bf7..84774a6c2d 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -21,7 +21,6 @@ import ( "context" "errors" "fmt" - "math/big" "os" "sync" "time" @@ -34,7 +33,7 @@ import ( var ( logger log.Logger - initialWaitTime = time.Duration(time.Second * 12) + initialWaitTime = time.Second * 12 // TODO: set to slotDuration * 2 ) // Service contains the VRF keys for the validator, as well as BABE configuation data @@ -385,23 +384,22 @@ func (b *Service) invokeBlockAuthoring(epoch uint64) { return } - head, err := b.blockState.BestBlockHeader() - if err != nil { - logger.Error("failed to get best block header", "error", err) - return - } - - // if we're at genesis, set the first slot number for the network - if head.Number.Cmp(big.NewInt(0)) == 0 { - epochStart = getCurrentSlot(b.slotDuration) - err = b.epochState.SetFirstSlot(epochStart) - if err != nil { - logger.Error("failed to set first slot number", "error", err) - return - } - } + // head, err := b.blockState.BestBlockHeader() + // if err != nil { + // logger.Error("failed to get best block header", "error", err) + // return + // } + + // // if we're at genesis, set the first slot number for the network + // if head.Number.Cmp(big.NewInt(0)) == 0 { + // epochStart = getCurrentSlot(b.slotDuration) + // err = b.epochState.SetFirstSlot(epochStart) + // if err != nil { + // logger.Error("failed to set first slot number", "error", err) + // return + // } + // } - logger.Info("initiating epoch", "number", epoch, "first slot of epoch", epochStart) err = b.initiateEpoch(epoch) if err != nil { logger.Error("failed to initiate epoch", "epoch", epoch, "error", err) diff --git a/lib/babe/epoch.go b/lib/babe/epoch.go index 762dc19de4..60d6b4fe61 100644 --- a/lib/babe/epoch.go +++ b/lib/babe/epoch.go @@ -18,8 +18,7 @@ package babe import ( "fmt" - - "github.com/ChainSafe/gossamer/dot/types" + //"github.com/ChainSafe/gossamer/dot/types" ) // initiateEpoch sets the epochData for the given epoch, runs the lottery for the slots in the epoch, @@ -41,20 +40,12 @@ func (b *Service) initiateEpoch(epoch uint64) error { return err } - var data *types.EpochData if !has { - // data = &types.EpochData{ - // Randomness: b.epochData.randomness, - // Authorities: b.epochData.authorities, - // } - - // err = b.epochState.SetEpochData(epoch, data) logger.Crit("no epoch data for next BABE epoch", "epoch", epoch) return errNoEpochData - } else { - data, err = b.epochState.GetEpochData(epoch) } + data, err := b.epochState.GetEpochData(epoch) if err != nil { return err } @@ -99,9 +90,26 @@ func (b *Service) initiateEpoch(epoch uint64) error { if err != nil { return err } - } else if b.blockState.BestBlockHash() == b.blockState.GenesisHash() { - // we are at genesis, set first slot using current time + } + + // if we're at genesis, we need to determine when the first slot of the network will be + // by checking when we will be able to produce block 1. + // note that this assumes there will only be one producer of block 1 + if b.blockState.BestBlockHash() == b.blockState.GenesisHash() { startSlot = getCurrentSlot(b.slotDuration) + + for i := startSlot; i < startSlot+b.epochLength; i++ { + proof, err := b.runLottery(i, epoch) //nolint + if err != nil { + return fmt.Errorf("error running slot lottery at slot %d: error %s", i, err) + } + + if proof != nil { + startSlot = i + } + } + + // we are at genesis, set first slot by checking at which slot we will be able to produce block 1 err = b.epochState.SetFirstSlot(startSlot) if err != nil { return err @@ -112,7 +120,7 @@ func (b *Service) initiateEpoch(epoch uint64) error { return nil } - logger.Debug("initiating epoch", "epoch", epoch, "start slot", startSlot) + logger.Info("initiating epoch", "epoch", epoch, "start slot", startSlot) for i := startSlot; i < startSlot+b.epochLength; i++ { if epoch > 0 { diff --git a/lib/babe/verify.go b/lib/babe/verify.go index f3b8ca2df5..9531ef397a 100644 --- a/lib/babe/verify.go +++ b/lib/babe/verify.go @@ -143,17 +143,13 @@ func (v *VerificationManager) SetOnDisabled(index uint32, header *types.Header) func (v *VerificationManager) VerifyBlock(header *types.Header) error { var ( - info *verifierInfo - epoch uint64 - has bool - err error + info *verifierInfo + has bool ) // special case for block 1 - the network doesn't necessarily start in epoch 1. // if this happens, the database will be missing info for epochs before the first block. if header.Number.Cmp(big.NewInt(1)) == 0 { - epoch = 0 - block1IsFinal, err := v.blockState.NumberIsFinalised(big.NewInt(1)) if err != nil { return fmt.Errorf("failed to check if block 1 is finalised: %w", err) @@ -174,7 +170,7 @@ func (v *VerificationManager) VerifyBlock(header *types.Header) error { } } - epoch, err = v.epochState.GetEpochForBlock(header) + epoch, err := v.epochState.GetEpochForBlock(header) if err != nil { return fmt.Errorf("failed to get epoch for block header: %w", err) }