public BlockSynchronizer(IChainService chainService, IBlockValidationService blockValidationService, IBlockExecutor blockExecutor, IBlockSet blockSet, IBlockHeaderValidator blockHeaderValidator) { _chainService = chainService; _blockValidationService = blockValidationService; _blockExecutor = blockExecutor; _blockSet = blockSet; _blockHeaderValidator = blockHeaderValidator; _stateFSM = new NodeStateFSM().Create(); _logger = LogManager.GetLogger(nameof(BlockSynchronizer)); _terminated = false; _executeNextBlock = true; MessageHub.Instance.Subscribe <StateEvent>(e => { _stateFSM.ProcessWithStateEvent(e); _logger?.Trace($"BlockSynchronizer CurrentState: {CurrentState}"); MessageHub.Instance.Publish(new FSMStateChanged(CurrentState)); }); MessageHub.Instance.Subscribe <EnteringState>(async inState => { if (inState.NodeState.ShouldLockMiningWhenEntering()) { MessageHub.Instance.Publish(new LockMining(true)); } switch (inState.NodeState) { case NodeState.Catching: await ReceiveNextValidBlock(); break; case NodeState.Caught: await ReceiveNextValidBlock(); break; case NodeState.ExecutingLoop: // This node is free to mine a block during executing maybe-incorrect block again and again. MessageHub.Instance.Publish(new LockMining(false)); break; case NodeState.GeneratingConsensusTx: MessageHub.Instance.Publish(new LockMining(false)); break; case NodeState.Reverting: await HandleFork(); break; } }); MessageHub.Instance.Subscribe <LeavingState>(inState => { if (inState.NodeState.ShouldUnlockMiningWhenLeaving()) { MessageHub.Instance.Publish(new LockMining(false)); } }); MessageHub.Instance.Subscribe <HeadersReceived>(async inHeaders => { if (inHeaders?.Headers == null || !inHeaders.Headers.Any()) { _logger?.Warn("Null headers or header list is empty."); return; } var headers = inHeaders.Headers.OrderByDescending(h => h.Index).ToList(); foreach (var blockHeader in headers) { // Get previous block from the chain var correspondingBlockHeader = await BlockChain.GetBlockByHeightAsync(blockHeader.Index - 1); // If the hash of this previous block corresponds to "previous block hash" of the current header // the link has been found if (correspondingBlockHeader.BlockHashToHex == blockHeader.PreviousBlockHash.DumpHex()) { // Launch header accepted event and return MessageHub.Instance.Publish(new HeaderAccepted(blockHeader)); return; } } // Launch unlinkable again with the last headers index MessageHub.Instance.Publish(new UnlinkableHeader(headers.Last())); }); MessageHub.Instance.Subscribe <DPoSStateChanged>(inState => { MessageHub.Instance.Publish(inState.IsMining ? StateEvent.MiningStart : StateEvent.MiningEnd); }); MessageHub.Instance.Subscribe <BlockMined>(inBlock => { // Update DPoS process. //MessageHub.Instance.Publish(UpdateConsensus.Update); AddMinedBlock(inBlock.Block); }); MessageHub.Instance.Subscribe <BlockMinedAndStored>(inBlock => { // Update DPoS process. MessageHub.Instance.Publish(UpdateConsensus.Update); HandleMinedAndStroedBlock(inBlock.Block); }); MessageHub.Instance.Subscribe <TerminationSignal>(signal => { if (signal.Module == TerminatedModuleEnum.BlockSynchronizer) { _terminated = true; MessageHub.Instance.Publish(new TerminatedModule(TerminatedModuleEnum.BlockSynchronizer)); } }); }
public BlockHeaderValidator(IBlockSet blockSet, IChainService chainService) { _blockSet = blockSet; _chainService = chainService; }