Exemple #1
0
        public LedgerSync(NodeState nodeState, NodeConfig nodeConfig, NetworkPacketSwitch networkPacketSwitch)
        {
            this.nodeState = nodeState;
            this.nodeConfig = nodeConfig;
            this.networkPacketSwitch = networkPacketSwitch;
            this.LedgerTree = nodeState.Ledger.LedgerTree; // Just aliasing.

            LedgerState = LedgerSyncStateTypes.ST_GOOD;

            this.networkPacketSwitch.LedgerSyncEvent += networkHandler_LedgerSyncEvent;

            TimerLedgerSync = new System.Timers.Timer();
            if (Enable) TimerLedgerSync.Elapsed += TimerLedgerSync_Elapsed;
            TimerLedgerSync.Enabled = true;
            TimerLedgerSync.Interval = nodeConfig.UpdateFrequencyLedgerSyncMS;
            TimerLedgerSync.Start();

            TimerLedgerSync_Root = new System.Timers.Timer();
            if (Enable) TimerLedgerSync_Root.Elapsed += TimerLedgerSync_Root_Elapsed;
            TimerLedgerSync_Root.Enabled = true;
            TimerLedgerSync_Root.Interval = nodeConfig.UpdateFrequencyLedgerSyncMS_Root;
            TimerLedgerSync_Root.Start();
        }
Exemple #2
0
        void handle_ST_DATA_FETCH()
        {
            rootBackoff = ROOT_BACKOFF;

            long totalOrderedNodes = 0;
            long totalOrderedLeaves = 0;

            while ((PendingNodesToBeFetched.Count > 0) &&
                (totalOrderedNodes < Common.LSYNC_MAX_ORDERED_NODES) &&
                (totalOrderedLeaves < Common.LSYNC_MAX_ORDERED_LEAVES))
            {
                NodeDataEntity nde = PendingNodesToBeFetched.Dequeue();

                if (nde.LeafCount <= Common.LSYNC_MAX_LEAVES_TO_FETCH)
                {
                    // Fetch all nodes below
                    List<NodeSocketData> nsds;

                    // A single random trusted node is okay for fetching data.
                    if (nodeConfig.GetRandomTrustedNode(out nsds, 1))
                    {
                        AllLeafDataRequest aldr = new AllLeafDataRequest(nde);

                        NetworkPacket request = new NetworkPacket(nodeConfig.PublicKey, PacketType.TPT_LSYNC_LEAF_REQUEST_ALL,
                            aldr.Serialize(), TNetUtils.GenerateNewToken());

                        networkPacketSwitch.AddToQueue(nsds[0].PublicKey, request);

                        totalOrderedLeaves += aldr.TotalRequestedLeaves;
                    }

                   // DebugPrint("Fetch Normal All Nodes Below", DisplayType.ImportantInfo);
                }
                else
                {
                    // Fetch selective nodes
                    //DebugPrint("Fetch Selective Nodes", DisplayType.ImportantInfo);

                    ListTreeNode currentNode;
                    if (LedgerTree.TraverseToNode(nde.AddressNibbles, out currentNode) == TraverseResult.Success)
                    {
                        if (currentNode.Hash != nde.NodeHash)
                        {
                            for (int i = 0; i < 16; i++)
                            {
                                Hash remoteChildHash = nde.Children[i];
                                ListTreeNode currentChild = currentNode.Children[i];

                                if (NodeFetchQueue.Count > Common.LSYNC_MAX_PENDING_QUEUE_LENGTH) break;

                                if (remoteChildHash != null)
                                {
                                    if (currentChild == null)
                                    {
                                        FetchRemoteNode(nde.AddressNibbles, (byte)i); totalOrderedNodes++;
                                    }
                                    else
                                    {
                                        if (remoteChildHash != currentChild.Hash)
                                        {
                                            FetchRemoteNode(nde.AddressNibbles, (byte)i); totalOrderedNodes++;
                                        }
                                    }
                                }
                                else
                                {
                                    //DebugPrint("REMOTE NULL !!", DisplayType.ImportantInfo);

                                    // HANDLE CASE FOR THE REMOTE HAVING NO NODE WHEN WE HAVE
                                    // VERIFY WITH OTHERS AND DELETE
                                    // ONLY NEEDED IF THE TRUSTED NODES ARE SENDING BAD DATA
                                    // SHOULD BE IMPLEMENTED BEFORE FINAL NETWORK COMPLETION
                                }
                            }
                        }
                    }
                    else
                    {
                        // ORDER ALL NODES BELOW. Probably in the initial condition.
                        for (int i = 0; i < 16; i++)
                        {
                            FetchRemoteNode(nde.AddressNibbles, (byte)i); totalOrderedNodes++;
                        }
                    }
                }
            }

            ProcessPendingRemoteFetches();

            if (PendingNodesToBeFetched.Count == 0) LedgerState = LedgerSyncStateTypes.ST_GOOD;
        }
