コード例 #1
0
        public bool TryGetFavouriteDelta(MultiHash previousDeltaDfsHash, out FavouriteDeltaBroadcast favourite)
        {
            Guard.Argument(previousDeltaDfsHash, nameof(previousDeltaDfsHash)).NotNull();
            _logger.Debug("Retrieving favourite candidate delta for the successor of delta {0}",
                          previousDeltaDfsHash);

            var cacheKey = GetCandidateListCacheKey(previousDeltaDfsHash);

            if (!_candidatesCache.TryGetValue(cacheKey, out ConcurrentBag <string> candidates))
            {
                _logger.Debug("Failed to retrieve any scored candidate with previous delta {0}",
                              previousDeltaDfsHash.ToBase32());
                favourite = default;
                return(false);
            }

            var bestCandidate = candidates.Select(c => _candidatesCache.Get(c) as IScoredCandidateDelta)
                                .Where(c => c != null)
                                .OrderByDescending(c => c.Score)
                                .ThenBy(c => c.Candidate.Hash.ToByteArray(), ByteUtil.ByteListMinSizeComparer.Default)
                                .First().Candidate;

            favourite = new FavouriteDeltaBroadcast
            {
                Candidate = bestCandidate,
                VoterId   = _localPeerIdentifier
            };

            _logger.Debug("Retrieved favourite candidate delta {candidate} for the successor of delta {previousDelta}",
                          bestCandidate.Hash.ToByteArray().ToBase32(),
                          previousDeltaDfsHash.ToBase32());

            return(true);
        }
コード例 #2
0
        /// <inheritdoc />
        public void BroadcastFavouriteCandidateDelta(FavouriteDeltaBroadcast favourite)
        {
            Guard.Argument(favourite, nameof(favourite)).NotNull().Require(c => c.IsValid());
            var protocolMessage = favourite.ToProtocolMessage(_peerId, CorrelationId.GenerateCorrelationId());

            _broadcastManager.BroadcastAsync(protocolMessage);

            _logger.Debug("Started broadcasting favourite candidate {0}", favourite);
        }
コード例 #3
0
        public void When_receiving_bad_favourite_should_log_and_not_hit_the_cache(FavouriteDeltaBroadcast badFavourite,
                                                                                  Type exceptionType)
        {
            var elector = new DeltaElector(_cache, _deltaProducersProvider, _reputationManager, _logger);

            elector.OnNext(badFavourite);

            _cache.DidNotReceiveWithAnyArgs().TryGetValue(Arg.Any <object>(), out Arg.Any <object>());
            _cache.DidNotReceiveWithAnyArgs().CreateEntry(Arg.Any <object>());
        }
コード例 #4
0
        public void FavouriteDeltaBroadcastDao_FavouriteDeltaBroadcast_Should_Be_Convertible()
        {
            var original = new FavouriteDeltaBroadcast
            {
                Candidate = DeltaHelper.GetCandidateDelta(_hashProvider, producerId: PeerIdHelper.GetPeerId("not me")),
                VoterId   = PeerIdHelper.GetPeerId("test")
            };

            var contextDao  = original.ToDao <FavouriteDeltaBroadcast, FavouriteDeltaBroadcastDao>(_mapperProvider);
            var reconverted =
                contextDao.ToProtoBuff <FavouriteDeltaBroadcastDao, FavouriteDeltaBroadcast>(_mapperProvider);

            reconverted.Should().Be(original);
        }
コード例 #5
0
        public void FavouriteDeltaBroadcast_IsValid_Should_Not_Throw_On_Valid_FavouriteDeltaBroadcast()
        {
            var candidate = new FavouriteDeltaBroadcast
            {
                Candidate = new CandidateDeltaBroadcast
                {
                    ProducerId = new PeerId {
                        PublicKey = "producer".ToUtf8ByteString()
                    },
                    Hash = ByteString.CopyFromUtf8("hash"),
                    PreviousDeltaDfsHash = ByteString.CopyFromUtf8("ok")
                },
                VoterId = new PeerId {
                    PublicKey = "voter".ToUtf8ByteString()
                },
            };

            candidate.IsValid().Should().BeTrue();
        }
