public PeerInfo?Allocate(PeerInfo?currentPeer, IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { UInt256?currentDiffOrNull = blockTree.BestSuggestedHeader?.TotalDifficulty; if (currentDiffOrNull == null) { return(_strategy.Allocate(currentPeer, peers, nodeStatsManager, blockTree)); } UInt256 currentDiff = currentDiffOrNull.Value; switch (_selectionType) { case TotalDiffSelectionType.Better: currentDiff += UInt256.One; break; case TotalDiffSelectionType.AtLeastTheSame: break; case TotalDiffSelectionType.CanBeSlightlyWorse: UInt256 lastBlockDiff = blockTree.BestSuggestedHeader?.Difficulty ?? 0; if (currentDiff >= lastBlockDiff) { currentDiff -= lastBlockDiff; } break; default: throw new ArgumentOutOfRangeException(); } return(_strategy.Allocate(currentPeer, peers.Where(p => p.TotalDifficulty >= currentDiff), nodeStatsManager, blockTree)); }
public void Should_allocate_by_speed_post_merge() { ulong[] totalDifficulties = { 1, 3, 2 }; int[] averageSpeed = { 5, 8, 10 }; PublicKey[] publicKeys = { TestItem.PublicKeyA, TestItem.PublicKeyB, TestItem.PublicKeyC }; PeerInfo[] peers = new PeerInfo[3]; INodeStatsManager _nodeStatsManager = Substitute.For <INodeStatsManager>(); for (int i = 0; i < 3; i++) { ISyncPeer syncPeer = Substitute.For <ISyncPeer>(); syncPeer.IsInitialized.Returns(true); Node node = new Node(publicKeys[i], "192.168.1.18", i); syncPeer.Node.Returns(node); syncPeer.TotalDifficulty.Returns(new UInt256(totalDifficulties[i])); peers[i] = new PeerInfo(syncPeer); peers[i].HeadNumber.Returns(1); INodeStats nodeStats = Substitute.For <INodeStats>(); nodeStats.GetAverageTransferSpeed(Arg.Any <TransferSpeedType>()).Returns(averageSpeed[i]); _nodeStatsManager.GetOrAdd(peers[i].SyncPeer.Node).Returns(nodeStats); } IPoSSwitcher poSSwitcher = Substitute.For <IPoSSwitcher>(); poSSwitcher.TerminalTotalDifficulty.Returns(new UInt256(1)); poSSwitcher.HasEverReachedTerminalBlock().Returns(true); IBeaconPivot beaconPivot = Substitute.For <IBeaconPivot>(); IPeerAllocationStrategy mergePeerAllocationStrategy = (new MergeBlocksSyncPeerAllocationStrategyFactory(poSSwitcher, beaconPivot, Substitute.For <ILogManager>())).Create(new BlocksRequest()); IBlockTree _blockTree = Substitute.For <IBlockTree>(); PeerInfo? info = mergePeerAllocationStrategy.Allocate(null, peers, _nodeStatsManager, _blockTree); Assert.AreEqual(info, peers[2]); // peer with highest highest speed }
public PeerInfo Allocate(PeerInfo currentPeer, IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { IPeerAllocationStrategy strategy = _priority ? _fastest : _slowest; peers = _minNumber == null ? peers : peers.Where(p => p.HeadNumber > _minNumber); PeerInfo allocated = strategy.Allocate(currentPeer, peers, nodeStatsManager, blockTree); return(allocated); }
public PeerInfo?Allocate(PeerInfo?currentPeer, IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { IEnumerable <PeerInfo> originalPeers = peers; peers = peers.Where(p => _supportedClientTypes.Contains(p.PeerClientType)); if (_allowOtherIfNone) { if (!peers.Any()) { peers = originalPeers; } } return(_strategy.Allocate(currentPeer, peers, nodeStatsManager, blockTree)); }
public PeerInfo?Allocate(PeerInfo?currentPeer, IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { UInt256?terminalTotalDifficulty = _poSSwitcher.TerminalTotalDifficulty; bool isPostMerge = IsPostMerge; IEnumerable <PeerInfo> peerInfos = peers as PeerInfo[] ?? peers.ToArray(); IEnumerable <PeerInfo> postTTDPeers = peerInfos.Where(p => p.TotalDifficulty >= terminalTotalDifficulty); bool anyPostMergePeers = postTTDPeers.Any(); if (_logger.IsTrace) { _logger.Trace($"{nameof(MergePeerAllocationStrategy)}: IsPostMerge: {isPostMerge} AnyPostMergePeers: {anyPostMergePeers}, CurrentPeer: {currentPeer} Peers: {string.Join(",", peerInfos)}"); } PeerInfo?peerInfo = isPostMerge || anyPostMergePeers ? _postMergeAllocationStrategy.Allocate(currentPeer, postTTDPeers, nodeStatsManager, blockTree) : _preMergeAllocationStrategy.Allocate(currentPeer, peerInfos, nodeStatsManager, blockTree); if (_logger.IsTrace) { _logger.Trace($"MergePeerAllocationStrategy: Result of peer allocation {peerInfo}"); } return(peerInfo); }
public void AllocateBestPeer(IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { PeerInfo current = Current; PeerInfo selected = _peerAllocationStrategy.Allocate(Current, peers, nodeStatsManager, blockTree); if (selected == current) { return; } AllocationChangeEventArgs args; lock (_allocationLock) { if (selected != null && selected.TryAllocate(Contexts)) { Current = selected; args = new AllocationChangeEventArgs(current, selected); current?.Free(Contexts); Replaced?.Invoke(this, args); } } }
public PeerInfo?Allocate(PeerInfo?currentPeer, IEnumerable <PeerInfo> peers, INodeStatsManager nodeStatsManager, IBlockTree blockTree) { return(_strategy.Allocate(currentPeer, peers.Where(p => p.SyncPeer.TryGetSatelliteProtocol <T>(_protocol, out _)), nodeStatsManager, blockTree)); }