private void Announce(TransactionBroadcast tx, uint256 hash)
        {
            var node = AttachedNode;

            if (node != null && node.State == NodeState.HandShaked)
            {
                tx.State         = BroadcastState.Announced;
                tx.AnnouncedTime = DateTime.UtcNow;
                node.SendMessageAsync(new InvPayload(InventoryType.MSG_TX, hash)).ConfigureAwait(false);
            }
        }
        internal void Announce(TransactionBroadcast tx, uint256 hash, bool force = false)
        {
            if (!force && BroadcastHub.ManualBroadcast)
            {
                return;
            }
            var node = AttachedNode;

            if (node != null && node.State == NodeState.HandShaked)
            {
                tx.State         = BroadcastState.Announced;
                tx.AnnouncedTime = DateTime.UtcNow;
                node.SendMessageAsync(new InvPayload(InventoryType.MSG_TX, hash)).ConfigureAwait(false);
            }
        }
        internal void BroadcastTransactionCore(Transaction transaction)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }
            var tx = new TransactionBroadcast();

            tx.Transaction = transaction;
            tx.State       = BroadcastState.NotSent;
            var hash = transaction.GetHash();

            if (_HashToTransaction.TryAdd(hash, tx))
            {
                Announce(tx, hash);
            }
        }
		private void Announce(TransactionBroadcast tx, uint256 hash)
		{
			var node = AttachedNode;
			if(node != null && node.State == NodeState.HandShaked)
			{
				tx.State = BroadcastState.Announced;
				tx.AnnouncedTime = DateTime.UtcNow;
				var unused = node.SendMessageAsync(new InvPayload(InventoryType.MSG_TX, hash)).ConfigureAwait(false);
			}
		}		
		internal void BroadcastTransactionCore(Transaction transaction)
		{
			if(transaction == null)
				throw new ArgumentNullException("transaction");
			var tx = new TransactionBroadcast();
			tx.Transaction = transaction;
			tx.State = BroadcastState.NotSent;
			var hash = transaction.GetHash();
			if(_HashToTransaction.TryAdd(hash, tx))
			{
				Announce(tx, hash);
			}
		}
        void AttachedNode_MessageReceived(Node node, IncomingMessage message)
        {
            if (message.Message.Payload is InvPayload invPayload)
            {
                foreach (uint256 hash in invPayload.Where(i => i.Type == InventoryType.MSG_TX).Select(i => i.Hash))
                {
                    TransactionBroadcast tx = GetTransaction(hash, true);
                    if (tx != null)
                    {
                        tx.State = BroadcastState.Accepted;
                    }

                    Transaction unused;
                    if (this.BroadcastHub.BroadcastedTransaction.TryRemove(hash, out unused))
                    {
                        this.BroadcastHub.OnTransactionBroadcasted(tx.Transaction);
                    }
                }
            }

            if ((message.Message.Payload is RejectPayload reject) && (reject.Message == "tx"))
            {
                TransactionBroadcast tx = GetTransaction(reject.Hash, true);
                if (tx != null)
                {
                    tx.State = BroadcastState.Rejected;
                }

                Transaction tx2;
                if (this.BroadcastHub.BroadcastedTransaction.TryRemove(reject.Hash, out tx2))
                {
                    this.BroadcastHub.OnTransactionRejected(tx2, reject);
                }
            }

            if (message.Message.Payload is GetDataPayload getData)
            {
                foreach (InventoryVector inventory in getData.Inventory.Where(i => i.Type == InventoryType.MSG_TX))
                {
                    TransactionBroadcast tx = GetTransaction(inventory.Hash, false);
                    if (tx != null)
                    {
                        tx.State = BroadcastState.Broadcasted;
                        var ping = new PingPayload();
                        tx.PingValue = ping.Nonce;
                        this.pingToTransaction.TryAdd(tx.PingValue, tx);
                        node.SendMessageAsync(new TxPayload(tx.Transaction));
                        node.SendMessageAsync(ping);
                    }
                }
            }

            if (message.Message.Payload is PongPayload pong)
            {
                TransactionBroadcast tx = GetTransaction(pong.Nonce, true);
                if (tx != null)
                {
                    tx.State = BroadcastState.Accepted;
                    Transaction unused;
                    if (this.BroadcastHub.BroadcastedTransaction.TryRemove(tx.Transaction.GetHash(), out unused))
                    {
                        this.BroadcastHub.OnTransactionBroadcasted(tx.Transaction);
                    }
                }
            }
        }