コード例 #6
0
        public void OnNext(FavouriteDeltaBroadcast candidate)
        {
            _logger.Verbose("Favourite candidate delta received {favourite}", candidate);
            try
            {
                Guard.Argument(candidate, nameof(candidate)).NotNull().Require(f => f.IsValid());

                var cid = candidate.Candidate.PreviousDeltaDfsHash.ToByteArray().ToCid();
                if (!_deltaProducersProvider
                    .GetDeltaProducersFromPreviousDelta(cid)
                    .Any(p => p.Equals(candidate.VoterId)))
                {
                    var reputationChange = new ReputationChange(candidate.VoterId, ReputationEventType.VoterIsNotProducer);
                    _reputationManager.OnNext(reputationChange);

                    _logger.Debug(
                        "Voter {voter} is not a producer for this cycle succeeding {deltaHash} and its vote has been discarded.",
                        candidate.VoterId, candidate.Candidate.PreviousDeltaDfsHash);
                    return;
                }

                var candidateListKey = GetCandidateListCacheKey(candidate);

                if (_candidatesCache.TryGetValue(candidateListKey,
                                                 out ConcurrentDictionary <FavouriteDeltaBroadcast, bool> retrieved))
                {
                    retrieved.TryAdd(candidate, default);
                    return;
                }

                _candidatesCache.Set(candidateListKey,
                                     new ConcurrentDictionary <FavouriteDeltaBroadcast, bool>(
                                         new[] { new KeyValuePair <FavouriteDeltaBroadcast, bool>(candidate, false) },
                                         FavouriteByHashAndVoterComparer.Default), _cacheEntryOptions());
            }
            catch (Exception e)
            {
                _logger.Error(e, "Failed to process favourite delta {0}", candidate);
            }
        }
コード例 #7
0
        public void OnNext(FavouriteDeltaBroadcast candidate)
        {
            _logger.Verbose("Favourite candidate delta received {favourite}", candidate);
            try
            {
                Guard.Argument(candidate, nameof(candidate)).NotNull().Require(f => f.IsValid());
                var multiHash = new MultiHash(candidate.Candidate.PreviousDeltaDfsHash.ToByteArray());
                if (!_deltaProducersProvider
                    .GetDeltaProducersFromPreviousDelta(multiHash)
                    .Any(p => p.Equals(candidate.VoterId)))
                {
                    //https://github.com/catalyst-network/Catalyst.Node/issues/827
                    _logger.Debug(
                        "Voter {voter} is not a producer for this cycle succeeding {deltaHash} and its vote has been discarded.",
                        candidate.VoterId, candidate.Candidate.PreviousDeltaDfsHash);
                    return;
                }

                var candidateListKey = GetCandidateListCacheKey(candidate, _hashProvider);

                if (_candidatesCache.TryGetValue(candidateListKey,
                                                 out ConcurrentDictionary <FavouriteDeltaBroadcast, bool> retrieved))
                {
                    retrieved.TryAdd(candidate, default);
                    return;
                }

                _candidatesCache.Set(candidateListKey,
                                     new ConcurrentDictionary <FavouriteDeltaBroadcast, bool>(
                                         new[] { new KeyValuePair <FavouriteDeltaBroadcast, bool>(candidate, false) },
                                         FavouriteByHashAndVoterComparer.Default), _cacheEntryOptions());
            }
            catch (Exception e)
            {
                _logger.Error(e, "Failed to process favourite delta {0}", candidate);
            }
        }
コード例 #8
0
 public static string GetCandidateListCacheKey(FavouriteDeltaBroadcast candidate)
 {
     return(nameof(DeltaElector) + "-" +
            candidate.Candidate.PreviousDeltaDfsHash.ToByteArray().ToCid());
 }
コード例 #9
0
 public void FavouriteDeltaBroadcast_IsValid_Should_Throw_On_Invalid_FavouriteDeltaBroadcast(FavouriteDeltaBroadcast favourite)
 {
     favourite.IsValid().Should().BeFalse();
 }
コード例 #10
0
 public static string GetCandidateListCacheKey(FavouriteDeltaBroadcast candidate, IHashProvider hashProvider)
 {
     return(nameof(DeltaElector) + "-" + hashProvider.Cast(candidate.Candidate.PreviousDeltaDfsHash.ToByteArray()));
 }
コード例 #11
0
        public void FavouriteByHashComparer_should_differentiate_by_candidate_hash_and_voter_only(FavouriteDeltaBroadcast x, FavouriteDeltaBroadcast y, bool comparisonResult)
        {
            var xHashCode = FavouriteByHashAndVoterComparer.Default.GetHashCode(x);
            var yHashCode = FavouriteByHashAndVoterComparer.Default.GetHashCode(y);

            if (xHashCode != 0 && yHashCode != 0)
            {
                xHashCode.Equals(yHashCode).Should().Be(comparisonResult);
            }

            FavouriteByHashAndVoterComparer.Default.Equals(x, y).Should().Be(comparisonResult);
        }