diff --git a/dot/services.go b/dot/services.go index 231a13fe5d..a1be078375 100644 --- a/dot/services.go +++ b/dot/services.go @@ -530,6 +530,7 @@ func (nodeBuilder) newSyncService(config *cfg.Config, st *state.Service, fg sync BlockImportHandler: cs, Telemetry: telemetryMailer, BadBlocks: genesisData.BadBlocks, + GrandpaState: st.Grandpa, RequestMaker: requestMaker, } fullSync := sync.NewFullSyncStrategy(syncCfg) diff --git a/dot/sync/block_importer.go b/dot/sync/block_importer.go index 395113c8a4..c5ae40b8e0 100644 --- a/dot/sync/block_importer.go +++ b/dot/sync/block_importer.go @@ -52,6 +52,11 @@ type ( VerifyBlockJustification(common.Hash, uint, []byte) (round uint64, setID uint64, err error) } + // GrandpaState is the interface for the state.GrandpaState + GrandpaState interface { + ApplyForcedChanges(importedHeader *types.Header) error + } + // BlockImportHandler is the interface for the handler of newly imported blocks BlockImportHandler interface { HandleBlockImport(block *types.Block, state *rtstorage.TrieState, announce bool) error @@ -64,6 +69,7 @@ type blockImporter struct { transactionState TransactionState babeVerifier BabeVerifier finalityGadget FinalityGadget + grandpaState GrandpaState blockImportHandler BlockImportHandler telemetry Telemetry } @@ -75,6 +81,7 @@ func newBlockImporter(cfg *FullSyncConfig) *blockImporter { transactionState: cfg.TransactionState, babeVerifier: cfg.BabeVerifier, finalityGadget: cfg.FinalityGadget, + grandpaState: cfg.GrandpaState, blockImportHandler: cfg.BlockImportHandler, telemetry: cfg.Telemetry, } @@ -104,31 +111,45 @@ func (b *blockImporter) importBlock(bd *types.BlockData, origin BlockOrigin) (im // or the index of the block data that errored on failure. func (b *blockImporter) processBlockData(blockData types.BlockData, origin BlockOrigin) error { if blockData.Header != nil { - header := blockData.Header + var ( + hasJustification = blockData.Justification != nil && len(*blockData.Justification) > 0 + round uint64 + setID uint64 + ) - if blockData.Body != nil { - err := b.processBlockDataWithHeaderAndBody(blockData, origin) + err := b.grandpaState.ApplyForcedChanges(blockData.Header) + if err != nil { + return fmt.Errorf("applying forced changes: %w", err) + } + + if hasJustification { + var err error + round, setID, err = b.finalityGadget.VerifyBlockJustification( + blockData.Header.Hash(), blockData.Header.Number, *blockData.Justification) if err != nil { - return fmt.Errorf("processing block data with header and body: %w", err) + return fmt.Errorf("verifying justification: %w", err) } } - if blockData.Justification != nil && len(*blockData.Justification) > 0 { - round, setID, err := b.finalityGadget.VerifyBlockJustification( - header.Hash(), header.Number, *blockData.Justification) + if blockData.Body != nil { + err := b.processBlockDataWithHeaderAndBody(blockData, origin) if err != nil { - return fmt.Errorf("verifying justification for block %s: %w", header.Hash().String(), err) + return fmt.Errorf("processing block data with header and body: %w", err) } + } - err = b.blockState.SetFinalisedHash(header.Hash(), round, setID) + if hasJustification { + header := blockData.Header + err := b.blockState.SetFinalisedHash(header.Hash(), round, setID) if err != nil { return fmt.Errorf("setting finalised hash: %w", err) } - err = b.blockState.SetJustification(header.Hash(), *blockData.Justification) if err != nil { return fmt.Errorf("setting justification for block number %d: %w", header.Number, err) } + + return nil } } err := b.blockState.CompareAndSetBlockData(&blockData) diff --git a/dot/sync/fullsync.go b/dot/sync/fullsync.go index 862e74327e..f87f83fbad 100644 --- a/dot/sync/fullsync.go +++ b/dot/sync/fullsync.go @@ -37,6 +37,7 @@ type FullSyncConfig struct { TransactionState TransactionState BabeVerifier BabeVerifier FinalityGadget FinalityGadget + GrandpaState GrandpaState BlockImportHandler BlockImportHandler Telemetry Telemetry BlockState BlockState