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
    }
Exemple #3
0
        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);
                }
            }
        }
Exemple #7
0
 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));
 }