Exemple #1
0
        private static int CompareCandidateHash(CandidateDeltaBroadcast x, CandidateDeltaBroadcast y)
        {
            var xByteArray = x?.Hash?.ToByteArray();
            var yByteArray = y?.Hash?.ToByteArray();

            return
                (ByteUtil.ByteListMinSizeComparer.Default.Compare(
                     xByteArray,
                     yByteArray));
        }
Exemple #2
0
        private void AddCandidateToCandidateHashLookup(CandidateDeltaBroadcast candidate,
                                                       int rankingFactor,
                                                       string candidateCacheKey)
        {
            var scoredDelta = new ScoredCandidateDelta(candidate, 100 * rankingFactor + 1);

            _candidatesCache.Set(candidateCacheKey, scoredDelta, _cacheEntryOptions());
            _logger.Verbose("Candidate {hash} with previous hash {previousHash} has score {scored}",
                            candidate.Hash.ToByteArray().ToBase32(),
                            candidate.PreviousDeltaDfsHash.ToByteArray().ToBase32(),
                            scoredDelta.Score);
        }
Exemple #3
0
        private void AddCandidateToPreviousHashLookup(CandidateDeltaBroadcast candidate, string candidateCacheKey)
        {
            var candidatesForPreviousHash =
                _candidatesCache.GetOrCreate(GetCandidateListCacheKey(candidate),
                                             c =>
            {
                c.SetOptions(_cacheEntryOptions());
                return(new ConcurrentBag <string>());
            });

            candidatesForPreviousHash.Add(candidateCacheKey);
            _logger.Verbose("Candidates for previous hash {previousHash} are {candidates}",
                            candidate.PreviousDeltaDfsHash.ToByteArray().ToBase32(), candidatesForPreviousHash);
        }
        public void CandidateDeltaBroadcastDao_CandidateDeltaBroadcast_Should_Be_Convertible()
        {
            var candidateDeltaBroadcastDao = GetMapper <CandidateDeltaBroadcastDao>();
            var previousHash = _hashProvider.ComputeMultiHash(Encoding.UTF8.GetBytes("previousHash"));
            var hash         = _hashProvider.ComputeMultiHash(Encoding.UTF8.GetBytes("anotherHash"));

            var original = new CandidateDeltaBroadcast
            {
                Hash                 = hash.ToArray().ToByteString(),
                ProducerId           = PeerIdHelper.GetPeerId("test"),
                PreviousDeltaDfsHash = previousHash.ToArray().ToByteString()
            };

            var candidateDeltaBroadcast = candidateDeltaBroadcastDao.ToDao(original);
            var reconverted             = candidateDeltaBroadcast.ToProtoBuff();

            reconverted.Should().Be(original);
        }
Exemple #5
0
        public void OnNext(CandidateDeltaBroadcast candidate)
        {
            try
            {
                var rankingFactor = GetProducerRankFactor(candidate);

                var candidateCacheKey = GetCandidateCacheKey(candidate);
                if (_candidatesCache.TryGetValue <IScoredCandidateDelta>(candidateCacheKey, out var retrievedScoredDelta))
                {
                    retrievedScoredDelta.IncreasePopularity(1);
                    _logger.Debug("Candidate {candidate} increased popularity to {score}", candidate, retrievedScoredDelta.Score);
                    return;
                }

                AddCandidateToCandidateHashLookup(candidate, rankingFactor, candidateCacheKey);
                AddCandidateToPreviousHashLookup(candidate, candidateCacheKey);
            }
            catch (Exception e)
            {
                _logger.Error(e, "Failed to Vote on the candidate delta {0}", candidate);
            }
        }
Exemple #6
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);
        }
Exemple #7
0
 public static string GetCandidateListCacheKey(CandidateDeltaBroadcast candidate) =>
 nameof(DeltaVoter) + "-" + candidate.PreviousDeltaDfsHash.ToByteArray().ToBase32();
        ///<inheritdoc />
        public CandidateDeltaBroadcast BuildCandidateDelta(MultiHash previousDeltaHash)
        {
            _logger.Debug("Building candidate delta locally");

            var allTransactions = _transactionRetriever.GetMempoolTransactionsByPriority();

            Guard.Argument(allTransactions, nameof(allTransactions))
            .NotNull("Mempool content returned null, check the mempool is actively running");

            var includedTransactions = GetValidTransactionsForDelta(allTransactions);
            var salt = GetSaltFromPreviousDelta(previousDeltaHash);

            var rawAndSaltedEntriesBySignature = includedTransactions.SelectMany(
                t => t.PublicEntries.Select(e => new RawEntryWithSaltedAndHashedEntry(e, salt, _hashProvider)));

            // (Eα;Oα)
            var shuffledEntriesBytes = rawAndSaltedEntriesBySignature
                                       .OrderBy(v => v.SaltedAndHashedEntry, ByteUtil.ByteListComparer.Default)
                                       .SelectMany(v => v.RawEntry.ToByteArray())
                                       .ToArray();

            // dn
            var signaturesInOrder = includedTransactions
                                    .Select(p => p.Signature.ToByteArray())
                                    .OrderBy(s => s, ByteUtil.ByteListComparer.Default)
                                    .SelectMany(b => b)
                                    .ToArray();

            // xf
            var summedFees = includedTransactions.Sum(t => t.SummedEntryFees());

            //∆Ln,j = L(f/E) + dn + E(xf, j)
            var coinbaseEntry = new CoinbaseEntry
            {
                Amount            = summedFees.ToUint256ByteString(),
                ReceiverPublicKey = _producerUniqueId.PublicKey.ToByteString()
            };
            var globalLedgerStateUpdate = shuffledEntriesBytes
                                          .Concat(signaturesInOrder)
                                          .Concat(coinbaseEntry.ToByteArray())
                                          .ToArray();

            //hj
            var candidate = new CandidateDeltaBroadcast
            {
                // h∆j
                Hash = _hashProvider.ComputeMultiHash(globalLedgerStateUpdate).ToArray().ToByteString(),

                // Idj
                ProducerId           = _producerUniqueId,
                PreviousDeltaDfsHash = previousDeltaHash.ToArray().ToByteString()
            };

            _logger.Debug("Building full delta locally");

            var producedDelta = new Delta
            {
                PreviousDeltaDfsHash = previousDeltaHash.ToArray().ToByteString(),
                MerkleRoot           = candidate.Hash,
                CoinbaseEntries      = { coinbaseEntry },
                PublicEntries        = { includedTransactions.SelectMany(t => t.PublicEntries) },
                TimeStamp            = Timestamp.FromDateTime(_dateTimeProvider.UtcNow)
            };

            _logger.Debug("Adding local candidate delta");

            _deltaCache.AddLocalDelta(candidate, producedDelta);

            return(candidate);
        }