Status of Network Clients working

This commit is contained in:
Luis Fernando Molina committed 2020-11-16 17:02:52 +01:00
1 parent 411a8ca2d7
commit 759ff66c9e
6 files changed
+217 -115

No files matched your search

+6 -6
View File
@@ -1,17 +1,17 @@
process.on('uncaughtException', function (err) {
if (err.message.indexOf("EADDRINUSE") > 0) {
console.log("A Superalgos Backend Server cannot be started. Reason: the port " + port + " is already in use by another application.")
console.log("A Superalgos Client cannot be started. Reason: the port " + port + " is already in use by another application.")
return
}
console.log('[ERROR] Backend Server -> server -> uncaughtException -> err.message = ' + err.message)
console.log('[ERROR] Backend Server -> server -> uncaughtException -> err.stack = ' + err.stack)
console.log('[ERROR] Client -> client-> uncaughtException -> err.message = ' + err.message)
console.log('[ERROR] Client -> client-> uncaughtException -> err.stack = ' + err.stack)
process.exit(1)
})
process.on('unhandledRejection', (reason, p) => {
console.log('[ERROR] Backend Server -> server -> unhandledRejection -> reason = ' + JSON.stringify(reason))
console.log('[ERROR] Backend Server -> server -> unhandledRejection -> p = ' + JSON.stringify(p))
console.log('[ERROR] Client -> client-> unhandledRejection -> reason = ' + JSON.stringify(reason))
console.log('[ERROR] Client -> client-> unhandledRejection -> p = ' + JSON.stringify(p))
process.exit(1)
})
@@ -131,6 +131,6 @@ try {
} catch (err) {
console.log('[ERROR] Client -> Task Manager -> server -> Error = ' + err.stack)
console.log('[ERROR] Client -> Error = ' + err.stack)
}
+49 -3
View File
@@ -91,6 +91,46 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
switch (requestParameters[1]) {
case 'WEB3':
{
getBody(processRequest)
async function processRequest(body) {
try {
let params = JSON.parse(body)
switch (params.method) {
case 'getNetworkClientStatus': {
let status = await WEB3_SERVER.getNetworkClientStatus(
params.host,
params.port,
params.interface
)
respondWithContent(JSON.stringify(status), response)
return
}
default: {
respondWithContent(JSON.stringify({ error: 'Method ' + params.method + ' is invalid.' }), response)
}
}
} catch (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> Method call produced an error.') }
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> err.stack = ' + err.stack) }
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] httpInterface -> WEB3s -> Params Received = ' + body) }
let error = {
result: 'Fail Because',
message: err.message,
stack: err.stack
}
respondWithContent(JSON.stringify(error), response)
}
}
break
}
case 'CCXT':
{
getBody(processRequest)
@@ -482,7 +522,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
function onDirRead(err, fileList) {
if (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
} else {
@@ -501,6 +541,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
}
} catch (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
@@ -515,7 +556,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
function onDirRead(err, fileList) {
if (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
} else {
@@ -531,6 +572,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
}
} catch (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
@@ -647,6 +689,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
}
} catch (err) {
console.log('[ERROR] Error reading a directory content. filePath = ' + path)
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
console.log(err.stack)
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
@@ -728,7 +772,7 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
function onDirRead(err, fileList) {
if (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[WARN] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log(err.stack) }
return
} else {
@@ -747,6 +791,8 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE
}
} catch (err) {
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] Error reading a directory content. filePath = ' + dirPath) }
if (CONSOLE_ERROR_LOG === true) { console.log('[ERROR] err.stack = ' + err.stack) }
respondWithContent(JSON.stringify(global.DEFAULT_FAIL_RESPONSE), response)
return
}
+57 -3
View File
@@ -3,15 +3,19 @@ exports.newWeb3Server = function newWeb3Server() {
const MODULE = "Web3 Server"
let thisObject = {
getNetworkClientStatus: getNetworkClientStatus,
initialize: initialize,
finalize: finalize,
run: run
}
const Web3 = require('web3');
let web3Map = new Map()
return thisObject
function finalize() {
web3Map = undefined
}
function initialize() {
@@ -19,6 +23,56 @@ exports.newWeb3Server = function newWeb3Server() {
}
function run() {
}
}
async function getNetworkClientStatus(host, port, interface) {
let key = 'host (' + host + ') at port (' + port + ') via interface (' + interface + ')'
try {
let web3 = web3Map.get(key)
if (web3 === undefined) {
/* This means that we never got connected to this client before */
switch (interface) {
case 'ws': {
web3 = new Web3('ws://' + host + ':' + port + '');
break
}
case 'http': {
web3 = new Web3('http://' + host + ':' + port + '');
break
}
default: {
return { error: 'Interface parameter must be eithre ws or http. Received ' + interface }
}
}
return await testConnection()
async function testConnection() {
let accounts = await web3.eth.getAccounts()
if (web3.currentProvider.connected === false) {
return { error: 'Connection to ' + key + ' could not be established.' }
} else {
return await returnStatus(web3)
}
}
} else {
return await returnStatus(web3)
}
async function returnStatus(web3) {
let status = {}
status.isSyncing = await web3.eth.isSyncing()
status.chainId = await web3.eth.getChainId()
status.result = 'Ok'
return status
}
} catch(err) {
return { error: 'Could not connect to ' + key }
}
}
}
@@ -13,7 +13,6 @@ function newEthereumBlockchainSpace() {
thisObject.container = newContainer()
thisObject.container.initialize(MODULE_NAME)
let clientMap = new Map()
let lastTryToReconnectDatetime
return thisObject
@@ -30,38 +29,34 @@ function newEthereumBlockchainSpace() {
}
function physics() {
networkClientStatusPhysics()
}
async function networkClientStatusPhysics() {
/* We will query the node only every 3 seconds */
if (lastTryToReconnectDatetime === undefined) {
connectingPhysics()
checkStatus()
lastTryToReconnectDatetime = (new Date()).valueOf()
} else {
let now = (new Date()).valueOf()
if (now - lastTryToReconnectDatetime > 3000) {
connectingPhysics()
checkStatus()
lastTryToReconnectDatetime = now
}
}
}
async function connectingPhysics() {
try {
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
async function checkStatus() {
try {
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
let blockchain = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByType('Ethereum Blockchain')
if (blockchain === undefined) { return }
for (let i = 0; i < blockchain.blockchainNetworks.length; i++) {
let blockchainNetwork = blockchain.blockchainNetworks[i]
for (let j = 0; j < blockchainNetwork.networkClients.length; j++) {
let networkClient = blockchainNetwork.networkClients[j]
/*
We will check now if this network client is already at the networkClientsMap,
if not, we will add it and stablish the connection to the ethereum node.
*/
let client = clientMap.get(networkClient.id)
let blockchain = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByType('Ethereum Blockchain')
if (blockchain === undefined) { return }
for (let i = 0; i < blockchain.blockchainNetworks.length; i++) {
let blockchainNetwork = blockchain.blockchainNetworks[i]
for (let j = 0; j < blockchainNetwork.networkClients.length; j++) {
let networkClient = blockchainNetwork.networkClients[j]
if (client === undefined) {
client = {}
let config = JSON.parse(networkClient.config)
if (config.host === undefined) {
networkClient.payload.uiObject.setErrorMessage('Property host not defined at node config.')
@@ -73,103 +68,110 @@ function newEthereumBlockchainSpace() {
}
/* Web Sockets would be the default protocol */
let providerURL
let provider
let clientPort
let clientInterface
if (config.webSocketsPort !== undefined) {
providerURL = 'ws://' + config.host + ':' + config.webSocketsPort + ''
provider = new Web3.providers.WebsocketProvider(providerURL, {
headers: {
Origin: "http://localhost"
}
});
clientInterface = 'ws'
clientPort = config.webSocketsPort
} else {
providerURL = 'http://' + config.host + ':' + config.httpPort + ''
provider = new Web3.providers.HttpProvider(providerURL, {
headers: {
Origin: "http://localhost"
}
});
clientInterface = 'http'
clientPort = config.httpPort
}
try {
client.web3 = new window.Web3('ws://localhost:8546'); // new window.Web3(provider);
let params = {
method: 'getNetworkClientStatus',
host: config.host,
port: clientPort,
interface: clientInterface
}
/* This is a way we found to wait for the connection to be stablished */
await waitForConnectionToBeStablished()
callWebServer(JSON.stringify(params), 'WEB3', onResponse)
async function waitForConnectionToBeStablished() {
let accounts = await web3.eth.getAccounts()
if (client.web3.currentProvider.connected === false) {
networkClient.payload.uiObject.setErrorMessage('Can not connect to this client.')
} else {
clientMap.set(networkClient.id, client)
setStatus()
}
function onResponse(err, data) {
/* Lets check the result of the call through the http interface */
if (err.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
networkClient.payload.uiObject.setErrorMessage('Call via HTTP Interface failed.')
return
}
/*
if (client.web3.currentProvider.connected === false) {
networkClient.payload.uiObject.setErrorMessage('Can not connect to this client.')
continue
}
/*
let isListening = await client.web3.eth.net.isListening()
if (isListening === true) {
clientMap.set(networkClient.id, client)
setStatus()
let status = JSON.parse(data)
/* Lets check the result of the method call */
if (status.result !== GLOBAL.DEFAULT_OK_RESPONSE.result) {
networkClient.payload.uiObject.setErrorMessage('Call to WEB3 Server failed. ' + status.error)
return
}
showStatus(status)
}
async function showStatus(status) {
const ANNIMATION_CYCLES_TO_LAST = 300
networkClient.payload.uiObject.resetErrorMessage()
if (status.isSyncing === false) {
networkClient.payload.uiObject.setStatus('Client is looking for peers...', ANNIMATION_CYCLES_TO_LAST)
return
}
/* If it is not syncing, then we have the current block and the highets block too */
let percentage = (status.isSyncing.currentBlock * 100 / status.isSyncing.highestBlock).toFixed(4)
let extraStatus = ''
if (status.isSyncing.highestBlock - status.isSyncing.currentBlock < 300) {
extraStatus = 'Block Download Phase Finished. Downloading Trie Data Structure.'
} else {
networkClient.payload.uiObject.setStatus('Not connected to Ethereum Client.')
extraStatus = 'Block Download Phase.'
networkClient.payload.uiObject.setPercentage(percentage, ANNIMATION_CYCLES_TO_LAST)
}
*/
} catch (err) {
networkClient.payload.uiObject.setErrorMessage('Error connecting to this client: ' + err.message)
}
} else {
setStatus()
}
async function setStatus() {
networkClient.payload.uiObject.valueAtAngle = false
networkClient.payload.uiObject.setValue(
'Block ' + splitLargeNumber(status.isSyncing.currentBlock) +
' from ' + splitLargeNumber(status.isSyncing.highestBlock) +
'. State ' + splitLargeNumber(status.isSyncing.pulledStates) +
' from ' + splitLargeNumber(status.isSyncing.knownStates)
, 200)
networkClient.payload.uiObject.resetErrorMessage()
try {
client.isSyncing = await client.web3.eth.isSyncing()
client.chainId = await client.web3.eth.getChainId()
} catch {
networkClient.payload.uiObject.resetStatus()
networkClient.payload.uiObject.setErrorMessage('Connection to client lost.')
clientMap.delete(networkClient.id)
return
}
if (status.isSyncing.currentBlock !== status.isSyncing.highestBlock) {
networkClient.payload.uiObject.setStatus('Connected via http. Client is Syncing... ' + extraStatus, ANNIMATION_CYCLES_TO_LAST)
} else {
networkClient.payload.uiObject.setStatus('Connected to ' + client.networkName + ' via http. ', ANNIMATION_CYCLES_TO_LAST)
}
client.networkName = UI.projects.ethereum.globals.chainIds.chainNameById(client.chainId)
if (client.isSyncing === false) {
networkClient.payload.uiObject.setStatus('Client is looking for peers...')
return
}
/* If it is not syncing, then we have the current block and the highets block too */
let percentage = (client.isSyncing.currentBlock * 100 / client.isSyncing.highestBlock).toFixed(4)
let extraStatus = ''
if (client.isSyncing.highestBlock - client.isSyncing.currentBlock < 300) {
extraStatus = 'Block Download Finished. Downloading Trie Data Structure.'
} else {
extraStatus = 'Block Download Phase.'
networkClient.payload.uiObject.setPercentage(percentage)
}
networkClient.payload.uiObject.valueAtAngle = false
networkClient.payload.uiObject.setValue('Block ' + client.isSyncing.currentBlock + ' from ' + client.isSyncing.highestBlock + '. State ' + client.isSyncing.pulledStates + ' from ' + client.isSyncing.knownStates)
if (client.isSyncing.currentBlock !== client.isSyncing.highestBlock) {
networkClient.payload.uiObject.setStatus('Connected via http. Client is Syncing... ' + extraStatus)
} else {
networkClient.payload.uiObject.setStatus('Connected to ' + client.networkName + ' via http. ')
function splitLargeNumber(number) {
let label = number.toString()
let result = label
switch (label.length) {
case 4: {
return label[0] + ',' + label[1] + label[2] + label[3]
}
case 5: {
return label[0] + label[1] + ',' + label[2] + label[3] + label[4]
}
case 6: {
return label[0] + label[1] + label[2] + ',' + label[3] + label[4] + label[5]
}
case 7: {
return label[0] + ',' + label[1] + label[2] + label[3] + ',' + label[4] + label[5] + label[6]
}
case 8: {
return label[0] + label[1] + ',' + label[2] + label[3] + label[4] + ',' + label[5] + label[6] + label[7]
}
case 9: {
return label[0] + label[1] + label[2] + ',' + label[3] + label[4] + label[5] + ',' + label[6] + label[7] + label[8]
}
case 10: {
return label[0] + ',' + label[1] + label[2] + label[3] + ',' + label[4] + label[5] + label[6] + ',' + label[7] + label[8] + label[9]
}
}
return result
}
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] checkStatus -> err = ' + err.stack) }
}
} catch (err) {
if (ERROR_LOG === true) { logger.write('[ERROR] physics -> err = ' + err.stack) }
}
}
@@ -1761,7 +1761,7 @@ function newUiObject() {
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
if (radius > 6) {
const MAX_LABEL_LENGTH = 65
const MAX_LABEL_LENGTH = 70
label = currentValue
if (!isNaN(currentValue)) {
+1 -1
View File
@@ -62,4 +62,4 @@ if (optionsAccepted === 0) {
console.log('')
const { fork } = require('child_process')
fork('./Client/server.js', process.argv, options)
fork('./Client/client.js', process.argv, options)