Esempio n. 1
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);
            }
        }
        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);
            }
        }
Esempio n. 3
0
        public void When_voter_not_a_producer_should_not_save_vote()
        {
            var favourite = DeltaHelper.GetFavouriteDelta(_hashProvider);

            _deltaProducersProvider
            .GetDeltaProducersFromPreviousDelta(Arg.Any <Cid>())
            .Returns(new List <PeerId> {
                PeerIdHelper.GetPeerId("the only known producer")
            });

            var elector = new DeltaElector(_cache, _deltaProducersProvider, _reputationManager, _logger);

            elector.OnNext(favourite);

            _deltaProducersProvider.Received(1)
            .GetDeltaProducersFromPreviousDelta(Arg.Is <Cid>(h =>
                                                             favourite.Candidate.PreviousDeltaDfsHash.Equals(h.ToArray().ToByteString())));
            _cache.DidNotReceiveWithAnyArgs().TryGetValue(default, out _);
        public DeltaVoterTests()
        {
            _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256"));

            _cache = Substitute.For <IMemoryCache>();

            _previousDeltaHash = _hashProvider.ComputeMultiHash(ByteUtil.GenerateRandomByteArray(32));

            _producerIds = "1234"
                           .Select((c, i) => PeerIdHelper.GetPeerId(c.ToString()))
                           .Shuffle();
            _producersProvider = Substitute.For <IDeltaProducersProvider>();
            _producersProvider.GetDeltaProducersFromPreviousDelta(Arg.Any <MultiHash>())
            .Returns(_producerIds);

            _localIdentifier = PeerIdHelper.GetPeerId("myself, a producer");
            _peerSettings    = _localIdentifier.ToSubstitutedPeerSettings();
            _logger          = Substitute.For <ILogger>();
        }
Esempio n. 5
0
        private int GetProducerRankFactor(CandidateDeltaBroadcast candidate)
        {
            var preferredProducers = _deltaProducersProvider
                                     .GetDeltaProducersFromPreviousDelta(new MultiHash(candidate.PreviousDeltaDfsHash.ToByteArray()));
            var ranking = preferredProducers.ToList()
                          .FindIndex(p => p.Equals(candidate.ProducerId));

            var identifier = candidate.ProducerId;

            _logger.Verbose("ranking for block produced by {producerId} = {ranking}",
                            identifier, ranking);

            if (ranking == -1)
            {
                throw new KeyNotFoundException(
                          $"Producer {candidate.ProducerId} " +
                          $"should not be sending candidate deltas with previous hash " +
                          $"{candidate.PreviousDeltaDfsHash.ToByteArray().ToBase32()}");
            }

            return(preferredProducers.Count - ranking);
        }