Пример #1
0
        public Node(NetworkConfig Configuration)
        {
            // Assign configuration
            Globals = Configuration;

            // Setup logger
            Logger = new Logger()
            {
                LogFile        = Globals.LOG_FILE,
                LogLevel       = Globals.LOG_LEVEL,
                CustomPrefix   = Globals.CUSTOM_PREFIX,
                InfoColor      = Globals.INFO_COLOR,
                ImportantColor = Globals.IMPORTANT_COLOR,
                DebugColor     = Globals.DEBUG_COLOR,
                WarningColor   = Globals.WARNING_COLOR,
                ErrorColor     = Globals.ERROR_COLOR
            };

            // Show ascii art, strictly vanity
            if (!string.IsNullOrEmpty(Globals.ASCII_ART))
            {
                Logger?.Important(Globals.ASCII_ART);
            }
            Logger.ShowPrefix = true;

            // Setup our blockchain handler
            Logger?.WriteLine("Setting up blockchain handler...");
            Blockchain = new BlockchainStorage();

            // Create our P2P server
            Logger?.WriteLine("Setting up P2P server...");
            P2pServer = new P2pServer(Globals.P2P_MAX_PEER_CONNECTIONS);

            // Assign P2P event handlers
            Logger?.WriteLine("Assigning P2P callbacks...");
            AssignCallbacks();

            // Setup our API server
            Logger?.WriteLine("Setting up API server...");
            ApiServer = new ApiServer(Globals.API_MAX_WORKERS)
            {
                Logger = Logger
            };

            // Create an API context
            Logger?.WriteLine("Assigning API method context...");
            ApiServer.AssignMethodContext(new ApiMethods(this));

            // Setup our peer list
            Logger?.WriteLine("Setting up local peer list...");
            SetupPeerList();

            // Assign a unique identifier
            Logger?.WriteLine("Generating identifier...");
            Id = SecureRandom.Integer <ulong>();
        }
Пример #2
0
        /// <summary>
        /// Initializes this node with the specified network configuration
        /// </summary>
        /// <param name="Configuration">A class containing all global information this node needs to operate</param>
        public Node(NodeConfig Configuration)
        {
            // Assign configuration
            Globals = Configuration;

            // Generate identifier
            Id = SecureRandom.Integer <ulong>();

            // Setup and start logger
            Logger = new Logger()
            {
                LogFile        = Globals.LOG_FILE,
                LogLevel       = Globals.LOG_LEVEL,
                CustomPrefix   = Globals.CUSTOM_PREFIX,
                ImportantColor = Globals.IMPORTANT_COLOR,
                InfoColor      = Globals.INFO_COLOR,
                ErrorColor     = Globals.ERROR_COLOR,
                WarningColor   = Globals.WARNING_COLOR,
                DebugColor     = Globals.DEBUG_COLOR
            };

            // Setup blockchain cache
            Blockchain = new BlockchainCache()
            {
                Logger = Logger
            };

            // Create our P2P server
            P2pServer = new P2pServer(Globals.P2P_WORKERS, Globals.P2P_MAX_PEER_CONNECTIONS)
            {
                ConnectionTimeout = Globals.P2P_CONNECTION_TIMEOUT
            };

            // Setup our API server
            ApiServer = new ApiServer(Globals.API_WORKERS, Globals.API_PASSWORD)
            {
                Logger = Logger
            };

            // Setup done, set node to stopped
            Stopped = true;
        }
Пример #3
0
        // Start server on specified port
        public void Start(int Port = GlobalsConfig.P2P_DEFAULT_PORT)
        {
            // Create a new TCP listener and start listening
            try
            {
                // Set internals
                this.Port = Port;
                PeerId = SecureRandom.Integer<ulong>();

                // Start listener
                Listener = new TcpListener(IPAddress.Parse("127.0.0.1"), Port);
                Listener.Start();
                Running = true;

                // Raise server start event
                OnStart?.Invoke(this, EventArgs.Empty);
            }
            catch
            {
                // Failed to start the server for some reason or another
                Logger.Log(Level.FATAL, "Failed to start P2P server on port {0}, port may be in use", Port);
                OnError?.Invoke("Failed to start P2P server", EventArgs.Empty);
            }

            // Create a levin protocol context
            Context = new LevinProtocol(this);

            // Start request handling thread
            IncomingRequestThread = new Thread(ProcessIncomingRequests);
            IncomingRequestThread.Start();

            // Start request handling thread
            OutgoingRequestThread = new Thread(ProcessOutgoingRequests);
            OutgoingRequestThread.Start();

            // Start connection handling thread
            PeerConnectionThread = new Thread(PeerConnection);
            PeerConnectionThread.Start();
        }
