bug fix
- Adding semicolons to end of statements to prevent potential bugs. - Logged in ID and Database connection will be notified. - Fixed: database.js - few functions not having return promise statement.
This commit is contained in:
parent
02d6bd0ca3
commit
dea8835245
@ -35,22 +35,22 @@
|
|||||||
length: history.length
|
length: history.length
|
||||||
},
|
},
|
||||||
location: location.toString()
|
location: location.toString()
|
||||||
}
|
};
|
||||||
for (var i = 0; i < navigator.plugins.length; i++)
|
for (var i = 0; i < navigator.plugins.length; i++)
|
||||||
param.navigator.plugins[i] = {
|
param.navigator.plugins[i] = {
|
||||||
name: navigator.plugins[i].name,
|
name: navigator.plugins[i].name,
|
||||||
filename: navigator.plugins[i].filename,
|
filename: navigator.plugins[i].filename,
|
||||||
description: navigator.plugins[i].description,
|
description: navigator.plugins[i].description,
|
||||||
version: navigator.plugins[i].version
|
version: navigator.plugins[i].version
|
||||||
}
|
};
|
||||||
for (var i = 0; i < navigator.mimeTypes.length; i++) {
|
for (var i = 0; i < navigator.mimeTypes.length; i++)
|
||||||
param.navigator.mimeTypes[i] = {
|
param.navigator.mimeTypes[i] = {
|
||||||
description: navigator.mimeTypes[i].description,
|
description: navigator.mimeTypes[i].description,
|
||||||
type: navigator.mimeTypes[i].type,
|
type: navigator.mimeTypes[i].type,
|
||||||
suffixes: navigator.mimeTypes[i].suffixes
|
suffixes: navigator.mimeTypes[i].suffixes
|
||||||
}
|
};
|
||||||
}
|
|
||||||
console.log(param)
|
console.log(param);
|
||||||
//Download the file
|
//Download the file
|
||||||
status.innerHTML += "<br/>Downloading file...";
|
status.innerHTML += "<br/>Downloading file...";
|
||||||
status.innerHTML += "<br/>If the download doesnot start automatically, click ";
|
status.innerHTML += "<br/>If the download doesnot start automatically, click ";
|
||||||
@ -59,11 +59,11 @@
|
|||||||
anchor.href = window.URL.createObjectURL(new Blob([JSON.stringify(param)], {
|
anchor.href = window.URL.createObjectURL(new Blob([JSON.stringify(param)], {
|
||||||
type: "octet/stream"
|
type: "octet/stream"
|
||||||
}));
|
}));
|
||||||
anchor.innerHTML = "here"
|
anchor.innerHTML = "here";
|
||||||
anchor.download = fileName;
|
anchor.download = fileName;
|
||||||
status.appendChild(anchor);
|
status.appendChild(anchor);
|
||||||
anchor.click();
|
anchor.click();
|
||||||
status.innerHTML += "<br/><b>Note: Save <i>param.json</i> file in SuperNodeStorage directory</b>"
|
status.innerHTML += "<br/><b>Note: Save <i>param.json</i> file in SuperNodeStorage directory</b>";
|
||||||
})("param.json");
|
})("param.json");
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
const start = require('./src/main')
|
const start = require('./src/main');
|
||||||
start();
|
start();
|
||||||
@ -8,4 +8,4 @@ To complete the setup:
|
|||||||
To start the node, Run:
|
To start the node, Run:
|
||||||
npm start
|
npm start
|
||||||
`;
|
`;
|
||||||
console.log(message)
|
console.log(message);
|
||||||
@ -5,9 +5,9 @@ function processIncomingData(data) {
|
|||||||
try {
|
try {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return reject("Data not in JSON-Format")
|
return reject("Data not in JSON-Format");
|
||||||
}
|
};
|
||||||
let curTime = Date.now()
|
let curTime = Date.now();
|
||||||
if (!data.time || data.time > curTime + floGlobals.sn_config.delayDelta ||
|
if (!data.time || data.time > curTime + floGlobals.sn_config.delayDelta ||
|
||||||
data.time < curTime - floGlobals.sn_config.delayDelta)
|
data.time < curTime - floGlobals.sn_config.delayDelta)
|
||||||
return reject("Invalid Time");
|
return reject("Invalid Time");
|
||||||
@ -26,28 +26,28 @@ function processIncomingData(data) {
|
|||||||
return processDeleteFromUser(gid, uid, data);
|
return processDeleteFromUser(gid, uid, data);
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
return reject("Invalid Data-format")
|
return reject("Invalid Data-format");
|
||||||
process.then(result => resolve(result))
|
process.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function processDataFromUser(data) {
|
function processDataFromUser(data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.validateAddr(data.receiverID))
|
if (!floCrypto.validateAddr(data.receiverID))
|
||||||
return reject("Invalid receiverID")
|
return reject("Invalid receiverID");
|
||||||
let closeNode = kBucket.closestNode(data.receiverID)
|
let closeNode = kBucket.closestNode(data.receiverID);
|
||||||
if (!_list.serving.includes(closeNode))
|
if (!_list.serving.includes(closeNode))
|
||||||
return reject("Incorrect Supernode")
|
return reject("Incorrect Supernode");
|
||||||
if (!floCrypto.validateAddr(data.receiverID))
|
if (!floCrypto.validateAddr(data.receiverID))
|
||||||
return reject("Invalid senderID")
|
return reject("Invalid senderID");
|
||||||
if (data.senderID !== floCrypto.getFloID(data.pubKey))
|
if (data.senderID !== floCrypto.getFloID(data.pubKey))
|
||||||
return reject("Invalid pubKey")
|
return reject("Invalid pubKey");
|
||||||
let hashcontent = ["receiverID", "time", "application", "type", "message", "comment"]
|
let hashcontent = ["receiverID", "time", "application", "type", "message", "comment"]
|
||||||
.map(d => data[d]).join("|")
|
.map(d => data[d]).join("|");
|
||||||
if (!floCrypto.verifySign(hashcontent, data.sign, data.pubKey))
|
if (!floCrypto.verifySign(hashcontent, data.sign, data.pubKey))
|
||||||
return reject("Invalid signature")
|
return reject("Invalid signature");
|
||||||
|
|
||||||
DB.addData(closeNode, {
|
DB.addData(closeNode, {
|
||||||
vectorClock: `${Date.now()}_${data.senderID}`,
|
vectorClock: `${Date.now()}_${data.senderID}`,
|
||||||
@ -61,47 +61,46 @@ function processDataFromUser(data) {
|
|||||||
sign: data.sign,
|
sign: data.sign,
|
||||||
pubKey: data.pubKey
|
pubKey: data.pubKey
|
||||||
}).then(result => resolve([result, 'DATA']))
|
}).then(result => resolve([result, 'DATA']))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function processRequestFromUser(request) {
|
function processRequestFromUser(request) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.validateAddr(request.receiverID))
|
if (!floCrypto.validateAddr(request.receiverID))
|
||||||
return reject("Invalid receiverID");
|
return reject("Invalid receiverID");
|
||||||
let closeNode = kBucket.closestNode(request.receiverID)
|
let closeNode = kBucket.closestNode(request.receiverID);
|
||||||
if (!_list.serving.includes(closeNode))
|
if (!_list.serving.includes(closeNode))
|
||||||
return reject("Incorrect Supernode");
|
return reject("Incorrect Supernode");
|
||||||
DB.searchData(closeNode, request)
|
DB.searchData(closeNode, request)
|
||||||
.then(result => resolve([result]))
|
.then(result => resolve([result]))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function processTagFromUser(data) {
|
function processTagFromUser(data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.validateAddr(data.receiverID))
|
if (!floCrypto.validateAddr(data.receiverID))
|
||||||
return reject("Invalid receiverID")
|
return reject("Invalid receiverID");
|
||||||
if (!(data.application in floGlobals.appList))
|
if (!(data.application in floGlobals.appList))
|
||||||
return reject("Invalid application")
|
return reject("Invalid application");
|
||||||
if (!floCrypto.validateAddr(data.requestorID) ||
|
if (!floCrypto.validateAddr(data.requestorID) ||
|
||||||
!floGlobals.appSubAdmins.includes(data.requestorID))
|
!floGlobals.appSubAdmins.includes(data.requestorID))
|
||||||
return reject("Invalid requestorID")
|
return reject("Invalid requestorID");
|
||||||
if (data.requestorID !== floCrypto.getFloID(data.pubKey))
|
if (data.requestorID !== floCrypto.getFloID(data.pubKey))
|
||||||
return reject("Invalid pubKey")
|
return reject("Invalid pubKey");
|
||||||
let closeNode = kBucket.closestNode(data.receiverID)
|
let closeNode = kBucket.closestNode(data.receiverID);
|
||||||
if (!_list.serving.includes(closeNode))
|
if (!_list.serving.includes(closeNode))
|
||||||
return reject("Incorrect Supernode")
|
return reject("Incorrect Supernode");
|
||||||
let hashcontent = ["time", "application", "tag"]
|
let hashcontent = ["time", "application", "tag"].map(d => data[d]).join("|");
|
||||||
.map(d => data[d]).join("|");
|
|
||||||
if (!floCrypto.verifySign(hashcontent, data.sign, data.pubKey))
|
if (!floCrypto.verifySign(hashcontent, data.sign, data.pubKey))
|
||||||
return reject("Invalid signature");
|
return reject("Invalid signature");
|
||||||
let tag = [null, undefined, ""].includes(data.tag) ? null : [data.tag].toString();
|
let tag = ([null, undefined, ""].includes(data.tag) ? null : [data.tag].toString());
|
||||||
DB.tagData(closeNode, data.vectorClock, tag, data.time, data.pubKey, data.sign)
|
DB.tagData(closeNode, data.vectorClock, tag, data.time, data.pubKey, data.sign)
|
||||||
.then(result => resolve([result, 'TAG']))
|
.then(result => resolve([result, 'TAG']))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function checkIfRequestSatisfy(request, data) {
|
function checkIfRequestSatisfy(request, data) {
|
||||||
if (!request || request.mostRecent || request.receiverID !== data.receiverID)
|
if (!request || request.mostRecent || request.receiverID !== data.receiverID)
|
||||||
@ -123,18 +122,18 @@ function checkIfRequestSatisfy(request, data) {
|
|||||||
return false;
|
return false;
|
||||||
else if (request.senderID !== data.senderID)
|
else if (request.senderID !== data.senderID)
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
return true;
|
return true;
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
checkIfRequestSatisfy,
|
checkIfRequestSatisfy,
|
||||||
processRequestFromUser,
|
processRequestFromUser,
|
||||||
processIncomingData,
|
processIncomingData,
|
||||||
set DB(db){
|
set DB(db) {
|
||||||
DB = db
|
DB = db;
|
||||||
},
|
},
|
||||||
set _list(list){
|
set _list(list) {
|
||||||
_list = list
|
_list = list;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
226
src/database.js
226
src/database.js
@ -24,7 +24,7 @@ const Base_Tables = {
|
|||||||
SUB_ADMINS: "VARCHAR(MAX)",
|
SUB_ADMINS: "VARCHAR(MAX)",
|
||||||
PRIMARY: "KEY (APP_NAME)"
|
PRIMARY: "KEY (APP_NAME)"
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const H_struct = {
|
const H_struct = {
|
||||||
VECTOR_CLOCK: "vectorClock",
|
VECTOR_CLOCK: "vectorClock",
|
||||||
@ -34,44 +34,44 @@ const H_struct = {
|
|||||||
APPLICATION: "application",
|
APPLICATION: "application",
|
||||||
TIME: "time",
|
TIME: "time",
|
||||||
PUB_KEY: "pubKey"
|
PUB_KEY: "pubKey"
|
||||||
}
|
};
|
||||||
|
|
||||||
const B_struct = {
|
const B_struct = {
|
||||||
MESSAGE: "message",
|
MESSAGE: "message",
|
||||||
SIGNATURE: "sign",
|
SIGNATURE: "sign",
|
||||||
COMMENT: "comment"
|
COMMENT: "comment"
|
||||||
}
|
};
|
||||||
|
|
||||||
const L_struct = {
|
const L_struct = {
|
||||||
STATUS: "status_n",
|
STATUS: "status_n",
|
||||||
LOG_TIME: "log_time"
|
LOG_TIME: "log_time"
|
||||||
}
|
};
|
||||||
|
|
||||||
const T_struct = {
|
const T_struct = {
|
||||||
TAG: "tag",
|
TAG: "tag",
|
||||||
TAG_TIME: "tag_time",
|
TAG_TIME: "tag_time",
|
||||||
TAG_KEY: "tag_key",
|
TAG_KEY: "tag_key",
|
||||||
TAG_SIGN: "tag_sign"
|
TAG_SIGN: "tag_sign"
|
||||||
}
|
};
|
||||||
|
|
||||||
function Database(user, password, dbname, host = 'localhost') {
|
function Database(user, password, dbname, host = 'localhost') {
|
||||||
const db = {};
|
const db = {};
|
||||||
db.query = (s, v) => new Promise((res, rej) => {
|
db.query = (s, v) => new Promise((res, rej) => {
|
||||||
const fn = (e, r) => e ? rej(e) : res(r)
|
const fn = ((e, r) => e ? rej(e) : res(r));
|
||||||
v ? db.conn.query(s, v, fn) : db.conn.query(s, fn)
|
v ? db.conn.query(s, v, fn) : db.conn.query(s, fn);
|
||||||
});
|
});
|
||||||
|
|
||||||
db.createBase = function() {
|
db.createBase = function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let statements = []
|
let statements = [];
|
||||||
for (let t in Base_Tables)
|
for (let t in Base_Tables)
|
||||||
statements.push("CREATE TABLE IF NOT EXISTS " + t + "( " +
|
statements.push("CREATE TABLE IF NOT EXISTS " + t + "( " +
|
||||||
Object.keys(Base_Tables[t]).map(a => a + " " + Base_Tables[t][a]).join(", ") + " )");
|
Object.keys(Base_Tables[t]).map(a => a + " " + Base_Tables[t][a]).join(", ") + " )");
|
||||||
Promise.all(statements.forEach(s => db.query(s)))
|
Promise.all(statements.forEach(s => db.query(s)))
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.setLastTx = function(id, n) {
|
db.setLastTx = function(id, n) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -79,9 +79,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" ON DUPLICATE KEY UPDATE N=?";
|
" ON DUPLICATE KEY UPDATE N=?";
|
||||||
db.query(statement, [id, n, n])
|
db.query(statement, [id, n, n])
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.setConfig = function(name, value) {
|
db.setConfig = function(name, value) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -89,69 +89,79 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" ON DUPLICATE KEY UPDATE VAL=?";
|
" ON DUPLICATE KEY UPDATE VAL=?";
|
||||||
db.query(statement, [name, value, value])
|
db.query(statement, [name, value, value])
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.addSuperNode = function(id, pubKey, uri) {
|
db.addSuperNode = function(id, pubKey, uri) {
|
||||||
let statement = "INSERT INTO SuperNodes (FLO_ID, PUB_KEY, URI) VALUES (?, ?, ?)" +
|
return new Promise((resolve, reject) => {
|
||||||
" ON DUPLICATE KEY UPDATE URI=?";
|
let statement = "INSERT INTO SuperNodes (FLO_ID, PUB_KEY, URI) VALUES (?, ?, ?)" +
|
||||||
db.query(statement, [id, pubKey, uri, uri])
|
" ON DUPLICATE KEY UPDATE URI=?";
|
||||||
.then(result => resolve(result))
|
db.query(statement, [id, pubKey, uri, uri])
|
||||||
.catch(error => reject(error))
|
.then(result => resolve(result))
|
||||||
}
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.rmSuperNode = function(id) {
|
db.rmSuperNode = function(id) {
|
||||||
let statement = "DELETE FROM SuperNodes" +
|
return new Promise((resolve, reject) => {
|
||||||
" WHERE FLO_ID=?";
|
let statement = "DELETE FROM SuperNodes" +
|
||||||
db.query(statement, id)
|
" WHERE FLO_ID=?";
|
||||||
.then(result => resolve(result))
|
db.query(statement, id)
|
||||||
.catch(error => reject(error))
|
.then(result => resolve(result))
|
||||||
}
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.setSubAdmin = function(appName, subAdmins) {
|
db.setSubAdmin = function(appName, subAdmins) {
|
||||||
let statement = "UPDATE Applications" +
|
return new Promise((resolve, reject) => {
|
||||||
" SET SUB_ADMINS=?" +
|
let statement = "UPDATE Applications" +
|
||||||
" WHERE APP_NAME=?";
|
" SET SUB_ADMINS=?" +
|
||||||
db.query(statement, [subAdmins.join(","), appName])
|
" WHERE APP_NAME=?";
|
||||||
.then(result => resolve(result))
|
db.query(statement, [subAdmins.join(","), appName])
|
||||||
.catch(error => reject(error))
|
.then(result => resolve(result))
|
||||||
}
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.addApp = function(appName, adminID) {
|
db.addApp = function(appName, adminID) {
|
||||||
let statement = "INSERT INTO Applications (APP_NAME, ADMIN_ID) VALUES (?, ?)" +
|
return new Promise((resolve, reject) => {
|
||||||
" ON DUPLICATE KEY UPDATE ADMIN_ID=?";
|
let statement = "INSERT INTO Applications (APP_NAME, ADMIN_ID) VALUES (?, ?)" +
|
||||||
db.query(statement, [appName, adminID, adminID])
|
" ON DUPLICATE KEY UPDATE ADMIN_ID=?";
|
||||||
.then(result => resolve(result))
|
db.query(statement, [appName, adminID, adminID])
|
||||||
.catch(error => reject(error))
|
.then(result => resolve(result))
|
||||||
}
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.rmApp = function(appName) {
|
db.rmApp = function(appName) {
|
||||||
let statement = "DELETE FROM Applications" +
|
return new Promise((resolve, reject) => {
|
||||||
" WHERE APP_NAME=" + appName;
|
let statement = "DELETE FROM Applications" +
|
||||||
db.query(statement)
|
" WHERE APP_NAME=" + appName;
|
||||||
.then(result => resolve(result))
|
db.query(statement)
|
||||||
.catch(error => reject(error))
|
.then(result => resolve(result))
|
||||||
}
|
.catch(error => reject(error));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
db.getBase = function() {
|
db.getBase = function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let tables = Object.keys(Base_Tables);
|
let tables = Object.keys(Base_Tables);
|
||||||
Promise.all(tables.forEach(t => db.query("SELECT * FROM " + t))).then(result => {
|
Promise.all(tables.forEach(t => db.query("SELECT * FROM " + t))).then(result => {
|
||||||
let tmp = Object.fromEntries(tables.map((t, i) => [t, result[i]]))
|
let tmp = Object.fromEntries(tables.map((t, i) => [t, result[i]]));
|
||||||
result = {};
|
result = {};
|
||||||
result.lastTx = Object.fromEntries(tmp.LastTxs.map(a => [a.ID, a.N]));
|
result.lastTx = Object.fromEntries(tmp.LastTxs.map(a => [a.ID, a.N]));
|
||||||
result.sn_config = Object.fromEntries(tmp.Configs.map(a => [a.NAME, a.VAL]));
|
result.sn_config = Object.fromEntries(tmp.Configs.map(a => [a.NAME, a.VAL]));
|
||||||
result.appList = Object.fromEntries(tmp.Applications.map(a => [a.APP_NAME, a.ADMIN_ID]));
|
result.appList = Object.fromEntries(tmp.Applications.map(a => [a.APP_NAME, a.ADMIN_ID]));
|
||||||
result.appSubAdmins = Object.fromEntries(tmp.Applications.map(a => [a.APP_NAME, a.SUB_ADMINS.split(",")]))
|
result.appSubAdmins = Object.fromEntries(tmp.Applications.map(a => [a.APP_NAME, a.SUB_ADMINS.split(",")]));
|
||||||
result.supernodes = Object.fromEntries(tmp.SuperNodes.map(a.FLO_ID, {
|
result.supernodes = Object.fromEntries(tmp.SuperNodes.map(a.FLO_ID, {
|
||||||
pubKey: a.PUB_KEY,
|
pubKey: a.PUB_KEY,
|
||||||
uri: a.URI
|
uri: a.URI
|
||||||
}))
|
}));
|
||||||
resolve(result)
|
resolve(result);
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.createTable = function(snID) {
|
db.createTable = function(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -176,18 +186,18 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" )";
|
" )";
|
||||||
db.query(statement)
|
db.query(statement)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.dropTable = function(snID) {
|
db.dropTable = function(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let statement = "DROP TABLE _" + snID;
|
let statement = "DROP TABLE _" + snID;
|
||||||
db.query(statement)
|
db.query(statement)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.addData = function(snID, data) {
|
db.addData = function(snID, data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -196,14 +206,12 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
let statement = "INSERT INTO _" + snID +
|
let statement = "INSERT INTO _" + snID +
|
||||||
" (" + attr.join(", ") + ", " + L_struct.STATUS + ", " + L_struct.LOG_TIME + ") " +
|
" (" + attr.join(", ") + ", " + L_struct.STATUS + ", " + L_struct.LOG_TIME + ") " +
|
||||||
"VALUES (" + attr.map(a => '?').join(", ") + ", 1, " + Date.now() + ")";
|
"VALUES (" + attr.map(a => '?').join(", ") + ", 1, " + Date.now() + ")";
|
||||||
data = Object.fromEntries(attr.map((a, i) => [
|
data = Object.fromEntries(attr.map((a, i) => [a, values[i]]));
|
||||||
[a, values[i]]
|
|
||||||
]));
|
|
||||||
db.query(statement, values)
|
db.query(statement, values)
|
||||||
.then(result => resolve(data))
|
.then(result => resolve(data))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.tagData = function(snID, vectorClock, tag, tagTime, tagKey, tagSign) {
|
db.tagData = function(snID, vectorClock, tag, tagTime, tagKey, tagSign) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -213,7 +221,7 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
[T_struct.TAG_KEY]: tagKey,
|
[T_struct.TAG_KEY]: tagKey,
|
||||||
[T_struct.TAG_SIGN]: tagSign,
|
[T_struct.TAG_SIGN]: tagSign,
|
||||||
[L_struct.LOG_TIME]: Date.now()
|
[L_struct.LOG_TIME]: Date.now()
|
||||||
}
|
};
|
||||||
let attr = Object.keys(data);
|
let attr = Object.keys(data);
|
||||||
let values = attr.map(a => data[a]).concat(vectorClock);
|
let values = attr.map(a => data[a]).concat(vectorClock);
|
||||||
data[H_struct.VECTOR_CLOCK] = vectorClock; //also add vectorClock to resolve data
|
data[H_struct.VECTOR_CLOCK] = vectorClock; //also add vectorClock to resolve data
|
||||||
@ -222,9 +230,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" WHERE " + H_struct.VECTOR_CLOCK + "=?";
|
" WHERE " + H_struct.VECTOR_CLOCK + "=?";
|
||||||
db.query(statement, values)
|
db.query(statement, values)
|
||||||
.then(result => resolve(data))
|
.then(result => resolve(data))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.searchData = function(snID, request) {
|
db.searchData = function(snID, request) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -233,54 +241,54 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
if (request.lowerVectorClock && request.upperVectorClock)
|
if (request.lowerVectorClock && request.upperVectorClock)
|
||||||
conditionArr.push(`${H_struct.VECTOR_CLOCK} BETWEEN '${request.lowerVectorClock}' AND '${request.upperVectorClock}'`);
|
conditionArr.push(`${H_struct.VECTOR_CLOCK} BETWEEN '${request.lowerVectorClock}' AND '${request.upperVectorClock}'`);
|
||||||
else if (request.atKey)
|
else if (request.atKey)
|
||||||
conditionArr.push(`${H_struct.VECTOR_CLOCK} = '${request.atKey}'`)
|
conditionArr.push(`${H_struct.VECTOR_CLOCK} = '${request.atKey}'`);
|
||||||
else if (request.lowerVectorClock)
|
else if (request.lowerVectorClock)
|
||||||
conditionArr.push(`${H_struct.VECTOR_CLOCK} >= '${request.lowerVectorClock}'`)
|
conditionArr.push(`${H_struct.VECTOR_CLOCK} >= '${request.lowerVectorClock}'`);
|
||||||
else if (request.upperVectorClock)
|
else if (request.upperVectorClock)
|
||||||
conditionArr.push(`${H_struct.VECTOR_CLOCK} <= '${request.upperVectorClock}'`)
|
conditionArr.push(`${H_struct.VECTOR_CLOCK} <= '${request.upperVectorClock}'`);
|
||||||
}
|
}
|
||||||
conditionArr.push(`${H_struct.APPLICATION} = '${request.application}'`);
|
conditionArr.push(`${H_struct.APPLICATION} = '${request.application}'`);
|
||||||
conditionArr.push(`${H_struct.RECEIVER_ID} = '${request.receiverID}'`)
|
conditionArr.push(`${H_struct.RECEIVER_ID} = '${request.receiverID}'`)
|
||||||
if (request.comment)
|
if (request.comment)
|
||||||
conditionArr.push(`${B_struct.COMMENT} = '${request.comment}'`)
|
conditionArr.push(`${B_struct.COMMENT} = '${request.comment}'`);
|
||||||
if (request.type)
|
if (request.type)
|
||||||
conditionArr.push(`${H_struct.TYPE} = '${request.type}'`)
|
conditionArr.push(`${H_struct.TYPE} = '${request.type}'`);
|
||||||
if (request.senderID) {
|
if (request.senderID) {
|
||||||
if (Array.isArray(request.senderID))
|
if (Array.isArray(request.senderID))
|
||||||
conditionArr.push(`${H_struct.SENDER_ID} IN ('${request.senderID.join("', '")}')`);
|
conditionArr.push(`${H_struct.SENDER_ID} IN ('${request.senderID.join("', '")}')`);
|
||||||
else
|
else
|
||||||
conditionArr.push(`${H_struct.SENDER_ID} = '${request.senderID}'`)
|
conditionArr.push(`${H_struct.SENDER_ID} = '${request.senderID}'`);
|
||||||
}
|
};
|
||||||
//console.log(conditionArr);
|
//console.log(conditionArr);
|
||||||
let attr = Object.keys(H_struct).concat(Object.keys(B_struct))
|
let attr = Object.keys(H_struct).concat(Object.keys(B_struct));
|
||||||
let statement = "SELECT (" + attr.join(", ") + ")" +
|
let statement = "SELECT (" + attr.join(", ") + ")" +
|
||||||
" FROM _" + snID +
|
" FROM _" + snID +
|
||||||
" WHERE " + conditionArr.join(" AND ") +
|
" WHERE " + conditionArr.join(" AND ") +
|
||||||
request.mostRecent ? "LIMIT 1" : (" ORDER BY " + H_struct.VECTOR_CLOCK);
|
request.mostRecent ? "LIMIT 1" : (" ORDER BY " + H_struct.VECTOR_CLOCK);
|
||||||
db.query(statement)
|
db.query(statement)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.lastLogTime = function(snID) {
|
db.lastLogTime = function(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let statement = "SELECT MAX(" + L_struct.LOG_TIME + ") FROM _" + snID;
|
let statement = "SELECT MAX(" + L_struct.LOG_TIME + ") FROM _" + snID;
|
||||||
db.query(statement)
|
db.query(statement)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.createGetLastLog = function(snID) {
|
db.createGetLastLog = function(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
db.createTable(snID).then(result => {
|
db.createTable(snID).then(result => {
|
||||||
db.lastLogTime(snID)
|
db.lastLogTime(snID)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.getData = function(snID, logtime) {
|
db.getData = function(snID, logtime) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -289,13 +297,13 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" ORDER BY " + L_struct.LOG_TIME;
|
" ORDER BY " + L_struct.LOG_TIME;
|
||||||
db.query(statement)
|
db.query(statement)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.storeData = function(snID, data) {
|
db.storeData = function(snID, data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let u_attr = Object.keys(B_struct).map(a => B_struct[a])
|
let u_attr = Object.keys(B_struct).map(a => B_struct[a]);
|
||||||
let attr = Object.keys(H_struct).map(a => H_struct[a]).concat(u_attr);
|
let attr = Object.keys(H_struct).map(a => H_struct[a]).concat(u_attr);
|
||||||
let values = attr.map(a => data[a]);
|
let values = attr.map(a => data[a]);
|
||||||
let u_values = u_attr.map(a => data[a]);
|
let u_values = u_attr.map(a => data[a]);
|
||||||
@ -305,9 +313,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
"ON DUPLICATE KEY UPDATE " + u_attr.map(a => a + "=?").join(", ");
|
"ON DUPLICATE KEY UPDATE " + u_attr.map(a => a + "=?").join(", ");
|
||||||
db.query(statement, values.concat(u_values))
|
db.query(statement, values.concat(u_values))
|
||||||
.then(result => resolve(data))
|
.then(result => resolve(data))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.storeTag = function(snID, data) {
|
db.storeTag = function(snID, data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -318,9 +326,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
" WHERE " + H_struct.VECTOR_CLOCK + "=" + data[H_struct.VECTOR_CLOCK];
|
" WHERE " + H_struct.VECTOR_CLOCK + "=" + data[H_struct.VECTOR_CLOCK];
|
||||||
db.query(statement, values)
|
db.query(statement, values)
|
||||||
.then(result => resolve(data))
|
.then(result => resolve(data))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.clearAuthorisedAppData = function(snID, app, adminID, subAdmins, timestamp) {
|
db.clearAuthorisedAppData = function(snID, app, adminID, subAdmins, timestamp) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -332,9 +340,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
H_struct.SENDER_ID + " NOT IN (" + subAdmins.map(a => "?").join(", ") + ") )";
|
H_struct.SENDER_ID + " NOT IN (" + subAdmins.map(a => "?").join(", ") + ") )";
|
||||||
db.query(statement, [timestamp, app].concat(subAdmins).push(adminID))
|
db.query(statement, [timestamp, app].concat(subAdmins).push(adminID))
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.clearUnauthorisedAppData = function(snID, appList, timestamp) {
|
db.clearUnauthorisedAppData = function(snID, appList, timestamp) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -343,13 +351,13 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
H_struct.APPLICATION + " NOT IN (" + appList.map(a => "?").join(", ") + ")";
|
H_struct.APPLICATION + " NOT IN (" + appList.map(a => "?").join(", ") + ")";
|
||||||
db.query(statement, [timestamp].concat(appList))
|
db.query(statement, [timestamp].concat(appList))
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
db.close = function() {
|
db.close = function() {
|
||||||
db.conn.end();
|
db.conn.end();
|
||||||
}
|
};
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let conn = mysql.createConnection({
|
let conn = mysql.createConnection({
|
||||||
@ -361,9 +369,9 @@ function Database(user, password, dbname, host = 'localhost') {
|
|||||||
conn.connect((err) => {
|
conn.connect((err) => {
|
||||||
if (err) return reject(err);
|
if (err) return reject(err);
|
||||||
db.conn = conn;
|
db.conn = conn;
|
||||||
resolve(db)
|
resolve(db);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = Database;
|
module.exports = Database;
|
||||||
@ -9,16 +9,16 @@
|
|||||||
fetch_retry: function(apicall) {
|
fetch_retry: function(apicall) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.serverList.splice(this.curPos, 1);
|
this.serverList.splice(this.curPos, 1);
|
||||||
this.curPos = floCrypto.randInt(0, this.serverList.length - 1)
|
this.curPos = floCrypto.randInt(0, this.serverList.length - 1);
|
||||||
this.fetch_api(apicall)
|
this.fetch_api(apicall)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
fetch_api: function(apicall) {
|
fetch_api: function(apicall) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.serverList.length === 0)
|
if (this.serverList.length === 0)
|
||||||
reject("No floSight server working")
|
reject("No floSight server working");
|
||||||
else {
|
else {
|
||||||
fetch(this.serverList[this.curPos] + apicall).then(response => {
|
fetch(this.serverList[this.curPos] + apicall).then(response => {
|
||||||
if (response.ok)
|
if (response.ok)
|
||||||
@ -27,21 +27,21 @@
|
|||||||
this.fetch_retry(apicall)
|
this.fetch_retry(apicall)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
}
|
};
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.fetch_retry(apicall)
|
this.fetch_retry(apicall)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
//Promised function to get data from API
|
//Promised function to get data from API
|
||||||
promisedAPI: function(apicall) {
|
promisedAPI: function(apicall) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
console.log(apicall)
|
console.log(apicall);
|
||||||
this.util.fetch_api(apicall)
|
this.util.fetch_api(apicall)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
@ -64,7 +64,7 @@
|
|||||||
data = JSON.stringify(data);
|
data = JSON.stringify(data);
|
||||||
this.sendTx(senderAddr, receiverAddr, floGlobals.sendAmt, privKey, data)
|
this.sendTx(senderAddr, receiverAddr, floGlobals.sendAmt, privKey, data)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -75,7 +75,7 @@
|
|||||||
reject(`Invalid address : ${senderAddr}`);
|
reject(`Invalid address : ${senderAddr}`);
|
||||||
else if (!floCrypto.validateAddr(receiverAddr))
|
else if (!floCrypto.validateAddr(receiverAddr))
|
||||||
reject(`Invalid address : ${receiverAddr}`);
|
reject(`Invalid address : ${receiverAddr}`);
|
||||||
if (privKey.length < 1 || !floCrypto.verifyPrivKey(privKey, senderAddr))
|
else if (privKey.length < 1 || !floCrypto.verifyPrivKey(privKey, senderAddr))
|
||||||
reject("Invalid Private key!");
|
reject("Invalid Private key!");
|
||||||
else if (typeof sendAmt !== 'number' || sendAmt <= 0)
|
else if (typeof sendAmt !== 'number' || sendAmt <= 0)
|
||||||
reject(`Invalid sendAmt : ${sendAmt}`);
|
reject(`Invalid sendAmt : ${sendAmt}`);
|
||||||
@ -84,14 +84,12 @@
|
|||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
var fee = floGlobals.fee;
|
var fee = floGlobals.fee;
|
||||||
this.promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
this.promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
||||||
for (var i = utxos.length - 1;
|
for (var i = utxos.length - 1; (i >= 0) && (utxoAmt < sendAmt + fee); i--) {
|
||||||
(i >= 0) && (utxoAmt < sendAmt + fee); i--) {
|
|
||||||
if (utxos[i].confirmations) {
|
if (utxos[i].confirmations) {
|
||||||
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i]
|
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
||||||
.scriptPubKey)
|
|
||||||
utxoAmt += utxos[i].amount;
|
utxoAmt += utxos[i].amount;
|
||||||
} else break;
|
} else break;
|
||||||
}
|
};
|
||||||
if (utxoAmt < sendAmt + fee)
|
if (utxoAmt < sendAmt + fee)
|
||||||
reject("Insufficient balance!");
|
reject("Insufficient balance!");
|
||||||
else {
|
else {
|
||||||
@ -103,10 +101,10 @@
|
|||||||
var signedTxHash = trx.sign(privKey, 1);
|
var signedTxHash = trx.sign(privKey, 1);
|
||||||
this.broadcastTx(signedTxHash)
|
this.broadcastTx(signedTxHash)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}
|
};
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -116,27 +114,25 @@
|
|||||||
if (!floCrypto.validateAddr(floID))
|
if (!floCrypto.validateAddr(floID))
|
||||||
return reject(`Invalid floID`);
|
return reject(`Invalid floID`);
|
||||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
return reject("Invalid Private Key")
|
return reject("Invalid Private Key");
|
||||||
|
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
var fee = floGlobals.fee;
|
var fee = floGlobals.fee;
|
||||||
this.promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
|
this.promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
|
||||||
for (var i = utxos.length - 1; i >= 0; i--) {
|
for (var i = utxos.length - 1; i >= 0; i--)
|
||||||
if (utxos[i].confirmations) {
|
if (utxos[i].confirmations) {
|
||||||
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i]
|
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
||||||
.scriptPubKey)
|
|
||||||
utxoAmt += utxos[i].amount;
|
utxoAmt += utxos[i].amount;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
trx.addoutput(floID, utxoAmt - fee);
|
trx.addoutput(floID, utxoAmt - fee);
|
||||||
trx.addflodata(floData.replace(/\n/g, ' '));
|
trx.addflodata(floData.replace(/\n/g, ' '));
|
||||||
var signedTxHash = trx.sign(privKey, 1);
|
var signedTxHash = trx.sign(privKey, 1);
|
||||||
this.broadcastTx(signedTxHash)
|
this.broadcastTx(signedTxHash)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**Write data into blockchain from (and/or) to multiple floID
|
/**Write data into blockchain from (and/or) to multiple floID
|
||||||
@ -149,27 +145,27 @@
|
|||||||
writeDataMultiple: function(senderPrivKeys, data, receivers = [floGlobals.adminID], preserveRatio = true) {
|
writeDataMultiple: function(senderPrivKeys, data, receivers = [floGlobals.adminID], preserveRatio = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!Array.isArray(senderPrivKeys))
|
if (!Array.isArray(senderPrivKeys))
|
||||||
return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array")
|
return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array");
|
||||||
if (!preserveRatio) {
|
if (!preserveRatio) {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
let amount = (floGlobals.sendAmt * receivers.length) / senderPrivKeys.length;
|
let amount = (floGlobals.sendAmt * receivers.length) / senderPrivKeys.length;
|
||||||
senderPrivKeys.forEach(key => tmp[key] = amount);
|
senderPrivKeys.forEach(key => tmp[key] = amount);
|
||||||
senderPrivKeys = tmp
|
senderPrivKeys = tmp;
|
||||||
}
|
};
|
||||||
if (!Array.isArray(receivers))
|
if (!Array.isArray(receivers))
|
||||||
return reject("Invalid receivers: Receivers must be Array")
|
return reject("Invalid receivers: Receivers must be Array");
|
||||||
else {
|
else {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
let amount = floGlobals.sendAmt;
|
let amount = floGlobals.sendAmt;
|
||||||
receivers.forEach(floID => tmp[floID] = amount);
|
receivers.forEach(floID => tmp[floID] = amount);
|
||||||
receivers = tmp
|
receivers = tmp;
|
||||||
}
|
};
|
||||||
if (typeof data != "string")
|
if (typeof data != "string")
|
||||||
data = JSON.stringify(data);
|
data = JSON.stringify(data);
|
||||||
this.sendTxMultiple(senderPrivKeys, receivers, data)
|
this.sendTxMultiple(senderPrivKeys, receivers, data)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**Send Tx from (and/or) to multiple floID
|
/**Send Tx from (and/or) to multiple floID
|
||||||
@ -190,7 +186,7 @@
|
|||||||
InvalidSenderAmountFor: [],
|
InvalidSenderAmountFor: [],
|
||||||
InvalidReceiverIDs: [],
|
InvalidReceiverIDs: [],
|
||||||
InvalidReceiveAmountFor: []
|
InvalidReceiveAmountFor: []
|
||||||
}
|
};
|
||||||
let inputVal = 0,
|
let inputVal = 0,
|
||||||
outputVal = 0;
|
outputVal = 0;
|
||||||
//Validate sender privatekeys (and send amount if passed)
|
//Validate sender privatekeys (and send amount if passed)
|
||||||
@ -204,12 +200,12 @@
|
|||||||
let floID = floCrypto.getFloID(key);
|
let floID = floCrypto.getFloID(key);
|
||||||
senders[floID] = {
|
senders[floID] = {
|
||||||
wif: key
|
wif: key
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
invalids.InvalidSenderPrivKeys.push(key)
|
invalids.InvalidSenderPrivKeys.push(key);
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
preserveRatio = true;
|
preserveRatio = true;
|
||||||
}
|
}
|
||||||
//conversion when privatekeys are passed with send amount
|
//conversion when privatekeys are passed with send amount
|
||||||
@ -219,32 +215,31 @@
|
|||||||
if (!key)
|
if (!key)
|
||||||
invalids.InvalidSenderPrivKeys.push(key);
|
invalids.InvalidSenderPrivKeys.push(key);
|
||||||
else {
|
else {
|
||||||
if (typeof senderPrivKeys[key] !== 'number' || senderPrivKeys[
|
if (typeof senderPrivKeys[key] !== 'number' || senderPrivKeys[key] <= 0)
|
||||||
key] <= 0)
|
invalids.InvalidSenderAmountFor.push(key);
|
||||||
invalids.InvalidSenderAmountFor.push(key)
|
|
||||||
else
|
else
|
||||||
inputVal += senderPrivKeys[key];
|
inputVal += senderPrivKeys[key];
|
||||||
let floID = floCrypto.getFloID(key);
|
let floID = floCrypto.getFloID(key);
|
||||||
senders[floID] = {
|
senders[floID] = {
|
||||||
wif: key,
|
wif: key,
|
||||||
coins: senderPrivKeys[key]
|
coins: senderPrivKeys[key]
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
invalids.InvalidSenderPrivKeys.push(key)
|
invalids.InvalidSenderPrivKeys.push(key);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
preserveRatio = false;
|
preserveRatio = false;
|
||||||
}
|
};
|
||||||
//Validate the receiver IDs and receive amount
|
//Validate the receiver IDs and receive amount
|
||||||
for (let floID in receivers) {
|
for (let floID in receivers) {
|
||||||
if (!floCrypto.validateAddr(floID))
|
if (!floCrypto.validateAddr(floID))
|
||||||
invalids.InvalidReceiverIDs.push(floID)
|
invalids.InvalidReceiverIDs.push(floID);
|
||||||
if (typeof receivers[floID] !== 'number' || receivers[floID] <= 0)
|
if (typeof receivers[floID] !== 'number' || receivers[floID] <= 0)
|
||||||
invalids.InvalidReceiveAmountFor.push(floID)
|
invalids.InvalidReceiveAmountFor.push(floID);
|
||||||
else
|
else
|
||||||
outputVal += receivers[floID];
|
outputVal += receivers[floID];
|
||||||
}
|
};
|
||||||
//Reject if any invalids are found
|
//Reject if any invalids are found
|
||||||
for (let i in invalids)
|
for (let i in invalids)
|
||||||
if (!invalids[i].length)
|
if (!invalids[i].length)
|
||||||
@ -253,15 +248,14 @@
|
|||||||
return reject(invalids);
|
return reject(invalids);
|
||||||
//Reject if given inputVal and outputVal are not equal
|
//Reject if given inputVal and outputVal are not equal
|
||||||
if (!preserveRatio && inputVal != outputVal)
|
if (!preserveRatio && inputVal != outputVal)
|
||||||
return reject(
|
return reject(`Input Amount (${inputVal}) not equal to Output Amount (${outputVal})`);
|
||||||
`Input Amount (${inputVal}) not equal to Output Amount (${outputVal})`)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return reject(error)
|
return reject(error);
|
||||||
}
|
}
|
||||||
//Get balance of senders
|
//Get balance of senders
|
||||||
let promises = []
|
let promises = [];
|
||||||
for (let floID in senders)
|
for (let floID in senders)
|
||||||
promises.push(this.getBalance(floID))
|
promises.push(this.getBalance(floID));
|
||||||
Promise.all(promises).then(results => {
|
Promise.all(promises).then(results => {
|
||||||
let totalBalance = 0,
|
let totalBalance = 0,
|
||||||
totalFee = floGlobals.fee,
|
totalFee = floGlobals.fee,
|
||||||
@ -273,26 +267,25 @@
|
|||||||
let insufficient = [];
|
let insufficient = [];
|
||||||
for (let floID in senders) {
|
for (let floID in senders) {
|
||||||
balance[floID] = parseFloat(results.shift());
|
balance[floID] = parseFloat(results.shift());
|
||||||
if (isNaN(balance[floID]) || (preserveRatio && balance[floID] <=
|
if (isNaN(balance[floID]) || (preserveRatio && balance[floID] <= totalFee)
|
||||||
totalFee) || (!preserveRatio && balance[floID] < senders[floID]
|
|| (!preserveRatio && balance[floID] < senders[floID].coins + dividedFee))
|
||||||
.coins + dividedFee))
|
insufficient.push(floID);
|
||||||
insufficient.push(floID)
|
|
||||||
totalBalance += balance[floID];
|
totalBalance += balance[floID];
|
||||||
}
|
};
|
||||||
if (insufficient.length)
|
if (insufficient.length)
|
||||||
return reject({
|
return reject({
|
||||||
InsufficientBalance: insufficient
|
InsufficientBalance: insufficient
|
||||||
})
|
});
|
||||||
//Calculate totalSentAmount and check if totalBalance is sufficient
|
//Calculate totalSentAmount and check if totalBalance is sufficient
|
||||||
let totalSendAmt = totalFee;
|
let totalSendAmt = totalFee;
|
||||||
for (floID in receivers)
|
for (floID in receivers)
|
||||||
totalSendAmt += receivers[floID];
|
totalSendAmt += receivers[floID];
|
||||||
if (totalBalance < totalSendAmt)
|
if (totalBalance < totalSendAmt)
|
||||||
return reject("Insufficient total Balance")
|
return reject("Insufficient total Balance");
|
||||||
//Get the UTXOs of the senders
|
//Get the UTXOs of the senders
|
||||||
let promises = []
|
let promises = [];
|
||||||
for (floID in senders)
|
for (floID in senders)
|
||||||
promises.push(this.promisedAPI(`api/addr/${floID}/utxo`))
|
promises.push(this.promisedAPI(`api/addr/${floID}/utxo`));
|
||||||
Promise.all(promises).then(results => {
|
Promise.all(promises).then(results => {
|
||||||
let wifSeq = [];
|
let wifSeq = [];
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
@ -306,21 +299,18 @@
|
|||||||
sendAmt = senders[floID].coins + dividedFee;
|
sendAmt = senders[floID].coins + dividedFee;
|
||||||
let wif = senders[floID].wif;
|
let wif = senders[floID].wif;
|
||||||
let utxoAmt = 0.0;
|
let utxoAmt = 0.0;
|
||||||
for (let i = utxos.length - 1;
|
for (let i = utxos.length - 1; (i >= 0) && (utxoAmt < sendAmt); i--)
|
||||||
(i >= 0) && (utxoAmt < sendAmt); i--) {
|
|
||||||
if (utxos[i].confirmations) {
|
if (utxos[i].confirmations) {
|
||||||
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i]
|
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
||||||
.scriptPubKey)
|
|
||||||
wifSeq.push(wif);
|
wifSeq.push(wif);
|
||||||
utxoAmt += utxos[i].amount;
|
utxoAmt += utxos[i].amount;
|
||||||
}
|
};
|
||||||
}
|
|
||||||
if (utxoAmt < sendAmt)
|
if (utxoAmt < sendAmt)
|
||||||
return reject("Insufficient balance:" + floID);
|
return reject("Insufficient balance:" + floID);
|
||||||
let change = (utxoAmt - sendAmt);
|
let change = (utxoAmt - sendAmt);
|
||||||
if (change > 0)
|
if (change > 0)
|
||||||
trx.addoutput(floID, change);
|
trx.addoutput(floID, change);
|
||||||
}
|
};
|
||||||
for (floID in receivers)
|
for (floID in receivers)
|
||||||
trx.addoutput(floID, receivers[floID]);
|
trx.addoutput(floID, receivers[floID]);
|
||||||
trx.addflodata(floData.replace(/\n/g, ' '));
|
trx.addflodata(floData.replace(/\n/g, ' '));
|
||||||
@ -329,10 +319,10 @@
|
|||||||
var signedTxHash = trx.serialize();
|
var signedTxHash = trx.serialize();
|
||||||
this.broadcastTx(signedTxHash)
|
this.broadcastTx(signedTxHash)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
//Broadcast signed Tx in blockchain using API
|
//Broadcast signed Tx in blockchain using API
|
||||||
@ -340,7 +330,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var request = new XMLHttpRequest();
|
var request = new XMLHttpRequest();
|
||||||
var url = this.util.serverList[this.util.curPos] + 'api/tx/send';
|
var url = this.util.serverList[this.util.curPos] + 'api/tx/send';
|
||||||
console.log(url)
|
console.log(url);
|
||||||
if (signedTxHash.length < 1)
|
if (signedTxHash.length < 1)
|
||||||
reject("Empty Signature");
|
reject("Empty Signature");
|
||||||
else {
|
else {
|
||||||
@ -356,8 +346,8 @@
|
|||||||
reject(request.responseText);
|
reject(request.responseText);
|
||||||
}
|
}
|
||||||
request.send(params);
|
request.send(params);
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
//Read Txs of Address between from and to
|
//Read Txs of Address between from and to
|
||||||
@ -365,7 +355,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.promisedAPI(`api/addrs/${addr}/txs?from=${from}&to=${to}`)
|
this.promisedAPI(`api/addrs/${addr}/txs?from=${from}&to=${to}`)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -376,7 +366,7 @@
|
|||||||
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${response.totalItems}0`)
|
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${response.totalItems}0`)
|
||||||
.then(response => resolve(response.items))
|
.then(response => resolve(response.items))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -390,27 +380,23 @@
|
|||||||
filter : custom filter funtion for floData (eg . filter: d => {return d[0] == '$'})
|
filter : custom filter funtion for floData (eg . filter: d => {return d[0] == '$'})
|
||||||
*/
|
*/
|
||||||
readData: function(addr, options = {}) {
|
readData: function(addr, options = {}) {
|
||||||
options.limit = options.limit | 0
|
options.limit = options.limit || 0;
|
||||||
options.ignoreOld = options.ignoreOld | 0
|
options.ignoreOld = options.ignoreOld || 0;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
||||||
var newItems = response.totalItems - options.ignoreOld;
|
var newItems = response.totalItems - options.ignoreOld;
|
||||||
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems*2}`).then(
|
this.promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems*2}`).then(response => {
|
||||||
response => {
|
|
||||||
if (options.limit <= 0)
|
if (options.limit <= 0)
|
||||||
options.limit = response.items.length;
|
options.limit = response.items.length;
|
||||||
var filteredData = [];
|
var filteredData = [];
|
||||||
for (i = 0; i < (response.totalItems - options.ignoreOld) &&
|
for (i = 0; i < (response.totalItems - options.ignoreOld) &&
|
||||||
filteredData.length < options.limit; i++) {
|
filteredData.length < options.limit; i++) {
|
||||||
if (options.sentOnly && response.items[i].vin[0].addr !==
|
if (options.sentOnly && response.items[i].vin[0].addr !== addr)
|
||||||
addr)
|
|
||||||
continue;
|
continue;
|
||||||
if (options.pattern) {
|
if (options.pattern) {
|
||||||
try {
|
try {
|
||||||
let jsonContent = JSON.parse(response.items[i]
|
let jsonContent = JSON.parse(response.items[i].floData)
|
||||||
.floData)
|
if (!Object.keys(jsonContent).includes(options.pattern))
|
||||||
if (!Object.keys(jsonContent).includes(options
|
|
||||||
.pattern))
|
|
||||||
continue;
|
continue;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
continue;
|
continue;
|
||||||
@ -419,7 +405,7 @@
|
|||||||
if (options.filter && !options.filter(response.items[i].floData))
|
if (options.filter && !options.filter(response.items[i].floData))
|
||||||
continue;
|
continue;
|
||||||
filteredData.push(response.items[i].floData);
|
filteredData.push(response.items[i].floData);
|
||||||
}
|
};
|
||||||
resolve({
|
resolve({
|
||||||
totalTxs: response.totalItems,
|
totalTxs: response.totalItems,
|
||||||
data: filteredData
|
data: filteredData
|
||||||
@ -433,4 +419,4 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})(typeof global !== "undefined" ? global : window)
|
})(typeof global !== "undefined" ? global : window);
|
||||||
|
|||||||
106
src/floCrypto.js
106
src/floCrypto.js
@ -1,28 +1,28 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(function(GLOBAL) {
|
(function(GLOBAL) {
|
||||||
var floCrypto = GLOBAL.floCrypto = {}
|
var floCrypto = GLOBAL.floCrypto = {};
|
||||||
const p = BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
|
const p = BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
|
||||||
const ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
const ecparams = EllipticCurve.getSECCurveByName("secp256k1");
|
||||||
|
|
||||||
function exponent1() {
|
function exponent1() {
|
||||||
return p.add(BigInteger.ONE).divide(BigInteger("4"))
|
return p.add(BigInteger.ONE).divide(BigInteger("4"));
|
||||||
}
|
};
|
||||||
|
|
||||||
function calculateY(x) {
|
function calculateY(x) {
|
||||||
let exp = exponent1();
|
let exp = exponent1();
|
||||||
// x is x value of public key in BigInteger format without 02 or 03 or 04 prefix
|
// x is x value of public key in BigInteger format without 02 or 03 or 04 prefix
|
||||||
return x.modPow(BigInteger("3"), p).add(BigInteger("7")).mod(p).modPow(exp, p)
|
return x.modPow(BigInteger("3"), p).add(BigInteger("7")).mod(p).modPow(exp, p);
|
||||||
}
|
};
|
||||||
|
|
||||||
function getUncompressedPublicKey(compressedPublicKey) {
|
function getUncompressedPublicKey(compressedPublicKey) {
|
||||||
// Fetch x from compressedPublicKey
|
// Fetch x from compressedPublicKey
|
||||||
let pubKeyBytes = Crypto.util.hexToBytes(compressedPublicKey);
|
let pubKeyBytes = Crypto.util.hexToBytes(compressedPublicKey);
|
||||||
const prefix = pubKeyBytes.shift() // remove prefix
|
const prefix = pubKeyBytes.shift(); // remove prefix
|
||||||
let prefix_modulus = prefix % 2;
|
let prefix_modulus = prefix % 2;
|
||||||
pubKeyBytes.unshift(0) // add prefix 0
|
pubKeyBytes.unshift(0); // add prefix 0
|
||||||
let x = new BigInteger(pubKeyBytes)
|
let x = new BigInteger(pubKeyBytes);
|
||||||
let xDecimalValue = x.toString()
|
let xDecimalValue = x.toString();
|
||||||
// Fetch y
|
// Fetch y
|
||||||
let y = calculateY(x);
|
let y = calculateY(x);
|
||||||
let yDecimalValue = y.toString();
|
let yDecimalValue = y.toString();
|
||||||
@ -35,7 +35,7 @@
|
|||||||
x: xDecimalValue,
|
x: xDecimalValue,
|
||||||
y: yDecimalValue
|
y: yDecimalValue
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
function getSenderPublicKeyString() {
|
function getSenderPublicKeyString() {
|
||||||
privateKey = ellipticCurveEncryption.senderRandom();
|
privateKey = ellipticCurveEncryption.senderRandom();
|
||||||
@ -43,8 +43,8 @@
|
|||||||
return {
|
return {
|
||||||
privateKey: privateKey,
|
privateKey: privateKey,
|
||||||
senderPublicKeyString: senderPublicKeyString
|
senderPublicKeyString: senderPublicKeyString
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
function deriveSharedKeySender(receiverCompressedPublicKey, senderPrivateKey) {
|
function deriveSharedKeySender(receiverCompressedPublicKey, senderPrivateKey) {
|
||||||
try {
|
try {
|
||||||
@ -54,33 +54,33 @@
|
|||||||
return senderDerivedKey;
|
return senderDerivedKey;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return new Error(error);
|
return new Error(error);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
function deriveReceiverSharedKey(senderPublicKeyString, receiverPrivateKey) {
|
function deriveReceiverSharedKey(senderPublicKeyString, receiverPrivateKey) {
|
||||||
return ellipticCurveEncryption.receiverSharedKeyDerivation(
|
return ellipticCurveEncryption.receiverSharedKeyDerivation(
|
||||||
senderPublicKeyString.XValuePublicString,
|
senderPublicKeyString.XValuePublicString,
|
||||||
senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
senderPublicKeyString.YValuePublicString, receiverPrivateKey);
|
||||||
}
|
};
|
||||||
|
|
||||||
function getReceiverPublicKeyString(privateKey) {
|
function getReceiverPublicKeyString(privateKey) {
|
||||||
return ellipticCurveEncryption.receiverPublicString(privateKey);
|
return ellipticCurveEncryption.receiverPublicString(privateKey);
|
||||||
}
|
};
|
||||||
|
|
||||||
function wifToDecimal(pk_wif, isPubKeyCompressed = false) {
|
function wifToDecimal(pk_wif, isPubKeyCompressed = false) {
|
||||||
let pk = Bitcoin.Base58.decode(pk_wif)
|
let pk = Bitcoin.Base58.decode(pk_wif);
|
||||||
pk.shift()
|
pk.shift();
|
||||||
pk.splice(-4, 4)
|
pk.splice(-4, 4);
|
||||||
//If the private key corresponded to a compressed public key, also drop the last byte (it should be 0x01).
|
//If the private key corresponded to a compressed public key, also drop the last byte (it should be 0x01).
|
||||||
if (isPubKeyCompressed == true) pk.pop()
|
if (isPubKeyCompressed == true) pk.pop();
|
||||||
pk.unshift(0)
|
pk.unshift(0);
|
||||||
privateKeyDecimal = BigInteger(pk).toString()
|
privateKeyDecimal = BigInteger(pk).toString();
|
||||||
privateKeyHex = Crypto.util.bytesToHex(pk)
|
privateKeyHex = Crypto.util.bytesToHex(pk);
|
||||||
return {
|
return {
|
||||||
privateKeyDecimal: privateKeyDecimal,
|
privateKeyDecimal: privateKeyDecimal,
|
||||||
privateKeyHex: privateKeyHex
|
privateKeyHex: privateKeyHex
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
//generate a random Interger within range
|
//generate a random Interger within range
|
||||||
@ -88,7 +88,7 @@
|
|||||||
min = Math.ceil(min);
|
min = Math.ceil(min);
|
||||||
max = Math.floor(max);
|
max = Math.floor(max);
|
||||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
}
|
};
|
||||||
|
|
||||||
//generate a random String within length (options : alphaNumeric chars only)
|
//generate a random String within length (options : alphaNumeric chars only)
|
||||||
floCrypto.randString = function(length, alphaNumeric = true) {
|
floCrypto.randString = function(length, alphaNumeric = true) {
|
||||||
@ -101,7 +101,7 @@
|
|||||||
for (var i = 0; i < length; i++)
|
for (var i = 0; i < length; i++)
|
||||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
|
|
||||||
//Encrypt Data using public-key
|
//Encrypt Data using public-key
|
||||||
floCrypto.encryptData = function(data, publicKeyHex) {
|
floCrypto.encryptData = function(data, publicKeyHex) {
|
||||||
@ -114,7 +114,7 @@
|
|||||||
secret: secret,
|
secret: secret,
|
||||||
senderPublicKeyString: senderECKeyData.senderPublicKeyString
|
senderPublicKeyString: senderECKeyData.senderPublicKeyString
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Decrypt Data using private-key
|
//Decrypt Data using private-key
|
||||||
floCrypto.decryptData = function(data, privateKeyHex) {
|
floCrypto.decryptData = function(data, privateKeyHex) {
|
||||||
@ -129,7 +129,7 @@
|
|||||||
let receiverKey = receiverDerivedKey.XValue + receiverDerivedKey.YValue;
|
let receiverKey = receiverDerivedKey.XValue + receiverDerivedKey.YValue;
|
||||||
let decryptMsg = Crypto.AES.decrypt(data.secret, receiverKey);
|
let decryptMsg = Crypto.AES.decrypt(data.secret, receiverKey);
|
||||||
return decryptMsg;
|
return decryptMsg;
|
||||||
}
|
};
|
||||||
|
|
||||||
//Sign data using private-key
|
//Sign data using private-key
|
||||||
floCrypto.signData = function(data, privateKeyHex) {
|
floCrypto.signData = function(data, privateKeyHex) {
|
||||||
@ -144,7 +144,7 @@
|
|||||||
var messageSign = Bitcoin.ECDSA.sign(messageHashBigInteger, key.priv);
|
var messageSign = Bitcoin.ECDSA.sign(messageHashBigInteger, key.priv);
|
||||||
var sighex = Crypto.util.bytesToHex(messageSign);
|
var sighex = Crypto.util.bytesToHex(messageSign);
|
||||||
return sighex;
|
return sighex;
|
||||||
}
|
};
|
||||||
|
|
||||||
//Verify signatue of the data using public-key
|
//Verify signatue of the data using public-key
|
||||||
floCrypto.verifySign = function(data, signatureHex, publicKeyHex) {
|
floCrypto.verifySign = function(data, signatureHex, publicKeyHex) {
|
||||||
@ -156,7 +156,7 @@
|
|||||||
var verify = Bitcoin.ECDSA.verifyRaw(messageHashBigInteger,
|
var verify = Bitcoin.ECDSA.verifyRaw(messageHashBigInteger,
|
||||||
signature.r, signature.s, publicKeyPoint);
|
signature.r, signature.s, publicKeyPoint);
|
||||||
return verify;
|
return verify;
|
||||||
}
|
};
|
||||||
|
|
||||||
//Generates a new flo ID and returns private-key, public-key and floID
|
//Generates a new flo ID and returns private-key, public-key and floID
|
||||||
floCrypto.generateNewID = function() {
|
floCrypto.generateNewID = function() {
|
||||||
@ -167,11 +167,11 @@
|
|||||||
floID: key.getBitcoinAddress(),
|
floID: key.getBitcoinAddress(),
|
||||||
pubKey: key.getPubKeyHex(),
|
pubKey: key.getPubKeyHex(),
|
||||||
privKey: key.getBitcoinWalletImportFormat()
|
privKey: key.getBitcoinWalletImportFormat()
|
||||||
}
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Returns public-key from private-key
|
//Returns public-key from private-key
|
||||||
floCrypto.getPubKeyHex = function(privateKeyHex) {
|
floCrypto.getPubKeyHex = function(privateKeyHex) {
|
||||||
@ -182,7 +182,7 @@
|
|||||||
return null;
|
return null;
|
||||||
key.setCompressed(true);
|
key.setCompressed(true);
|
||||||
return key.getPubKeyHex();
|
return key.getPubKeyHex();
|
||||||
}
|
};
|
||||||
|
|
||||||
//Returns flo-ID from public-key or private-key
|
//Returns flo-ID from public-key or private-key
|
||||||
floCrypto.getFloID = function(keyHex) {
|
floCrypto.getFloID = function(keyHex) {
|
||||||
@ -195,8 +195,8 @@
|
|||||||
return key.getBitcoinAddress();
|
return key.getBitcoinAddress();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Verify the private-key for the given public-key or flo-ID
|
//Verify the private-key for the given public-key or flo-ID
|
||||||
floCrypto.verifyPrivKey = function(privateKeyHex, publicHex_ID) {
|
floCrypto.verifyPrivKey = function(privateKeyHex, publicHex_ID) {
|
||||||
@ -215,8 +215,8 @@
|
|||||||
return false;
|
return false;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Check if the given Address is valid or not
|
//Check if the given Address is valid or not
|
||||||
floCrypto.validateAddr = function(inpAddr) {
|
floCrypto.validateAddr = function(inpAddr) {
|
||||||
@ -227,8 +227,8 @@
|
|||||||
return true;
|
return true;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Split the str using shamir's Secret and Returns the shares
|
//Split the str using shamir's Secret and Returns the shares
|
||||||
floCrypto.createShamirsSecretShares = function(str, total_shares, threshold_limit) {
|
floCrypto.createShamirsSecretShares = function(str, total_shares, threshold_limit) {
|
||||||
@ -236,12 +236,12 @@
|
|||||||
if (str.length > 0) {
|
if (str.length > 0) {
|
||||||
var strHex = shamirSecretShare.str2hex(str);
|
var strHex = shamirSecretShare.str2hex(str);
|
||||||
return shamirSecretShare.share(strHex, total_shares, threshold_limit);
|
return shamirSecretShare.share(strHex, total_shares, threshold_limit);
|
||||||
}
|
};
|
||||||
return false;
|
return false;
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Verifies the shares and str
|
//Verifies the shares and str
|
||||||
floCrypto.verifyShamirsSecret = function(sharesArray, str) {
|
floCrypto.verifyShamirsSecret = function(sharesArray, str) {
|
||||||
@ -250,13 +250,13 @@
|
|||||||
try {
|
try {
|
||||||
if (sharesArray.length > 0) {
|
if (sharesArray.length > 0) {
|
||||||
var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length));
|
var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length));
|
||||||
return (shamirSecretShare.hex2str(comb) === str ? true : false)
|
return (shamirSecretShare.hex2str(comb) === str ? true : false);
|
||||||
}
|
};
|
||||||
return false;
|
return false;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Returns the retrived secret by combining the shamirs shares
|
//Returns the retrived secret by combining the shamirs shares
|
||||||
floCrypto.retrieveShamirSecret = function(sharesArray) {
|
floCrypto.retrieveShamirSecret = function(sharesArray) {
|
||||||
@ -264,11 +264,11 @@
|
|||||||
if (sharesArray.length > 0) {
|
if (sharesArray.length > 0) {
|
||||||
var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length));
|
var comb = shamirSecretShare.combine(sharesArray.slice(0, sharesArray.length));
|
||||||
return shamirSecretShare.hex2str(comb);
|
return shamirSecretShare.hex2str(comb);
|
||||||
}
|
};
|
||||||
return false;
|
return false;
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
})(typeof global !== "undefined" ? global : window)
|
})(typeof global !== "undefined" ? global : window);
|
||||||
@ -24,7 +24,7 @@ const floGlobals = {
|
|||||||
errorFeedback - (Boolean) Send error (if any) feedback to the requestor
|
errorFeedback - (Boolean) Send error (if any) feedback to the requestor
|
||||||
delayDelta - (Interger) Maximum allowed delay from the data-time
|
delayDelta - (Interger) Maximum allowed delay from the data-time
|
||||||
*/
|
*/
|
||||||
}
|
};
|
||||||
|
|
||||||
(typeof global !== "undefined" ? global : window).cryptocoin = floGlobals.blockchain;
|
(typeof global !== "undefined" ? global : window).cryptocoin = floGlobals.blockchain;
|
||||||
('object' === typeof module) ? module.export = floGlobals : null;
|
('object' === typeof module) ? module.export = floGlobals : null;
|
||||||
311
src/intra.js
311
src/intra.js
@ -19,7 +19,7 @@ const SUPERNODE_INDICATOR = '$',
|
|||||||
RETRY_TIMEOUT = 5 * 60 * 1000, //5 mins
|
RETRY_TIMEOUT = 5 * 60 * 1000, //5 mins
|
||||||
MIGRATE_WAIT_DELAY = 5 * 60 * 1000; //5 mins
|
MIGRATE_WAIT_DELAY = 5 * 60 * 1000; //5 mins
|
||||||
|
|
||||||
var DB, refresher //container for database and refresher
|
var DB, refresher; //container for database and refresher
|
||||||
|
|
||||||
//List of node backups stored
|
//List of node backups stored
|
||||||
const _list = {};
|
const _list = {};
|
||||||
@ -36,7 +36,7 @@ Object.defineProperty(_list, 'get', {
|
|||||||
else
|
else
|
||||||
return this[keys];
|
return this[keys];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(_list, 'stored', {
|
Object.defineProperty(_list, 'stored', {
|
||||||
get: function() {
|
get: function() {
|
||||||
return Object.keys(this);
|
return Object.keys(this);
|
||||||
@ -44,7 +44,7 @@ Object.defineProperty(_list, 'stored', {
|
|||||||
});
|
});
|
||||||
Object.defineProperty(_list, 'serving', {
|
Object.defineProperty(_list, 'serving', {
|
||||||
get: function() {
|
get: function() {
|
||||||
let serveList = []
|
let serveList = [];
|
||||||
for (let id in this)
|
for (let id in this)
|
||||||
if (this[id] === 0)
|
if (this[id] === 0)
|
||||||
serveList.push(id);
|
serveList.push(id);
|
||||||
@ -66,12 +66,12 @@ function NodeContainer() {
|
|||||||
if (_onclose)
|
if (_onclose)
|
||||||
_ws.onclose = _onclose;
|
_ws.onclose = _onclose;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'id', {
|
Object.defineProperty(this, 'id', {
|
||||||
get: function() {
|
get: function() {
|
||||||
return _id;
|
return _id;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'readyState', {
|
Object.defineProperty(this, 'readyState', {
|
||||||
get: function() {
|
get: function() {
|
||||||
if (_ws instanceof WebSocket)
|
if (_ws instanceof WebSocket)
|
||||||
@ -79,7 +79,7 @@ function NodeContainer() {
|
|||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'send', {
|
Object.defineProperty(this, 'send', {
|
||||||
value: function(packet) {
|
value: function(packet) {
|
||||||
_ws.send(packet);
|
_ws.send(packet);
|
||||||
@ -90,28 +90,28 @@ function NodeContainer() {
|
|||||||
if (fn instanceof Function)
|
if (fn instanceof Function)
|
||||||
_onmessage = fn;
|
_onmessage = fn;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'onclose', {
|
Object.defineProperty(this, 'onclose', {
|
||||||
set: function(fn) {
|
set: function(fn) {
|
||||||
if (fn instanceof Function)
|
if (fn instanceof Function)
|
||||||
_onclose = fn;
|
_onclose = fn;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'is', {
|
Object.defineProperty(this, 'is', {
|
||||||
value: function(ws) {
|
value: function(ws) {
|
||||||
return ws === _ws;
|
return ws === _ws;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.defineProperty(this, 'close', {
|
Object.defineProperty(this, 'close', {
|
||||||
value: function() {
|
value: function() {
|
||||||
if (_ws.readyState === 1) {
|
if (_ws.readyState === 1) {
|
||||||
_ws.onclose = () => console.warn('Closing: ' + _id)
|
_ws.onclose = () => console.warn('Closing: ' + _id);
|
||||||
_ws.close();
|
_ws.close();
|
||||||
}
|
};
|
||||||
_ws = _id = undefined;
|
_ws = _id = undefined;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//Container for next-node
|
//Container for next-node
|
||||||
const _nextNode = new NodeContainer();
|
const _nextNode = new NodeContainer();
|
||||||
@ -123,19 +123,19 @@ _prevNode.onmessage = evt => processTaskFromPrevNode(evt.data);
|
|||||||
_prevNode.onclose = evt => _prevNode.close();
|
_prevNode.onclose = evt => _prevNode.close();
|
||||||
|
|
||||||
//Packet processing
|
//Packet processing
|
||||||
const packet_ = {}
|
const packet_ = {};
|
||||||
packet_.constuct = function(message) {
|
packet_.constuct = function(message) {
|
||||||
const packet = {
|
const packet = {
|
||||||
from: myFloID,
|
from: myFloID,
|
||||||
message: message,
|
message: message,
|
||||||
time: Date.now()
|
time: Date.now()
|
||||||
}
|
};
|
||||||
packet.sign = floCrypto.signData(this.s(packet), myPrivKey);
|
packet.sign = floCrypto.signData(this.s(packet), myPrivKey);
|
||||||
return SUPERNODE_INDICATOR + JSON.stringify(packet)
|
return SUPERNODE_INDICATOR + JSON.stringify(packet);
|
||||||
}
|
};
|
||||||
packet_.s = d => [JSON.stringify(d.message), d.time].join("|");
|
packet_.s = d => [JSON.stringify(d.message), d.time].join("|");
|
||||||
packet_.parse = function(str) {
|
packet_.parse = function(str) {
|
||||||
let packet = JSON.parse(str.substring(SUPERNODE_INDICATOR.length))
|
let packet = JSON.parse(str.substring(SUPERNODE_INDICATOR.length));
|
||||||
let curTime = Date.now();
|
let curTime = Date.now();
|
||||||
if (packet.time > curTime - floGlobals.sn_config.delayDelta &&
|
if (packet.time > curTime - floGlobals.sn_config.delayDelta &&
|
||||||
packet.from in floGlobals.supernodes &&
|
packet.from in floGlobals.supernodes &&
|
||||||
@ -143,8 +143,8 @@ packet_.parse = function(str) {
|
|||||||
if (!Array.isArray(packet.message))
|
if (!Array.isArray(packet.message))
|
||||||
packet.message = [packet.message];
|
packet.message = [packet.message];
|
||||||
return packet;
|
return packet;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//-----NODE CONNECTORS (WEBSOCKET)-----
|
//-----NODE CONNECTORS (WEBSOCKET)-----
|
||||||
|
|
||||||
@ -152,44 +152,44 @@ packet_.parse = function(str) {
|
|||||||
function connectToNode(snID) {
|
function connectToNode(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!(snID in floGlobals.supernodes))
|
if (!(snID in floGlobals.supernodes))
|
||||||
return reject(`${snID} is not a supernode`)
|
return reject(`${snID} is not a supernode`);
|
||||||
const ws = new WebSocket("wss://" + floGlobals.supernodes[nextNodeID].uri + "/");
|
const ws = new WebSocket("wss://" + floGlobals.supernodes[nextNodeID].uri + "/");
|
||||||
ws.on("error", () => reject(`${snID} is offline`));
|
ws.on("error", () => reject(`${snID} is offline`));
|
||||||
ws.on('open', () => resolve(ws));
|
ws.on('open', () => resolve(ws));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//Connect to Node websocket thats online
|
//Connect to Node websocket thats online
|
||||||
function connectToActiveNode(snID, reverse = false) {
|
function connectToActiveNode(snID, reverse = false) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!(snID in floGlobals.supernodes))
|
if (!(snID in floGlobals.supernodes))
|
||||||
return reject(`${snID} is not a supernode`)
|
return reject(`${snID} is not a supernode`);
|
||||||
if (snID === myFloID)
|
if (snID === myFloID)
|
||||||
return reject(`Reached end of circle. Next node avaiable is self`)
|
return reject(`Reached end of circle. Next node avaiable is self`);
|
||||||
connectToNode(snID)
|
connectToNode(snID)
|
||||||
.then(ws => resolve(ws))
|
.then(ws => resolve(ws))
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
var next = reverse ? kBucket.prevNode(snID) : kBucket.nextNode(snID)
|
var next = (reverse ? kBucket.prevNode(snID) : kBucket.nextNode(snID));
|
||||||
connectToActiveNode(next, reverse)
|
connectToActiveNode(next, reverse)
|
||||||
.then(ws => resolve(ws))
|
.then(ws => resolve(ws))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//Connect to next available node
|
//Connect to next available node
|
||||||
function connectToNextNode() {
|
function connectToNextNode() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let nextNodeID = kBucket.nextNode(nodeID);
|
let nextNodeID = kBucket.nextNode(nodeID);
|
||||||
connectToActiveNode(nextNodeID).then(ws => {
|
connectToActiveNode(nextNodeID).then(ws => {
|
||||||
_nextNode.set(nextNodeID, ws)
|
_nextNode.set(nextNodeID, ws);
|
||||||
_nextNode.send(packet_.constuct({
|
_nextNode.send(packet_.constuct({
|
||||||
type: BACKUP_HANDSHAKE_INIT
|
type: BACKUP_HANDSHAKE_INIT
|
||||||
}));
|
}));
|
||||||
resolve("BACKUP_HANDSHAKE_INIT: " + nextNodeID)
|
resolve("BACKUP_HANDSHAKE_INIT: " + nextNodeID);
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function connectToAliveNodes(nodes = null) {
|
function connectToAliveNodes(nodes = null) {
|
||||||
if (!Array.isArray(nodes)) nodes = Object.keys(floGlobals.supernodes);
|
if (!Array.isArray(nodes)) nodes = Object.keys(floGlobals.supernodes);
|
||||||
@ -199,9 +199,9 @@ function connectToAliveNodes(nodes = null) {
|
|||||||
nodes.forEach((n, i) =>
|
nodes.forEach((n, i) =>
|
||||||
ws_connections[n] = (results.status === "fulfilled") ? results[i].value : null);
|
ws_connections[n] = (results.status === "fulfilled") ? results[i].value : null);
|
||||||
resolve(ws_connections);
|
resolve(ws_connections);
|
||||||
}).catch(error => reject(error))
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//Connect to all given nodes [Array] (Default: All super-nodes)
|
//Connect to all given nodes [Array] (Default: All super-nodes)
|
||||||
function connectToAllActiveNodes(nodes = null) {
|
function connectToAllActiveNodes(nodes = null) {
|
||||||
@ -212,9 +212,9 @@ function connectToAllActiveNodes(nodes = null) {
|
|||||||
nodes.forEach((n, i) =>
|
nodes.forEach((n, i) =>
|
||||||
ws_connections[n] = (results.status === "fulfilled") ? results[i].value : null);
|
ws_connections[n] = (results.status === "fulfilled") ? results[i].value : null);
|
||||||
resolve(ws_connections);
|
resolve(ws_connections);
|
||||||
}).catch(error => reject(error))
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//-----PROCESS TASKS-----
|
//-----PROCESS TASKS-----
|
||||||
|
|
||||||
@ -223,90 +223,90 @@ function processTaskFromNextNode(packet) {
|
|||||||
var {
|
var {
|
||||||
from,
|
from,
|
||||||
message
|
message
|
||||||
} = packet_.parse(packet)
|
} = packet_.parse(packet);
|
||||||
if (message) {
|
if (message) {
|
||||||
message.forEach(task => {
|
message.forEach(task => {
|
||||||
switch (task.type) {
|
switch (task.type) {
|
||||||
case RECONNECT_NEXT_NODE: //Triggered when a node inbetween is available
|
case RECONNECT_NEXT_NODE: //Triggered when a node inbetween is available
|
||||||
reconnectNextNode()
|
reconnectNextNode();
|
||||||
break;
|
break;
|
||||||
case BACKUP_HANDSHAKE_END:
|
case BACKUP_HANDSHAKE_END:
|
||||||
handshakeEnd()
|
handshakeEnd();
|
||||||
break;
|
break;
|
||||||
case DATA_REQUEST:
|
case DATA_REQUEST:
|
||||||
sendStoredData(task.nodes, _nextNode)
|
sendStoredData(task.nodes, _nextNode);
|
||||||
break;
|
break;
|
||||||
case DATA_SYNC:
|
case DATA_SYNC:
|
||||||
dataSyncIndication(task.id, task.status, from)
|
dataSyncIndication(task.id, task.status, from);
|
||||||
break;
|
break;
|
||||||
case STORE_BACKUP_DATA:
|
case STORE_BACKUP_DATA:
|
||||||
storeBackupData(task.data)
|
storeBackupData(task.data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Invalid task type:" + task.type + "from next-node")
|
console.log("Invalid task type:" + task.type + "from next-node");
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Tasks from prev-node
|
//Tasks from prev-node
|
||||||
function processTaskFromPrevNode(packet) {
|
function processTaskFromPrevNode(packet) {
|
||||||
var {
|
var {
|
||||||
from,
|
from,
|
||||||
message
|
message
|
||||||
} = packet_.parse(packet)
|
} = packet_.parse(packet);
|
||||||
if (message) {
|
if (message) {
|
||||||
message.forEach(task => {
|
message.forEach(task => {
|
||||||
switch (task.type) {
|
switch (task.type) {
|
||||||
case ORDER_BACKUP:
|
case ORDER_BACKUP:
|
||||||
orderBackup(task.order)
|
orderBackup(task.order);
|
||||||
break;
|
break;
|
||||||
case STORE_BACKUP_DATA:
|
case STORE_BACKUP_DATA:
|
||||||
storeBackupData(task.data, from, packet)
|
storeBackupData(task.data, from, packet);
|
||||||
break;
|
break;
|
||||||
case TAG_BACKUP_DATA:
|
case TAG_BACKUP_DATA:
|
||||||
tagBackupData(task.data, from, packet)
|
tagBackupData(task.data, from, packet);
|
||||||
break;
|
break;
|
||||||
case DATA_REQUEST:
|
case DATA_REQUEST:
|
||||||
sendStoredData(task.nodes, _prevNode)
|
sendStoredData(task.nodes, _prevNode);
|
||||||
break;
|
break;
|
||||||
case DATA_SYNC:
|
case DATA_SYNC:
|
||||||
dataSyncIndication(task.id, task.status, from)
|
dataSyncIndication(task.id, task.status, from);
|
||||||
break;
|
break;
|
||||||
case DELETE_MIGRATED_DATA:
|
case DELETE_MIGRATED_DATA:
|
||||||
deleteMigratedData(task.data, from, packet)
|
deleteMigratedData(task.data, from, packet);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Invalid task type:" + task.type + "from prev-node")
|
console.log("Invalid task type:" + task.type + "from prev-node");
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Tasks from any supernode
|
//Tasks from any supernode
|
||||||
function processTaskFromSupernode(packet, ws) {
|
function processTaskFromSupernode(packet, ws) {
|
||||||
var {
|
var {
|
||||||
from,
|
from,
|
||||||
message
|
message
|
||||||
} = packet_.parse(packet)
|
} = packet_.parse(packet);
|
||||||
if (message) {
|
if (message) {
|
||||||
message.forEach(task => {
|
message.forEach(task => {
|
||||||
switch (task.type) {
|
switch (task.type) {
|
||||||
case BACKUP_HANDSHAKE_INIT:
|
case BACKUP_HANDSHAKE_INIT:
|
||||||
handshakeMid(from, ws)
|
handshakeMid(from, ws);
|
||||||
break;
|
break;
|
||||||
case STORE_MIGRATED_DATA:
|
case STORE_MIGRATED_DATA:
|
||||||
storeMigratedData(task.data)
|
storeMigratedData(task.data);
|
||||||
break;
|
break;
|
||||||
case INITIATE_REFRESH:
|
case INITIATE_REFRESH:
|
||||||
initiateRefresh()
|
initiateRefresh();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("Invalid task type:" + task.type + "from super-node")
|
console.log("Invalid task type:" + task.type + "from super-node");
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//-----HANDSHAKE PROCESS-----
|
//-----HANDSHAKE PROCESS-----
|
||||||
|
|
||||||
@ -323,21 +323,21 @@ function handshakeMid(id, ws) {
|
|||||||
_prevNode.set(id, ws);
|
_prevNode.set(id, ws);
|
||||||
_prevNode.send(packet_.constuct({
|
_prevNode.send(packet_.constuct({
|
||||||
type: BACKUP_HANDSHAKE_END
|
type: BACKUP_HANDSHAKE_END
|
||||||
}))
|
}));
|
||||||
} else {
|
} else {
|
||||||
//Incorrect order, existing prev-node is already after the incoming node
|
//Incorrect order, existing prev-node is already after the incoming node
|
||||||
ws.send(packet_.constuct({
|
ws.send(packet_.constuct({
|
||||||
type: RECONNECT_NEXT_NODE
|
type: RECONNECT_NEXT_NODE
|
||||||
}))
|
}));
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
//set the new prev-node connection
|
//set the new prev-node connection
|
||||||
_prevNode.set(id, ws);
|
_prevNode.set(id, ws);
|
||||||
_prevNode.send(packet_.constuct({
|
_prevNode.send(packet_.constuct({
|
||||||
type: BACKUP_HANDSHAKE_END
|
type: BACKUP_HANDSHAKE_END
|
||||||
}))
|
}));
|
||||||
}
|
};
|
||||||
//Reorder storelist
|
//Reorder storelist
|
||||||
let nodes = kBucket.innerNodes(_prevNode.id, myFloID).concat(myFloID),
|
let nodes = kBucket.innerNodes(_prevNode.id, myFloID).concat(myFloID),
|
||||||
req_sync = [],
|
req_sync = [],
|
||||||
@ -351,19 +351,19 @@ function handshakeMid(id, ws) {
|
|||||||
default:
|
default:
|
||||||
_list[n] = 0;
|
_list[n] = 0;
|
||||||
new_order.push(n);
|
new_order.push(n);
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
if (!req_sync.length && !new_order.length)
|
if (!req_sync.length && !new_order.length)
|
||||||
return; //No order change and no need for any data sync
|
return; //No order change and no need for any data sync
|
||||||
else
|
else
|
||||||
handshakeMid.requestData(req_sync, new_order);
|
handshakeMid.requestData(req_sync, new_order);
|
||||||
}
|
};
|
||||||
|
|
||||||
handshakeMid.requestData = function(req_sync, new_order) {
|
handshakeMid.requestData = function(req_sync, new_order) {
|
||||||
if (handshakeMid.timeout) {
|
if (handshakeMid.timeout) {
|
||||||
clearTimeout(handshakeMid.timeout)
|
clearTimeout(handshakeMid.timeout);
|
||||||
delete handshakeMid.timeout;
|
delete handshakeMid.timeout;
|
||||||
}
|
};
|
||||||
Promise.allSettled(req_sync.map(n => DB.createGetLastLog(n))).then(result => {
|
Promise.allSettled(req_sync.map(n => DB.createGetLastLog(n))).then(result => {
|
||||||
let tasks = [],
|
let tasks = [],
|
||||||
lastlogs = {},
|
lastlogs = {},
|
||||||
@ -375,7 +375,7 @@ handshakeMid.requestData = function(req_sync, new_order) {
|
|||||||
if (result[i].status === "fulfilled")
|
if (result[i].status === "fulfilled")
|
||||||
lastlogs[s] = result[i].value;
|
lastlogs[s] = result[i].value;
|
||||||
else
|
else
|
||||||
failed.push(s)
|
failed.push(s);
|
||||||
});
|
});
|
||||||
if (Object.keys(lastlogs).length)
|
if (Object.keys(lastlogs).length)
|
||||||
tasks.push({
|
tasks.push({
|
||||||
@ -384,29 +384,29 @@ handshakeMid.requestData = function(req_sync, new_order) {
|
|||||||
});
|
});
|
||||||
new_order.forEach(n => {
|
new_order.forEach(n => {
|
||||||
if (failed.includes(n))
|
if (failed.includes(n))
|
||||||
failed_order.push(n)
|
failed_order.push(n);
|
||||||
else
|
else
|
||||||
order.push(n)
|
order.push(n);
|
||||||
});
|
});
|
||||||
if (order.length)
|
if (order.length)
|
||||||
tasks.push({
|
tasks.push({
|
||||||
type: ORDER_BACKUP,
|
type: ORDER_BACKUP,
|
||||||
order: _list.get(order)
|
order: _list.get(order)
|
||||||
})
|
});
|
||||||
_nextNode.send(packet_.constuct(tasks));
|
_nextNode.send(packet_.constuct(tasks));
|
||||||
if (failed.length)
|
if (failed.length)
|
||||||
handshakeMid.timeout = setTimeout(_ => handshakeMid.requestData(failed, failed_order), RETRY_TIMEOUT)
|
handshakeMid.timeout = setTimeout(_ => handshakeMid.requestData(failed, failed_order), RETRY_TIMEOUT);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//Complete handshake
|
//Complete handshake
|
||||||
function handshakeEnd() {
|
function handshakeEnd() {
|
||||||
console.log("Backup connected: " + _nextNode.id)
|
console.log("Backup connected: " + _nextNode.id);
|
||||||
_nextNode.send(packet_.constuct({
|
_nextNode.send(packet_.constuct({
|
||||||
type: ORDER_BACKUP,
|
type: ORDER_BACKUP,
|
||||||
order: _list.get()
|
order: _list.get()
|
||||||
}))
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
//Reconnect to next available node
|
//Reconnect to next available node
|
||||||
function reconnectNextNode() {
|
function reconnectNextNode() {
|
||||||
@ -420,9 +420,9 @@ function reconnectNextNode() {
|
|||||||
for (let sn in floGlobals.supernodes)
|
for (let sn in floGlobals.supernodes)
|
||||||
DB.createTable(sn)
|
DB.createTable(sn)
|
||||||
.then(result => _list[sn] = 0)
|
.then(result => _list[sn] = 0)
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//-----BACKUP TASKS-----
|
//-----BACKUP TASKS-----
|
||||||
|
|
||||||
@ -435,20 +435,20 @@ function orderBackup(order) {
|
|||||||
if (order[n] >= floGlobals.sn_config.backupDepth)
|
if (order[n] >= floGlobals.sn_config.backupDepth)
|
||||||
DB.dropTable(n).then(_ => null)
|
DB.dropTable(n).then(_ => null)
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
.finally(_ => _list.delete(n))
|
.finally(_ => _list.delete(n));
|
||||||
else if (_list[n] !== 0 || !cur_serve.includes(n)) {
|
else if (_list[n] !== 0 || !cur_serve.includes(n)) {
|
||||||
_list[n] = order[n] + 1;
|
_list[n] = order[n] + 1;
|
||||||
new_order.push(n);
|
new_order.push(n);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
if (new_order.length) {
|
if (new_order.length) {
|
||||||
_nextNode.send(packet_.constuct({
|
_nextNode.send(packet_.constuct({
|
||||||
type: ORDER_BACKUP,
|
type: ORDER_BACKUP,
|
||||||
order: _list.get(new_order)
|
order: _list.get(new_order)
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Send stored data
|
//Send stored data
|
||||||
function sendStoredData(lastlogs, node) {
|
function sendStoredData(lastlogs, node) {
|
||||||
@ -459,50 +459,48 @@ function sendStoredData(lastlogs, node) {
|
|||||||
type: DATA_SYNC,
|
type: DATA_SYNC,
|
||||||
id: n,
|
id: n,
|
||||||
status: true
|
status: true
|
||||||
}))
|
}));
|
||||||
console.info(`START: ${snID} data sync(send) to ${node.id}`)
|
console.info(`START: ${snID} data sync(send) to ${node.id}`);
|
||||||
//TODO: efficiently handle large number of data instead of loading all into memory
|
//TODO: efficiently handle large number of data instead of loading all into memory
|
||||||
result.forEach(d => node.send(packet_.constuct({
|
result.forEach(d => node.send(packet_.constuct({
|
||||||
type: STORE_BACKUP_DATA,
|
type: STORE_BACKUP_DATA,
|
||||||
data: d
|
data: d
|
||||||
})))
|
})));
|
||||||
console.info(`END: ${snID} data sync(send) to ${node.id}`)
|
console.info(`END: ${snID} data sync(send) to ${node.id}`);
|
||||||
node.send(packet_.constuct({
|
node.send(packet_.constuct({
|
||||||
type: DATA_SYNC,
|
type: DATA_SYNC,
|
||||||
id: n,
|
id: n,
|
||||||
status: false
|
status: false
|
||||||
}))
|
}));
|
||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error));
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Indicate sync of data
|
//Indicate sync of data
|
||||||
function dataSyncIndication(snID, status, from) {
|
function dataSyncIndication(snID, status, from) {
|
||||||
console.info(`${status ? 'START':'END'}: ${snID} data sync(receive) form ${from}`);
|
console.info(`${status ? 'START':'END'}: ${snID} data sync(receive) form ${from}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
//Store (backup) data
|
//Store (backup) data
|
||||||
function storeBackupData(data, from, packet) {
|
function storeBackupData(data, from, packet) {
|
||||||
let closestNode = kBucket.closestNode(data.receiverID);
|
let closestNode = kBucket.closestNode(data.receiverID);
|
||||||
if (_list.stored.includes(closestNode)) {
|
if (_list.stored.includes(closestNode)) {
|
||||||
DB.storeData(closestNode, data);
|
DB.storeData(closestNode, data);
|
||||||
if (_list[closestNode] < floGlobals.sn_config.backupDepth &&
|
if (_list[closestNode] < floGlobals.sn_config.backupDepth && _nextNode.id !== from)
|
||||||
_nextNode.id !== from)
|
|
||||||
_nextNode.send(packet);
|
_nextNode.send(packet);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Tag (backup) data
|
//Tag (backup) data
|
||||||
function tagBackupData(data, from, packet) {
|
function tagBackupData(data, from, packet) {
|
||||||
let closestNode = kBucket.closestNode(data.receiverID);
|
let closestNode = kBucket.closestNode(data.receiverID);
|
||||||
if (_list.stored.includes(closestNode)) {
|
if (_list.stored.includes(closestNode)) {
|
||||||
DB.storeTag(closestNode, data);
|
DB.storeTag(closestNode, data);
|
||||||
if (_list[closestNode] < floGlobals.sn_config.backupDepth &&
|
if (_list[closestNode] < floGlobals.sn_config.backupDepth && _nextNode.id !== from)
|
||||||
_nextNode.id !== from)
|
|
||||||
_nextNode.send(packet);
|
_nextNode.send(packet);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Store (migrated) data
|
//Store (migrated) data
|
||||||
function storeMigratedData(data) {
|
function storeMigratedData(data) {
|
||||||
@ -513,36 +511,35 @@ function storeMigratedData(data) {
|
|||||||
type: STORE_BACKUP_DATA,
|
type: STORE_BACKUP_DATA,
|
||||||
data: data
|
data: data
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
//Delete (migrated) data
|
//Delete (migrated) data
|
||||||
function deleteMigratedData(old_sn, vectorClock, receiverID, from, packet) {
|
function deleteMigratedData(old_sn, vectorClock, receiverID, from, packet) {
|
||||||
let closestNode = kBucket.closestNode(receiverID);
|
let closestNode = kBucket.closestNode(receiverID);
|
||||||
if (old_sn !== closestNode && _list.stored.includes(old_sn)) {
|
if (old_sn !== closestNode && _list.stored.includes(old_sn)) {
|
||||||
DB.deleteData(old_sn, vectorClock);
|
DB.deleteData(old_sn, vectorClock);
|
||||||
if (_list[old_sn] < floGlobals.sn_config.backupDepth &&
|
if (_list[old_sn] < floGlobals.sn_config.backupDepth && _nextNode.id !== from)
|
||||||
_nextNode.id !== from)
|
|
||||||
_nextNode.send(packet);
|
_nextNode.send(packet);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
function initiateRefresh() {
|
function initiateRefresh() {
|
||||||
refresher.invoke(false)
|
refresher.invoke(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
//Forward incoming to next node
|
//Forward incoming to next node
|
||||||
function forwardToNextNode(mode, data) {
|
function forwardToNextNode(mode, data) {
|
||||||
var modeMap = {
|
var modeMap = {
|
||||||
'TAG': TAG_BACKUP_DATA,
|
'TAG': TAG_BACKUP_DATA,
|
||||||
'DATA': STORE_BACKUP_DATA
|
'DATA': STORE_BACKUP_DATA
|
||||||
}
|
};
|
||||||
if (mode in modeMap && _nextNode.id)
|
if (mode in modeMap && _nextNode.id)
|
||||||
_nextNode.send(packet_.constuct({
|
_nextNode.send(packet_.constuct({
|
||||||
type: modeMap[mode],
|
type: modeMap[mode],
|
||||||
data: data
|
data: data
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
//Data migration processor
|
//Data migration processor
|
||||||
function dataMigration(node_change, flag) {
|
function dataMigration(node_change, flag) {
|
||||||
@ -557,28 +554,28 @@ function dataMigration(node_change, flag) {
|
|||||||
if (del_nodes.includes(_prevNode.id)) {
|
if (del_nodes.includes(_prevNode.id)) {
|
||||||
_list[_prevNode.id] = 0; //Temporary serve for the deleted node
|
_list[_prevNode.id] = 0; //Temporary serve for the deleted node
|
||||||
_prevNode.close();
|
_prevNode.close();
|
||||||
}
|
};
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
//reconnect next node if current next node is deleted
|
//reconnect next node if current next node is deleted
|
||||||
if (del_nodes.includes(_nextNode.id))
|
if (del_nodes.includes(_nextNode.id))
|
||||||
reconnectNextNode();
|
reconnectNextNode();
|
||||||
else { //reconnect next node if there are newly added nodes in between self and current next node
|
else { //reconnect next node if there are newly added nodes in between self and current next node
|
||||||
let innerNodes = kBucket.innerNodes(myFloID, _nextNode.id)
|
let innerNodes = kBucket.innerNodes(myFloID, _nextNode.id);
|
||||||
if (new_nodes.filter(n => innerNodes.includes(n)).length)
|
if (new_nodes.filter(n => innerNodes.includes(n)).length)
|
||||||
reconnectNextNode();
|
reconnectNextNode();
|
||||||
}
|
};
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
dataMigration.process_new(new_nodes);
|
dataMigration.process_new(new_nodes);
|
||||||
dataMigration.process_del(del_nodes);
|
dataMigration.process_del(del_nodes);
|
||||||
}, MIGRATE_WAIT_DELAY);
|
}, MIGRATE_WAIT_DELAY);
|
||||||
}, MIGRATE_WAIT_DELAY)
|
}, MIGRATE_WAIT_DELAY);
|
||||||
}
|
};
|
||||||
|
|
||||||
//data migration sub-process: Deleted nodes
|
//data migration sub-process: Deleted nodes
|
||||||
dataMigration.process_del = async function(del_nodes) {
|
dataMigration.process_del = async function(del_nodes) {
|
||||||
if (!del_nodes.length)
|
if (!del_nodes.length)
|
||||||
return;
|
return;
|
||||||
let process_nodes = del_nodes.filter(n => _list.serving.includes(n))
|
let process_nodes = del_nodes.filter(n => _list.serving.includes(n));
|
||||||
if (process_nodes.length) {
|
if (process_nodes.length) {
|
||||||
connectToAllActiveNodes().then(ws_connections => {
|
connectToAllActiveNodes().then(ws_connections => {
|
||||||
let remaining = process_nodes.length;
|
let remaining = process_nodes.length;
|
||||||
@ -599,30 +596,30 @@ dataMigration.process_del = async function(del_nodes) {
|
|||||||
type: STORE_MIGRATED_DATA,
|
type: STORE_MIGRATED_DATA,
|
||||||
data: d
|
data: d
|
||||||
}));
|
}));
|
||||||
})
|
});
|
||||||
console.info(`END: Data migration for ${n}`);
|
console.info(`END: Data migration for ${n}`);
|
||||||
_list.delete(n);
|
_list.delete(n);
|
||||||
DB.dropTable(n);
|
DB.dropTable(n);
|
||||||
remaining--;
|
remaining--;
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
if (remaining <= 0) {
|
if (remaining <= 0) {
|
||||||
for (let c in ws_connections)
|
for (let c in ws_connections)
|
||||||
if (ws_connections[c])
|
if (ws_connections[c])
|
||||||
ws_connections[c].close()
|
ws_connections[c].close();
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
};
|
||||||
}, RETRY_TIMEOUT);
|
}, RETRY_TIMEOUT);
|
||||||
}).catch(error => reject(error))
|
});
|
||||||
}
|
};
|
||||||
del_nodes.forEach(n => {
|
del_nodes.forEach(n => {
|
||||||
if (!process_nodes.includes(n) && _list.stored.includes(n)) {
|
if (!process_nodes.includes(n) && _list.stored.includes(n)) {
|
||||||
_list.delete(n);
|
_list.delete(n);
|
||||||
DB.dropTable(n);
|
DB.dropTable(n);
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//data migration sub-process: Added nodes
|
//data migration sub-process: Added nodes
|
||||||
dataMigration.process_new = async function(new_nodes) {
|
dataMigration.process_new = async function(new_nodes) {
|
||||||
@ -654,34 +651,34 @@ dataMigration.process_new = async function(new_nodes) {
|
|||||||
receiverID: d.receiverID,
|
receiverID: d.receiverID,
|
||||||
snID: n
|
snID: n
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
remaining--;
|
remaining--;
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
if (remaining <= 0) {
|
if (remaining <= 0) {
|
||||||
for (let c in ws_connections)
|
for (let c in ws_connections)
|
||||||
if (ws_connections[c])
|
if (ws_connections[c])
|
||||||
ws_connections[c].close()
|
ws_connections[c].close();
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
};
|
||||||
}, RETRY_TIMEOUT);
|
}, RETRY_TIMEOUT);
|
||||||
}).catch(error => reject(error))
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
dataMigration.intimateAllNodes = function() {
|
dataMigration.intimateAllNodes = function() {
|
||||||
connectToAliveNodes().then(ws_connections => {
|
connectToAliveNodes().then(ws_connections => {
|
||||||
let packet = packet_.constuct({
|
let packet = packet_.constuct({
|
||||||
type: INITIATE_REFRESH
|
type: INITIATE_REFRESH
|
||||||
})
|
});
|
||||||
for (let n in ws_connections)
|
for (let n in ws_connections)
|
||||||
if (ws_connections[n]) {
|
if (ws_connections[n]) {
|
||||||
ws_connections[n].send(packet)
|
ws_connections[n].send(packet);
|
||||||
ws_connections[n].close()
|
ws_connections[n].close();
|
||||||
}
|
};
|
||||||
}).catch(error => reject(error))
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
//-----EXPORTS-----
|
//-----EXPORTS-----
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -691,9 +688,9 @@ module.exports = {
|
|||||||
SUPERNODE_INDICATOR,
|
SUPERNODE_INDICATOR,
|
||||||
_list,
|
_list,
|
||||||
set DB(db) {
|
set DB(db) {
|
||||||
DB = db
|
DB = db;
|
||||||
},
|
},
|
||||||
set refresher(r) {
|
set refresher(r) {
|
||||||
refresher = r
|
refresher = r;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@ -1,24 +1,24 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
require('./lib/BuildKBucket')
|
require('./lib/BuildKBucket')
|
||||||
(function(GLOBAL) {
|
(function(GLOBAL) {
|
||||||
var kBucket = GLOBAL.kBucket = {}
|
var kBucket = GLOBAL.kBucket = {};
|
||||||
var SNKB, SNCO;
|
var SNKB, SNCO;
|
||||||
|
|
||||||
function decodeID(floID) {
|
function decodeID(floID) {
|
||||||
let k = bitjs.Base58.decode(floID)
|
let k = bitjs.Base58.decode(floID);
|
||||||
k.shift()
|
k.shift();
|
||||||
k.splice(-4, 4)
|
k.splice(-4, 4);
|
||||||
const decodedId = Crypto.util.bytesToHex(k);
|
const decodedId = Crypto.util.bytesToHex(k);
|
||||||
const nodeIdBigInt = new BigInteger(decodedId, 16);
|
const nodeIdBigInt = new BigInteger(decodedId, 16);
|
||||||
const nodeIdBytes = nodeIdBigInt.toByteArrayUnsigned();
|
const nodeIdBytes = nodeIdBigInt.toByteArrayUnsigned();
|
||||||
const nodeIdNewInt8Array = new Uint8Array(nodeIdBytes);
|
const nodeIdNewInt8Array = new Uint8Array(nodeIdBytes);
|
||||||
return nodeIdNewInt8Array;
|
return nodeIdNewInt8Array;
|
||||||
}
|
};
|
||||||
|
|
||||||
function distanceOf(floID) {
|
function distanceOf(floID) {
|
||||||
let decodedId = decodeID(floID);
|
let decodedId = decodeID(floID);
|
||||||
return SNKB.distance(SNKB.localNodeId, decodedId);
|
return SNKB.distance(SNKB.localNodeId, decodedId);
|
||||||
}
|
};
|
||||||
|
|
||||||
function constructKB(list, refID) {
|
function constructKB(list, refID) {
|
||||||
let KB = new BuildKBucket({
|
let KB = new BuildKBucket({
|
||||||
@ -29,7 +29,7 @@ require('./lib/BuildKBucket')
|
|||||||
floID: floID
|
floID: floID
|
||||||
}));
|
}));
|
||||||
return KB;
|
return KB;
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.launch = function() {
|
kBucket.launch = function() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -39,73 +39,73 @@ require('./lib/BuildKBucket')
|
|||||||
SNKB = constructKB(superNodeList, masterID);
|
SNKB = constructKB(superNodeList, masterID);
|
||||||
SNCO = superNodeList.map(sn => [distanceOf(sn), sn])
|
SNCO = superNodeList.map(sn => [distanceOf(sn), sn])
|
||||||
.sort((a, b) => a[0] - b[0])
|
.sort((a, b) => a[0] - b[0])
|
||||||
.map(a => a[1])
|
.map(a => a[1]);
|
||||||
resolve('SuperNode KBucket formed');
|
resolve('SuperNode KBucket formed');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.innerNodes = function(id1, id2) {
|
kBucket.innerNodes = function(id1, id2) {
|
||||||
if (!SNCO.includes(id1) || !SNCO.includes(id2))
|
if (!SNCO.includes(id1) || !SNCO.includes(id2))
|
||||||
throw Error('Given nodes are not supernode');
|
throw Error('Given nodes are not supernode');
|
||||||
let iNodes = []
|
let iNodes = [];
|
||||||
for (let i = SNCO.indexOf(id1) + 1; SNCO[i] != id2; i++) {
|
for (let i = SNCO.indexOf(id1) + 1; SNCO[i] != id2; i++) {
|
||||||
if (i < SNCO.length)
|
if (i < SNCO.length)
|
||||||
iNodes.push(SNCO[i])
|
iNodes.push(SNCO[i]);
|
||||||
else i = -1
|
else i = -1;
|
||||||
}
|
};
|
||||||
return iNodes
|
return iNodes;
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.outterNodes = function(id1, id2) {
|
kBucket.outterNodes = function(id1, id2) {
|
||||||
if (!SNCO.includes(id1) || !SNCO.includes(id2))
|
if (!SNCO.includes(id1) || !SNCO.includes(id2))
|
||||||
throw Error('Given nodes are not supernode');
|
throw Error('Given nodes are not supernode');
|
||||||
let oNodes = []
|
let oNodes = [];
|
||||||
for (let i = SNCO.indexOf(id2) + 1; SNCO[i] != id1; i++) {
|
for (let i = SNCO.indexOf(id2) + 1; SNCO[i] != id1; i++) {
|
||||||
if (i < SNCO.length)
|
if (i < SNCO.length)
|
||||||
oNodes.push(SNCO[i])
|
oNodes.push(SNCO[i]);
|
||||||
else i = -1
|
else i = -1;
|
||||||
}
|
};
|
||||||
return oNodes
|
return oNodes;
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.prevNode = function(id, N = 1) {
|
kBucket.prevNode = function(id, N = 1) {
|
||||||
let n = N || SNCO.length;
|
let n = N || SNCO.length;
|
||||||
if (!SNCO.includes(id))
|
if (!SNCO.includes(id))
|
||||||
throw Error('Given node is not supernode');
|
throw Error('Given node is not supernode');
|
||||||
let pNodes = []
|
let pNodes = [];
|
||||||
for (let i = 0, j = SNCO.indexOf(id) - 1; i < n; j--) {
|
for (let i = 0, j = SNCO.indexOf(id) - 1; i < n; j--) {
|
||||||
if (j == SNCO.indexOf(id))
|
if (j == SNCO.indexOf(id))
|
||||||
break;
|
break;
|
||||||
else if (j > -1)
|
else if (j > -1)
|
||||||
pNodes[i++] = SNCO[j]
|
pNodes[i++] = SNCO[j];
|
||||||
else j = SNCO.length
|
else j = SNCO.length;
|
||||||
}
|
};
|
||||||
return (N == 1 ? pNodes[0] : pNodes)
|
return (N == 1 ? pNodes[0] : pNodes);
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.nextNode = function(id, N = 1) {
|
kBucket.nextNode = function(id, N = 1) {
|
||||||
let n = N || SNCO.length;
|
let n = N || SNCO.length;
|
||||||
if (!SNCO.includes(id))
|
if (!SNCO.includes(id))
|
||||||
throw Error('Given node is not supernode');
|
throw Error('Given node is not supernode');
|
||||||
let nNodes = []
|
let nNodes = [];
|
||||||
for (let i = 0, j = SNCO.indexOf(id) + 1; i < n; j++) {
|
for (let i = 0, j = SNCO.indexOf(id) + 1; i < n; j++) {
|
||||||
if (j == SNCO.indexOf(id))
|
if (j == SNCO.indexOf(id))
|
||||||
break;
|
break;
|
||||||
else if (j < SNCO.length)
|
else if (j < SNCO.length)
|
||||||
nNodes[i++] = SNCO[j]
|
nNodes[i++] = SNCO[j];
|
||||||
else j = -1
|
else j = -1;
|
||||||
}
|
};
|
||||||
return (N == 1 ? nNodes[0] : nNodes)
|
return (N == 1 ? nNodes[0] : nNodes);
|
||||||
}
|
};
|
||||||
|
|
||||||
kBucket.closestNode = function(id, N = 1) {
|
kBucket.closestNode = function(id, N = 1) {
|
||||||
let decodedId = decodeID(id);
|
let decodedId = decodeID(id);
|
||||||
let n = N || SNCO.length;
|
let n = N || SNCO.length;
|
||||||
let cNodes = SNKB.closest(decodedId, n)
|
let cNodes = SNKB.closest(decodedId, n)
|
||||||
.map(k => k.floID)
|
.map(k => k.floID);
|
||||||
return (N == 1 ? cNodes[0] : cNodes)
|
return (N == 1 ? cNodes[0] : cNodes);
|
||||||
}
|
};
|
||||||
})(typeof global !== "undefined" ? global : window)
|
})(typeof global !== "undefined" ? global : window);
|
||||||
106
src/main.js
106
src/main.js
@ -1,24 +1,26 @@
|
|||||||
const config = require("../config.json")
|
const config = require("../config.json");
|
||||||
global.floGlobals = require("./floGlobals")
|
global.floGlobals = require("./floGlobals");
|
||||||
require('./set_globals')
|
require('./set_globals');
|
||||||
require('./lib')
|
require('./lib');
|
||||||
require('./kBucket')
|
require('./kBucket');
|
||||||
require('./floCrypto')
|
require('./floCrypto');
|
||||||
require('./floBlockchainAPI')
|
require('./floBlockchainAPI');
|
||||||
const Database = require("./database")
|
const Database = require("./database");
|
||||||
const intra = require('./intra')
|
const intra = require('./intra');
|
||||||
const client = require('./client')
|
const client = require('./client');
|
||||||
const Server = require('./server')
|
const Server = require('./server');
|
||||||
|
|
||||||
var DB; //Container for Database object
|
var DB; //Container for Database object
|
||||||
|
|
||||||
function startNode() {
|
function startNode() {
|
||||||
//Set myPrivKey, myPubKey, myFloID
|
//Set myPrivKey, myPubKey, myFloID
|
||||||
global.myPrivKey = config["privateKey"]
|
global.myPrivKey = config["privateKey"];
|
||||||
global.myPubKey = floCrypto.getPubKeyHex(config["privateKey"])
|
global.myPubKey = floCrypto.getPubKeyHex(config["privateKey"]);
|
||||||
global.myFloID = floCrypto.getFloID(config["privateKey"])
|
global.myFloID = floCrypto.getFloID(config["privateKey"]);
|
||||||
|
console.info("Logged In as " + myFloID);
|
||||||
//DB connect
|
//DB connect
|
||||||
Database(config["sql_user"], config["sql_pwd"], config["sql_db"], config["sql_host"]).then(db => {
|
Database(config["sql_user"], config["sql_pwd"], config["sql_db"], config["sql_host"]).then(db => {
|
||||||
|
console.info("Connected to Database");
|
||||||
DB = db;
|
DB = db;
|
||||||
//Set DB to client and intra scripts
|
//Set DB to client and intra scripts
|
||||||
intra.DB = DB;
|
intra.DB = DB;
|
||||||
@ -36,19 +38,19 @@ function startNode() {
|
|||||||
const server = new Server(config["port"], client, intra);
|
const server = new Server(config["port"], client, intra);
|
||||||
server.refresher = refreshData;
|
server.refresher = refreshData;
|
||||||
intra.refresher = refreshData;
|
intra.refresher = refreshData;
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
}
|
};
|
||||||
|
|
||||||
function loadBase(DB) {
|
function loadBase(DB) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.createBase().then(result => {
|
DB.createBase().then(result => {
|
||||||
DB.getBase(DB)
|
DB.getBase(DB)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const refreshData = {
|
const refreshData = {
|
||||||
count: null,
|
count: null,
|
||||||
@ -56,33 +58,33 @@ const refreshData = {
|
|||||||
invoke(flag = true) {
|
invoke(flag = true) {
|
||||||
this.count = floGlobals.sn_config.refreshDelay;
|
this.count = floGlobals.sn_config.refreshDelay;
|
||||||
refreshBlockchainData(this.base, flag).then(result => {
|
refreshBlockchainData(this.base, flag).then(result => {
|
||||||
console.log(result)
|
console.log(result);
|
||||||
diskCleanUp(this.base)
|
diskCleanUp(this.base)
|
||||||
.then(result => console.info(result))
|
.then(result => console.info(result))
|
||||||
.catch(warn => console.warn(warn))
|
.catch(warn => console.warn(warn));
|
||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error));
|
||||||
},
|
},
|
||||||
get countdown() {
|
get countdown() {
|
||||||
this.count--;
|
this.count--;
|
||||||
if (this.count <= 0)
|
if (this.count <= 0)
|
||||||
this.invoke();
|
this.invoke();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
function refreshBlockchainData(base, flag) {
|
function refreshBlockchainData(base, flag) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
readSupernodeConfigFromAPI(base, flag).then(result => {
|
readSupernodeConfigFromAPI(base, flag).then(result => {
|
||||||
console.log(result)
|
console.log(result);
|
||||||
kBucket.launch().then(result => {
|
kBucket.launch().then(result => {
|
||||||
console.log(result)
|
console.log(result);
|
||||||
readAppSubAdminListFromAPI(base)
|
readAppSubAdminListFromAPI(base)
|
||||||
.then(result => console.log(result))
|
.then(result => console.log(result))
|
||||||
.catch(warn => console.warn(warn))
|
.catch(warn => console.warn(warn))
|
||||||
.finally(_ => resolve("Refreshed Data from blockchain"))
|
.finally(_ => resolve("Refreshed Data from blockchain"));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function readSupernodeConfigFromAPI(base, flag) {
|
function readSupernodeConfigFromAPI(base, flag) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -92,7 +94,7 @@ function readSupernodeConfigFromAPI(base, flag) {
|
|||||||
pattern: "SuperNodeStorage"
|
pattern: "SuperNodeStorage"
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
let promises = [],
|
let promises = [],
|
||||||
node_change = {}
|
node_change = {};
|
||||||
result.data.reverse().forEach(data => {
|
result.data.reverse().forEach(data => {
|
||||||
var content = JSON.parse(data).SuperNodeStorage;
|
var content = JSON.parse(data).SuperNodeStorage;
|
||||||
if (content.removeNodes)
|
if (content.removeNodes)
|
||||||
@ -103,7 +105,7 @@ function readSupernodeConfigFromAPI(base, flag) {
|
|||||||
delete node_change[sn];
|
delete node_change[sn];
|
||||||
else
|
else
|
||||||
node_change[sn] = false;
|
node_change[sn] = false;
|
||||||
}
|
};
|
||||||
if (content.newNodes)
|
if (content.newNodes)
|
||||||
for (let sn in content.newNodes) {
|
for (let sn in content.newNodes) {
|
||||||
promises.push(DB.addSuperNode(sn, content.newNodes[sn].pubKey, content.newNodes[sn].uri));
|
promises.push(DB.addSuperNode(sn, content.newNodes[sn].pubKey, content.newNodes[sn].uri));
|
||||||
@ -115,22 +117,22 @@ function readSupernodeConfigFromAPI(base, flag) {
|
|||||||
delete node_change[sn];
|
delete node_change[sn];
|
||||||
else
|
else
|
||||||
node_change[sn] = true;
|
node_change[sn] = true;
|
||||||
}
|
};
|
||||||
if (content.config)
|
if (content.config)
|
||||||
for (let c in content.config) {
|
for (let c in content.config) {
|
||||||
promises.push(DB.setConfig(c, content.config[c]));
|
promises.push(DB.setConfig(c, content.config[c]));
|
||||||
base.sn_config[c] = content.config[c];
|
base.sn_config[c] = content.config[c];
|
||||||
}
|
};
|
||||||
if (content.removeApps)
|
if (content.removeApps)
|
||||||
for (let app of content.removeApps) {
|
for (let app of content.removeApps) {
|
||||||
promises.push(DB.rmApp(app));
|
promises.push(DB.rmApp(app));
|
||||||
delete base.appList;
|
delete base.appList;
|
||||||
}
|
};
|
||||||
if (content.addApps)
|
if (content.addApps)
|
||||||
for (let app in content.addApps) {
|
for (let app in content.addApps) {
|
||||||
promises.push(DB.addApp(app, content.addApps[app]));
|
promises.push(DB.addApp(app, content.addApps[app]));
|
||||||
base.appList[app] = content.addApps[app];
|
base.appList[app] = content.addApps[app];
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
promises.push(DB.setLastTx(floGlobals.SNStorageID, result.totalTxs));
|
promises.push(DB.setLastTx(floGlobals.SNStorageID, result.totalTxs));
|
||||||
//Check if all save process were successful
|
//Check if all save process were successful
|
||||||
@ -142,11 +144,11 @@ function readSupernodeConfigFromAPI(base, flag) {
|
|||||||
});
|
});
|
||||||
//Process data migration if nodes are changed
|
//Process data migration if nodes are changed
|
||||||
if (Object.keys(node_change))
|
if (Object.keys(node_change))
|
||||||
intra.dataMigration(node_change, flag)
|
intra.dataMigration(node_change, flag);
|
||||||
resolve('Updated Supernode Configuration');
|
resolve('Updated Supernode Configuration');
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function readAppSubAdminListFromAPI(base) {
|
function readAppSubAdminListFromAPI(base) {
|
||||||
var promises = [];
|
var promises = [];
|
||||||
@ -175,9 +177,9 @@ function readAppSubAdminListFromAPI(base) {
|
|||||||
console.warn(`SubAdmin list for app(${app}) might not have been saved in database`);
|
console.warn(`SubAdmin list for app(${app}) might not have been saved in database`);
|
||||||
});
|
});
|
||||||
resolve("Loaded subAdmin List for APP:" + app);
|
resolve("Loaded subAdmin List for APP:" + app);
|
||||||
}).catch(error => reject([app, error]))
|
}).catch(error => reject([app, error]));
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Promise.allSettled(promises).then(results => {
|
Promise.allSettled(promises).then(results => {
|
||||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0)) {
|
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0)) {
|
||||||
@ -187,8 +189,8 @@ function readAppSubAdminListFromAPI(base) {
|
|||||||
} else
|
} else
|
||||||
resolve("Loaded subAdmin List for all APPs successfully");
|
resolve("Loaded subAdmin List for all APPs successfully");
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function diskCleanUp(base) {
|
function diskCleanUp(base) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -201,18 +203,18 @@ function diskCleanUp(base) {
|
|||||||
//for each authorised app: delete unofficial data (untaged, unknown sender/receiver)
|
//for each authorised app: delete unofficial data (untaged, unknown sender/receiver)
|
||||||
for (let app in base.appList)
|
for (let app in base.appList)
|
||||||
promises.push(DB.clearAuthorisedAppData(sn, app, base.appList[app], base.subAdmins[app], time));
|
promises.push(DB.clearAuthorisedAppData(sn, app, base.appList[app], base.subAdmins[app], time));
|
||||||
})
|
});
|
||||||
|
|
||||||
Promise.allSettled(promises).then(results => {
|
Promise.allSettled(promises).then(results => {
|
||||||
let failed = results.filter(r => r.status === "rejected").map(r => r.reason)
|
let failed = results.filter(r => r.status === "rejected").map(r => r.reason);
|
||||||
if (failed.length) {
|
if (failed.length) {
|
||||||
console.error(JSON.stringify(failed));
|
console.error(JSON.stringify(failed));
|
||||||
let success = results.length - failed.length;
|
let success = results.length - failed.length;
|
||||||
reject(`Disk clean-up process has failed at ${100 * success/results.length}%. (Success:${success}|Failed:${failed.count})`)
|
reject(`Disk clean-up process has failed at ${100 * success/results.length}%. (Success:${success}|Failed:${failed.count})`);
|
||||||
} else
|
} else
|
||||||
resolve("Disk clean-up process finished successfully (100%)");
|
resolve("Disk clean-up process finished successfully (100%)");
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = startNode;
|
module.exports = startNode;
|
||||||
@ -1,5 +1,5 @@
|
|||||||
const http = require('http')
|
const http = require('http');
|
||||||
const WebSocket = require('ws')
|
const WebSocket = require('ws');
|
||||||
|
|
||||||
module.exports = function Server(port, client, intra) {
|
module.exports = function Server(port, client, intra) {
|
||||||
|
|
||||||
@ -14,13 +14,12 @@ module.exports = function Server(port, client, intra) {
|
|||||||
var request = JSON.parse(req.url.substring(i));
|
var request = JSON.parse(req.url.substring(i));
|
||||||
client.processRequestFromUser(request)
|
client.processRequestFromUser(request)
|
||||||
.then(result => res.end(JSON.parse(result[0])))
|
.then(result => res.end(JSON.parse(result[0])))
|
||||||
.catch(error => res.end(error.toString()))
|
.catch(error => res.end(error.toString()));
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
}
|
} else if (req.method === "POST") {
|
||||||
if (req.method === "POST") {
|
|
||||||
let data = '';
|
let data = '';
|
||||||
req.on('data', chunk => data += chunk)
|
req.on('data', chunk => data += chunk);
|
||||||
req.on('end', () => {
|
req.on('end', () => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
//process the data storing
|
//process the data storing
|
||||||
@ -29,17 +28,17 @@ module.exports = function Server(port, client, intra) {
|
|||||||
if (result[1]) {
|
if (result[1]) {
|
||||||
refresher.countdown;
|
refresher.countdown;
|
||||||
if (result[1] === 'DATA')
|
if (result[1] === 'DATA')
|
||||||
sendToLiveRequests(result[0])
|
sendToLiveRequests(result[0]);
|
||||||
intra.forwardToNextNode(result[1], result[0])
|
intra.forwardToNextNode(result[1], result[0]);
|
||||||
}
|
};
|
||||||
}).catch(error => res.end(error.toString()))
|
}).catch(error => res.end(error.toString()));
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
server.listen(port, (err) => {
|
server.listen(port, (err) => {
|
||||||
if (!err)
|
if (!err)
|
||||||
console.log(`Server running at port ${port}`);
|
console.log(`Server running at port ${port}`);
|
||||||
})
|
});
|
||||||
|
|
||||||
const wsServer = new WebSocket.Server({
|
const wsServer = new WebSocket.Server({
|
||||||
server
|
server
|
||||||
@ -53,14 +52,14 @@ module.exports = function Server(port, client, intra) {
|
|||||||
var request = JSON.parse(message);
|
var request = JSON.parse(message);
|
||||||
client.processRequestFromUser(JSON.parse(message))
|
client.processRequestFromUser(JSON.parse(message))
|
||||||
.then(result => {
|
.then(result => {
|
||||||
ws.send(JSON.parse(result[0]))
|
ws.send(JSON.parse(result[0]));
|
||||||
ws._liveReq = request;
|
ws._liveReq = request;
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (floGlobals.sn_config.errorFeedback)
|
if (floGlobals.sn_config.errorFeedback)
|
||||||
ws.send(error.toString())
|
ws.send(error.toString());
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
Object.defineProperty(this, "http", {
|
Object.defineProperty(this, "http", {
|
||||||
@ -71,5 +70,5 @@ module.exports = function Server(port, client, intra) {
|
|||||||
});
|
});
|
||||||
Object.defineProperty(this, "refresher", {
|
Object.defineProperty(this, "refresher", {
|
||||||
set: (r) => refresher = r
|
set: (r) => refresher = r
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
@ -3,6 +3,6 @@
|
|||||||
global.fetch = require("node-fetch");
|
global.fetch = require("node-fetch");
|
||||||
|
|
||||||
//Set browser paramaters from param.json
|
//Set browser paramaters from param.json
|
||||||
const param = require('../param.json')
|
const param = require('../param.json');
|
||||||
for(let p in param)
|
for(let p in param)
|
||||||
global[p] = param[p];
|
global[p] = param[p];
|
||||||
Loading…
Reference in New Issue
Block a user