예제 #1
0
        public ResponseCode OnTransactionReceived(ProtocolMessage protocolMessage)
        {
            var transactionBroadcast = protocolMessage.FromProtocolMessage <TransactionBroadcast>();
            var transactionValid     = _validator.ValidateTransaction(transactionBroadcast.PublicEntry);

            if (!transactionValid)
            {
                return(ResponseCode.Error);
            }

            var transactionDao = transactionBroadcast.PublicEntry.ToDao <PublicEntry, PublicEntryDao>(_mapperProvider);

            _logger.Verbose("Adding transaction {id} to mempool", transactionDao.Id);

            if (_mempool.Service.TryReadItem(transactionDao.Id))
            {
                _logger.Information("Transaction {id} already exists in mempool", transactionDao.Id);
                return(ResponseCode.Exists);
            }

            _mempool.Service.CreateItem(transactionDao);

            _logger.Information("Broadcasting {signature} transaction", protocolMessage);
            _broadcastManager.BroadcastAsync(protocolMessage).ConfigureAwait(false);

            return(ResponseCode.Successful);
        }
예제 #2
0
        public ResponseCode OnTransactionReceived(ProtocolMessage protocolMessage)
        {
            var transaction      = protocolMessage.FromProtocolMessage <TransactionBroadcast>();
            var transactionValid = _validator.ValidateTransaction(transaction, _peerSettings.NetworkType);

            if (!transactionValid)
            {
                return(ResponseCode.Error);
            }

            var transactionSignature = transaction.Signature;

            _logger.Verbose("Adding transaction {signature} to mempool", transactionSignature);

            // https://github.com/catalyst-network/Catalyst.Node/issues/910 - should we fail or succeed if we already have the transaction in the ledger?
            if (_mempool.Repository.TryReadItem(transactionSignature.RawBytes))
            {
                _logger.Information("Transaction {signature} already exists in mempool", transactionSignature);
                return(ResponseCode.Error);
            }

            _mempool.Repository.CreateItem(transaction);

            _logger.Information("Broadcasting {signature} transaction", protocolMessage);
            _broadcastManager.BroadcastAsync(protocolMessage);
            return(ResponseCode.Successful);
        }
예제 #3
0
        private void DeltaHeightOnNext(ProtocolMessage protocolMessage)
        {
            var peerId          = protocolMessage.PeerId;
            var latestDeltaHash = protocolMessage.FromProtocolMessage <LatestDeltaHashResponse>();

            var peer = _peerRepository.Get(peerId);

            if (peer != null)
            {
                peer.Touch();
                _peerRepository.Update(peer);
            }

            DeltaHeightRanker.Add(peerId, latestDeltaHash);
        }
예제 #4
0
        private void SendBroadcastMessages(ProtocolMessage message, BroadcastMessage broadcastMessage)
        {
            try
            {
                var innerMessage       = message.FromProtocolMessage <ProtocolMessage>();
                var isOwnerOfBroadcast = innerMessage.PeerId.Equals(_peerId);

                if (isOwnerOfBroadcast)
                {
                    innerMessage  = innerMessage.Sign(_signer, _signingContext);
                    message.Value = innerMessage.ToByteString();
                }

                // The fan out is how many peers to broadcast to
                var fanOut = isOwnerOfBroadcast
                    ? BroadcastOwnerMaximumGossipPeersPerRound
                    : (int)Math.Max(GetMaxGossipCycles(broadcastMessage), MaxGossipPeersPerRound);

                var peersToGossip = GetRandomPeers(fanOut);

                var correlationId = innerMessage.CorrelationId.ToCorrelationId();

                //CLEAN UP
                foreach (var peerIdentifier in peersToGossip)
                {
                    _logger.Verbose("Broadcasting message {message}", message);
                    var protocolMessage = message.Clone();
                    protocolMessage.PeerId = _peerId;
                    _peerClient.SendMessage(new MessageDto(
                                                protocolMessage,
                                                peerIdentifier)
                                            );
                }

                var updateCount = (uint)peersToGossip.Count;
                if (updateCount <= 0)
                {
                    return;
                }

                broadcastMessage.BroadcastCount += updateCount;
                UpdatePendingRequest(correlationId, broadcastMessage);
            }
            catch (Exception e)
            {
                _logger.Error(e, nameof(SendBroadcastMessages));
            }
        }
예제 #5
0
        private async Task BroadcastInnerAsync(ProtocolMessage signedMessage)
        {
            var innerMessage = signedMessage.FromProtocolMessage <ProtocolMessage>();

            if (innerMessage.IsBroadCastMessage())
            {
                throw new NotSupportedException("Cannot broadcast a message which is already a gossip type");
            }

            var correlationId = innerMessage.CorrelationId.ToCorrelationId();
            var gossipRequest = await GetOrCreateAsync(correlationId).ConfigureAwait(false);

            if (!CanBroadcast(gossipRequest))
            {
                return;
            }

            SendBroadcastMessages(signedMessage, gossipRequest);
        }
        public ResponseCode OnTransactionReceived(ProtocolMessage protocolMessage)
        {
            var         transactionBroadcast = protocolMessage.FromProtocolMessage <TransactionBroadcast>();
            PublicEntry publicEntry          = transactionBroadcast.PublicEntry;

            if (publicEntry.SenderAddress.Length == 32)
            {
                var transactionValid = _validator.ValidateTransaction(publicEntry);
                if (!transactionValid)
                {
                    return(ResponseCode.Error);
                }

                byte[] kvmAddressBytes = Keccak.Compute(publicEntry.SenderAddress.ToByteArray()).Bytes.AsSpan(12).ToArray();
                string hex             = kvmAddressBytes.ToHexString() ?? throw new ArgumentNullException("kvmAddressBytes.ToHexString()");
                publicEntry.SenderAddress = kvmAddressBytes.ToByteString();

                if (publicEntry.ReceiverAddress.Length == 1)
                {
                    publicEntry.ReceiverAddress = ByteString.Empty;
                }
            }

            var transactionDao = transactionBroadcast.PublicEntry.ToDao <PublicEntry, PublicEntryDao>(_mapperProvider);

            _logger.Verbose("Adding transaction {id} to mempool", transactionDao.Id);

            if (_mempool.Service.TryReadItem(transactionDao.Id))
            {
                _logger.Information("Transaction {id} already exists in mempool", transactionDao.Id);
                return(ResponseCode.Exists);
            }

            _mempool.Service.CreateItem(transactionDao);

            _logger.Information("Broadcasting {signature} transaction", protocolMessage);
            _broadcastManager.BroadcastAsync(protocolMessage).ConfigureAwait(false);

            return(ResponseCode.Successful);
        }