public JsonResponse onStatus(Dictionary <string, object> parameters) { JsonError error = null; Dictionary <string, object> networkArray = new Dictionary <string, object>(); networkArray.Add("Core Version", CoreConfig.version); networkArray.Add("Node Version", CoreConfig.productVersion); string netType = "mainnet"; if (CoreConfig.isTestNet) { netType = "testnet"; } networkArray.Add("Network type", netType); networkArray.Add("My time", Clock.getTimestamp()); networkArray.Add("Network time difference", Core.networkTimeDifference); networkArray.Add("My External IP", IxianHandler.publicIP); //networkArray.Add("Listening interface", context.Request.RemoteEndPoint.Address.ToString()); networkArray.Add("Queues", "Rcv: " + NetworkQueue.getQueuedMessageCount() + ", RcvTx: " + NetworkQueue.getTxQueuedMessageCount() + ", SendClients: " + NetworkServer.getQueuedMessageCount() + ", SendServers: " + NetworkClientManager.getQueuedMessageCount() + ", Storage: " + Storage.getQueuedQueryCount() + ", Logging: " + Logging.getRemainingStatementsCount() + ", Pending Transactions: " + PendingTransactions.pendingTransactionCount()); networkArray.Add("Node Deprecation Block Limit", Config.nodeDeprecationBlock); string dltStatus = "Active"; if (Node.blockSync.synchronizing) { dltStatus = "Synchronizing"; } if (Node.blockChain.getTimeSinceLastBLock() > 1800) // if no block for over 1800 seconds { dltStatus = "ErrorLongTimeNoBlock"; } if (Node.blockProcessor.networkUpgraded) { dltStatus = "ErrorForkedViaUpgrade"; } networkArray.Add("Update", checkUpdate()); networkArray.Add("DLT Status", dltStatus); string bpStatus = "Stopped"; if (Node.blockProcessor.operating) { bpStatus = "Running"; } networkArray.Add("Block Processor Status", bpStatus); networkArray.Add("Block Height", Node.blockChain.getLastBlockNum()); networkArray.Add("Block Version", Node.blockChain.getLastBlockVersion()); networkArray.Add("Network Block Height", IxianHandler.getHighestKnownNetworkBlockHeight()); networkArray.Add("Node Type", PresenceList.myPresenceType); networkArray.Add("Connectable", NetworkServer.isConnectable()); if (parameters.ContainsKey("verbose")) { networkArray.Add("Required Consensus", Node.blockChain.getRequiredConsensus()); networkArray.Add("Wallets", Node.walletState.numWallets); networkArray.Add("Presences", PresenceList.getTotalPresences()); networkArray.Add("Supply", Node.walletState.calculateTotalSupply().ToString()); networkArray.Add("Applied TX Count", TransactionPool.getTransactionCount() - TransactionPool.getUnappliedTransactions().Count()); networkArray.Add("Unapplied TX Count", TransactionPool.getUnappliedTransactions().Count()); networkArray.Add("WS Checksum", Crypto.hashToString(Node.walletState.calculateWalletStateChecksum())); networkArray.Add("WS Delta Checksum", Crypto.hashToString(Node.walletState.calculateWalletStateChecksum(true))); networkArray.Add("Network Clients", NetworkServer.getConnectedClients()); networkArray.Add("Network Servers", NetworkClientManager.getConnectedClients(true)); } networkArray.Add("Masters", PresenceList.countPresences('M')); networkArray.Add("Relays", PresenceList.countPresences('R')); networkArray.Add("Clients", PresenceList.countPresences('C')); networkArray.Add("Workers", PresenceList.countPresences('W')); return(new JsonResponse { result = networkArray, error = error }); }
static public bool update() { if (serverStarted == false) { /*if(Node.blockProcessor.operating == true) * {*/ Logging.info("Starting Network Server now."); // Start the node server if (!isMasterNode()) { Logging.info("Network server is not enabled in modes other than master node."); } else { NetworkServer.beginNetworkOperations(); } serverStarted = true; //} } // Check for node deprecation if (checkCurrentBlockDeprecation(Node.blockChain.getLastBlockNum()) == false) { ConsoleHelpers.verboseConsoleOutput = true; Logging.consoleOutput = true; shutdownMessage = string.Format("Your DLT node can only handle blocks up to #{0}. Please update to the latest version from www.ixian.io", Config.nodeDeprecationBlock); Logging.error(shutdownMessage); IxianHandler.forceShutdown = true; running = false; return(running); } // Check for sufficient node balance if (checkMasternodeBalance() == false) { //running = false; } TimeSpan last_isolate_time_diff = DateTime.UtcNow - lastIsolateTime; if (Node.blockChain.getTimeSinceLastBLock() > 900 && (last_isolate_time_diff.TotalSeconds < 0 || last_isolate_time_diff.TotalSeconds > 1800)) // if no block for over 900 seconds with cooldown of 1800 seconds { CoreNetworkUtils.isolate(); lastIsolateTime = DateTime.UtcNow; } // TODO TODO TODO TODO this is a global flood control and should be also done per node to detect attacks // I propose getting average traffic from different types of nodes and detect a node that's sending // disproportionally more messages than the other nodes, provided thatthe network queue is over a certain limit int total_queued_messages = NetworkQueue.getQueuedMessageCount() + NetworkQueue.getTxQueuedMessageCount(); if (floodPause == false && total_queued_messages > 5000) { Logging.warn("Flooding detected, isolating the node."); NetworkClientManager.stop(); if (isMasterNode()) { NetworkServer.stopNetworkOperations(); } floodPause = true; } else if (floodPause == true && total_queued_messages < 100) { Logging.warn("Data after flooding processed, reconnecting the node."); NetworkClientManager.start(); if (isMasterNode()) { NetworkServer.beginNetworkOperations(); } floodPause = false; } return(running); }
// Receive thread protected virtual void recvLoop() { socketReadBuffer = new byte[8192]; lastMessageStatTime = DateTime.UtcNow; while (running) { TLC.Report(); // Let the protocol handler receive and handle messages try { byte[] data = readSocketData(); if (data != null) { parseDataInternal(data, this); messagesPerSecond++; } } catch (Exception e) { if (running) { Logging.warn(string.Format("recvRE: Disconnected client {0} with exception {1}", getFullAddress(), e.ToString())); } state = RemoteEndpointState.Closed; } // Check if the client disconnected if (state == RemoteEndpointState.Closed) { running = false; break; } TimeSpan timeSinceLastStat = DateTime.UtcNow - lastMessageStatTime; if (timeSinceLastStat.TotalSeconds < 0 || timeSinceLastStat.TotalSeconds > 2) { lastMessageStatTime = DateTime.UtcNow; lastMessagesPerSecond = (int)(messagesPerSecond / timeSinceLastStat.TotalSeconds); messagesPerSecond = 0; } if (lastMessagesPerSecond < 1) { lastMessagesPerSecond = 1; } // Sleep a while to throttle the client // Check if there are too many messages // TODO TODO TODO this can be handled way better int total_message_count = NetworkQueue.getQueuedMessageCount() + NetworkQueue.getTxQueuedMessageCount(); if (total_message_count > 500) { Thread.Sleep(100 * lastMessagesPerSecond); if (messagesPerSecond == 0) { lastMessageStatTime = DateTime.UtcNow; } lastDataReceivedTime = Clock.getTimestamp(); } else if (total_message_count > 100) { Thread.Sleep(total_message_count / 10); } else { Thread.Sleep(1); } } }