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."); }
// 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."); }
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); } }
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); } }