示例#1
0
        /// <summary>
        /// The entrance of block syncing.
        /// First step is to validate block header of this block.
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        public async Task ReceiveBlock(IBlock block)
        {
            if (_terminated)
            {
                return;
            }

            var isReceiveBlock = await IsReceiveBlock(block);

            if (!isReceiveBlock)
            {
                return;
            }

            if (!_blockSet.IsBlockReceived(block.GetHash(), block.Index))
            {
                _blockSet.AddBlock(block);
                // Notify the network layer the block has been accepted.
                MessageHub.Instance.Publish(new BlockAccepted(block));
            }

            if (CurrentState != NodeState.Catching && CurrentState != NodeState.Caught)
            {
                return;
            }

            var blockHeaderValidationResult =
                await _blockHeaderValidator.ValidateBlockHeaderAsync(block.Header);

            _logger?.Trace(
                $"BlockHeader validation result: {blockHeaderValidationResult.ToString()} - {block.BlockHashToHex}. Height: *{block.Index}*");

            if (blockHeaderValidationResult == BlockHeaderValidationResult.Success)
            {
                // Catching -> BlockValidating
                // Caught -> BlockValidating
                MessageHub.Instance.Publish(StateEvent.ValidBlockHeader);
                await HandleBlock(block);
            }

            if (blockHeaderValidationResult == BlockHeaderValidationResult.Unlinkable)
            {
                MessageHub.Instance.Publish(new UnlinkableHeader(block.Header));
            }

            if (blockHeaderValidationResult == BlockHeaderValidationResult.MaybeForked)
            {
                MessageHub.Instance.Publish(StateEvent.LongerChainDetected);
            }

            if (blockHeaderValidationResult == BlockHeaderValidationResult.Branched)
            {
                MessageHub.Instance.Publish(new LockMining(false));
            }

            if (await IsRequestNextBlockAgain(block))
            {
                MessageHub.Instance.Publish(new BlockAccepted(block));
            }
        }