Exemplo n.º 1
0
        public static void resubscribeEvents()
        {
            lock (NetworkClientManager.networkClients)
            {
                foreach (var client in NetworkClientManager.networkClients)
                {
                    if (client.isConnected() && client.helloReceived)
                    {
                        if (client.presenceAddress.type != 'M' && client.presenceAddress.type != 'H')
                        {
                            continue;
                        }

                        // Get presences
                        client.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                            (byte)'R'
                        });
                        client.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                            (byte)'M'
                        });
                        client.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                            (byte)'H'
                        });

                        byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.all, new byte[0]);
                        client.sendData(ProtocolMessageCode.detachEvent, event_data);
                        subscribeToEvents(client);
                    }
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Subscribes client to transactionFrom, transactionTo and balance
        /// </summary>
        /// <remarks>
        ///  This function is used to ensure that the remote endpoing has listed the correct IP and port information for their `PresenceList` entry.
        /// </remarks>
        /// <param name="endpoint">Target endpoint to verify for connectivity.</param>
        public static void subscribeToEvents(RemoteEndpoint endpoint)
        {
            if (endpoint.presenceAddress.type != 'M')
            {
                return;
            }

            // TODO TODO TODO events can be optimized as there is no real need to subscribe them to every connected node

            // Subscribe to transaction events, for own addresses
            var    my_addresses = IxianHandler.getWalletStorage().getMyAddresses();
            Cuckoo filter       = new Cuckoo(my_addresses.Count());

            foreach (var addr in my_addresses)
            {
                filter.Add(addr.address);
            }
            byte[] filter_data = filter.getFilterBytes();
            byte[] event_data  = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionFrom, filter_data);
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);

            event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionTo, filter_data);
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);

            event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.balance, filter_data);
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);
        }
Exemplo n.º 3
0
        private static void subscribeToEvents(RemoteEndpoint endpoint)
        {
            CoreProtocolMessage.subscribeToEvents(endpoint);

            byte[] friend_matcher = FriendList.getFriendCuckooFilter();
            if (friend_matcher != null)
            {
                byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.keepAlive, friend_matcher);
                endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);
            }
        }
Exemplo n.º 4
0
 public static void resubscribeEvents()
 {
     lock (NetworkClientManager.networkClients)
     {
         foreach (var client in NetworkClientManager.networkClients)
         {
             if (client.isConnected() && client.helloReceived)
             {
                 byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.all, new byte[0]);
                 client.sendData(ProtocolMessageCode.detachEvent, event_data);
                 subscribeToEvents(client);
             }
         }
     }
 }
Exemplo n.º 5
0
        private static void subscribeToEvents(RemoteEndpoint endpoint)
        {
            if (endpoint.presenceAddress.type != 'M')
            {
                return;
            }
            // Get presences
            endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                (byte)'R'
            });
            endpoint.sendData(ProtocolMessageCode.getRandomPresences, new byte[1] {
                (byte)'M'
            });

            // TODO TODO TODO events can be optimized as there is no real need to subscribe them to every connected node

            // Subscribe to transaction events
            byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionFrom, IxianHandler.getWalletStorage().getPrimaryAddress());
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);

            event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionTo, IxianHandler.getWalletStorage().getPrimaryAddress());
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);

            event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.balance, IxianHandler.getWalletStorage().getPrimaryAddress());
            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);


            List <byte[]> match_addresses = FriendList.getHiddenMatchAddresses();

            if (match_addresses != null)
            {
                foreach (var address in match_addresses)
                {
                    event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.keepAlive, address);
                    endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);
                }
            }
        }
