예제 #1
0
        private async Task RefreshPeerInfo(PeerInfo peerInfo, CancellationToken token)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Requesting head block info from {peerInfo.SyncPeer.Node:s}");
            }

            ISyncPeer          syncPeer          = peerInfo.SyncPeer;
            Task <BlockHeader> getHeadHeaderTask = peerInfo.SyncPeer.GetHeadBlockHeader(peerInfo.HeadHash, token);
            Task delayTask       = Task.Delay(InitTimeout, token);
            Task firstToComplete = await Task.WhenAny(getHeadHeaderTask, delayTask);

            await firstToComplete.ContinueWith(
                t =>
            {
                if (firstToComplete.IsFaulted || firstToComplete == delayTask)
                {
                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                    }
                    syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault");
                    SyncEvent?.Invoke(this, new SyncEventArgs(syncPeer, peerInfo.IsInitialized ? Synchronization.SyncEvent.Failed : Synchronization.SyncEvent.InitFailed));
                }
                else if (firstToComplete.IsCanceled)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"InitPeerInfo canceled for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                    }
                    SyncEvent?.Invoke(this, new SyncEventArgs(syncPeer, peerInfo.IsInitialized ? Synchronization.SyncEvent.Cancelled : Synchronization.SyncEvent.InitCancelled));
                    token.ThrowIfCancellationRequested();
                }
                else
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Received head block info from {syncPeer.Node:c} with head block numer {getHeadHeaderTask.Result}");
                    }
                    if (!peerInfo.IsInitialized)
                    {
                        SyncEvent?.Invoke(
                            this,
                            new SyncEventArgs(syncPeer, Synchronization.SyncEvent.InitCompleted));
                    }

                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"REFRESH Updating header of {peerInfo} from {peerInfo.HeadNumber} to {getHeadHeaderTask.Result.Number}");
                    }
                    peerInfo.HeadNumber = getHeadHeaderTask.Result.Number;
                    peerInfo.HeadHash   = getHeadHeaderTask.Result.Hash;

                    BlockHeader parent = _blockTree.FindHeader(getHeadHeaderTask.Result.ParentHash);
                    if (parent != null)
                    {
                        peerInfo.TotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + getHeadHeaderTask.Result.Difficulty;
                    }

                    peerInfo.IsInitialized = true;
                    foreach ((SyncPeerAllocation allocation, object _) in _allocations)
                    {
                        if (allocation.Current == peerInfo)
                        {
                            allocation.Refresh();
                        }
                    }
                }
            }, token);
        }
