diff --git a/Desktop/DesktopApp.js b/Desktop/DesktopApp.js index 6581230a1..90693c4a7 100644 --- a/Desktop/DesktopApp.js +++ b/Desktop/DesktopApp.js @@ -1,10 +1,12 @@ exports.newDesktopApp = function newDesktopApp() { let thisObject = { - socialGraph: undefined, + userProfiles: undefined, + p2pNetworkClient: undefined, p2pNetwork: undefined, webSocketsClient: undefined, webSocketsInterface: undefined, + socialGraph: undefined, run: run } @@ -13,37 +15,53 @@ exports.newDesktopApp = function newDesktopApp() { return thisObject async function run() { - /* - This is the Personal Social Graph for the user running this App. - */ - thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph() - await thisObject.socialGraph.initialize() - /* - We can join now the P2P Network as a client app. - */ - thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork() - await thisObject.p2pNetwork.initialize('Network Client') - /* - Here we will pick a Network Node from all users profiles available that do have a Network Node running. - */ - let selectedNetworkNode = thisObject.p2pNetwork.p2pNodesToConnect[0] - /* - This is the Web Sockets client that interacts with the Superalgos Network. - */ - thisObject.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient() - await thisObject.webSocketsClient.initialize('Network Client', selectedNetworkNode) - /* - These are the Network Interfaces by which the Web App interacts with this Desktop Client. - */ - thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface() - thisObject.webSocketsInterface.initialize() - console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT) + setupNetwork() + setupServices() + async function setupNetwork() { + /* + We set up ourselves as a Network Client. + */ + thisObject.p2pNetworkClient = SA.projects.network.modules.p2pNetworkClient.newNetworkModulesP2PNetworkClient() + await thisObject.p2pNetworkClient.initialize() + /* + We will read all user profiles plugins and get from there our network identity. + */ + thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles() + await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClient) + /* + We set up the P2P Network. + */ + thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork() + await thisObject.p2pNetwork.initialize('Network Client') + /* + Here we will pick a Network Node from all users profiles available that do have a Network Node running. + */ + let selectedNetworkNode = thisObject.p2pNetwork.p2pNodesToConnect[0] + /* + This is the Web Sockets client that interacts with the Superalgos Network. + */ + thisObject.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient() + await thisObject.webSocketsClient.initialize('Network Client', thisObject.p2pNetworkClient, selectedNetworkNode) + } - thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface() - thisObject.httpInterface.initialize() - console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT) + async function setupServices() { + /* + This is the Personal Social Graph for the user running this App. + */ + thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph() + await thisObject.socialGraph.initialize() + /* + These are the Network Interfaces by which the Web App interacts with this Desktop Client. + */ + thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface() + thisObject.webSocketsInterface.initialize() + console.log('Desktop Client Web Sockets Interface ....................................... Listening at port ' + global.env.DESKTOP_WEB_SOCKETS_INTERFACE_PORT) + thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface() + thisObject.httpInterface.initialize() + console.log('Desktop Client Http Interface .............................................. Listening at port ' + global.env.DESKTOP_HTTP_INTERFACE_PORT) + } } } diff --git a/Network/NetwokNode.js b/Network/NetwokNode.js index 91fb26487..faa70ab93 100644 --- a/Network/NetwokNode.js +++ b/Network/NetwokNode.js @@ -1,11 +1,13 @@ exports.newNetworkNode = function newNetworkNode() { let thisObject = { + userProfiles: undefined, + p2pNetwork: undefined, + p2pNetworkPeers: undefined, + p2pNetworkNode: undefined, webSocketsInterface: undefined, socialGraphService: undefined, storage: undefined, - p2pNetwork: undefined, - p2pNetworkPeers: undefined, run: run } @@ -14,32 +16,50 @@ exports.newNetworkNode = function newNetworkNode() { return thisObject async function run() { - /* - The Social Graph Service is the first and for now, the only service this Network Node provides. - */ - thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph() - await thisObject.socialGraphService.initialize() - /* - The Sotrage deals with persisting the Social Graph. - */ - thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage() - thisObject.storage.initialize() - /* - Let's discover who is at the p2p network. - */ - thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork() - await thisObject.p2pNetwork.initialize('Network Peer') - /* - We can join now the P2P Network as a new peer there. - */ - thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers() - await thisObject.p2pNetworkPeers.initialize() - /* - Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface. - */ - thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface() - thisObject.webSocketsInterface.initialize() - console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort) + await setupNetwork() + await setupServices() + + async function setupNetwork() { + /* + We set up ourselves as a Network Node. + */ + thisObject.p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode() + await thisObject.p2pNetworkNode.initialize() + /* + We will read all user profiles plugins and get from there our network identity. + */ + thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles() + await thisObject.userProfiles.initialize(global.env.P2P_NETWORK_NODE_SIGNING_ACCOUNT, thisObject.p2pNetworkNode) + /* + Let's discover who is at the p2p network. + */ + thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork() + await thisObject.p2pNetwork.initialize('Network Peer') + /* + We can join now the P2P Network as a new peer there. + */ + thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers() + await thisObject.p2pNetworkPeers.initialize() + } + + async function setupServices() { + /* + The Social Graph Service is the first and for now, the only service this Network Node provides. + */ + thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph() + await thisObject.socialGraphService.initialize() + /* + The Sotrage deals with persisting the Social Graph. + */ + thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage() + thisObject.storage.initialize() + /* + Other Network Nodes and Client Apps will communicate with this Network Node via it's Websocket Interface. + */ + thisObject.webSocketsInterface = NT.projects.network.modules.webSocketsInterface.newNetworkModulesWebSocketsInterface() + thisObject.webSocketsInterface.initialize() + console.log('Network Node Web Sockets Interface ....................................... Listening at port ' + JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort) + } } } diff --git a/Projects/Network/NT/Modules/WebSocketsInterface.js b/Projects/Network/NT/Modules/WebSocketsInterface.js index 99cee0fc1..2ceaf7182 100644 --- a/Projects/Network/NT/Modules/WebSocketsInterface.js +++ b/Projects/Network/NT/Modules/WebSocketsInterface.js @@ -39,7 +39,7 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock } function initialize() { - let port = JSON.parse(NT.networkNode.p2pNetwork.thisNetworkNode.node.config).webSocketsPort + let port = JSON.parse(NT.networkNode.p2pNetworkNode.node.config).webSocketsPort thisObject.socketServer = new SA.nodeModules.ws.Server({ port: port }) thisObject.clientInterface = NT.projects.socialTrading.modules.clientInterface.newSocialTradingModulesClientInterface() @@ -64,7 +64,8 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock let caller = { socket: socket, userProfile: undefined, - role: undefined + role: undefined, + node: undefined } caller.socket.id = SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId() @@ -250,6 +251,32 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock } } /* + The caller needs to provide it's Node. + */ + if (messageHeader.callerNode === undefined) { + let response = { + result: 'Error', + message: 'node Not Provided.' + } + caller.socket.send(JSON.stringify(response)) + caller.socket.close() + return + } + /* + The caller's Node needs to be parseable. + */ + try { + caller.node = JSON.parse(messageHeader.callerNode) + } catch (err) { + let response = { + result: 'Error', + message: 'node Not Coorrect JSON Format.' + } + caller.socket.send(JSON.stringify(response)) + caller.socket.close() + return + } + /* The caller needs to provide it's User Profile Handle. */ if (messageHeader.callerProfileHandle === undefined) { @@ -261,7 +288,6 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock caller.socket.close() return } - caller.userProfileHandle = messageHeader.callerProfileHandle /* The caller needs to provide a callerTimestamp. @@ -491,13 +517,18 @@ exports.newNetworkModulesWebSocketsInterface = function newNetworkModulesWebSock } function broadcastToPeers(message, caller) { + /* + The Boradcast to network peers is not done via + the network peers incomming connections, but + on the outgoing connections only. + */ let callerIdToAVoid if (caller.role === 'Network Peer') { - callerIdToAVoid = caller.socket.id + callerIdToAVoid = caller.node.id } - for (let i = 0; i < thisObject.networkPeers.length; i++) { - let networkPeer = thisObject.networkPeers[i] - if (networkPeer.socket.id === callerIdToAVoid) { continue } + for (let i = 0; i < NT.networkNode.p2pNetworkPeers.outgoingConnectedPeers.length; i++) { + let networkPeer = NT.networkNode.p2pNetworkPeers.outgoingConnectedPeers[i] + if (networkPeer.p2pNetworkNode.node.id === callerIdToAVoid) { continue } networkPeer.socket.send(message) } } diff --git a/Projects/Network/SA/Modules/P2PNetwork.js b/Projects/Network/SA/Modules/P2PNetwork.js index 131f82e60..9c660c2e4 100644 --- a/Projects/Network/SA/Modules/P2PNetwork.js +++ b/Projects/Network/SA/Modules/P2PNetwork.js @@ -4,9 +4,7 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() { of this current node to other peers. */ let thisObject = { - joinTheNetworkAsNetworkPeer: joinTheNetworkAsNetworkPeer, p2pNodesToConnect: undefined, - thisNetworkNode: undefined, /* Framework Functions */ initialize: initialize, finalize: finalize @@ -38,18 +36,10 @@ exports.newNetworkModulesP2PNetwork = function newNetworkModulesP2PNetwork() { let p2pNetworkNode = SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES[i] if (thisP2PNodeId !== p2pNetworkNode.node.id) { thisObject.p2pNodesToConnect.push(p2pNetworkNode) - } else { - thisObject.thisNetworkNode = p2pNetworkNode } } break } } } - - function joinTheNetworkAsNetworkPeer() { - /* - To join the network we will need to thorugh the list of Network Nodes and pick one to connect to. - */ - } } \ No newline at end of file diff --git a/Projects/Network/SA/Modules/P2PNetworkClient.js b/Projects/Network/SA/Modules/P2PNetworkClient.js new file mode 100644 index 000000000..daa0bdb08 --- /dev/null +++ b/Projects/Network/SA/Modules/P2PNetworkClient.js @@ -0,0 +1,27 @@ +exports.newNetworkModulesP2PNetworkClient = function newNetworkModulesP2PNetworkClient() { + /* + This module represents the P2P Network Client running at the moment. + */ + let thisObject = { + + node: undefined, + blockchainAccount: undefined, + userProfile: undefined, + + /* Framework Functions */ + initialize: initialize, + finalize: finalize + } + + return thisObject + + function finalize() { + thisObject.node = undefined + thisObject.blockchainAccount = undefined + thisObject.userProfile = undefined + } + + async function initialize() { + + } +} \ No newline at end of file diff --git a/Projects/Network/SA/Modules/P2PNetworkPeers.js b/Projects/Network/SA/Modules/P2PNetworkPeers.js index e22197804..fe8b5aac0 100644 --- a/Projects/Network/SA/Modules/P2PNetworkPeers.js +++ b/Projects/Network/SA/Modules/P2PNetworkPeers.js @@ -39,7 +39,7 @@ exports.newNetworkModulesP2PNetworkPeers = function newNetworkModulesP2PNetworkP peer.p2pNetworkNode = NT.networkNode.p2pNetwork.p2pNodesToConnect[i] if (isOutgoingConnectedPeer(peer) === true) { continue } peer.webSocketsClient = SA.projects.network.modules.webSocketsNetworkClient.newNetworkModulesWebSocketsNetworkClient() - await peer.webSocketsClient.initialize('Network Peer', peer.p2pNetworkNode, onConnectionClosed) + await peer.webSocketsClient.initialize('Network Peer', NT.networkNode.p2pNetworkNode, peer.p2pNetworkNode, onConnectionClosed) .then(addPeer) .catch(onError) diff --git a/Projects/Network/SA/Modules/UserProfiles.js b/Projects/Network/SA/Modules/UserProfiles.js index 48f8a2f76..09df3e54a 100644 --- a/Projects/Network/SA/Modules/UserProfiles.js +++ b/Projects/Network/SA/Modules/UserProfiles.js @@ -18,7 +18,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles() } - async function initialize() { + async function initialize(signingAccountChildCodeName, p2pNetworkIdentity) { let pluginFileNames = await SA.projects.communityPlugins.utilities.plugins.getPluginFileNames( 'Governance', @@ -65,7 +65,7 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles() let signatureObject = config.signature let web3 = new SA.nodeModules.web3() let blockchainAccount = web3.eth.accounts.recover(signatureObject) - SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile) + SA.projects.network.globals.memory.maps.USER_PROFILES_BY_BLOKCHAIN_ACCOUNT.set(blockchainAccount, userProfile) /* If the Signing Account is for a P2P node, we will add the node to the array of available nodes at the p2p network. */ @@ -85,12 +85,22 @@ exports.newNetworkModulesUserProfiles = function newNetworkModulesUserProfiles() } if (config.webSocketsPort === undefined) { continue - } + } let p2pNetworkNode = SA.projects.network.modules.p2pNetworkNode.newNetworkModulesP2PNetworkNode() p2pNetworkNode.initialize(signingAccount.signingAccountChild, userProfile, blockchainAccount) SA.projects.network.globals.memory.arrays.P2P_NETWORK_NODES.push(p2pNetworkNode) } + /* + Now, we will extract the information from the User Profile, specifically of our identity at the p2p network. + */ + if ( + signingAccount.signingAccountChild.id === SA.secrets.map.get(signingAccountChildCodeName).signingAccountChildId + ) { + p2pNetworkIdentity.node = signingAccount.signingAccountChild + p2pNetworkIdentity.blockchainAccount = blockchainAccount + p2pNetworkIdentity.userProfile = userProfile + } } } } diff --git a/Projects/Network/SA/Modules/WebSocketsNetworkClient.js b/Projects/Network/SA/Modules/WebSocketsNetworkClient.js index a7605f6b9..4760e1919 100644 --- a/Projects/Network/SA/Modules/WebSocketsNetworkClient.js +++ b/Projects/Network/SA/Modules/WebSocketsNetworkClient.js @@ -8,6 +8,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb port: undefined, callerRole: undefined, p2pNetworkNode: undefined, + p2pNetworkIdentity: undefined, onConnectionClosedCallBack: undefined, sendMessage: sendMessage, initialize: initialize, @@ -29,6 +30,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb thisObject.port = undefined thisObject.callerRole = undefined thisObject.p2pNetworkNode = undefined + thisObject.p2pNetworkIdentity = undefined thisObject.onConnectionClosedCallBack = undefined web3 = undefined @@ -36,9 +38,10 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb onMessageFunctionsMap = undefined } - async function initialize(callerRole, p2pNetworkNode, onConnectionClosedCallBack) { + async function initialize(callerRole, p2pNetworkIdentity, p2pNetworkNode, onConnectionClosedCallBack) { thisObject.callerRole = callerRole + thisObject.p2pNetworkIdentity = p2pNetworkIdentity thisObject.p2pNetworkNode = p2pNetworkNode thisObject.onConnectionClosedCallBack = onConnectionClosedCallBack @@ -99,6 +102,7 @@ exports.newNetworkModulesWebSocketsNetworkClient = function newNetworkModulesWeb callerRole: thisObject.callerRole, callerProfileHandle: SA.secrets.map.get(global.env.DESKTOP_APP_SIGNING_ACCOUNT).userProfileHandle, callerTimestamp: callerTimestamp, + callerNode: JSON.stringify(thisObject.p2pNetworkIdentity.node), step: 'One' } thisObject.socketClient.send(JSON.stringify(message)) diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index feebfdbbf..93a9be097 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -1419,6 +1419,12 @@ "propertyName": "p2pNetworkPeers", "functionName": "newNetworkModulesP2PNetworkPeers", "fileName": "P2PNetworkPeers.js" + }, + { + "name": "P2P Network Client", + "propertyName": "p2pNetworkClient", + "functionName": "newNetworkModulesP2PNetworkClient", + "fileName": "P2PNetworkClient.js" } ], "utilities": [ diff --git a/Projects/Social-Trading/DK/modules/SocialGraph.js b/Projects/Social-Trading/DK/modules/SocialGraph.js index faf71cee4..7816d51e5 100644 --- a/Projects/Social-Trading/DK/modules/SocialGraph.js +++ b/Projects/Social-Trading/DK/modules/SocialGraph.js @@ -14,7 +14,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc no need to ask it to a network node. */ let thisObject = { - userProfiles: undefined, initialize: initialize, finalize: finalize } @@ -26,7 +25,6 @@ exports.newSocialTradingModulesSocialGraph = function newSocialTradingModulesSoc } async function initialize() { - thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles() - await thisObject.userProfiles.initialize() + } } \ No newline at end of file diff --git a/Projects/Social-Trading/NT/Modules/SocialGraph.js b/Projects/Social-Trading/NT/Modules/SocialGraph.js index f31c44a43..d3b611439 100644 --- a/Projects/Social-Trading/NT/Modules/SocialGraph.js +++ b/Projects/Social-Trading/NT/Modules/SocialGraph.js @@ -9,7 +9,7 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() { their posts. */ let thisObject = { - userProfiles: undefined, + /* Framework Functions */ initialize: initialize, finalize: finalize @@ -22,7 +22,6 @@ exports.newNetworkModulesSocialGraph = function newNetworkModulesSocialGraph() { } async function initialize() { - thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles() - await thisObject.userProfiles.initialize() + } } \ No newline at end of file