Пример #1
0
        private static void queueLoop(List <QueueMessageRecv> queue)
        {
            // Prepare an special message object to use while receiving and parsing, without locking up the queue messages
            QueueMessageRecv active_message = new QueueMessageRecv();

            while (!shouldStop)
            {
                TLC.Report();
                bool message_found = false;
                lock (queue)
                {
                    if (queue.Count > 0)
                    {
                        // Pick the oldest message
                        active_message = queue[0];
                        message_found  = true;
                        // Remove it from the queue
                        queue.RemoveAt(0);
                    }
                }

                if (message_found)
                {
                    Logging.trace("Received {0} ({1}B) - {2}...", active_message.code, active_message.data.Length, Crypto.hashToString(active_message.data.Take(60).ToArray()));
                    // Active message set, attempt to parse it
                    IxianHandler.parseProtocolMessage(active_message.code, active_message.data, active_message.endpoint);
                }
                else
                {
                    // Sleep for 10ms to prevent cpu waste
                    Thread.Sleep(10);
                }
            }
            Logging.info("Network queue thread stopped.");
        }
Пример #2
0
            // Actual tx network queue logic
            public static void txqueueThreadLoop()
            {
                // Prepare an special message object to use while receiving and parsing, without locking up the queue messages
                QueueMessageRecv active_message = new QueueMessageRecv();
                QueueMessageRecv candidate      = new QueueMessageRecv();

                while (!shouldStop)
                {
                    TLC.Report();
                    bool message_found = false;
                    lock (txqueueMessages)
                    {
                        if (txqueueMessages.Count > 0)
                        {
                            // Pick the oldest message
                            candidate               = txqueueMessages[0];
                            active_message.code     = candidate.code;
                            active_message.data     = candidate.data;
                            active_message.checksum = candidate.checksum;
                            active_message.endpoint = candidate.endpoint;
                            message_found           = true;
                        }
                    }

                    if (message_found)
                    {
                        // Active message set, attempt to parse it
                        ProtocolMessage.parseProtocolMessage(active_message.code, active_message.data, active_message.endpoint);
                        lock (txqueueMessages)
                        {
                            // Remove it from the queue
                            txqueueMessages.Remove(candidate);
                        }
                        // Sleep a bit to allow other threads to do their thing
                        Thread.Yield();
                    }
                    else
                    {
                        // Sleep for 10ms to prevent cpu waste
                        Thread.Sleep(10);
                    }
                }
                Logging.info("Network Tx queue thread stopped.");
            }