예제 #2
0
        private async Task ExecuteRefreshTask(RefreshTotalDiffTask refreshTotalDiffTask, CancellationToken token)
        {
            PeerInfo peerInfo = refreshTotalDiffTask.PeerInfo;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Requesting head block info from {peerInfo.SyncPeer.Node:s}");
            }

            ISyncPeer syncPeer                   = peerInfo.SyncPeer;
            var       getHeadHeaderTask          = peerInfo.SyncPeer.GetHeadBlockHeader(refreshTotalDiffTask.BlockHash ?? peerInfo.HeadHash, token);
            CancellationTokenSource delaySource  = new CancellationTokenSource();
            CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(delaySource.Token, token);
            Task delayTask       = Task.Delay(InitTimeout, linkedSource.Token);
            Task firstToComplete = await Task.WhenAny(getHeadHeaderTask, delayTask);

            await firstToComplete.ContinueWith(
                t =>
            {
                try
                {
                    if (firstToComplete.IsFaulted || firstToComplete == delayTask)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                        syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - timeout");
                    }
                    else if (firstToComplete.IsCanceled)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"InitPeerInfo canceled for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncCancelled : NodeStatsEventType.SyncInitCancelled);
                        token.ThrowIfCancellationRequested();
                    }
                    else
                    {
                        delaySource.Cancel();
                        BlockHeader header = getHeadHeaderTask.Result;
                        if (header == null)
                        {
                            if (_logger.IsDebug)
                            {
                                _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                            }

                            _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                            syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - null response");
                            return;
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Received head block info from {syncPeer.Node:c} with head block numer {header.Number}");
                        }
                        if (!peerInfo.IsInitialized)
                        {
                            _stats.ReportSyncEvent(syncPeer.Node, NodeStatsEventType.SyncInitCompleted);
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"REFRESH Updating header of {peerInfo} from {peerInfo.HeadNumber} to {header.Number}");
                        }

                        BlockHeader parent = _blockTree.FindHeader(header.ParentHash, BlockTreeLookupOptions.None);
                        if (parent != null)
                        {
                            UInt256 newTotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty;
                            if (newTotalDifficulty >= peerInfo.TotalDifficulty)
                            {
                                peerInfo.TotalDifficulty = newTotalDifficulty;
                                peerInfo.HeadNumber      = header.Number;
                                peerInfo.HeadHash        = header.Hash;
                            }
                        }
                        else if (header.Number > peerInfo.HeadNumber)
                        {
                            peerInfo.HeadNumber = header.Number;
                            peerInfo.HeadHash   = header.Hash;
                        }

                        peerInfo.IsInitialized = true;
                        foreach ((SyncPeerAllocation allocation, object _) in _replaceableAllocations)
                        {
                            if (allocation.Current == peerInfo)
                            {
                                allocation.Refresh();
                            }
                        }

                        _signals.Set();
                        PeerAdded?.Invoke(this, EventArgs.Empty);
                    }
                }
                finally
                {
                    linkedSource.Dispose();
                    delaySource.Dispose();
                }
            }, token);
        }
예제 #3
0
        private async Task ExecuteRefreshTask(RefreshTotalDiffTask refreshTotalDiffTask, CancellationToken token)
        {
            ISyncPeer syncPeer = refreshTotalDiffTask.SyncPeer;

            if (_logger.IsTrace)
            {
                _logger.Trace($"Requesting head block info from {syncPeer.Node:s}");
            }

            var getHeadHeaderTask = syncPeer.GetHeadBlockHeader(refreshTotalDiffTask.BlockHash ?? syncPeer.HeadHash, token);
            CancellationTokenSource delaySource  = new CancellationTokenSource();
            CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(delaySource.Token, token);
            Task delayTask       = Task.Delay(InitTimeout, linkedSource.Token);
            Task firstToComplete = await Task.WhenAny(getHeadHeaderTask, delayTask);

            await firstToComplete.ContinueWith(
                t =>
            {
                try
                {
                    if (firstToComplete == delayTask)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"InitPeerInfo timed out for node: {syncPeer.Node:c}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, syncPeer.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                        syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - timeout");
                    }
                    else if (firstToComplete.IsFaulted)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, syncPeer.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                        syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - timeout");
                    }
                    else if (firstToComplete.IsCanceled)
                    {
                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"InitPeerInfo canceled for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }
                        _stats.ReportSyncEvent(syncPeer.Node, syncPeer.IsInitialized ? NodeStatsEventType.SyncCancelled : NodeStatsEventType.SyncInitCancelled);
                        token.ThrowIfCancellationRequested();
                    }
                    else
                    {
                        delaySource.Cancel();
                        BlockHeader header = getHeadHeaderTask.Result;
                        if (header == null)
                        {
                            if (_logger.IsDebug)
                            {
                                _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                            }
                            _stats.ReportSyncEvent(syncPeer.Node, syncPeer.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                            syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault - null response");
                            return;
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"Received head block info from {syncPeer.Node:c} with head block numer {header.Number}");
                        }
                        if (!syncPeer.IsInitialized)
                        {
                            _stats.ReportSyncEvent(syncPeer.Node, NodeStatsEventType.SyncInitCompleted);
                        }

                        if (_logger.IsTrace)
                        {
                            _logger.Trace($"REFRESH Updating header of {syncPeer} from {syncPeer.HeadNumber} to {header.Number}");
                        }

                        BlockHeader parent = _blockTree.FindParentHeader(header, BlockTreeLookupOptions.None);
                        if (parent != null)
                        {
                            UInt256 newTotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty;
                            if (newTotalDifficulty >= syncPeer.TotalDifficulty)
                            {
                                syncPeer.TotalDifficulty = newTotalDifficulty;
                                syncPeer.HeadNumber      = header.Number;
                                syncPeer.HeadHash        = header.Hash;
                            }
                        }
                        else if (header.Number > syncPeer.HeadNumber)
                        {
                            syncPeer.HeadNumber = header.Number;
                            syncPeer.HeadHash   = header.Hash;
                        }

                        syncPeer.IsInitialized = true;

                        SignalPeersChanged();
                    }
                }
                finally
                {
                    linkedSource.Dispose();
                    delaySource.Dispose();
                }
            }, token);
        }
