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); }
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); }
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); }
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); }