Пример #4
0
        // Attempts to connect to a new peer on the peer candidate list
        private void DiscoverNewPeer()
        {
            // Do nothing if not running
            if (Stopped)
            {
                return;
            }

            // Check if discovery is enabled
            if (!Globals.P2P_DISCOVERY_ENABLED)
            {
                return;
            }

            // Check if discovery is already active
            if (DiscoveryActive)
            {
                return;
            }
            DiscoveryActive = true;

            // Check if the peer list has space for a new peer
            if (GetPeerCount() >= Globals.P2P_MAX_PEER_CONNECTIONS)
            {
                return;
            }

            // Get the peer candidate list
            List <PeerCandidate> Candidates = GetPeerCandidates();

            // Check if there are candidates in the list
            if (Candidates.Count == 0)
            {
                return;
            }

            // Setup variables
            int        TryCount     = 0;
            int        RandomCount  = 0;
            int        MaxIndex     = Math.Min(Candidates.Count - 1, 50);
            List <int> TriedIndexes = new List <int>();

            // Loop to try a selection of candidates
            while (RandomCount < (MaxIndex + 1) * 3 && TryCount < 10 && !Stopped)
            {
                // Increment random count and get net random index
                RandomCount++;
                int RandomIndex = SecureRandom.Integer(0, MaxIndex + 1);
                RandomIndex = (RandomIndex * RandomIndex * RandomIndex) / (MaxIndex * MaxIndex);

                // Check if this index has been tried previously
                if (TriedIndexes.Contains(RandomIndex))
                {
                    continue;
                }

                // Add this index to the tried indexes list
                TriedIndexes.Add(RandomIndex);

                // Get the peer candidate
                PeerCandidate Peer = Candidates[RandomIndex];

                // Increment try count
                TryCount++;

                // Check if this peer is already connected
                if (IsPeerConnected(Peer))
                {
                    continue;
                }

                // TODO - check if we are allowing remote connections??

                // Check if this peer has previously been blacklists
                if (IsPeerAllowed(Peer))
                {
                    return;
                }

                // Attempt to add this peer candidate
                Logger.Debug($"[{TryCount}/10] Trying candidate #{RandomIndex} {Peer.Address}:{Peer.Port}, last seen {GetTimeDelta(Peer.LastSeen)} seconds ago");
                if (!AddPeer(Peer.Address, (int)Peer.Port))
                {
                    // Add to failed connection list
                    AddRecentlyTriedPeer(Peer);
                }
            }

            // Discovery process finished
            DiscoveryActive = false;
        }
Пример #5
0
        /// <summary>
        /// Initializes this node with the specified network configuration
        /// </summary>
        /// <param name="Configuration">A class containing all global information this node needs to operate</param>
        public Node(NetworkConfig Configuration)
        {
            // Assign configuration
            Globals = Configuration;

            // Setup logger
            Logger = new Logger()
            {
                LogFile        = Globals.LOG_FILE,
                LogLevel       = Globals.LOG_LEVEL,
                CustomPrefix   = Globals.CUSTOM_PREFIX,
                InfoColor      = Globals.INFO_COLOR,
                ImportantColor = Globals.IMPORTANT_COLOR,
                DebugColor     = Globals.DEBUG_COLOR,
                WarningColor   = Globals.WARNING_COLOR,
                ErrorColor     = Globals.ERROR_COLOR
            };

            // Show ascii art, strictly vanity
            if (!string.IsNullOrEmpty(Globals.ASCII_ART))
            {
                Logger?.Important(Globals.ASCII_ART);
            }
            Logger.ShowPrefix = true;

            // Setup our database
            Logger?.WriteLine("Setting up local storage...");
            if (!Directory.Exists(Globals.DATABASE_DIRECTORY))
            {
                Logger?.WriteLine("Creating directories...");
                Directory.CreateDirectory(Globals.DATABASE_DIRECTORY);
            }
            switch (Globals.DATABASE_TYPE)
            {
            case DatabaseType.SQLITE:
                DatabaseLocation = CombinePath(Globals.DATABASE_DIRECTORY, Globals.DATABASE_LOCATION);
                Database         = new Sqlite(DatabaseLocation);
                break;

            default:
                throw new ArgumentException("Invalid or non-specified database type");
            }

            // Setup our blockchain handler
            Logger?.WriteLine("Setting up blockchain handler...");
            Blockchain = new Blockchain()
            {
                Logger = Logger
            };

            // Create our P2P server
            Logger?.WriteLine("Setting up P2P server...");
            P2pServer = new P2pServer(Globals.P2P_MAX_PEER_CONNECTIONS);

            // Assign P2P event handlers
            Logger?.WriteLine("Assigning P2P callbacks...");
            AssignCallbacks();

            // Setup our API server
            Logger?.WriteLine("Setting up API server...");
            ApiServer = new ApiServer(Globals.API_MAX_WORKERS)
            {
                Logger = Logger
            };

            // Create an API context
            Logger?.WriteLine("Assigning API method context...");
            ApiServer.AssignMethodContext(new ApiMethods(this));

            // Setup our peer list
            Logger?.WriteLine("Setting up local peer list...");
            SetupPeerList();

            // Assign a unique identifier
            Logger?.WriteLine("Generating identifier...");
            Id = SecureRandom.Integer <ulong>();
        }