Пример #3
0
        public static void receiveProtocolMessage(ProtocolMessageCode code, byte[] data, uint checksum, MessagePriority priority, RemoteEndpoint endpoint)
        {
            QueueMessageRecv message = new QueueMessageRecv
            {
                code       = code,
                data       = data,
                length     = data.Length,
                checksum   = checksum,
                endpoint   = endpoint,
                helperData = extractHelperData(code, data)
            };

            if (priority == MessagePriority.medium)
            {
                lock (queueMediumPriority)
                {
                    if (message.helperData != null)
                    {
                        if (queueMediumPriority.Exists(x => x.code == message.code && x.helperData.SequenceEqual(message.helperData)))
                        {
                            int msg_index = queueMediumPriority.FindIndex(x => x.code == message.code && message.helperData.SequenceEqual(x.helperData));
                            if (queueMediumPriority[msg_index].length < message.length)
                            {
                                queueMediumPriority[msg_index] = message;
                            }
                            return;
                        }
                    }

                    if (queueMediumPriority.Exists(x => x.code == message.code && x.checksum == message.checksum))
                    {
                        Logging.trace("Attempting to add a duplicate message (code: {0}) to the network queue", code);
                        return;
                    }

                    queueMediumPriority.Add(message);
                }
                return;
            }

            lock (queueLowPriority)
            {
                // Move block related messages to txqueue
                bool found_get_request = false;
                bool found_tx_request  = false;
                switch (code)
                {
#pragma warning disable CS0618 // Type or member is obsolete
                case ProtocolMessageCode.getTransaction:
                case ProtocolMessageCode.getTransaction2:
                case ProtocolMessageCode.getTransaction3:
                case ProtocolMessageCode.getTransactions:
                case ProtocolMessageCode.getTransactions2:
                case ProtocolMessageCode.getBlock:
                case ProtocolMessageCode.getBlock2:
                case ProtocolMessageCode.getBlock3:
                case ProtocolMessageCode.getBlockHeaders:
                case ProtocolMessageCode.getBlockHeaders2:
                case ProtocolMessageCode.getSignatures:
                case ProtocolMessageCode.getBlockSignatures2:
                case ProtocolMessageCode.getPIT:
                case ProtocolMessageCode.getPIT2:
#pragma warning restore CS0618 // Type or member is obsolete
                    found_get_request = true;
                    found_tx_request  = true;
                    break;

#pragma warning disable CS0618 // Type or member is obsolete
                case ProtocolMessageCode.transactionsChunk:
                case ProtocolMessageCode.transactionsChunk2:
                case ProtocolMessageCode.newTransaction:
                case ProtocolMessageCode.transactionData:
                case ProtocolMessageCode.blockTransactionsChunk:
                case ProtocolMessageCode.blockHeaders:
                case ProtocolMessageCode.blockHeaders2:
                case ProtocolMessageCode.newBlock:
                case ProtocolMessageCode.blockData:
                case ProtocolMessageCode.pitData:
                case ProtocolMessageCode.pitData2:
                case ProtocolMessageCode.inventory:
                case ProtocolMessageCode.inventory2:
#pragma warning restore CS0618 // Type or member is obsolete
                    found_get_request = false;
                    found_tx_request  = true;
                    break;
                }
                if (found_tx_request)
                {
                    if (found_get_request)
                    {
                        if (message.helperData != null)
                        {
                            if (queueLowPriority.Exists(x => x.code == message.code && x.helperData.SequenceEqual(message.helperData) && x.endpoint == message.endpoint))
                            {
                                int msg_index = queueLowPriority.FindIndex(x => x.code == message.code && message.helperData.SequenceEqual(x.helperData));
                                if (queueLowPriority[msg_index].length < message.length)
                                {
                                    queueLowPriority[msg_index] = message;
                                }
                                return;
                            }
                        }

                        if (queueLowPriority.Exists(x => x.code == message.code && x.checksum == message.checksum && x.endpoint == message.endpoint))
                        {
                            Logging.trace("Attempting to add a duplicate message (code: {0}) to the network queue", code);
                            return;
                        }
                    }
                    else
                    {
                        if (message.helperData != null)
                        {
                            if (queueLowPriority.Exists(x => x.code == message.code && x.helperData.SequenceEqual(message.helperData)))
                            {
                                int msg_index = queueLowPriority.FindIndex(x => x.code == message.code && message.helperData.SequenceEqual(x.helperData));
                                if (queueLowPriority[msg_index].length < message.length)
                                {
                                    queueLowPriority[msg_index] = message;
                                }
                                return;
                            }
                        }

                        if (queueLowPriority.Exists(x => x.code == message.code && x.checksum == message.checksum))
                        {
                            Logging.trace("Attempting to add a duplicate message (code: {0}) to the network queue", code);
                            return;
                        }
                    }

                    bool add = true;
                    if (queueLowPriority.Count > 20)
                    {
                        switch (code)
                        {
#pragma warning disable CS0618 // Type or member is obsolete
                        case ProtocolMessageCode.getTransaction:
                        case ProtocolMessageCode.getTransaction2:
                        case ProtocolMessageCode.getTransaction3:
                        case ProtocolMessageCode.getTransactions:
                        case ProtocolMessageCode.getTransactions2:
                        case ProtocolMessageCode.getBlock:
                        case ProtocolMessageCode.getBlock2:
                        case ProtocolMessageCode.getBlock3:
                        case ProtocolMessageCode.getBlockHeaders:
                        case ProtocolMessageCode.getBlockHeaders2:
                        case ProtocolMessageCode.newBlock:
                        case ProtocolMessageCode.blockData:
                        case ProtocolMessageCode.getSignatures:
                        case ProtocolMessageCode.getBlockSignatures2:
                        case ProtocolMessageCode.getPIT:
                        case ProtocolMessageCode.getPIT2:
                        case ProtocolMessageCode.inventory:
                        case ProtocolMessageCode.inventory2:
#pragma warning restore CS0618 // Type or member is obsolete
                        {
                            queueLowPriority.Insert(5, message);
                            add = false;
                            break;
                        }
                        }
                    }
                    if (add)
                    {
                        // Add it to the tx queue
                        queueLowPriority.Add(message);
                    }
                    return;
                }
            }

            lock (queueHighPriority)
            {
                // ignore duplicates
                if (queueHighPriority.Exists(x => x.code == message.code && x.checksum == message.checksum && x.endpoint == message.endpoint))
                {
                    Logging.trace("Attempting to add a duplicate message (code: {0}) to the network queue", code);
                    return;
                }

                // Handle normal messages, but prioritize block-related messages
                switch (code)
                {
                case ProtocolMessageCode.bye:
                case ProtocolMessageCode.hello:
                case ProtocolMessageCode.helloData:
                    queueHighPriority.Insert(0, message);
                    return;

                case ProtocolMessageCode.keepAlivePresence:
                case ProtocolMessageCode.getPresence:
                case ProtocolMessageCode.getPresence2:
                case ProtocolMessageCode.updatePresence:
                    // Prioritize if queue is large
                    if (queueHighPriority.Count > 10)
                    {
                        queueHighPriority.Insert(5, message);
                        return;
                    }

                    break;
                }

                // Add it to the normal queue
                queueHighPriority.Add(message);
            }
        }