Exemplo n.º 6
0
        // Unified protocol message parsing
        public static void parseProtocolMessage(ProtocolMessageCode code, byte[] data, RemoteEndpoint endpoint)
        {
            if (endpoint == null)
            {
                Logging.error("Endpoint was null. parseProtocolMessage");
                return;
            }
            try
            {
                switch (code)
                {
                case ProtocolMessageCode.hello:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (CoreProtocolMessage.processHelloMessage(endpoint, reader))
                            {
                                CoreProtocolMessage.sendHelloMessage(endpoint, true);
                                endpoint.helloReceived = true;
                                return;
                            }
                        }
                    }
                }
                break;


                case ProtocolMessageCode.helloData:
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            if (CoreProtocolMessage.processHelloMessage(endpoint, reader))
                            {
                                ulong  last_block_num       = reader.ReadUInt64();
                                int    bcLen                = reader.ReadInt32();
                                byte[] block_checksum       = reader.ReadBytes(bcLen);
                                int    wsLen                = reader.ReadInt32();
                                byte[] walletstate_checksum = reader.ReadBytes(wsLen);
                                int    consensus            = reader.ReadInt32();

                                endpoint.blockHeight = last_block_num;

                                int block_version = reader.ReadInt32();

                                Node.setLastBlock(last_block_num, block_checksum, walletstate_checksum, block_version);
                                Node.setRequiredConsensus(consensus);

                                // Check for legacy level
                                ulong legacy_level = reader.ReadUInt64();

                                // Check for legacy node
                                if (Legacy.isLegacy(legacy_level))
                                {
                                    // TODO TODO TODO TODO check this out
                                    //endpoint.setLegacy(true);
                                }

                                // Process the hello data
                                endpoint.helloReceived = true;
                                NetworkClientManager.recalculateLocalTimeDifference();
                            }
                            // Get presences
                            endpoint.sendData(ProtocolMessageCode.syncPresenceList, new byte[1]);

                            // Subscribe to transaction events
                            byte[] event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionFrom, Node.walletStorage.getPrimaryAddress());
                            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);

                            event_data = NetworkEvents.prepareEventMessageData(NetworkEvents.Type.transactionTo, Node.walletStorage.getPrimaryAddress());
                            endpoint.sendData(ProtocolMessageCode.attachEvent, event_data);
                        }
                    }
                    break;

                case ProtocolMessageCode.s2data:
                {
                    StreamProcessor.receiveData(data, endpoint);
                }
                break;

                case ProtocolMessageCode.s2keys:
                {
                    Console.WriteLine("NET: Receiving S2 keys!");
                    //        StreamProcessor.receivedKeys(data, socket);
                }
                break;

                case ProtocolMessageCode.syncPresenceList:
                {
                    byte[] pdata = PresenceList.getBytes();
                    //       byte[] ba = prepareProtocolMessage(ProtocolMessageCode.presenceList, pdata);
                    //       socket.Send(ba, SocketFlags.None);
                }
                break;

                case ProtocolMessageCode.presenceList:
                {
                    Logging.info("NET: Receiving complete presence list");
                    PresenceList.syncFromBytes(data);
                    //       NetworkClientManager.searchForStreamNode();
                }
                break;

                case ProtocolMessageCode.updatePresence:
                {
                    Console.WriteLine("NET: Receiving presence list update");
                    // Parse the data and update entries in the presence list
                    PresenceList.updateFromBytes(data);
                }
                break;


                case ProtocolMessageCode.balance:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            int    address_length = reader.ReadInt32();
                            byte[] address        = reader.ReadBytes(address_length);

                            // Retrieve the latest balance
                            IxiNumber balance = reader.ReadString();

                            if (address.SequenceEqual(Node.walletStorage.getPrimaryAddress()))
                            {
                                Node.balance = balance;
                            }

                            // Retrieve the blockheight for the balance
                            ulong blockheight = reader.ReadUInt64();
                            Node.blockHeight = blockheight;
                        }
                    }
                }
                break;

                case ProtocolMessageCode.transactionData:
                {
                    // TODO: check for errors/exceptions
                    Transaction transaction = new Transaction(data);
                    TransactionCache.addTransaction(transaction);
                }
                break;

                case ProtocolMessageCode.newTransaction:
                {
                    // Forward the new transaction message to the DLT network
                    Logging.info("RECIEVED NEW TRANSACTION");

                    Transaction transaction = new Transaction(data);
                    if (transaction.toList.Keys.First().SequenceEqual(Node.walletStorage.getPrimaryAddress()))
                    {
                        TransactionCache.addTransaction(transaction);
                    }
                }
                break;

                case ProtocolMessageCode.bye:
                {
                    using (MemoryStream m = new MemoryStream(data))
                    {
                        using (BinaryReader reader = new BinaryReader(m))
                        {
                            endpoint.stop();

                            bool byeV1 = false;
                            try
                            {
                                int    byeCode    = reader.ReadInt32();
                                string byeMessage = reader.ReadString();
                                string byeData    = reader.ReadString();

                                byeV1 = true;

                                if (byeCode != 200)
                                {
                                    Logging.warn(string.Format("Disconnected with message: {0} {1}", byeMessage, byeData));
                                }

                                if (byeCode == 600)
                                {
                                    if (IxiUtils.validateIPv4(byeData))
                                    {
                                        if (NetworkClientManager.getConnectedClients().Length < 2)
                                        {
                                            Config.publicServerIP = byeData;
                                            Logging.info("Changed internal IP Address to " + byeData + ", reconnecting");
                                        }
                                    }
                                }
                                else if (byeCode == 601)
                                {
                                    Logging.error("This node must be connectable from the internet, to connect to the network.");
                                    Logging.error("Please setup uPNP and/or port forwarding on your router for port " + Config.serverPort + ".");
                                }
                            }
                            catch (Exception)
                            {
                            }
                            if (byeV1)
                            {
                                return;
                            }

                            reader.BaseStream.Seek(0, SeekOrigin.Begin);

                            // Retrieve the message
                            string message = reader.ReadString();

                            if (message.Length > 0)
                            {
                                Logging.info(string.Format("Disconnected with message: {0}", message));
                            }
                            else
                            {
                                Logging.info("Disconnected");
                            }
                        }
                    }
                }
                break;

                default:
                    break;
                }
            }
            catch (Exception e)
            {
                Logging.error(string.Format("Error parsing network message. Details: {0}", e.ToString()));
            }
        }