public static void sendHelloMessage(RemoteEndpoint endpoint, bool sendHelloData, byte[] challenge_response)
        {
            using (MemoryStream m = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(m))
                {
                    string publicHostname = string.Format("{0}:{1}", Config.publicServerIP, Config.serverPort);

                    // Send the node version
                    writer.Write(CoreConfig.protocolVersion);

                    // Send the public node address
                    byte[] address = Node.walletStorage.getPrimaryAddress();
                    writer.Write(address.Length);
                    writer.Write(address);

                    // Send the testnet designator
                    writer.Write(Config.isTestNet);

                    char node_type = Node.getNodeType();
                    writer.Write(node_type);

                    // Send the version
                    writer.Write(Config.version);

                    // Send the node device id
                    writer.Write(Config.device_id);

                    // Send the wallet public key
                    writer.Write(Node.walletStorage.getPrimaryPublicKey().Length);
                    writer.Write(Node.walletStorage.getPrimaryPublicKey());

                    // Send listening port
                    writer.Write(Config.serverPort);

                    // Send timestamp
                    long timestamp = Core.getCurrentTimestamp();
                    writer.Write(timestamp);

                    // send signature
                    byte[] signature = CryptoManager.lib.getSignature(Encoding.UTF8.GetBytes(CoreConfig.ixianChecksumLockString + "-" + Config.device_id + "-" + timestamp + "-" + publicHostname), Node.walletStorage.getPrimaryPrivateKey());
                    writer.Write(signature.Length);
                    writer.Write(signature);


                    if (sendHelloData)
                    {
                        Block block = Node.getLastBlock();
                        if (block == null)
                        {
                            Logging.warn("Clients are connecting, but we have no blocks yet to send them!");
                            return;
                        }


                        ulong lastBlock = block.blockNum;
                        writer.Write(lastBlock);

                        writer.Write(block.blockChecksum.Length);
                        writer.Write(block.blockChecksum);

                        writer.Write(block.walletStateChecksum.Length);
                        writer.Write(block.walletStateChecksum);

                        writer.Write(Node.getRequiredConsensus());

                        writer.Write(block.version);

                        // Write the legacy level
                        writer.Write(Legacy.getLegacyLevel());

                        writer.Write(challenge_response.Length);
                        writer.Write(challenge_response);

                        endpoint.sendData(ProtocolMessageCode.helloData, m.ToArray());
                    }
                    else
                    {
                        List <byte> challenge = new List <byte>();

                        challenge.AddRange(Node.walletStorage.getPrimaryAddress());
                        Random rnd = new Random();
                        challenge.AddRange(BitConverter.GetBytes(rnd.Next(20000)));

                        byte[] challenge_bytes = challenge.ToArray();

                        endpoint.challenge = challenge_bytes;

                        writer.Write(challenge_bytes.Length);
                        writer.Write(challenge_bytes);

                        endpoint.sendData(ProtocolMessageCode.hello, m.ToArray());
                    }
                }
            }
        }