Ejemplo n.º 1
0
        public bool TryGetLocalDelta(CandidateDeltaBroadcast candidate, out Delta delta)
        {
            var tryGetLocalDelta = _memoryCache.TryGetValue(GetLocalDeltaCacheKey(candidate), out delta);

            _logger.Verbose("Retrieved full details {delta}", delta?.ToString() ?? "nothing");
            return(tryGetLocalDelta);
        }
Ejemplo n.º 2
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);
            }
        }
        public static ScoredCandidateDelta GetScoredCandidateDelta(IHashProvider hashProvider,
                                                                   CandidateDeltaBroadcast candidate = default,
                                                                   int score = 0)
        {
            var candidateDelta = candidate ?? DeltaHelper.GetCandidateDelta(hashProvider);

            return(new ScoredCandidateDelta(candidateDelta, score));
        }
Ejemplo n.º 4
0
        private void ValidateDeltaCandidate(CandidateDeltaBroadcast candidate, byte[] expectedBytesToHash)
        {
            candidate.Should().NotBeNull();
            candidate.ProducerId.Should().Be(_producerId);
            candidate.PreviousDeltaDfsHash.ToByteArray().SequenceEqual(_previousDeltaHash.ToArray()).Should().BeTrue();

            var expectedHash = _hashProvider.ComputeMultiHash(expectedBytesToHash).ToCid();

            candidate.Hash.ToByteArray().Should().BeEquivalentTo(expectedHash.ToArray());
        }
        public void CandidateDeltaBroadcast_IsValid_Should_Not_Throw_On_Valid_CandidateDeltaBroadcast()
        {
            var candidate = new CandidateDeltaBroadcast
            {
                ProducerId           = PeerIdHelper.GetPeerId("hello"),
                Hash                 = ByteString.CopyFromUtf8("yes"),
                PreviousDeltaDfsHash = ByteString.CopyFromUtf8("bla")
            };

            candidate.IsValid().Should().BeTrue();
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        public void Execute(DeltaBuilderContext context)
        {
            byte[] salt = GetSaltFromPreviousDelta(context.PreviousDeltaHash);

            IEnumerable <RawEntryWithSaltedAndHashedEntry> rawAndSaltedEntriesBySignature = context.Transactions.Select(e => new RawEntryWithSaltedAndHashedEntry(e, salt, _hashProvider));

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

            // dn
            byte[] signaturesInOrder = context.Transactions
                                       .Select(p => p.Signature.ToByteArray())
                                       .OrderBy(s => s, ByteUtil.ByteListComparer.Default)
                                       .SelectMany(b => b)
                                       .ToArray();

            // xf
            UInt256 summedFees = context.Transactions.Sum(t => t.GasPrice.ToUInt256() * t.GasLimit);

            //∆Ln,j = L(f/E) + dn + E(xf, j)
            context.CoinbaseEntry = new CoinbaseEntry
            {
                Amount            = summedFees.ToUint256ByteString(),
                ReceiverPublicKey = _producerUniqueId.PublicKey.ToByteString()
            };

            byte[] globalLedgerStateUpdate = shuffledEntriesBytes
                                             .Concat(signaturesInOrder)
                                             .Concat(context.CoinbaseEntry.ToByteArray())
                                             .ToArray();

            //hj
            CandidateDeltaBroadcast candidate = new CandidateDeltaBroadcast
            {
                // h∆j
                Hash = MultiBase.Decode(_hashProvider.ComputeMultiHash(globalLedgerStateUpdate).ToCid())
                       .ToByteString(),

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

            context.Candidate = candidate;
        }
Ejemplo n.º 9
0
        /// <inheritdoc />
        public void BroadcastCandidate(CandidateDeltaBroadcast candidate)
        {
            Guard.Argument(candidate, nameof(candidate)).NotNull().Require(c => c.IsValid());
            _logger.Information("Broadcasting candidate delta {0}", candidate);

            if (!candidate.ProducerId.Equals(_peerId))
            {
                _logger.Warning($"{nameof(BroadcastCandidate)} " +
                                "should only be called by the producer of a candidate.");
                return;
            }

            var protocolMessage = candidate.ToProtocolMessage(_peerId, CorrelationId.GenerateCorrelationId());

            _broadcastManager.BroadcastAsync(protocolMessage).ConfigureAwait(false);

            _logger.Debug("Broadcast candidate {0} done.", candidate);
        }
Ejemplo n.º 10
0
        public void CandidateDeltaBroadcastDao_CandidateDeltaBroadcast_Should_Be_Convertible()
        {
            var previousHash = _hashProvider.ComputeMultiHash(Encoding.UTF8.GetBytes("previousHash"));
            var hash         = _hashProvider.ComputeMultiHash(Encoding.UTF8.GetBytes("anotherHash"));

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

            var candidateDeltaBroadcast =
                original.ToDao <CandidateDeltaBroadcast, CandidateDeltaBroadcastDao>(_mapperProvider);
            var reconverted =
                candidateDeltaBroadcast.ToProtoBuff <CandidateDeltaBroadcastDao, CandidateDeltaBroadcast>(
                    _mapperProvider);

            reconverted.Should().Be(original);
        }
Ejemplo n.º 11
0
        private int GetProducerRankFactor(CandidateDeltaBroadcast candidate)
        {
            var preferredProducers = _deltaProducersProvider
                                     .GetDeltaProducersFromPreviousDelta(candidate.PreviousDeltaDfsHash.ToByteArray().ToCid());
            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().ToCid()}");
            }

            return(preferredProducers.Count - ranking);
        }