예제 #4
0
        private async Task RefreshPeerInfo(PeerInfo peerInfo, CancellationToken token)
        {
            if (_logger.IsTrace)
            {
                _logger.Trace($"Requesting head block info from {peerInfo.SyncPeer.Node:s}");
            }

            ISyncPeer          syncPeer          = peerInfo.SyncPeer;
            Task <BlockHeader> getHeadHeaderTask = peerInfo.SyncPeer.GetHeadBlockHeader(peerInfo.HeadHash, token);
            Task delayTask       = Task.Delay(InitTimeout, token);
            Task firstToComplete = await Task.WhenAny(getHeadHeaderTask, delayTask);

            await firstToComplete.ContinueWith(
                t =>
            {
                if (firstToComplete.IsFaulted || firstToComplete == delayTask)
                {
                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                    }
                    _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed : NodeStatsEventType.SyncInitFailed);
                    syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault");
                }
                else if (firstToComplete.IsCanceled)
                {
                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"InitPeerInfo canceled for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                    }
                    _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncCancelled : NodeStatsEventType.SyncInitCancelled);
                    token.ThrowIfCancellationRequested();
                }
                else
                {
                    BlockHeader header = getHeadHeaderTask.Result;
                    if (header == null)
                    {
                        if (_logger.IsDebug)
                        {
                            _logger.Debug($"InitPeerInfo failed for node: {syncPeer.Node:c}{Environment.NewLine}{t.Exception}");
                        }

                        _stats.ReportSyncEvent(syncPeer.Node, peerInfo.IsInitialized ? NodeStatsEventType.SyncFailed: NodeStatsEventType.SyncInitFailed);
                        syncPeer.Disconnect(DisconnectReason.DisconnectRequested, "refresh peer info fault");
                        return;
                    }

                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"Received head block info from {syncPeer.Node:c} with head block numer {header.Number}");
                    }
                    if (!peerInfo.IsInitialized)
                    {
                        _stats.ReportSyncEvent(syncPeer.Node, NodeStatsEventType.SyncInitCompleted);
                    }

                    if (_logger.IsTrace)
                    {
                        _logger.Trace($"REFRESH Updating header of {peerInfo} from {peerInfo.HeadNumber} to {header.Number}");
                    }
                    peerInfo.HeadNumber = header.Number;
                    peerInfo.HeadHash   = header.Hash;

                    BlockHeader parent = _blockTree.FindHeader(header.ParentHash, BlockTreeLookupOptions.None);
                    if (parent != null)
                    {
                        peerInfo.TotalDifficulty = (parent.TotalDifficulty ?? UInt256.Zero) + header.Difficulty;
                    }

                    peerInfo.IsInitialized = true;
                    foreach ((SyncPeerAllocation allocation, object _) in _allocations)
                    {
                        if (allocation.Current == peerInfo)
                        {
                            allocation.Refresh();
                        }
                    }
                }
            }, token);
        }