// Removes a peer from the peer list private void RemovePeer(Peer Peer) { // Lock peer list to prevent race conditions lock (PeerList) { // Check if peer is null, why not if (Peer == null) { return; } // Remove peer from the peer list if (PeerList.Contains(Peer)) { PeerList.Remove(Peer); OnPeerDisconnected(Peer); } // Dispose of peer Peer.Dispose(); // Stop and remove the underlying P2pPeer Peer.P2pPeer.Stop(); P2pServer.RemovePeer(Peer.P2pPeer); } }
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>(); }
/// <summary> /// Starts this node and any associated threads /// </summary> /// <returns>True if started successfully</returns> public bool Start() { // Start blockchain handler Logger.WriteLine("Starting blockchain handler..."); Logger?.WriteLine($"Database location: {DatabaseLocation}"); try { Blockchain.Start(Database); } catch (Exception e) { Logger?.Error($"Could not start blockchain handler: {e.Message}"); return(false); } Logger?.WriteLine($"Blockchain handler started"); // Start P2P server Logger?.WriteLine("Starting P2P server..."); if (P2pPort == 0) { P2pPort = Globals.P2P_DEFAULT_PORT; } try { P2pServer.Start(P2pPort, Globals.P2P_POLLING_INTERVAL); } catch (Exception e) { Logger?.Error($"Could not start P2P server: {e.Message}"); return(false); } Logger?.WriteLine($"P2P server started on port {P2pServer.Port}"); // Start API server Logger?.WriteLine("Starting API server..."); if (ApiPort == 0) { ApiPort = Globals.API_DEFAULT_PORT; } try { ApiServer.Start(ApiPort); } catch (Exception e) { Logger?.Error($"Could not start API server: {e.Message}"); return(false); } Logger?.WriteLine($"API server started on port {ApiServer.Port}"); // Start sync process Logger?.WriteLine("Starting sync process..."); StartSync(); // Start is completed Logger?.Important($"Node initialized with ID {Id}"); return(true); }
// Stops our node and ends all threads in a safe manner public void Stop() { // Stop API server Logger?.WriteLine("Stopping API server..."); ApiServer.Stop(); // Stop P2P server Logger?.WriteLine("Stopping P2P server..."); P2pServer.Stop(); // Dispose of all connected peers Logger?.WriteLine("Disposing of peers..."); foreach (var Peer in PeerList) { Peer.Dispose(); } Logger?.Important("Node stopped."); }
/// <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; }
/// <summary> /// Adds a peer to the connection queue to be accepted when space is available /// </summary> /// <param name="Address">The remote peer's host address</param> /// <param name="Port">The remote peer's listening port</param> /// <returns>True if connection was made</returns> public bool AddPeer(string Address, int Port) { // Add peer to server return(P2pServer.AddPeer(Address, Port)); }
// Manually adds a peer to our P2P peer list, replacing one if needed public void ForceAddPeer(string Address, int Port) { // Force-add peer to server P2pServer.ForceAddPeer(Address, Port); }
// Manually adds a peer to our P2P connection queue public void AddPeer(string Address, int Port) { // Add peer to server P2pServer.AddPeer(Address, Port); }
/// <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>(); }