diff --git a/src/libs/blockchain/routines/Sync.ts b/src/libs/blockchain/routines/Sync.ts index b4eafab43..eee6a1ba9 100644 --- a/src/libs/blockchain/routines/Sync.ts +++ b/src/libs/blockchain/routines/Sync.ts @@ -70,12 +70,12 @@ export async function fastSync( peerlist = [singlePeer] } // Selecting the first peer - let firstPeer = peerlist[0] - console.log("[SYNC] First peer is " + firstPeer.connectionString) + let firstPeer: Peer = peerlist[0] + console.log("[SYNC] First peer is " + firstPeer.connection.string) // Asking the first peer for the last block number let blockNumberResponse = await demostdlib.remoteCall( - firstPeer.connectionString, + firstPeer.connection.string, firstPeer, "getLastBlockNumber", "nodeCall", @@ -122,7 +122,7 @@ export async function fastSync( // TODO Test if it is more logic to just download the headers and, once a chain has been estabilished, download the blocks // TODO And by test i mean we have to do it let blockResponse = await demostdlib.remoteCall( - firstPeer.connectionString, + firstPeer.connection.string, firstPeer, "getBlockByNumber", "nodeCall", @@ -175,12 +175,12 @@ export async function fastSync( // TODO Sync reimplementation export async function Sync(peer: Peer): Promise { - if (!peer.socket) { - console.log("[SYNC] Peer has no socket: " + peer.connectionString) + if (!peer.connection.socket) { + console.log("[SYNC] Peer has no socket: " + peer.connection.string) return false } - if(!peer.socket.connected) { - console.log("[SYNC] Peer socket is not connected: " + peer.connectionString) + if(!peer.connection.socket.connected) { + console.log("[SYNC] Peer socket is not connected: " + peer.connection.string) return false } // Getting our last block number and hash @@ -248,7 +248,7 @@ export async function Sync(peer: Peer): Promise { async function askLastBlockNumber(peer: Peer): Promise { let blockNumberResponse = await demostdlib.remoteCall( - peer.connectionString, + peer.connection.string, peer, "getLastBlockNumber", "nodeCall", @@ -266,7 +266,7 @@ async function askLastBlockNumber(peer: Peer): Promise { async function askBlockByNumber(peer: Peer, blockNumber: number): Promise { let blockResponse = await demostdlib.remoteCall( - peer.connectionString, + peer.connection.string, peer, "getBlockByNumber", "nodeCall", diff --git a/src/libs/communications/comlink.ts b/src/libs/communications/comlink.ts index 90e3cf17d..28b824425 100644 --- a/src/libs/communications/comlink.ts +++ b/src/libs/communications/comlink.ts @@ -99,9 +99,9 @@ export default class ComLink { console.log("[COMMUNICATIONS] Invalid message") return [false, "Invalid message"] } - if (peer.socket) { + if (peer.connection.socket) { console.log( - "[COMMUNICATIONS] Sending message to peer " + peer.socket.id, + "[COMMUNICATIONS] Sending message to peer " + peer.connection.socket.id, ) // NOTE Removing privated key from message if present if (message.privateKey) { @@ -149,7 +149,7 @@ export default class ComLink { } // INFO Broadcast a ComLink object to a peer (usually called by the above methods) async broadcastToPeer(peer: Peer) { - let _socket = peer.socket + let _socket = peer.connection.socket console.log("[COMMUNICATIONS] Broadcast message to peer") // NOTE Here we make sure that we dont have private data in the message if (this.chain.current.currentMessage.privateKey) { @@ -165,7 +165,7 @@ export default class ComLink { // INFO Support for sending to a socket directly async broadcastToSocketPeer(socket: Socket) { let compatible_peer = new Peer() - compatible_peer.socket = socket + compatible_peer.connection.socket = socket await this.broadcastToPeer(compatible_peer) } diff --git a/src/libs/consensus/mechanisms/BFT.ts b/src/libs/consensus/mechanisms/BFT.ts index a2f707643..1443c95e7 100644 --- a/src/libs/consensus/mechanisms/BFT.ts +++ b/src/libs/consensus/mechanisms/BFT.ts @@ -252,7 +252,7 @@ export default class QBFT { let peer = peerlist[i] const response = await new Promise(resolve => { - peer.socket.emit( + peer.connection.socket.emit( "voteRequest", { parameter: parameter, diff --git a/src/libs/network/client.ts b/src/libs/network/client.ts index 06e7644fc..378aed97a 100644 --- a/src/libs/network/client.ts +++ b/src/libs/network/client.ts @@ -15,7 +15,7 @@ import terminalkit from "terminal-kit" import Peer from "../peer/Peer" import ClientListeners from "./clientListeners" import CommonListeners from "./commonListeners" - +import log from "src/utilities/logger" const term = terminalkit.terminal // NOTE Sleep function @@ -26,20 +26,34 @@ async function sleep(ms) { } export default class Client { - - static async connectToPeerObject(peer: Peer): Promise<[boolean, Peer | null]> { - // Just a wrapper around the connectToPeer function - const address = peer.connectionString.split(">")[0] - const port = parseInt(peer.connectionString.split(">")[1]) - const connectedPeer = await this.connectToPeer(address, port) - if (!connectedPeer) { + static async connectToPeerObject( + peer: Peer, + ): Promise<[boolean, Peer | null]> { + // We can work with a connection string and it would be better to do so + if (peer.connection.string) { + log.info("[CLIENT] Peer has a connection string: trying to connect using it") + const address = peer.connection.string.split(">")[0] + const port = parseInt(peer.connection.string.split(">")[1]) + const connectedPeer: Peer | null = await this.connectToPeer(address, port) + if (!connectedPeer) { + return [false, null] + } else { + return [true, connectedPeer] + } + } + // We can work with a simple socket anyway + else if (peer.connection.socket) { + log.info("[CLIENT] Peer has a socket but no connection string: trying to use it") + return [peer.connection.socket.connected, peer] // ? If it is not connected we should try to reconnect + } + // We can't work with a peer without a socket or a connection string + else { + log.error("[CLIENT] Peer has no socket or connection string: cannot connect") return [false, null] - } else { - return [true, connectedPeer] } } - // ! Refactor to accept a Peer object (made with PeerManager.extractPeerFromString) + // ? Refactor to accept a Peer object (made with PeerManager.extractPeerFromString) static async connectToPeer( address: string = "localhost", port: number = 53550, @@ -52,12 +66,18 @@ export default class Client { const connectionSocket = io(address + ":" + port) connectionSocket.on("connect", async () => { - term.green( + term.yellow( "[CLIENT] Connected to peer at " + address + ":" + port + "\n", ) + log.info("[CLIENT] Connecting to peer at " + address + ":" + port) _peerForged.identity = "placeholder" // TODO Add identity filling and verification - _peerForged.socket = connectionSocket - _peerForged.connectionString = address + ">" + port + _peerForged.connection.socket = connectionSocket + _peerForged.connection.string = address + ">" + port + term.yellow( + "[CLIENT] Connection string set to " + + _peerForged.connection.string + + "\n", + ) const commonListeners = new CommonListeners(_peerForged) const clientListeners = new ClientListeners(_peerForged) await commonListeners.runListeners() @@ -69,12 +89,32 @@ export default class Client { //Timeout and timer for the connection (yes, a blocking one) while (timeout > 0) { if (connected) { + log.info( + "[CLIENT] Connected to peer at " + address + ":" + port, + ) + term.green( + "[CLIENT] Connected to peer at " + + address + + ":" + + port + + "\n", + ) return _peerForged } else { timeout -= 100 await sleep(100) } } + log.error( + "[CLIENT] Failed to connect to peer at " + address + ":" + port, + ) + term.red( + "[CLIENT] Failed to connect to peer at " + + address + + ":" + + port + + "\n", + ) return null } diff --git a/src/libs/network/clientListeners.ts b/src/libs/network/clientListeners.ts index e356475f6..cb71092a0 100644 --- a/src/libs/network/clientListeners.ts +++ b/src/libs/network/clientListeners.ts @@ -13,13 +13,14 @@ KyneSys Labs: https://www.kynesys.xyz/ import terminalkit from "terminal-kit" import { PeerManager } from "../peer" +import { Peer } from "../peer" const term = terminalkit.terminal export default class ClientListeners { - private peer: any + private peer: Peer - constructor(peer: any) { + constructor(peer: Peer) { this.peer = peer } @@ -28,7 +29,7 @@ export default class ClientListeners { } private connectListener = async () => { - this.peer.socket.on("connect", async connected_socket => { + this.peer.connection.socket.on("connect", async () => { term.green("[CLIENT] Connected to peer\n") PeerManager.getInstance().addPeer(this.peer) }) diff --git a/src/libs/network/commonListeners.ts b/src/libs/network/commonListeners.ts index 57e4927da..968c79d2f 100644 --- a/src/libs/network/commonListeners.ts +++ b/src/libs/network/commonListeners.ts @@ -18,13 +18,14 @@ import ResponseRegistry from "../communications/responseRegistry" import { cryptography } from "../crypto" import getRemoteIP from "../network/routines/getRemoteIP" import { PeerManager } from "../peer" +import { Peer } from "src/libs/peer" const term = terminalkit.terminal export default class CommonListeners { - private peer: any + private peer: Peer - constructor(peer: any) { + constructor(peer: Peer) { this.peer = peer } @@ -37,7 +38,7 @@ export default class CommonListeners { } private disconnectListener = async () => { - this.peer.socket.on("disconnect", async () => { + this.peer.connection.socket.on("disconnect", async () => { // Removing the peer from the list if it was in term.yellow("[COMMON] Peer disconnected") PeerManager.getInstance().removePeer(this.peer) @@ -48,7 +49,7 @@ export default class CommonListeners { // ? REVIEW Send the remote ip too let remote_ip = await getRemoteIP() let message = "Please authenticate me: " + remote_ip - this.peer.socket.on("auth_ask", async (data: { message: string }) => { + this.peer.connection.socket.on("auth_ask", async (data: { message: string }) => { //console.log(data) // REVIEW Signing data.message with the private key let _signature = cryptography.sign( @@ -61,13 +62,13 @@ export default class CommonListeners { _signature, sharedState.getInstance().identity.ed25519.publicKey, ] - this.peer.socket.emit("auth_reply", _sendBack) + this.peer.connection.socket.emit("auth_reply", _sendBack) }) } // INFO For non sensitive data private publicListener = async () => { - this.peer.socket.on("public", request => async () => { + this.peer.connection.socket.on("public", request => async () => { console.log("[PEER] Received") let response = { muid: request.muid, @@ -84,12 +85,12 @@ export default class CommonListeners { } // Once the response should be processed, we need to send it back // TODO Would be better to have requests with is_reply set to true or false instead of two listeners - this.peer.socket.emit("public_reply", response) + this.peer.connection.socket.emit("public_reply", response) }) } private comlinkReplyListener = async () => { - this.peer.socket.on("comlink_reply", async request => { + this.peer.connection.socket.on("comlink_reply", async request => { // request is a ComLink object with the same structure as the comlink listener below console.log("[PEER] Received reply to " + request.muid) //console.log(JSON.stringify(request, null, 2)) @@ -109,7 +110,7 @@ export default class CommonListeners { // Parsing the comlink let parsed_comlink = await ComLinkUtils.parseComlink( request, - this.peer.socket, + this.peer.connection.socket, ) if (!parsed_comlink) { return @@ -126,14 +127,14 @@ export default class CommonListeners { ResponseRegistry.getInstance().registerResponse( request.chain.current.currentMessage, request.muid, - this.peer.socket, + this.peer.connection.socket, connection_string, ) }) } private errorListener = async () => { - this.peer.socket.on("error", async request => { + this.peer.connection.socket.on("error", async request => { console.log("[PEER] Received error:") //console.log(request) }) diff --git a/src/libs/network/routines/nodecalls/getPeerlist.ts b/src/libs/network/routines/nodecalls/getPeerlist.ts index 1c57f63e1..70ded15ae 100644 --- a/src/libs/network/routines/nodecalls/getPeerlist.ts +++ b/src/libs/network/routines/nodecalls/getPeerlist.ts @@ -9,7 +9,7 @@ export default async function getPeerlist(): Promise { let response = [] as Peer[] // Filling response with peers without socket objects for (let peer of socketized_response) { - peer.socket = null + peer.connection.socket = null response.push(peer) } return response diff --git a/src/libs/network/routines/timeSync.ts b/src/libs/network/routines/timeSync.ts index e7d75ee6a..6715bb22e 100644 --- a/src/libs/network/routines/timeSync.ts +++ b/src/libs/network/routines/timeSync.ts @@ -24,7 +24,7 @@ export default async function getPeerTime( id: any, ): Promise { // A peer object must have a valid socket - if (!peer.socket) { + if (!peer.connection.socket) { return null } diff --git a/src/libs/network/server.ts b/src/libs/network/server.ts index dcdac9291..31fede305 100644 --- a/src/libs/network/server.ts +++ b/src/libs/network/server.ts @@ -9,7 +9,8 @@ KyneSys Labs: https://www.kynesys.xyz/ */ -import { Server as ServerType } from "socket.io" +import { Server as ServerType, Socket as ServerSocket } from "socket.io" +import { Socket } from "socket.io-client" import ServerListeners from "src/libs/network/serverListeners" import { Peer } from "src/libs/peer" import terminalkit from "terminal-kit" @@ -22,7 +23,8 @@ export default class Server { term.green("[SERVER] Peer connected\n") const newPeer = new Peer() - newPeer.setSocket(peerSocket) + newPeer.connection.serverSocket = peerSocket // ? is this useful? + newPeer.connection.socket = peerSocket as any as Socket // ? If it works, don't touch it //newPeer.setIdentity(identity.ed25519.publicKey) //PeerManager.getInstance().addPeer(newPeer) const serverListeners = new ServerListeners(newPeer) diff --git a/src/libs/network/serverHandlers.ts b/src/libs/network/serverHandlers.ts index 49e700996..f052529e5 100644 --- a/src/libs/network/serverHandlers.ts +++ b/src/libs/network/serverHandlers.ts @@ -43,6 +43,7 @@ import terminalkit from "terminal-kit" import { AddressInfo, + BundleContent, ExecutionResult, IWeb2Payload, IWeb2Request, @@ -62,12 +63,39 @@ import Block from "../blockchain/block" import { BlockContent } from "../../../../sdks/src/types/blockchain/blocks" import handleWeb2Request from "./routines/transactions/handleWeb2Request" import getPeerInfo from "./routines/nodecalls/getPeerInfo" +import forge from "node-forge" +import { PeerManager } from "docker/node_base/src/libs/peer" let term = terminalkit.terminal export default class ServerHandlers { // ANCHOR BrowserRequest + // SECTION Hello Peer + static async handleHelloPeer(content: BundleContent): Promise<{ response: any, require_reply: boolean, extra: any }> { + let connectionString = content.message as string // This is also the signed message to verify the peer + let signature = content.data.signature as forge.pki.ed25519.BinaryBuffer // REVIEW is this the right type? + let publicKey = content.data.publicKey as forge.pki.PublicKey + // Let's verify the peer + let verified = Cryptography.verify(connectionString, signature, publicKey) + if (!verified) { + return { response: false, require_reply: false, extra: "Invalid signature" } + } + // Creating a Peer object + let peer = new Peer() + peer.identity = publicKey as forge.pki.ed25519.BinaryBuffer + peer.connection.string = connectionString + let isConnected = await peer.connect() + if (!isConnected) { + return { response: false, require_reply: false, extra: "Could not connect to peer" } + } + let isAddedToPeerlist = PeerManager.getInstance().addPeer(peer) + if (!isAddedToPeerlist) { + return { response: false, require_reply: false, extra: "Could not add peer to peerlist" } + } + return { response: true, require_reply: false, extra: null } + } + // SECTION Login On Chain static async handleLoginRequest(content: BrowserRequest) { // A browser login request is the first step for a user to confirm their identity diff --git a/src/libs/network/serverListeners.ts b/src/libs/network/serverListeners.ts index a070bef29..43b2537ed 100644 --- a/src/libs/network/serverListeners.ts +++ b/src/libs/network/serverListeners.ts @@ -46,7 +46,7 @@ export default class ServerListeners { // INFO this set of listeners does not require authentication and // are not comlink as well, so they need to have their own listeners async browserRequestListener() { - this.peer.socket.on("browser_request", async request => { + this.peer.connection.socket.on("browser_request", async request => { term.yellow("[SERVER] Received browser request\n") // NOTE request MUST be a string conforming to BrowserRequest interface let req: BrowserRequest = JSON.parse(request) @@ -67,7 +67,7 @@ export default class ServerListeners { browserResponse = [false, "Invalid request"] break } - this.peer.socket.emit( + this.peer.connection.socket.emit( "browser_response", JSON.stringify(browserResponse), ) @@ -82,34 +82,36 @@ export default class ServerListeners { A message is just a message, so it is handled by its type. */ async comlinkListener() { - this.peer.socket.on("comlink", async request => { + this.peer.connection.socket.on("comlink", async request => { await this.manageComLink(request) }) // TODO See in communications.js and find the best way to validate, check and digest the request } // This method is used to check the comlink before processing it - async preflightComLinkChecks(request: any): Promise { + async preflightComLinkChecks(request: any): Promise<{ _comlink_request: ComLink, content: BundleContent, id_ed25519: forge.pki.KeyPair, receiver: any } > { term.yellow("[SERVER] Received comlink\n") console.log(request) const id_ed25519 = sharedState.getInstance().identity.ed25519 - const receiver = this.peer.socket + const receiver = this.peer.connection.socket let _comlink_request: ComLink // TODO This can be put into securityModule for consistency try { // Parsing comlink _comlink_request = await comlinkUtils.parseComlink( request, - this.peer.socket, + this.peer.connection.socket, ) if (!_comlink_request) { let error = "Error while parsing comlink request\n" - return error// TODO Better error handling + log.error(error) + return null// TODO Better error handling } - } catch (error) { - term.red(error) + } catch (e) { + let error = "Error while parsing comlink request: " + e + log.error(error) console.log("Returning") - return error // TODO Better error handling + return null // TODO Better error handling } // We can now extract the comlink and the content to be used in the handlers console.log( @@ -135,7 +137,6 @@ export default class ServerListeners { console.log("[serverListeners] content.type: " + content.type) console.log("[serverListeners] content.extra: " + content.extra) - // NOTE Intercepts the comlink and checks if it is a L2PS request if (content.type === "l2ps") { ;({ response, require_reply, extra } = await ServerHandlers.handleL2PS(content)) if (!response) { @@ -155,21 +156,25 @@ export default class ServerListeners { return } - /* NOTE If we are here, we have a transaction or we error out - if (content.type !== "transaction") { - term.red.bold( - "[SERVER] Received a non recognized comlink, aborting", - ) - console.log(content.type) - await demostdlib.reply( - _comlink_request, - false, - false, - "invalid comlink type", - ) - receiver.emit("comlink_reply", _comlink_request) // reply is managed in the common listeners - return - } */ + // NOTE As first step, we check if this is a peer pairing request + /* This endpoint requires content to be: + content.message = connection_string + content.data.signature = signature of the connection_string + content.data.publicKey = public key of the peer signing the connection_string + */ + // ? This is still unused (delete this line once it is used) + if (content.type === "hello_peer") { + ;({ response, require_reply, extra } = await ServerHandlers.handleHelloPeer(content)) + if (!response) { + if (!extra) { + extra = "Error while handling Hello Peer request: error not specified" + } + log.error("Error while handling Hello Peer request: " + extra) + response = false + extra = "Error while handling Hello Peer request: " + extra + require_reply = false + } + } // TODO Better to modularize this // REVIEW We use the 'extra' field to see if it is a confirmTx request (prior to execution) @@ -200,7 +205,7 @@ export default class ServerListeners { // REVIEW This method needs to actually verify if the transaction is valid var result = await ServerHandlers.handleExecuteTransaction( content.data as ValidityData, - this.peer.socket, + this.peer.connection.socket, ) // Destructuring the result to get the extra, require_reply and response ;({ extra, require_reply, response } = result) @@ -262,7 +267,7 @@ export default class ServerListeners { // INFO Register or update a peer identity and connection string async authReplyListener() { // REVIEW Auth reply listener should not add a client to the peerlist if is read only - this.peer.socket.on("auth_reply", async data => { + this.peer.connection.socket.on("auth_reply", async data => { let identity = await cryptography.load("./.demos_identity") term.yellow("[SERVER] Received auth reply") // Unpack the data for readability @@ -279,17 +284,17 @@ export default class ServerListeners { ) // Disconnect if the verification is false if (!_verification) { - this.peer.socket.emit("auth_fail") - this.peer.socket.disconnect() + this.peer.connection.socket.emit("auth_fail") + this.peer.connection.socket.disconnect() } // Getting the public IP of the peer so we can add it to the peerlist let remote_ip = original_message.split(":")[0].trim() let connection_string = remote_ip + ">53550>" + original_identity // ! Allow dynamic ports // ? REVIEW build the Peer object and add it to the peerlist (connection string missing atm) let new_peer: Peer = new Peer() - new_peer.socket = this.peer.socket + new_peer.connection.socket = this.peer.connection.socket new_peer.identity = original_identity - new_peer.connectionString = connection_string + new_peer.connection.string = connection_string PeerManager.getInstance().addPeer(new_peer) log.info("Peer added to the peerlist: " + connection_string) } else { @@ -303,16 +308,16 @@ export default class ServerListeners { signature: _signature, identity: identity.publicKey, } - this.peer.socket.emit("auth_ok", _reply) + this.peer.connection.socket.emit("auth_ok", _reply) }) } authAskEmit = async () => { - await this.peer.socket.emit("auth_ask", "sign this") + await this.peer.connection.socket.emit("auth_ask", "sign this") } voteRequestListener = async () => { - this.peer.socket.on("voteRequest", async (request, callback) => { + this.peer.connection.socket.on("voteRequest", async (request, callback) => { term.yellow("[SERVER] Received vote request\n") //console.log(request) let voteResponse: string diff --git a/src/libs/peer/Peer.ts b/src/libs/peer/Peer.ts index 0eabb56d0..8258f0638 100644 --- a/src/libs/peer/Peer.ts +++ b/src/libs/peer/Peer.ts @@ -12,48 +12,69 @@ KyneSys Labs: https://www.kynesys.xyz/ import type { IPeerConfig } from "@kynesyslabs/demosdk/types" import forge from "node-forge" import { Socket } from "socket.io-client" +import { Socket as ServerSocket } from "socket.io" import log from "src/utilities/logger" +import { io } from "socket.io-client" export default class Peer { - connectionString: string - socket: Socket - identity: forge.pki.ed25519.BinaryBuffer // public key - - constructor(config?: IPeerConfig) { - this.connectionString = config?.connectionString - this.socket = config?.socket - this.identity = config?.identity + // connection informations + public connection: { + string: string // this is optional and is mostly used for permanent connections + socket: Socket // this is the socket object from the client pov and is mandatory + serverSocket: ServerSocket // this is the socket object from a server pov and is mandatory } - - // Methods - // INFO Set the connection string of the peer - setConnectionString(connectionString: string) { - this.connectionString = connectionString + public identity: forge.pki.ed25519.BinaryBuffer // public key + // verification informations + public verification: { + status: boolean // has been verified against the public key + message: string // message from the peer at the time of verification + timestamp: number // timestamp of the verification } - // INFO Set the socket of the peer - setSocket(socket: Socket) { - this.socket = socket + // status informations + public status: { + online: boolean // is the peer online + timestamp: number // timestamp of the last online status check } - // INFO Set the identity of the peer - setIdentity(identity: forge.pki.ed25519.BinaryBuffer) { - this.identity = identity + + // Creating an empty peer + constructor() { + this.connection = { + string: "", + socket: null, + serverSocket: null, + } + this.identity = null + this.verification = { + status: false, + message: null, + timestamp: null, + } + this.status = { + online: false, + timestamp: null, + } } - // INFO Getting the socket or die trying - getSocket(): Socket { - if (!this.socket) { - return null + // Methods to handle the peer + + // INFO Connect to a peer + async connect(): Promise { + try { + this.connection.socket = io(this.connection.string) + } catch (error) { + log.error("Peer connection to " + this.connection.string + " failed: " + error) + return false } - return this.socket + return true } // INFO Check online status for a peer - async checkOnlineStatus() { // ? Review - const socket = this.getSocket() - if (!socket) { + async checkOnlineStatus(): Promise { + if (!this.connection.socket) { return false } // We have a socket, lets check if is connected - return socket.connected + return this.connection.socket.connected } + } diff --git a/src/libs/peer/PeerManager.ts b/src/libs/peer/PeerManager.ts index 8a5e7f240..3541a1074 100644 --- a/src/libs/peer/PeerManager.ts +++ b/src/libs/peer/PeerManager.ts @@ -103,8 +103,8 @@ export default class PeerManager { for await (const _peer of Object.values(this.peerList)) { const peerInstance = new Peer() peerInstance.identity = _peer.identity - peerInstance.connectionString = _peer.connectionString - peerInstance.socket = _peer.socket + peerInstance.connection.string = _peer.connection.string + peerInstance.connection.socket = _peer.connection.socket const onlinePeerStatus = await peerInstance.checkOnlineStatus() if (onlinePeerStatus) { onlinePeers.push(peerInstance) @@ -125,8 +125,8 @@ export default class PeerManager { this.peerList[identity] = peer console.log("[PEERMANAGER] Peer added") console.log("Identity: " + peer.identity.toString("hex")) - console.log("Connection string: " + peer.connectionString) - if (!peer.connectionString) { + console.log("Connection string: " + peer.connection.string) + if (!peer.connection.string) { console.log("[WARN] No connection string detected") } // FIXME Run the routine in peers to get it @@ -167,8 +167,15 @@ export default class PeerManager { } const peer = new Peer() peer.identity = Buffer.from(currentPublicKey, "hex") - peer.connectionString = currentPeerAddress + ">" + currentPeerPort - // NOTE peer.socket = null + // ! Remove debug code + try { + peer.connection.string = currentPeerAddress + ">" + currentPeerPort + } catch (error) { + console.log("[PEERMANAGER] Error extracting peer from string: " + error) + log.critical("Error extracting peer from string: " + error) + process.exit(1) + } + // NOTE peer.connection.socket = null return peer } diff --git a/src/libs/peer/routines/getPeerConnectionString.ts b/src/libs/peer/routines/getPeerConnectionString.ts index a036e2c46..a2a8e8658 100644 --- a/src/libs/peer/routines/getPeerConnectionString.ts +++ b/src/libs/peer/routines/getPeerConnectionString.ts @@ -23,7 +23,7 @@ export default async function getPeerConnectionString( id: any, ): Promise { // A peer object must have a valid socket - if (!peer.socket) { + if (!peer.connection.socket) { return null } // Asking the peer for its identity diff --git a/src/libs/peer/routines/getPeerIdentity.ts b/src/libs/peer/routines/getPeerIdentity.ts index 08c737620..82629ca9d 100644 --- a/src/libs/peer/routines/getPeerIdentity.ts +++ b/src/libs/peer/routines/getPeerIdentity.ts @@ -20,7 +20,7 @@ export default async function getPeerIdentity( expectedKey: string, ): Promise { // A peer object must have a valid socket - if (!peer.socket) { + if (!peer.connection.socket) { return null } diff --git a/src/libs/peer/routines/peerBootstrap.ts b/src/libs/peer/routines/peerBootstrap.ts index 2419a137a..5c25b7504 100644 --- a/src/libs/peer/routines/peerBootstrap.ts +++ b/src/libs/peer/routines/peerBootstrap.ts @@ -50,14 +50,14 @@ export default async function peerBootstrap( ) // REVIEW Connection test and add to valid_peers // Trying to connect and retrieve the socket for the given peer using Peer class - let _currentTestingPeer = PeerManager.extractPeerFromString(_currentPeerURL) + let _currentTestingPeer: Peer = PeerManager.extractPeerFromString(_currentPeerURL) // TODO See PeerManager.extractPeerFromString and Client.connectToPeer comments let _currentPeerObject = await Client.connectToPeer( currentPeerAddress, currentPeerPort, ) // Returns the Peer object if (_currentPeerObject) { - console.log("[BOOTSTRAP] _currentPeerObject has a socket id: " + _currentPeerObject.socket.id) + console.log("[BOOTSTRAP] _currentPeerObject has a socket id: " + _currentPeerObject.connection.socket.id) // Adding identity if any console.log( "[BOOTSTRAP] Testing " + currentPeerAddress + " identity", @@ -71,7 +71,15 @@ export default async function peerBootstrap( console.log( "[BOOSTRAP: overriding connectionstring] " + _currentPeerURL, ) - _currentPeerObject.connectionString = _currentPeerURL // Adding this step + console.log(_currentPeerObject) + // ! remove debug code + try { + _currentPeerObject.connection.string = _currentPeerURL // Adding this step + } catch (error) { + console.log("[PEERBOOTSTRAP] Error setting connection string: " + error) + log.critical("Error setting connection string: " + error) + process.exit(1) + } console.log( "[BOOTSTRAP] OK: Valid peer " + currentPeerAddress + @@ -88,7 +96,7 @@ export default async function peerBootstrap( } else */ console.warn("[PEERBOOTSTRAP] Adding peer to peerlist") //console.warn(_currentPeerObject) - if (_currentPeerObject.socket.connected) { + if (_currentPeerObject.connection.socket.connected) { let inserted = PeerManager.getInstance().addPeer(_currentPeerObject) if (!inserted) { diff --git a/src/libs/utils/demostdlib/remoteCall.ts b/src/libs/utils/demostdlib/remoteCall.ts index 4b98158d4..425683f34 100644 --- a/src/libs/utils/demostdlib/remoteCall.ts +++ b/src/libs/utils/demostdlib/remoteCall.ts @@ -38,9 +38,9 @@ export async function remoteCall( console.log("[SYNC] Finalized the message") // Putting the message into a new comlink console.log("[SYNC] Putting the message into the comlink using socket: ") - console.log(peer.socket) + console.log(peer.connection.socket) console.log( - "[SYNC] Asking " + peer.socket.id + " for " + type + "\n" + message, + "[SYNC] Asking " + peer.connection.socket.id + " for " + type + "\n" + message, ) // Preparing for a response _comlink.properties.require_reply = requireReply diff --git a/src/utilities/logger.ts b/src/utilities/logger.ts index b49597fdd..339d6d7dd 100644 --- a/src/utilities/logger.ts +++ b/src/utilities/logger.ts @@ -22,33 +22,47 @@ export default class log { return new Date().toISOString() } - static info(message: string) { + static info(message: string, logToTerminal: boolean = true) { const logEntry = `[INFO] [${this.getTimestamp()}] ${message}\n` - term.bold(logEntry.trim()) + if (logToTerminal) { + term.bold(logEntry.trim()) + } fs.appendFileSync(this.LOG_INFO_FILE, logEntry) } - static error(message: string) { + static error(message: string, logToTerminal: boolean = true) { const logEntry = `[ERROR] [${this.getTimestamp()}] ${message}\n` - term.red(logEntry.trim()) + if (logToTerminal) { + term.red(logEntry.trim()) + } + fs.appendFileSync(this.LOG_INFO_FILE, logEntry) fs.appendFileSync(this.LOG_ERROR_FILE, logEntry) } - static debug(message: string) { + static debug(message: string, logToTerminal: boolean = true) { const logEntry = `[DEBUG] [${this.getTimestamp()}] ${message}\n` - term.magenta(logEntry.trim()) + if (logToTerminal) { + term.magenta(logEntry.trim()) + } + fs.appendFileSync(this.LOG_INFO_FILE, logEntry) fs.appendFileSync(this.LOG_DEBUG_FILE, logEntry) } - static warning(message: string) { + static warning(message: string, logToTerminal: boolean = true) { const logEntry = `[WARNING] [${this.getTimestamp()}] ${message}\n` - term.yellow(logEntry.trim()) + if (logToTerminal) { + term.yellow(logEntry.trim()) + } + fs.appendFileSync(this.LOG_INFO_FILE, logEntry) fs.appendFileSync(this.LOG_WARNING_FILE, logEntry) } - static critical(message: string) { - const logEntry = `[CRITICAL] [${this.getTimestamp()}] ${message}\n` - term.bold.red(logEntry.trim()) + static critical(message: string, logToTerminal: boolean = true) { + const logEntry = `[CRITICAL] [${this.getTimestamp()}] ${message}\n` + if (logToTerminal) { + term.bold.red(logEntry.trim()) + } + fs.appendFileSync(this.LOG_INFO_FILE, logEntry) fs.appendFileSync(this.LOG_CRITICAL_FILE, logEntry) } diff --git a/src/utilities/mainLoop.ts b/src/utilities/mainLoop.ts index 677cc8a59..a5eff26b9 100644 --- a/src/utilities/mainLoop.ts +++ b/src/utilities/mainLoop.ts @@ -120,7 +120,7 @@ export default async function mainLoop() { currentlyOnlinePeers = onlinePeers.map(peer => { return { identity: peer.identity, - connectionString: peer.connectionString, + connectionString: peer.connection.string, } }) }