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); }
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)); }
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(); }
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); }
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 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; }
/// <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); }
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); }
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); }
public static string GetLocalDeltaCacheKey(CandidateDeltaBroadcast candidate) { return(nameof(DeltaCache) + "-LocalDelta-" + MultiBase.Encode(candidate.Hash.ToByteArray(), "base32")); }
public void AddLocalDelta(CandidateDeltaBroadcast localCandidate, Delta delta) { _logger.Verbose("Adding full details of candidate delta {candidate}", localCandidate); _memoryCache.Set(GetLocalDeltaCacheKey(localCandidate), delta, _entryOptions()); }
///<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(); }
public static string GetLocalDeltaCacheKey(CandidateDeltaBroadcast candidate) { return(nameof(DeltaCache) + "-LocalDelta-" + candidate.Hash); }
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>()); }
public static string GetCandidateListCacheKey(CandidateDeltaBroadcast candidate) { return(nameof(DeltaVoter) + "-" + candidate.PreviousDeltaDfsHash.ToByteArray().ToCid()); }
public ScoredCandidateDelta(CandidateDeltaBroadcast candidate, int score) { Candidate = candidate; _score = score; }