Exemple #3
0
        void TimerLedgerSync_Root_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            lock (LedgerSyncLock)
            {
                switch (LedgerState)
                {
                    case LedgerSyncStateTypes.ST_GOOD:

                        if (PendingNodesToBeFetched.Count == 0)
                        {
                            if(rootBackoff > 0)
                                rootBackoff--;

                            if (rootBackoff <= 0)
                            {
                                handle_ST_ROOT();
                            }
                        }
                        else
                        {
                            LedgerState = LedgerSyncStateTypes.ST_DATA_FETCH;
                            handle_ST_DATA_FETCH();
                        }

                        break;
                }
            }
        }
Exemple #4
0
        void HandleRootResponse(NetworkPacket packet)
        {
            // Check that the packet is valid.
            if (networkPacketSwitch.VerifyPendingPacket(packet))
            {
                RootDataResponse rdrm = new RootDataResponse();
                rdrm.Deserialize(packet.Data);

                /// Compare with current tree and matchup.

                if (LedgerTree.RootNode.Hash != rdrm.RootHash) // Need to match up child nodes.
                {
                    DebugPrint("MISMATCH: RootResponse from " + packet.PublicKeySource + " : " + packet.Data.Length + " Bytes", DisplayType.Warning);

                    LedgerState = LedgerSyncStateTypes.ST_DATA_FETCH;

                    for (int i = 0; i < 16; i++)
                    {
                        NodeDataEntity remoteChild = rdrm.Children[i];
                        ListTreeNode currentChild = LedgerTree.RootNode.Children[i];

                        if (PendingNodesToBeFetched.Count > Common.LSYNC_MAX_PENDING_QUEUE_LENGTH) break;

                        if (remoteChild != null)
                        {
                            if (currentChild == null)
                            {
                                // Download all the data below the node.
                                // Needs to be handled properly, as it may have millions of nodes.

                                PendingNodesToBeFetched.Enqueue(remoteChild);
                            }
                            else
                            {
                                if (remoteChild.NodeHash != currentChild.Hash)
                                {
                                    PendingNodesToBeFetched.Enqueue(remoteChild);
                                }
                            }
                        }
                        else
                        {
                            // HANDLE CASE FOR THE REMOTE HAVING NO NODE WHEN WE HAVE
                            // VERIFY WITH OTHERS AND DELETE
                            // ONLY NEEDED IF THE TRUSTED NODES ARE SENDING BAD DATA
                            // SHOULD BE IMPLEMENTED BEFORE FINAL NETWORK COMPLETION
                        }
                    }
                }
                else
                {
                    DebugPrint("ROOT IS SYNCHRONZED WITH: " + packet.PublicKeySource, DisplayType.ImportantInfo);
                }

            }
            else
            {
                DebugPrint("Packet VER FAILED : HandleRootResponse().", DisplayType.Warning);
            }
        }