Пример #4
0
            public static void receiveProtocolMessage(ProtocolMessageCode code, byte[] data, byte[] checksum, RemoteEndpoint endpoint)
            {
                QueueMessageRecv message = new QueueMessageRecv
                {
                    code       = code,
                    data       = data,
                    length     = data.Length,
                    checksum   = checksum,
                    endpoint   = endpoint,
                    helperData = extractHelperData(code, data)
                };


                lock (txqueueMessages)
                {
                    // Move transaction messages to the transaction queue
                    if (code == ProtocolMessageCode.newTransaction || code == ProtocolMessageCode.transactionData ||
                        code == ProtocolMessageCode.transactionsChunk || code == ProtocolMessageCode.newBlock || code == ProtocolMessageCode.blockData ||
                        code == ProtocolMessageCode.newBlockSignature || code == ProtocolMessageCode.blockSignatures)
                    {
                        if (message.helperData != null)
                        {
                            if (txqueueMessages.Exists(x => x.code == message.code && x.helperData.SequenceEqual(message.helperData)))
                            {
                                int msg_index = txqueueMessages.FindIndex(x => x.code == message.code && message.helperData.SequenceEqual(x.helperData));
                                if (txqueueMessages[msg_index].length < message.length)
                                {
                                    txqueueMessages[msg_index] = message;
                                }
                                return;
                            }
                        }

                        if (txqueueMessages.Exists(x => x.code == message.code && x.checksum.SequenceEqual(message.checksum)))
                        {
                            //Logging.warn(string.Format("Attempting to add a duplicate message (code: {0}) to the network queue", code));
                            return;
                        }

                        if (txqueueMessages.Count > 20 &&
                            (code == ProtocolMessageCode.transactionsChunk || code == ProtocolMessageCode.newBlock || code == ProtocolMessageCode.blockData || code == ProtocolMessageCode.blockSignatures))
                        {
                            txqueueMessages.Insert(5, message);
                        }
                        else
                        {
                            // Add it to the tx queue
                            txqueueMessages.Add(message);
                        }
                        return;
                    }
                }

                lock (queueMessages)
                {
                    // ignore duplicates
                    if (queueMessages.Exists(x => x.code == message.code && x.checksum.SequenceEqual(message.checksum) && x.endpoint == message.endpoint))
                    {
                        //Logging.warn(string.Format("Attempting to add a duplicate message (code: {0}) to the network queue", code));
                        return;
                    }

                    // Handle normal messages, but prioritize block-related messages
                    if (code == ProtocolMessageCode.bye || code == ProtocolMessageCode.hello || code == ProtocolMessageCode.helloData)
                    {
                        queueMessages.Insert(0, message);
                        return;
                    }
                    else if (code == ProtocolMessageCode.keepAlivePresence || code == ProtocolMessageCode.getPresence ||
                             code == ProtocolMessageCode.updatePresence)
                    {
                        // Prioritize if queue is large
                        if (queueMessages.Count > 10)
                        {
                            queueMessages.Insert(5, message);
                            return;
                        }
                    }

                    // Add it to the normal queue
                    queueMessages.Add(message);
                }
            }