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}");
            }
        }
예제 #4
0
        /// <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);
        }
예제 #7
0
        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()));
 }