Пример #1
0
 // Initializes a new incoming packet
 internal Packet(PacketHeader Header, PortableStorage Body)
 {
     Type        = (PacketType)Header.CommandCode;
     Flag        = (PacketFlag)Header.Flag;
     this.Header = Header;
     this.Body   = Body;
 }
Пример #2
0
        // Processes our packet reading buffer to deserialize it into a usable packet
        internal void ProcessBuffer(byte[] Data)
        {
            // Add this data to our working byte buffer
            Buffer = Buffer.AppendBytes(Data);

            // Header deserialization
            if (State == ReadState.Header)
            {
                // Check if we have enough data for a packet header
                if (Buffer.Length < 33)
                {
                    return;
                }

                // Attempt to deserialize our packet header
                try
                {
                    // Store header data and set our read state to body
                    Header = new PacketHeader(Buffer);
                    State  = ReadState.Body;
                }
                catch { }

                // Remove the bytes we read from our buffer
                Buffer = Buffer.SubBytes(33, Buffer.Length - 33);
            }

            // Body deserialization
            if (State == ReadState.Body)
            {
                // Check whether our buffer is the correct size
                if ((ulong)Buffer.LongLength < Header.PayloadSize)
                {
                    return;
                }

                // Attempt to deserialize our packet body
                try
                {
                    // Get body bytes
                    var BodyBytes = Buffer.SubBytes(0, (int)Header.PayloadSize);

                    // Store deserialized body object
                    var Body = new PortableStorage(BodyBytes, out _);

                    // Invoke our packet received handler
                    Node.HandlePacket(this, new Packet(Header, Body));
                }
                catch { }

                // Remove the bytes we read from our buffer
                Buffer = Buffer.SubBytes((int)Header.PayloadSize, Buffer.Length - (int)Header.PayloadSize);

                // Reset our read state back to header
                State = ReadState.Header;
            }
        }
Пример #3
0
 // Handles core sync data sent by peers
 private void AddSyncData(Peer Peer, PortableStorage SyncData)
 {
     // TODO - handle syncing
     // TODO - queue sync data?
     // TODO - compare heights and top block ids of peers?
     if (SyncData["current_height"] > Blockchain.KnownHeight)
     {
         Blockchain.KnownHeight = SyncData["current_height"];
     }
 }
Пример #4
0
            // Serializes request data into a byte array
            public byte[] Serialize()
            {
                // Create a portable storage
                PortableStorage Storage = new PortableStorage();

                // Add entries
                Storage.AddEntryAsBinary("txs", Txs);

                // Return serialized byte array
                return(Storage.Serialize());
            }
Пример #5
0
            // Serializes request data into a byte array
            public byte[] Serialize()
            {
                // Create a portable storage
                PortableStorage Storage = new PortableStorage();

                // Add entries
                Storage.AddEntry("payload_data", PayloadData);

                // Return serialized byte array
                return(Storage.Serialize());
            }
Пример #6
0
            // Deseriaizes response data
            public static Request Deserialize(byte[] Data)
            {
                // Deserialize data
                PortableStorage Storage = new PortableStorage();

                Storage.Deserialize(Data);

                // Populate and return new response
                return(new Request
                {
                    Txs = Hashing.DeserializeHashArray((string)Storage.GetEntry("txs"))
                });
            }
Пример #7
0
            // Serializes response data
            public byte[] Serialize()
            {
                // Create a portable storage
                PortableStorage Storage = new PortableStorage();

                // Add entries
                Storage.AddEntry("local_time", LocalTime);
                Storage.AddEntry("payload_data", PayloadData);
                Storage.AddEntryAsBinary("local_peerlist", LocalPeerlist);

                // Return serialized byte array
                return(Storage.Serialize());
            }
Пример #8
0
            // Deseriaizes response data
            public static Request Deserialize(byte[] Data)
            {
                // Deserialize data
                PortableStorage Storage = new PortableStorage();

                Storage.Deserialize(Data);

                // Populate and return new response
                return(new Request
                {
                    PayloadData = CoreSyncData.Deserialize(Storage.GetEntry("payload_data"))
                });
            }
