public override void HandleBroadcast(IObserverDto <ProtocolMessage> messageDto) { try { var deserialised = messageDto.Payload.FromProtocolMessage <DeltaDfsHashBroadcast>(); var previousHash = _hashProvider.Cast(deserialised.PreviousDeltaDfsHash.ToByteArray()); if (previousHash == null) { Logger.Error($"PreviousDeltaDfsHash is not a valid hash"); return; } var newHash = _hashProvider.Cast(deserialised.DeltaDfsHash.ToByteArray()); if (newHash == null) { Logger.Error($"DeltaDfsHash is not a valid hash"); return; } _deltaHashProvider.TryUpdateLatestHash(previousHash, newHash); } catch (Exception exception) { Logger.Error(exception, "Failed to update latest delta hash from incoming broadcast message."); } }
public void When_candidate_not_in_cache_should_build_ScoredCandidate_with_ranking_and_store_it() { _voter = new DeltaVoter(_cache, _producersProvider, _peerSettings, _logger); var candidate = DeltaHelper.GetCandidateDelta(_hashProvider, _previousDeltaHash, producerId: _producerIds.First()); var candidateHashAsString = _hashProvider.Cast(candidate.Hash.ToByteArray()).ToBase32(); var addedEntry = Substitute.For <ICacheEntry>(); _cache.CreateEntry(Arg.Is <string>(s => s.EndsWith(candidateHashAsString))) .Returns(addedEntry); _voter.OnNext(candidate); _cache.Received(1).TryGetValue(Arg.Is <string>(s => s.EndsWith(candidateHashAsString)), out Arg.Any <object>()); _cache.ReceivedWithAnyArgs(2).CreateEntry(Arg.Any <object>()); _cache.Received(1).CreateEntry(Arg.Is <string>(s => s.EndsWith(candidateHashAsString))); addedEntry.Value.Should().BeAssignableTo <IScoredCandidateDelta>(); var scoredCandidateDelta = (IScoredCandidateDelta)addedEntry.Value; scoredCandidateDelta.Candidate.Hash.SequenceEqual(candidate.Hash).Should().BeTrue(); scoredCandidateDelta.Score.Should().Be(100 * _producerIds.Count + 1); }
private async Task BroadcastNewDfsFileAddressAsync(Cid dfsFileAddress, ByteString previousDeltaHash) { if (dfsFileAddress == null) { return; } try { _logger.Verbose("Broadcasting new delta dfs address {dfsAddress} for delta with previous delta hash {previousDeltaHash}", dfsFileAddress, _hashProvider.Cast(previousDeltaHash.ToByteArray())); var newDeltaHashOnDfs = new DeltaDfsHashBroadcast { DeltaDfsHash = dfsFileAddress.ToArray().ToByteString(), PreviousDeltaDfsHash = previousDeltaHash }.ToProtocolMessage(_peerId, CorrelationId.GenerateCorrelationId()); await _broadcastManager.BroadcastAsync(newDeltaHashOnDfs).ConfigureAwait(false); } catch (Exception exception) { _logger.Error(exception, "Failed to broadcast new dfs address {dfsAddress}"); } }
/// <inheritdoc /> public IEnumerable <MultiHash> CacheDeltasBetween(MultiHash latestKnownDeltaHash, MultiHash targetDeltaHash, CancellationToken cancellationToken) { var thisHash = targetDeltaHash; do { if (!DeltaCache.TryGetOrAddConfirmedDelta(thisHash, out var retrievedDelta, cancellationToken)) { yield break; } var previousDfsHash = _hashProvider.Cast(retrievedDelta.PreviousDeltaDfsHash.ToByteArray()); _logger.Debug("Retrieved delta {previous} as predecessor of {current}", previousDfsHash, thisHash); yield return(thisHash); thisHash = previousDfsHash; } while (!thisHash.Equals(latestKnownDeltaHash) && !cancellationToken.IsCancellationRequested); yield return(thisHash); }
public void StartProducing() { _constructionProducingSubscription = _cycleEventsProvider.PhaseChanges .Where(p => p.Name == PhaseName.Construction && p.Status == PhaseStatus.Producing) .Select(p => _deltaBuilder.BuildCandidateDelta(p.PreviousDeltaDfsHash)) .Subscribe(c => { _deltaVoter.OnNext(c); _deltaHub.BroadcastCandidate(c); }); _campaigningProductionSubscription = _cycleEventsProvider.PhaseChanges .Where(p => p.Name == PhaseName.Campaigning && p.Status == PhaseStatus.Producing) .Select(p => { _deltaVoter.TryGetFavouriteDelta(p.PreviousDeltaDfsHash, out var favourite); return(favourite); }) .Where(f => f != null) .Subscribe(f => { _deltaHub.BroadcastFavouriteCandidateDelta(f); _deltaElector.OnNext(f); }); _votingProductionSubscription = _cycleEventsProvider.PhaseChanges .Where(p => p.Name == PhaseName.Voting && p.Status == PhaseStatus.Producing) .Select(p => _deltaElector.GetMostPopularCandidateDelta(p.PreviousDeltaDfsHash)) .Where(c => c != null) .Select(c => { _deltaCache.TryGetLocalDelta(c, out var delta); return(delta); }) .Where(d => d != null) .Subscribe(d => { _logger.Information("New Delta following {deltaHash} published", d.PreviousDeltaDfsHash); var newCid = _deltaHub.PublishDeltaToDfsAndBroadcastAddressAsync(d) .ConfigureAwait(false).GetAwaiter().GetResult(); var previousHash = _hashProvider.Cast(d.PreviousDeltaDfsHash.ToByteArray()); _deltaHashProvider.TryUpdateLatestHash(previousHash, newCid.Hash); }); }
/// <summary> /// </summary> /// <param name="getFileFromDfsRequest"></param> /// <param name="channelHandlerContext"></param> /// <param name="senderPeerId"></param> /// <param name="correlationId"></param> /// <returns></returns> protected override GetFileFromDfsResponse HandleRequest(GetFileFromDfsRequest getFileFromDfsRequest, IChannelHandlerContext channelHandlerContext, PeerId senderPeerId, ICorrelationId correlationId) { Guard.Argument(getFileFromDfsRequest, nameof(getFileFromDfsRequest)).NotNull(); Guard.Argument(channelHandlerContext, nameof(channelHandlerContext)).NotNull(); Guard.Argument(senderPeerId, nameof(senderPeerId)).NotNull(); long fileLen = 0; FileTransferResponseCodeTypes responseCodeType; var task = Task.Run(async() => { try { responseCodeType = await Task.Run(async() => { var stream = await _dfs.ReadAsync(_hashProvider.Cast(getFileFromDfsRequest.DfsHash.FromBase32())).ConfigureAwait(false); fileLen = stream.Length; using (var fileTransferInformation = new UploadFileTransferInformation( stream, senderPeerId, PeerSettings.PeerId, channelHandlerContext.Channel, correlationId )) { return(_fileTransferFactory.RegisterTransfer(fileTransferInformation)); } }).ConfigureAwait(false); } catch (Exception e) { Logger.Error(e, "Failed to handle GetFileFromDfsRequestHandler after receiving message {0}", getFileFromDfsRequest); responseCodeType = FileTransferResponseCodeTypes.Error; } return(ReturnResponse(responseCodeType, fileLen)); }); return(task.Result); }
protected override GetDeltaResponse HandleRequest(GetDeltaRequest getDeltaRequest, IChannelHandlerContext channelHandlerContext, PeerId senderPeerId, ICorrelationId correlationId) { Guard.Argument(getDeltaRequest, nameof(getDeltaRequest)).NotNull(); Guard.Argument(channelHandlerContext, nameof(channelHandlerContext)).NotNull(); Guard.Argument(senderPeerId, nameof(senderPeerId)).NotNull(); Logger.Verbose("received message of type GetDeltaRequest:"); Logger.Verbose("{getDeltaRequest}", getDeltaRequest); var hash = _hashProvider.Cast(getDeltaRequest.DeltaDfsHash.ToByteArray()); _deltaCache.TryGetOrAddConfirmedDelta(hash, out var delta); return(new GetDeltaResponse { Delta = delta }); }
public static string GetCandidateListCacheKey(FavouriteDeltaBroadcast candidate, IHashProvider hashProvider) { return(nameof(DeltaElector) + "-" + hashProvider.Cast(candidate.Candidate.PreviousDeltaDfsHash.ToByteArray())); }