From 5cd4263f571a1ee142653325e3379c338e93988a Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 18 Jul 2022 12:11:39 +0530 Subject: [PATCH 01/12] temp --- lib/babe/epoch_handler.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/babe/epoch_handler.go b/lib/babe/epoch_handler.go index b2cde8af8c..7648b405ce 100644 --- a/lib/babe/epoch_handler.go +++ b/lib/babe/epoch_handler.go @@ -135,6 +135,7 @@ func (h *epochHandler) run(ctx context.Context, errCh chan<- error) { panic(fmt.Sprintf("no VRF proof for authoring slot! slot=%d", swt.slotNum)) } + logger.Infof("handling slot %d", swt.slotNum) err := h.handleSlot(h.epochNumber, swt.slotNum, h.epochData.authorityIndex, h.slotToPreRuntimeDigest[swt.slotNum]) if err != nil { logger.Warnf("failed to handle slot %d: %s", swt.slotNum, err) From f57fa84b9d71224a18c6775acdf072244f93fe39 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 18 Jul 2022 21:10:15 +0530 Subject: [PATCH 02/12] temp --- dot/state/epoch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/dot/state/epoch.go b/dot/state/epoch.go index 0b5ab5db83..c83e6195a8 100644 --- a/dot/state/epoch.go +++ b/dot/state/epoch.go @@ -264,6 +264,7 @@ func (s *EpochState) GetEpochData(epoch uint64, header *types.Header) (*types.Ep s.nextEpochDataLock.RLock() defer s.nextEpochDataLock.RUnlock() + // here inMemoryEpochData, err := s.nextEpochData.Retrieve(s.blockState, epoch, header) if err != nil { return nil, fmt.Errorf("failed to get epoch data from memory: %w", err) From 12fde0bf795afa6b42c50417629ddc600a0e9901 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Wed, 3 Aug 2022 19:04:02 +0800 Subject: [PATCH 03/12] temp --- lib/babe/babe.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/babe/babe.go b/lib/babe/babe.go index d0dd5fa4e7..8b991b29f4 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -497,6 +497,20 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } + slotNumOfTheBestBlock, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) + if err != nil { + return err + } + + // When can this happen, + // - inconsistency in slot calculation, like may be rust code and go code running simultaneously, + // it does not produce the same slot number. Otherwise, why would I have a block for a slot number + // that is ongoing? + // - Also, should I even accept a block for the ongoing slot number? I feel like noce + if slotNumOfTheBestBlock == slotNum { + + } + if parentHeader == nil { return errNilParentHeader } From ae2fa69833c0938adc55425b33c458c3ae7531e2 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Thu, 4 Aug 2022 20:15:44 +0530 Subject: [PATCH 04/12] While authoring a new block, if we find that best block was authored in the current slot, we should author a new block as child of best block's parent. This would create forks in the chain which would get resolved eventually. --- lib/babe/babe.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/babe/babe.go b/lib/babe/babe.go index 8b991b29f4..1716f68424 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -502,13 +502,14 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } - // When can this happen, - // - inconsistency in slot calculation, like may be rust code and go code running simultaneously, - // it does not produce the same slot number. Otherwise, why would I have a block for a slot number - // that is ongoing? - // - Also, should I even accept a block for the ongoing slot number? I feel like noce if slotNumOfTheBestBlock == slotNum { + // pick parent of best block instead to handle slot + newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) + if err != nil { + return err + } + parentHeader = newParentHeader } if parentHeader == nil { From cc2ffaf477e4f17c4a4b23e22f42a5ad1699e620 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Thu, 4 Aug 2022 20:25:46 +0530 Subject: [PATCH 05/12] clean up --- dot/state/epoch.go | 1 - lib/babe/babe.go | 4 ++-- lib/babe/epoch_handler.go | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dot/state/epoch.go b/dot/state/epoch.go index c83e6195a8..0b5ab5db83 100644 --- a/dot/state/epoch.go +++ b/dot/state/epoch.go @@ -264,7 +264,6 @@ func (s *EpochState) GetEpochData(epoch uint64, header *types.Header) (*types.Ep s.nextEpochDataLock.RLock() defer s.nextEpochDataLock.RUnlock() - // here inMemoryEpochData, err := s.nextEpochData.Retrieve(s.blockState, epoch, header) if err != nil { return nil, fmt.Errorf("failed to get epoch data from memory: %w", err) diff --git a/lib/babe/babe.go b/lib/babe/babe.go index 1716f68424..4fd8c68009 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -499,14 +499,14 @@ func (b *Service) handleSlot(epoch, slotNum uint64, slotNumOfTheBestBlock, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) if err != nil { - return err + return fmt.Errorf("could not get slot for block %s: %w", parentHeader.Hash(), err) } if slotNumOfTheBestBlock == slotNum { // pick parent of best block instead to handle slot newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) if err != nil { - return err + return fmt.Errorf("could not get header for hash %s: %w", parentHeader.ParentHash, err) } parentHeader = newParentHeader diff --git a/lib/babe/epoch_handler.go b/lib/babe/epoch_handler.go index 706245fd61..52e75ba3dd 100644 --- a/lib/babe/epoch_handler.go +++ b/lib/babe/epoch_handler.go @@ -135,7 +135,6 @@ func (h *epochHandler) run(ctx context.Context, errCh chan<- error) { panic(fmt.Sprintf("no VRF proof for authoring slot! slot=%d", swt.slotNum)) } - logger.Infof("handling slot %d", swt.slotNum) err := h.handleSlot(h.epochNumber, swt.slotNum, h.epochData.authorityIndex, h.slotToPreRuntimeDigest[swt.slotNum]) if err != nil { logger.Warnf("failed to handle slot %d: %s", swt.slotNum, err) From cbc44d2ca03e07342023a59b7beecf2f5be555be Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Fri, 5 Aug 2022 20:59:30 +0530 Subject: [PATCH 06/12] add a check for current slot is greater than slot in best block --- lib/babe/babe.go | 8 ++++++-- lib/babe/errors.go | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/babe/babe.go b/lib/babe/babe.go index 4fd8c68009..e4b8b65c8f 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -497,12 +497,16 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } - slotNumOfTheBestBlock, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) + bestBlockSlotNum, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) if err != nil { return fmt.Errorf("could not get slot for block %s: %w", parentHeader.Hash(), err) } - if slotNumOfTheBestBlock == slotNum { + if bestBlockSlotNum > slotNum { + return errLaggingSlot + } + + if bestBlockSlotNum == slotNum { // pick parent of best block instead to handle slot newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) if err != nil { diff --git a/lib/babe/errors.go b/lib/babe/errors.go index 670f85dcf1..4548ed3a3b 100644 --- a/lib/babe/errors.go +++ b/lib/babe/errors.go @@ -78,6 +78,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("cannot claim slot, current slot is smaller than slot of best block") other Other invalidCustom InvalidCustom From 3de132f4f7b0c5b85892205ee0aede1244130244 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Tue, 16 Aug 2022 15:20:01 +0530 Subject: [PATCH 07/12] test for err slot lagging --- lib/babe/babe_integration_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index ec5d31a0b6..550ea9cac4 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -301,3 +301,30 @@ func TestService_PauseAndResume(t *testing.T) { err = bs.Stop() require.NoError(t, err) } + +func TestService_HandleSlotWithSameSlot(t *testing.T) { + cfg := &ServiceConfig{ + Authority: true, + Lead: true, + } + babeService := createTestService(t, cfg) + + err := babeService.Start() + require.NoError(t, err) + defer func() { + _ = babeService.Stop() + }() + + time.Sleep(babeService.constants.slotDuration * 2) + + header, err := babeService.blockState.BestBlockHeader() + require.NoError(t, err) + + bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(header.Hash()) + require.NoError(t, err) + + // todo: create predigest + var preRuntimeDigest *types.PreRuntimeDigest + err = babeService.handleSlot(babeService.epochHandler.epochNumber, bestBlockSlotNum-1, babeService.epochHandler.epochData.authorityIndex, preRuntimeDigest) + require.ErrorAs(t, err, errLaggingSlot) +} From a63a0739800f6ec0ade711229d287021ce60c764 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Wed, 17 Aug 2022 14:48:11 +0530 Subject: [PATCH 08/12] test --- lib/babe/babe_integration_test.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index 550ea9cac4..95f71ebc47 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -323,8 +323,20 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(header.Hash()) require.NoError(t, err) - // todo: create predigest - var preRuntimeDigest *types.PreRuntimeDigest + slotnum := uint64(1) + slot := Slot{ + start: time.Now(), + duration: 1 * time.Second, + number: slotnum, + } + testVRFOutputAndProof := &VrfOutputAndProof{} + preRuntimeDigest, err := types.NewBabePrimaryPreDigest( + 0, slot.number, + testVRFOutputAndProof.output, + testVRFOutputAndProof.proof, + ).ToPreRuntimeDigest() + require.NoError(t, err) + err = babeService.handleSlot(babeService.epochHandler.epochNumber, bestBlockSlotNum-1, babeService.epochHandler.epochData.authorityIndex, preRuntimeDigest) require.ErrorAs(t, err, errLaggingSlot) } From aca3b683ef2ebf9be1639acad1441e66a3c444a2 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Wed, 17 Aug 2022 20:41:16 +0530 Subject: [PATCH 09/12] fix test for errLaggingSlot --- lib/babe/babe_integration_test.go | 26 +++++++++++++++++++++++--- lib/genesis/test_utils.go | 17 ++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index 95f71ebc47..eb009aec46 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -15,6 +15,7 @@ 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/genesis" "github.com/ChainSafe/gossamer/lib/runtime" @@ -315,7 +316,20 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { _ = babeService.Stop() }() - time.Sleep(babeService.constants.slotDuration * 2) + // 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 * 10) header, err := babeService.blockState.BestBlockHeader() require.NoError(t, err) @@ -335,8 +349,14 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { testVRFOutputAndProof.output, testVRFOutputAndProof.proof, ).ToPreRuntimeDigest() + require.NoError(t, err) - err = babeService.handleSlot(babeService.epochHandler.epochNumber, bestBlockSlotNum-1, babeService.epochHandler.epochData.authorityIndex, preRuntimeDigest) - require.ErrorAs(t, err, errLaggingSlot) + err = babeService.handleSlot( + babeService.epochHandler.epochNumber, + bestBlockSlotNum-1, + babeService.epochHandler.epochData.authorityIndex, + preRuntimeDigest) + + require.ErrorIs(t, err, errLaggingSlot) } diff --git a/lib/genesis/test_utils.go b/lib/genesis/test_utils.go index 418d743d33..7fb94428dc 100644 --- a/lib/genesis/test_utils.go +++ b/lib/genesis/test_utils.go @@ -13,6 +13,7 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" + "github.com/ChainSafe/gossamer/pkg/scale" "github.com/stretchr/testify/require" ) @@ -100,8 +101,22 @@ func newGenesisTrieAndHeader(t *testing.T, gen *Genesis) (*trie.Trie, *types.Hea genTrie, err := NewTrieFromGenesis(gen) require.NoError(t, err) + babeDigest := types.NewBabeDigest() + err = babeDigest.Set(types.BabePrimaryPreDigest{AuthorityIndex: 0}) + require.NoError(t, err) + + bdEnc, err := scale.Marshal(babeDigest) + require.NoError(t, err) + + digest := types.NewDigest() + err = digest.Add(types.PreRuntimeDigest{ + ConsensusEngineID: types.BabeEngineID, + Data: bdEnc, + }) + require.NoError(t, err) + genesisHeader, err := types.NewHeader(common.NewHash([]byte{0}), - genTrie.MustHash(), trie.EmptyHash, 0, types.NewDigest()) + genTrie.MustHash(), trie.EmptyHash, 0, digest) require.NoError(t, err) return genTrie, genesisHeader From 9c9f47b61883410140666f87758c1c55823d261f Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Wed, 17 Aug 2022 21:00:08 +0530 Subject: [PATCH 10/12] test that we create a fork if best block is authored in the same slot that we are claiming at the moment --- lib/babe/babe_integration_test.go | 65 ++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index eb009aec46..0b03489b98 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -303,7 +303,7 @@ func TestService_PauseAndResume(t *testing.T) { require.NoError(t, err) } -func TestService_HandleSlotWithSameSlot(t *testing.T) { +func TestService_HandleSlotWithLaggingSlot(t *testing.T) { cfg := &ServiceConfig{ Authority: true, Lead: true, @@ -360,3 +360,66 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { require.ErrorIs(t, err, errLaggingSlot) } + +func TestService_HandleSlotWithSameSlot(t *testing.T) { + cfg := &ServiceConfig{ + Authority: true, + Lead: true, + } + babeService := createTestService(t, cfg) + + err := babeService.Start() + require.NoError(t, err) + defer func() { + _ = babeService.Stop() + }() + + // 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 * 10) + + bestBlockHeader, err := babeService.blockState.BestBlockHeader() + require.NoError(t, err) + + bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(bestBlockHeader.Hash()) + require.NoError(t, err) + + slotnum := uint64(1) + slot := Slot{ + start: time.Now(), + duration: 1 * time.Second, + number: slotnum, + } + testVRFOutputAndProof := &VrfOutputAndProof{} + preRuntimeDigest, err := types.NewBabePrimaryPreDigest( + 0, slot.number, + testVRFOutputAndProof.output, + testVRFOutputAndProof.proof, + ).ToPreRuntimeDigest() + + require.NoError(t, err) + + err = babeService.handleSlot( + babeService.epochHandler.epochNumber, + bestBlockSlotNum, + babeService.epochHandler.epochData.authorityIndex, + preRuntimeDigest) + + require.NoError(t, err) + + // test that newly created block is sibling of bestBlockHeader + siblings := babeService.blockState.GetAllBlocksAtDepth(bestBlockHeader.ParentHash) + require.GreaterOrEqual(t, len(siblings), 2) + require.Contains(t, bestBlockHeader.Hash(), siblings) +} From 527f51534db2b86d4f105ad433eefc60687625ca Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 22 Aug 2022 22:17:24 +0530 Subject: [PATCH 11/12] temp --- lib/babe/babe.go | 36 ++++++++++++++++++------------- lib/babe/babe_integration_test.go | 13 ++++++++--- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/babe/babe.go b/lib/babe/babe.go index e4b8b65c8f..72a0fc604f 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -497,27 +497,32 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } - bestBlockSlotNum, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) - if err != nil { - return fmt.Errorf("could not get slot for block %s: %w", parentHeader.Hash(), err) - } - - if bestBlockSlotNum > slotNum { - return errLaggingSlot + if parentHeader == nil { + return errNilParentHeader } - if bestBlockSlotNum == slotNum { - // pick parent of best block instead to handle slot - newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) + atGenesisBlock := b.blockState.GenesisHash().Equal(parentHeader.Hash()) + if !atGenesisBlock { + bestBlockSlotNum, err := b.blockState.GetSlotForBlock(parentHeader.Hash()) if err != nil { - return fmt.Errorf("could not get header for hash %s: %w", parentHeader.ParentHash, err) + return fmt.Errorf("could not get slot for block %s: %w", parentHeader.Hash(), err) } - parentHeader = newParentHeader - } + if bestBlockSlotNum > slotNum { + return errLaggingSlot + } - if parentHeader == nil { - return errNilParentHeader + if bestBlockSlotNum == slotNum { + // pick parent of best block instead to handle slot + newParentHeader, err := b.blockState.GetHeader(parentHeader.ParentHash) + if err != nil { + return fmt.Errorf("could not get header for hash %s: %w", parentHeader.ParentHash, err) + } + if newParentHeader == nil { + return errNilParentHeader + } + parentHeader = newParentHeader + } } // there is a chance that the best block header may change in the course of building the block, @@ -557,6 +562,7 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } + fmt.Printf("block %s\nblock number %d\n\n", block.Header.Hash(), block.Header.Number) logger.Infof( "built block %d with hash %s, state root %s, epoch %d and slot %d", block.Header.Number, block.Header.Hash(), block.Header.StateRoot, epoch, slotNum) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index 0b03489b98..eba0c19ae7 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -6,6 +6,7 @@ package babe import ( + "fmt" "path/filepath" "testing" "time" @@ -388,18 +389,18 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { babeService.blockState.AddBlock(block) time.Sleep(babeService.constants.slotDuration * 10) - + _ = babeService.Stop() bestBlockHeader, err := babeService.blockState.BestBlockHeader() require.NoError(t, err) bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(bestBlockHeader.Hash()) require.NoError(t, err) - slotnum := uint64(1) + // slotnum := uint64(1) slot := Slot{ start: time.Now(), duration: 1 * time.Second, - number: slotnum, + number: bestBlockSlotNum, } testVRFOutputAndProof := &VrfOutputAndProof{} preRuntimeDigest, err := types.NewBabePrimaryPreDigest( @@ -417,9 +418,15 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { preRuntimeDigest) require.NoError(t, err) + fmt.Printf("\nbestBlockHeader %s\nblock number %d\n\n", bestBlockHeader.Hash(), bestBlockHeader.Number) + time.Sleep(20 * time.Second) // test that newly created block is sibling of bestBlockHeader siblings := babeService.blockState.GetAllBlocksAtDepth(bestBlockHeader.ParentHash) + fmt.Println() + fmt.Println(siblings) + temphead, _ := babeService.blockState.GetHeader(siblings[0]) + fmt.Printf("temphead number %d\n\n", temphead.Number) require.GreaterOrEqual(t, len(siblings), 2) require.Contains(t, bestBlockHeader.Hash(), siblings) } From cecc3086226d012e4a97ce8586e01af2b74d6ecc Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Mon, 29 Aug 2022 20:03:08 +0530 Subject: [PATCH 12/12] fixed tests --- dot/services.go | 1 + dot/types/authority.go | 4 +- lib/babe/babe.go | 1 - lib/babe/babe_integration_test.go | 106 +++++++++++++++++++++--------- 4 files changed, 78 insertions(+), 34 deletions(-) diff --git a/dot/services.go b/dot/services.go index a9bc446d3f..4cdbeb73d8 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 8962568880..9005cb911a 100644 --- a/dot/types/authority.go +++ b/dot/types/authority.go @@ -15,7 +15,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 72a0fc604f..f6f18d4e8b 100644 --- a/lib/babe/babe.go +++ b/lib/babe/babe.go @@ -562,7 +562,6 @@ func (b *Service) handleSlot(epoch, slotNum uint64, return err } - fmt.Printf("block %s\nblock number %d\n\n", block.Header.Hash(), block.Header.Number) logger.Infof( "built block %d with hash %s, state root %s, epoch %d and slot %d", block.Header.Number, block.Header.Hash(), block.Header.StateRoot, epoch, slotNum) diff --git a/lib/babe/babe_integration_test.go b/lib/babe/babe_integration_test.go index eba0c19ae7..5d96f9a8f0 100644 --- a/lib/babe/babe_integration_test.go +++ b/lib/babe/babe_integration_test.go @@ -6,7 +6,6 @@ package babe import ( - "fmt" "path/filepath" "testing" "time" @@ -330,7 +329,7 @@ func TestService_HandleSlotWithLaggingSlot(t *testing.T) { 1, testEpochIndex, epochData) babeService.blockState.AddBlock(block) - time.Sleep(babeService.constants.slotDuration * 10) + time.Sleep(babeService.constants.slotDuration * 1) header, err := babeService.blockState.BestBlockHeader() require.NoError(t, err) @@ -363,40 +362,95 @@ func TestService_HandleSlotWithLaggingSlot(t *testing.T) { } func TestService_HandleSlotWithSameSlot(t *testing.T) { - cfg := &ServiceConfig{ + alice := keyring.Alice().(*sr25519.Keypair) + bob := keyring.Bob().(*sr25519.Keypair) + + // Create babe service for alice + cfgAlice := &ServiceConfig{ Authority: true, Lead: true, + Keypair: alice, + } + cfgAlice.AuthData = []types.Authority{ + { + Key: alice.Public().(*sr25519.PublicKey), + Weight: 1, + }, + { + Key: bob.Public().(*sr25519.PublicKey), + Weight: 1, + }, } - babeService := createTestService(t, cfg) - err := babeService.Start() + // Create babe service for bob + cfgBob := &ServiceConfig{ + Authority: true, + Lead: true, + Keypair: bob, + } + cfgBob.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() { - _ = babeService.Stop() + _ = babeServiceBob.Stop() }() - // add a block - parentHash := babeService.blockState.GenesisHash() - rt, err := babeService.blockState.GetRuntime(nil) + time.Sleep(babeServiceBob.constants.slotDuration * 5) + + // create a block using bob + parentHash := babeServiceBob.blockState.GenesisHash() + rt, err := babeServiceBob.blockState.GetRuntime(nil) require.NoError(t, err) - epochData, err := babeService.initiateEpoch(testEpochIndex) + epochData, err := babeServiceBob.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)}, + block := createTestBlock(t, babeServiceBob, emptyHeader, [][]byte{common.MustHexToBytes(ext)}, 1, testEpochIndex, epochData) - babeService.blockState.AddBlock(block) - time.Sleep(babeService.constants.slotDuration * 10) - _ = babeService.Stop() - bestBlockHeader, err := babeService.blockState.BestBlockHeader() + err = babeServiceBob.Stop() + require.NoError(t, err) + + babeServiceAlice := createTestService(t, cfgAlice) + + err = babeServiceAlice.Start() + require.NoError(t, err) + defer func() { + _ = babeServiceAlice.Stop() + }() + time.Sleep(babeServiceAlice.constants.slotDuration * 1) + + // Add block created by Bob to Alice + babeServiceAlice.blockState.AddBlock(block) + + time.Sleep(babeServiceAlice.constants.slotDuration * 1) + + bestBlockHeader, err := babeServiceAlice.blockState.BestBlockHeader() + require.NoError(t, err) + + require.Equal(t, block.Header.Hash().String(), bestBlockHeader.Hash().String()) + + // If the slot we are claiming is same as slot in best header, test that we don't + // through any error and can claim slot. + bestBlockSlotNum, err := babeServiceAlice.blockState.GetSlotForBlock(bestBlockHeader.Hash()) require.NoError(t, err) - bestBlockSlotNum, err := babeService.blockState.GetSlotForBlock(bestBlockHeader.Hash()) + err = babeServiceAlice.Stop() require.NoError(t, err) - // slotnum := uint64(1) slot := Slot{ start: time.Now(), duration: 1 * time.Second, @@ -408,25 +462,13 @@ func TestService_HandleSlotWithSameSlot(t *testing.T) { testVRFOutputAndProof.output, testVRFOutputAndProof.proof, ).ToPreRuntimeDigest() - require.NoError(t, err) - err = babeService.handleSlot( - babeService.epochHandler.epochNumber, + err = babeServiceAlice.handleSlot( + babeServiceAlice.epochHandler.epochNumber, bestBlockSlotNum, - babeService.epochHandler.epochData.authorityIndex, + babeServiceAlice.epochHandler.epochData.authorityIndex, preRuntimeDigest) - require.NoError(t, err) - fmt.Printf("\nbestBlockHeader %s\nblock number %d\n\n", bestBlockHeader.Hash(), bestBlockHeader.Number) - time.Sleep(20 * time.Second) - // test that newly created block is sibling of bestBlockHeader - siblings := babeService.blockState.GetAllBlocksAtDepth(bestBlockHeader.ParentHash) - fmt.Println() - fmt.Println(siblings) - temphead, _ := babeService.blockState.GetHeader(siblings[0]) - fmt.Printf("temphead number %d\n\n", temphead.Number) - require.GreaterOrEqual(t, len(siblings), 2) - require.Contains(t, bestBlockHeader.Hash(), siblings) }