Пример #9
0
            // Deseriaizes response data
            public static Response Deserialize(byte[] Data)
            {
                // Deserialize data
                PortableStorage Storage = new PortableStorage();

                Storage.Deserialize(Data);

                // Populate and return new response
                return(new Response
                {
                    Status = (string)Storage.GetEntry("status"),
                    PeerId = (ulong)Storage.GetEntry("peer_id")
                });
            }
Пример #10
0
            // Deseriaizes response data
            public static Response Deserialize(byte[] Data)
            {
                // Deserialize data
                PortableStorage Storage = new PortableStorage();

                Storage.Deserialize(Data);

                // Populate and return new response
                return(new Response
                {
                    LocalTime = (ulong)Storage.GetEntry("local_time"),
                    PayloadData = CoreSyncData.Deserialize(Storage.GetEntry("payload_data")),
                    LocalPeerlist = Storage.DeserializeArrayFromBinary <PeerlistEntry>("local_peerlist")
                });
            }
Пример #11
0
 // Initializes a new outgoing packet
 internal Packet(PacketType Type, PacketFlag Flag, bool ResponseRequired, bool Success = true)
 {
     this.Type = Type;
     this.Flag = Flag;
     Body      = new PortableStorage();
     Header    = new PacketHeader()
     {
         Signature        = 0x0101010101012101UL,
         ProtocolVersion  = 1,
         CommandCode      = (uint)Type,
         ResponseRequired = ResponseRequired,
         ReturnCode       = (uint)(Success ? 0 : 1), // 0 = success
         Flag             = (uint)Flag
     };
 }
Пример #12
0
        // Handles core sync data sent by peers
        private void HandleSyncData(Peer Peer, PortableStorage SyncData)
        {
            // Update peer height
            Peer.Height = SyncData["current_height"];

            // Check if peer is syncing
            if (Peer.State == PeerState.SYNCHRONIZING)
            {
                return;
            }

            // Check if we have this block stored
            if (Blockchain.IsBlockStored(SyncData["top_id"]))
            {
                Peer.State = PeerState.NORMAL;
                return;
            }

            // Update observed height
            UpdateObservedHeight(Peer.Height);

            // Get the height difference between the local cache and remote node
            int Diff = (int)Blockchain.KnownHeight - (int)Blockchain.Height;
            int Days = Math.Abs(Diff) / (86_400 / Globals.CURRENCY_DIFFICULTY_TARGET);

            // Print how for behind/ahead we are
            StringBuilder Output = new StringBuilder($"[{Peer.Address}:{Peer.Port} {Peer.P2pPeer.Direction}] ");

            Output.Append($"Your {Globals.CURRENCY_NAME} node is syncing with the network");
            if (Diff >= 0)
            {
                Output.Append($" ({Math.Round((decimal)Blockchain.Height / Peer.Height * 100, 2)}% complete)");

                Output.Append($". You are {Diff} blocks ({Days} days) behind ");
            }
            else
            {
                Output.Append($". You are {Math.Abs(Diff)} blocks ({Days} days) ahead of ");
            }
            Output.Append("the current peer you're connected to. Please be patient while we synchronise with the network!");

            // If peer isn't validated, this is first contact
            if (!Peer.Validated)
            {
                Logger.Important(Output);
            }
            else
            {
                Logger.Debug(Output);
            }

            // Log debug message
            Logger.Debug($"Remote top block height: {Peer.Height}, id: {SyncData["top_id"]}");

            // TODO - this is just test code

            /*Blockchain.StoreBlock(new Block()
             * {
             *  Height = Peer.Height,
             *  Hash = SyncData["top_id"]
             * });*/

            // Set new peer state
            Peer.State = PeerState.SYNC_REQUIRED;

            // Construct a response packet
            var Request = new Packet(PacketType.NOTIFY_CHAIN_REQUEST, PacketFlag.REQUEST, true)
            {
                ["block_ids"] = GetSparseChain()
            };

            // Send our request
            Peer.SendMessage(Request);
            // TODO - handle syncing
            Peer.State = PeerState.SYNCHRONIZING;
        }