Adding start-node process
This commit is contained in:
parent
433c395f8b
commit
854e88dde3
9
config.json
Normal file
9
config.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"privateKey": "Replace_with_private_key",
|
||||
"port": "8080",
|
||||
|
||||
"sql_user": "user",
|
||||
"sql_pwd": "password",
|
||||
"sql_db": "supernode",
|
||||
"sql_host": "localhost"
|
||||
}
|
||||
@ -5,8 +5,8 @@ const floGlobals = {
|
||||
|
||||
//Required for blockchain API operators
|
||||
apiURL: {
|
||||
FLO: ['https://explorer.mediciland.com/', 'https://livenet.flocha.in/', 'https://flosight.duckdns.org/', 'http://livenet-explorer.floexperiments.com'],
|
||||
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
|
||||
FLO: ['https://explorer.mediciland.com/', 'https://livenet.flocha.in/', 'https://flosight.duckdns.org/', 'http://livenet-explorer.floexperiments.com'],
|
||||
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
|
||||
},
|
||||
SNStorageID: "FNaN9McoBAEFUjkRmNQRYLmBF8SpS7Tgfk",
|
||||
//sendAmt: 0.001,
|
||||
@ -14,13 +14,9 @@ const floGlobals = {
|
||||
|
||||
//Required for Supernode operations
|
||||
supernodes: {}, //each supnernode must be stored as floID : {uri:<uri>,pubKey:<publicKey>}
|
||||
defaultDisk : "General",
|
||||
appList:{},
|
||||
appSubAdmins:{},
|
||||
serveList : [],
|
||||
storedList : [],
|
||||
backupNodes : [],
|
||||
supernodeConfig : {}
|
||||
appList: {},
|
||||
appSubAdmins: {},
|
||||
sn_config: {}
|
||||
/* List of supernode configurations (all blockchain controlled by SNStorageID)
|
||||
backupDepth - (Interger) Number of backup nodes
|
||||
refreshDelay - (Interger) Count of requests for triggering read-blockchain and autodelete
|
||||
@ -28,6 +24,5 @@ const floGlobals = {
|
||||
errorFeedback - (Boolean) Send error (if any) feedback to the requestor
|
||||
delayDelta - (Interger) Maximum allowed delay from the data-time
|
||||
*/
|
||||
}
|
||||
|
||||
if('object' === typeof module) module.export = floGlobals;
|
||||
}
|
||||
('object' === typeof module) ? module.export = floGlobals : null;
|
||||
@ -412,7 +412,7 @@ function sendStoredData(lastlogs, node) {
|
||||
id: n,
|
||||
status: false
|
||||
}))
|
||||
}).catch(error => reject(error))
|
||||
}).catch(error => console.error(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -457,11 +457,17 @@ function forwardToNextNode(mode, data) {
|
||||
}));
|
||||
}
|
||||
|
||||
function dataMigration(node_change){
|
||||
console.log("data migration")
|
||||
//TODO
|
||||
}
|
||||
|
||||
//-----EXPORTS-----
|
||||
module.exports = {
|
||||
processTaskFromSupernode,
|
||||
setBlockchainParameters,
|
||||
forwardToNextNode,
|
||||
dataMigration,
|
||||
SUPERNODE_INDICATOR,
|
||||
_list,
|
||||
set DB(db){
|
||||
|
||||
@ -31,16 +31,16 @@ require('./lib/BuildKBucket')
|
||||
return KB;
|
||||
}
|
||||
|
||||
kBucket.launch = function(masterID, superNodeList) {
|
||||
kBucket.launch = function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
//let superNodeList = Object.keys(floGlobals.supernodes);
|
||||
//let masterID = floGlobals.SNStorageID;
|
||||
let superNodeList = Object.keys(floGlobals.supernodes);
|
||||
let masterID = floGlobals.SNStorageID;
|
||||
SNKB = constructKB(superNodeList, masterID);
|
||||
SNCO = superNodeList.map(sn => [distanceOf(sn), sn])
|
||||
.sort((a, b) => a[0] - b[0])
|
||||
.map(a => a[1])
|
||||
resolve('Supernode KBucket formed');
|
||||
resolve('SuperNode KBucket formed');
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
|
||||
@ -3,12 +3,14 @@ const WebSocket = require('ws')
|
||||
|
||||
module.exports = function Server(port, client, intra) {
|
||||
|
||||
var refresher; //container for refresher
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.method === "GET") {
|
||||
//GET request (requesting data)
|
||||
req.on('end', () => {
|
||||
let i = req.url.indexOf("?");
|
||||
if (i) {
|
||||
if (i !== -1) {
|
||||
var request = JSON.parse(req.url.substring(i));
|
||||
client.processRequestFromUser(request)
|
||||
.then(result => res.end(JSON.parse(result[0])))
|
||||
@ -25,6 +27,7 @@ module.exports = function Server(port, client, intra) {
|
||||
client.processIncomingData(data).then(result => {
|
||||
res.end(result[0]);
|
||||
if (result[1]) {
|
||||
refresher.countdown;
|
||||
if (result[1] === 'DATA')
|
||||
sendToLiveRequests(result[0])
|
||||
intra.forwardToNextNode(result[1], result[0])
|
||||
@ -66,4 +69,7 @@ module.exports = function Server(port, client, intra) {
|
||||
Object.defineProperty(this, "webSocket", {
|
||||
get: () => wsServer
|
||||
});
|
||||
Object.defineProperty(this, "refresher", {
|
||||
set: (r) => refresher = r
|
||||
})
|
||||
}
|
||||
195
src/start.js
Normal file
195
src/start.js
Normal file
@ -0,0 +1,195 @@
|
||||
const config = require("../config.json")
|
||||
global.floGlobals = require("./floGlobals")
|
||||
require('./lib')
|
||||
require('./lib/BuildKBucket')
|
||||
require('./floCrypto')
|
||||
require('./floBlockchainAPI')
|
||||
const Database = require("./database")
|
||||
const intra = require('./intra')
|
||||
const client = require('./client')
|
||||
const Server = require('./server')
|
||||
|
||||
var DB; //Container for Database object
|
||||
|
||||
function startNode() {
|
||||
//Set myPrivKey, myPubKey, myFloID
|
||||
global.myPrivKey = config["privateKey"]
|
||||
global.myPubKey = floCrypto.getPubKeyHex(config["privateKey"])
|
||||
global.myFloID = floCrypto.getFloID(config["privateKey"])
|
||||
//DB connect
|
||||
Database(config["sql_user"], config["sql_pwd"], config["sql_db"], config["sql_host"]).then(db => {
|
||||
DB = db;
|
||||
//Set DB to client and intra scripts
|
||||
intra.DB = DB;
|
||||
client.DB = DB;
|
||||
client._list = intra._list;
|
||||
loadBase().then(base => {
|
||||
//Set base data from DB to floGlobals
|
||||
floGlobals.supernodes = base.supernodes;
|
||||
floGlobals.sn_config = base.sn_config;
|
||||
floGlobals.appList = base.appList;
|
||||
floGlobals.appSubAdmins = base.appSubAdmins;
|
||||
refreshData.base = base;
|
||||
refreshData.invoke();
|
||||
//Start Server
|
||||
const server = new Server(config["port"], client, intra);
|
||||
server.refresher = refreshData;
|
||||
}).catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
}
|
||||
|
||||
function loadBase(DB) {
|
||||
return new Promise((resolve, reject) => {
|
||||
DB.createBase().then(result => {
|
||||
DB.getBase(DB)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
const refreshData = {
|
||||
count: null,
|
||||
base: null,
|
||||
invoke() {
|
||||
this.count = floGlobals.sn_config.refreshDelay;
|
||||
refreshBlockchainData(this.base).then(result => {
|
||||
console.log(result)
|
||||
diskCleanUp()
|
||||
.then(result => console.info(result))
|
||||
.catch(error => console.error(error))
|
||||
}).catch(error => console.error(error))
|
||||
},
|
||||
get countdown() {
|
||||
this.count--;
|
||||
if (this.count <= 0)
|
||||
this.invoke();
|
||||
}
|
||||
}
|
||||
|
||||
function refreshBlockchainData(base) {
|
||||
return new Promise((resolve, reject) => {
|
||||
readSupernodeConfigFromAPI(base).then(result => {
|
||||
console.log(result)
|
||||
kBucket.launch().then(result => {
|
||||
console.log(result)
|
||||
readAppSubAdminListFromAPI(base)
|
||||
.then(result => console.log(result))
|
||||
.catch(error => console.warn(error))
|
||||
.finally(_ => resolve("Refreshed Data from blockchain"))
|
||||
}).catch(error => reject(error))
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
function readSupernodeConfigFromAPI(base) {
|
||||
return new Promise((resolve, reject) => {
|
||||
floBlockchainAPI.readData(floGlobals.SNStorageID, {
|
||||
ignoreOld: base.lastTx[floGlobals.SNStorageID],
|
||||
sentOnly: true,
|
||||
pattern: "SuperNodeStorage"
|
||||
}).then(result => {
|
||||
let promises = [],
|
||||
node_change = {}
|
||||
result.data.reverse().forEach(data => {
|
||||
var content = JSON.parse(data).SuperNodeStorage;
|
||||
if (content.removeNodes)
|
||||
for (let sn of content.removeNodes) {
|
||||
promises.push(DB.rmSuperNode(sn));
|
||||
delete base.supernodes[sn];
|
||||
if (node_change[sn] === true)
|
||||
delete node_change[sn];
|
||||
else
|
||||
node_change[sn] = false;
|
||||
}
|
||||
if (content.newNodes)
|
||||
for (let sn in content.newNodes) {
|
||||
promises.push(DB.addSuperNode(sn, content.newNodes[sn].pubKey, content.newNodes[sn].uri));
|
||||
base.supernodes[sn] = {
|
||||
pubKey: content.newNodes[sn].pubKey,
|
||||
uri: content.newNodes[sn].uri
|
||||
};
|
||||
if (node_change[sn] === false)
|
||||
delete node_change[sn];
|
||||
else
|
||||
node_change[sn] = true;
|
||||
}
|
||||
if (content.config)
|
||||
for (let c in content.config) {
|
||||
promises.push(DB.setConfig(c, content.config[c]));
|
||||
base.sn_config[c] = content.config[c];
|
||||
}
|
||||
if (content.removeApps)
|
||||
for (let app of content.removeApps) {
|
||||
promises.push(DB.rmApp(app));
|
||||
delete base.appList;
|
||||
}
|
||||
if (content.addApps)
|
||||
for (let app in content.addApps) {
|
||||
promises.push(DB.addApp(app, content.addApps[app]));
|
||||
base.appList[app] = content.addApps[app];
|
||||
}
|
||||
});
|
||||
promises.push(DB.setLastTx(floGlobals.SNStorageID, result.totalTxs));
|
||||
//Check if all save process were successful
|
||||
Promise.allSettled(promises).then(results => {
|
||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0))
|
||||
console.warn("Some data might not have been saved in database correctly");
|
||||
else
|
||||
console.log("All data are saved in database");
|
||||
});
|
||||
//Process data migration if nodes are changed
|
||||
if (Object.keys(node_change))
|
||||
intra.dataMigration(node_change)
|
||||
resolve('Updated Supernode Configuration');
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
function readAppSubAdminListFromAPI(base) {
|
||||
var promises = [];
|
||||
//Load for each apps
|
||||
for (let app in base.appList) {
|
||||
promises.push(new Promise((resolve, reject) => {
|
||||
floBlockchainAPI.readData(base.appList[app], {
|
||||
ignoreOld: base.lastTx[`${app}_${base.appList[app]}`],
|
||||
sentOnly: true,
|
||||
pattern: app
|
||||
}).then(result => {
|
||||
let subAdmins = new Set(base.appSubAdmins[app]);
|
||||
result.data.reverse().forEach(data => {
|
||||
let content = JSON.parse(result.data[i])[app];
|
||||
if (Array.isArray(content.removeSubAdmin))
|
||||
content.removeSubAdmin.forEach(sa => subAdmins.delete(sa));
|
||||
if (Array.isArray(content.addSubAdmin))
|
||||
content.addSubAdmin.forEach(sa => subAdmins.add(sa));
|
||||
});
|
||||
base.appSubAdmins[app] = Array.from(subAdmins);
|
||||
Promise.allSettled([
|
||||
DB.setLastTx(`${app}_${base.appList[app]}`, result.totalTxs),
|
||||
DB.setSubAdmin(app, base.appSubAdmins[app])
|
||||
]).then(results => {
|
||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0))
|
||||
console.warn(`SubAdmin list for app(${app}) might not have been saved in database`);
|
||||
});
|
||||
resolve("Loaded subAdmin List for APP:" + app);
|
||||
}).catch(error => reject([app, error]))
|
||||
}));
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.allSettled(results => {
|
||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0)) {
|
||||
let error = Object.fromEntries(results.filter(r => r.status === "rejected").map(r => r.reason));
|
||||
console.error(JSON.stringify(error));
|
||||
reject(`subAdmin List for APPS(${Object.keys(error)} might not have loaded correctly`);
|
||||
} else
|
||||
resolve("Loaded subAdmin List for all APPs successfully");
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
function diskCleanUp(){
|
||||
//TODO: Clear all unauthorised data from before deleteDelay
|
||||
}
|
||||
|
||||
module.exports = startNode;
|
||||
Loading…
Reference in New Issue
Block a user