Ejemplo n.º 12
0
 public static string GetLocalDeltaCacheKey(CandidateDeltaBroadcast candidate)
 {
     return(nameof(DeltaCache) + "-LocalDelta-" + MultiBase.Encode(candidate.Hash.ToByteArray(), "base32"));
 }
Ejemplo n.º 13
0
 public void AddLocalDelta(CandidateDeltaBroadcast localCandidate, Delta delta)
 {
     _logger.Verbose("Adding full details of candidate delta {candidate}", localCandidate);
     _memoryCache.Set(GetLocalDeltaCacheKey(localCandidate), delta, _entryOptions());
 }
Ejemplo n.º 14
0
        ///<inheritdoc />
        public CandidateDeltaBroadcast BuildCandidateDelta(Cid previousDeltaHash)
        {
            _logger.Error("Current height: " + _deltaIndexService.Height());

            _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.Select(
                x => new RawEntryWithSaltedAndHashedEntry(x, 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.TransactionFees.ToUInt256());

            //∆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 = MultiBase.Decode(_hashProvider.ComputeMultiHash(globalLedgerStateUpdate).ToCid())
                       .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 },
                TimeStamp            = Timestamp.FromDateTime(_dateTimeProvider.UtcNow)
            };

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

            _deltaCache.AddLocalDelta(candidate, producedDelta);

            return(candidate);
        }
 public void CandidateDeltaBroadcast_IsValid_Should_Return_False_On_Invalid_CandidateDeltaBroadcast(CandidateDeltaBroadcast candidate)
 {
     candidate.IsValid().Should().BeFalse();
 }
Ejemplo n.º 16
0
 public static string GetLocalDeltaCacheKey(CandidateDeltaBroadcast candidate)
 {
     return(nameof(DeltaCache) + "-LocalDelta-" + candidate.Hash);
 }
Ejemplo n.º 17
0
        public void When_candidate_is_dodgy_should_log_and_return_without_hitting_the_cache(CandidateDeltaBroadcast dodgyCandidate)
        {
            _voter = new DeltaVoter(_cache, _producersProvider, _peerSettings, _logger);

            _voter.OnNext(dodgyCandidate);

            _cache.DidNotReceiveWithAnyArgs().TryGetValue(Arg.Any <object>(), out Arg.Any <object>());
            _cache.DidNotReceiveWithAnyArgs().CreateEntry(Arg.Any <object>());
        }
Ejemplo n.º 18
0
 public static string GetCandidateListCacheKey(CandidateDeltaBroadcast candidate)
 {
     return(nameof(DeltaVoter) + "-" + candidate.PreviousDeltaDfsHash.ToByteArray().ToCid());
 }
Ejemplo n.º 19
0
 public ScoredCandidateDelta(CandidateDeltaBroadcast candidate, int score)
 {
     Candidate = candidate;
     _score    = score;
 }