update stdop and beautify

This commit is contained in:
sairajzero 2020-09-07 21:27:34 +05:30
parent 1e57f4f6ab
commit 0bdf806d36

View File

@ -7624,25 +7624,35 @@ Bitcoin.Util = {
//Returns public-key from private-key //Returns public-key from private-key
getPubKeyHex: function (privateKeyHex) { getPubKeyHex: function (privateKeyHex) {
if (!privateKeyHex)
return null;
var key = new Bitcoin.ECKey(privateKeyHex); var key = new Bitcoin.ECKey(privateKeyHex);
if (key.priv == null) { if (key.priv == null)
alert("Invalid Private key"); return null;
return;
}
key.setCompressed(true); key.setCompressed(true);
var pubkeyHex = key.getPubKeyHex(); var pubkeyHex = key.getPubKeyHex();
return pubkeyHex; return pubkeyHex;
}, },
//Returns flo-ID from public-key //Returns flo-ID from public-key or private-key
getFloIDfromPubkeyHex: function (pubkeyHex) { getFloID: function (keyHex) {
var key = new Bitcoin.ECKey().setPub(pubkeyHex); if(!pubkeyHex)
return null;
try {
var key = new Bitcoin.ECKey(privateKeyHex);
if (key.priv == null)
key.setPub(pubkeyHex);
var floID = key.getBitcoinAddress(); var floID = key.getBitcoinAddress();
return floID; return floID;
} catch (e) {
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
verifyPrivKey: function (privateKeyHex, pubKey_floID, isfloID = true) { verifyPrivKey: function (privateKeyHex, pubKey_floID, isfloID = true) {
if(!privateKeyHex || !pubKey_floID)
return false;
try { try {
var key = new Bitcoin.ECKey(privateKeyHex); var key = new Bitcoin.ECKey(privateKeyHex);
if (key.priv == null) if (key.priv == null)
@ -7661,6 +7671,8 @@ Bitcoin.Util = {
//Check if the given Address is valid or not //Check if the given Address is valid or not
validateAddr: function (inpAddr) { validateAddr: function (inpAddr) {
if(!inpAddr)
return false;
try { try {
var addr = new Bitcoin.Address(inpAddr); var addr = new Bitcoin.Address(inpAddr);
return true; return true;
@ -7698,7 +7710,7 @@ Bitcoin.Util = {
} }
return false; return false;
} catch { } catch {
return false return false;
} }
} }
} }
@ -7745,7 +7757,7 @@ Bitcoin.Util = {
//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));
@ -7762,22 +7774,24 @@ Bitcoin.Util = {
}, },
//Write Data into blockchain //Write Data into blockchain
writeData: function (senderAddr, Data, PrivKey, receiverAddr = floGlobals.adminID) { writeData: function (senderAddr, data, privKey, receiverAddr = floGlobals.adminID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.sendTx(senderAddr, receiverAddr, floGlobals.sendAmt, PrivKey, Data) if (typeof data != "string")
data = JSON.stringify(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))
}); });
}, },
//Send Tx to blockchain //Send Tx to blockchain
sendTx: function (senderAddr, receiverAddr, sendAmt, PrivKey, floData = '') { sendTx: function (senderAddr, receiverAddr, sendAmt, privKey, floData = '') {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(senderAddr)) if (!floCrypto.validateAddr(senderAddr))
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)) 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}`);
@ -7801,8 +7815,8 @@ Bitcoin.Util = {
var change = utxoAmt - sendAmt - fee; var change = utxoAmt - sendAmt - fee;
if (change > 0) if (change > 0)
trx.addoutput(senderAddr, change); trx.addoutput(senderAddr, change);
trx.addflodata(floData); 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))
@ -7812,11 +7826,237 @@ Bitcoin.Util = {
}); });
}, },
//merge all UTXOs of a given floID into a single UTXO
mergeUTXOs: function (floID, privKey, floData = '') {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(`Invalid floID`);
if (!floCrypto.verifyPrivKey(privKey, floID))
return reject("Invalid Private Key")
var trx = bitjs.transaction();
var utxoAmt = 0.0;
var fee = floGlobals.fee;
this.promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
for (var i = utxos.length - 1; i >= 0; i--) {
if (utxos[i].confirmations) {
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i]
.scriptPubKey)
utxoAmt += utxos[i].amount;
}
}
trx.addoutput(floID, utxoAmt - fee);
trx.addflodata(floData.replace(/\n/g, ' '));
var signedTxHash = trx.sign(privKey, 1);
this.broadcastTx(signedTxHash)
.then(txid => resolve(txid))
.catch(error => reject(error))
}).catch(error => reject(error))
})
},
/**Write data into blockchain from (and/or) to multiple floID
* @param {Array} senderPrivKeys List of sender private-keys
* @param {string} data FLO data of the txn
* @param {Array} receivers List of receivers
* @param {boolean} preserveRatio (optional) preserve ratio or equal contribution
* @return {Promise}
*/
writeDataMultiple: function (senderPrivKeys, data, receivers = [floGlobals.adminID], preserveRatio = true) {
return new Promise((resolve, reject) => {
if (!Array.isArray(senderPrivKeys))
return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array")
if (!preserveRatio) {
let tmp = {};
let amount = (floGlobals.sendAmt * receivers.length) / senderPrivKeys.length;
senderPrivKeys.forEach(key => tmp[key] = amount);
senderPrivKeys = tmp
}
if (!Array.isArray(receivers))
return reject("Invalid receivers: Receivers must be Array")
else {
let tmp = {};
let amount = floGlobals.sendAmt;
receivers.forEach(floID => tmp[floID] = amount);
receivers = tmp
}
if (typeof data != "string")
data = JSON.stringify(data);
this.sendTxMultiple(senderPrivKeys, receivers, data)
.then(txid => resolve(txid))
.catch(error => reject(error))
})
},
/**Send Tx from (and/or) to multiple floID
* @param {Array or Object} senderPrivKeys List of sender private-key (optional: with coins to be sent)
* @param {Object} receivers List of receivers with respective amount to be sent
* @param {string} floData FLO data of the txn
* @return {Promise}
*/
sendTxMultiple: function (senderPrivKeys, receivers, floData = '') {
return new Promise((resolve, reject) => {
let senders = {},
preserveRatio;
//check for argument validations
try {
let invalids = {
InvalidSenderPrivKeys: [],
InvalidSenderAmountFor: [],
InvalidReceiverIDs: [],
InvalidReceiveAmountFor: []
}
let inputVal = 0,
outputVal = 0;
//Validate sender privatekeys (and send amount if passed)
//conversion when only privateKeys are passed (preserveRatio mode)
if (Array.isArray(senderPrivKeys)) {
senderPrivKeys.forEach(key => {
try {
if (!key)
invalids.InvalidSenderPrivKeys.push(key);
else {
let floID = floCrypto.getFloID(key);
senders[floID] = {
wif: key
}
}
} catch (error) {
invalids.InvalidSenderPrivKeys.push(key)
}
})
preserveRatio = true;
}
//conversion when privatekeys are passed with send amount
else {
for (let key in senderPrivKeys) {
try {
if (!key)
invalids.InvalidSenderPrivKeys.push(key);
else {
if (typeof senderPrivKeys[key] !== 'number' || senderPrivKeys[
key] <= 0)
invalids.InvalidSenderAmountFor.push(key)
else
inputVal += senderPrivKeys[key];
let floID = floCrypto.getFloID(key);
senders[floID] = {
wif: key,
coins: senderPrivKeys[key]
}
}
} catch (error) {
invalids.InvalidSenderPrivKeys.push(key)
}
}
preserveRatio = false;
}
//Validate the receiver IDs and receive amount
for (let floID in receivers) {
if (!floCrypto.validateAddr(floID))
invalids.InvalidReceiverIDs.push(floID)
if (typeof receivers[floID] !== 'number' || receivers[floID] <= 0)
invalids.InvalidReceiveAmountFor.push(floID)
else
outputVal += receivers[floID];
}
//Reject if any invalids are found
for (let i in invalids)
if (!invalids[i].length)
delete invalids[i];
if (Object.keys(invalids).length)
return reject(invalids);
//Reject if given inputVal and outputVal are not equal
if (!preserveRatio && inputVal != outputVal)
return reject(
`Input Amount (${inputVal}) not equal to Output Amount (${outputVal})`)
} catch (error) {
return reject(error)
}
//Get balance of senders
let promises = []
for (let floID in senders)
promises.push(this.getBalance(floID))
Promise.all(promises).then(results => {
let totalBalance = 0,
totalFee = floGlobals.fee,
balance = {};
//Divide fee among sender if not for preserveRatio
if (!preserveRatio)
var dividedFee = totalFee / Object.keys(senders).length;
//Check if balance of each sender is sufficient enough
let insufficient = [];
for (let floID in senders) {
balance[floID] = parseFloat(results.shift());
if (isNaN(balance[floID]) || (preserveRatio && balance[floID] <=
totalFee) || (!preserveRatio && balance[floID] < senders[floID]
.coins + dividedFee))
insufficient.push(floID)
totalBalance += balance[floID];
}
if (insufficient.length)
return reject({
InsufficientBalance: insufficient
})
//Calculate totalSentAmount and check if totalBalance is sufficient
let totalSendAmt = totalFee;
for (floID in receivers)
totalSendAmt += receivers[floID];
if (totalBalance < totalSendAmt)
return reject("Insufficient total Balance")
//Get the UTXOs of the senders
let promises = []
for (floID in senders)
promises.push(this.promisedAPI(`api/addr/${floID}/utxo`))
Promise.all(promises).then(results => {
let wifSeq = [];
var trx = bitjs.transaction();
for (floID in senders) {
let utxos = results.shift();
let sendAmt;
if (preserveRatio) {
let ratio = (balance[floID] / totalBalance);
sendAmt = totalSendAmt * ratio;
} else
sendAmt = senders[floID].coins + dividedFee;
let wif = senders[floID].wif;
let utxoAmt = 0.0;
for (let i = utxos.length - 1;
(i >= 0) && (utxoAmt < sendAmt); i--) {
if (utxos[i].confirmations) {
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i]
.scriptPubKey)
wifSeq.push(wif);
utxoAmt += utxos[i].amount;
}
}
if (utxoAmt < sendAmt)
return reject("Insufficient balance:" + floID);
let change = (utxoAmt - sendAmt);
if (change > 0)
trx.addoutput(floID, change);
}
for (floID in receivers)
trx.addoutput(floID, receivers[floID]);
trx.addflodata(floData.replace(/\n/g, ' '));
for (let i = 0; i < wifSeq.length; i++)
trx.signinput(i, wifSeq[i], 1);
var signedTxHash = trx.serialize();
this.broadcastTx(signedTxHash)
.then(txid => resolve(txid))
.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
broadcastTx: function (signedTxHash) { broadcastTx: function (signedTxHash) {
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)
if (signedTxHash.length < 1) if (signedTxHash.length < 1)
reject("Empty Signature"); reject("Empty Signature");
else { else {
@ -7866,7 +8106,7 @@ Bitcoin.Util = {
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 | 1000 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 => {
@ -7881,13 +8121,17 @@ Bitcoin.Util = {
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 && !response.items[i].floData if (options.pattern) {
.startsWith(options.pattern, 0) && !response.items[i] try {
.floData.startsWith(options.pattern, 2)) let jsonContent = JSON.parse(response.items[i]
.floData)
if (!Object.keys(jsonContent).includes(options
.pattern))
continue; continue;
if (options.contains && !response.items[i].floData.includes( } catch (error) {
options.contains))
continue; continue;
}
}
if (options.filter && !options.filter(response.items[i] if (options.filter && !options.filter(response.items[i]
.floData)) .floData))
continue; continue;
@ -8097,7 +8341,7 @@ Bitcoin.Util = {
this.connect(snID) this.connect(snID)
.then(node => resolve(node)) .then(node => resolve(node))
.catch(error => { .catch(error => {
if(reverse) if (reverse)
var nxtNode = this.kBucket.prevNode(snID); var nxtNode = this.kBucket.prevNode(snID);
else else
var nxtNode = this.kBucket.nextNode(snID); var nxtNode = this.kBucket.nextNode(snID);
@ -8215,7 +8459,7 @@ Bitcoin.Util = {
else { //Serving Users else { //Serving Users
//Delete request from receiver //Delete request from receiver
if(data.delete){ if (data.delete) {
let closeNode = floSupernode.kBucket.closestNode(data.from); let closeNode = floSupernode.kBucket.closestNode(data.from);
if (floGlobals.serveList.includes(closeNode) && if (floGlobals.serveList.includes(closeNode) &&
data.senderID == floCrypto.getFloIDfromPubkeyHex(data.pubKey) && data.senderID == floCrypto.getFloIDfromPubkeyHex(data.pubKey) &&
@ -8224,8 +8468,7 @@ Bitcoin.Util = {
//indicate backup nodes to delete data //indicate backup nodes to delete data
} }
} } else {
else{
let closeNode = floSupernode.kBucket.closestNode(data.receiverID) let closeNode = floSupernode.kBucket.closestNode(data.receiverID)
if (floGlobals.serveList.includes(closeNode) && if (floGlobals.serveList.includes(closeNode) &&
data.senderID == floCrypto.getFloIDfromPubkeyHex(data.pubKey) && data.senderID == floCrypto.getFloIDfromPubkeyHex(data.pubKey) &&
@ -8241,14 +8484,15 @@ Bitcoin.Util = {
type: data.type, type: data.type,
comment: data.comment comment: data.comment
} }
compactIDB.addData(floGlobals.diskList.includes(value.application) ? value.application : floGlobals compactIDB.addData(floGlobals.diskList.includes(value.application) ? value.application :
floGlobals
.defaultDisk, value, key, `SN_${closeNode}`) .defaultDisk, value, key, `SN_${closeNode}`)
sendBackupData(key, value, closeNode); sendBackupData(key, value, closeNode);
} }
} }
} }
if((refreshData.countdown--) <=0 ) if ((refreshData.countdown--) <= 0)
refreshData(); refreshData();
} catch (error) { } catch (error) {
console.log(error.message); console.log(error.message);
@ -8268,7 +8512,7 @@ Bitcoin.Util = {
const compactIDB = { const compactIDB = {
setDefaultDB: function (dbName) { setDefaultDB: function (dbName) {
this.dbName = dbName; this.defaultDB = dbName;
}, },
initDB: function (dbName, objectStores = {}, version = null, removeStores = []) { initDB: function (dbName, objectStores = {}, version = null, removeStores = []) {
@ -8313,7 +8557,7 @@ Bitcoin.Util = {
}); });
}, },
openDB: function (dbName = this.dbName) { openDB: function (dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var idb = indexedDB.open(dbName); var idb = indexedDB.open(dbName);
idb.onerror = (event) => reject("Error in opening IndexedDB!"); idb.onerror = (event) => reject("Error in opening IndexedDB!");
@ -8321,7 +8565,7 @@ Bitcoin.Util = {
}); });
}, },
deleteDB: function (dbName = this.dbName) { deleteDB: function (dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var deleteReq = indexedDB.deleteDatabase(dbName);; var deleteReq = indexedDB.deleteDatabase(dbName);;
deleteReq.onerror = (event) => reject("Error deleting database!"); deleteReq.onerror = (event) => reject("Error deleting database!");
@ -8329,7 +8573,7 @@ Bitcoin.Util = {
}); });
}, },
writeData: function (obsName, data, key = false, dbName = this.dbName) { writeData: function (obsName, data, key = false, dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => { this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readwrite").objectStore(obsName); var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
@ -8343,7 +8587,7 @@ Bitcoin.Util = {
}); });
}, },
addData: function (obsName, data, key = false, dbName = this.dbName) { addData: function (obsName, data, key = false, dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => { this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readwrite").objectStore(obsName); var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
@ -8357,7 +8601,7 @@ Bitcoin.Util = {
}); });
}, },
removeData: function (obsName, key, dbName = this.dbName) { removeData: function (obsName, key, dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => { this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readwrite").objectStore(obsName); var obs = db.transaction(obsName, "readwrite").objectStore(obsName);
@ -8383,7 +8627,7 @@ Bitcoin.Util = {
}); });
}, },
readData: function (obsName, key, dbName = this.dbName) { readData: function (obsName, key, dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => { this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readonly").objectStore(obsName); var obs = db.transaction(obsName, "readonly").objectStore(obsName);
@ -8397,7 +8641,7 @@ Bitcoin.Util = {
}); });
}, },
readAllData: function (obsName, dbName = this.dbName) { readAllData: function (obsName, dbName = this.defaultDB) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.openDB(dbName).then(db => { this.openDB(dbName).then(db => {
var obs = db.transaction(obsName, "readonly").objectStore(obsName); var obs = db.transaction(obsName, "readonly").objectStore(obsName);
@ -8419,7 +8663,7 @@ Bitcoin.Util = {
}); });
}, },
searchData: function (obsName, options = {}, dbName = this.dbName) { searchData: function (obsName, options = {}, dbName = this.defaultDB) {
options.lowerKey = options.atKey || options.lowerKey || 0 options.lowerKey = options.atKey || options.lowerKey || 0
options.upperKey = options.atKey || options.upperKey || false options.upperKey = options.atKey || options.upperKey || false
options.patternEval = options.patternEval || ((k, v) => { options.patternEval = options.patternEval || ((k, v) => {
@ -8473,7 +8717,8 @@ Bitcoin.Util = {
if (myFloID in floGlobals.supernodes) { if (myFloID in floGlobals.supernodes) {
initIndexedDBforSupernodeDataStorage(myFloID).then(result => { initIndexedDBforSupernodeDataStorage(myFloID).then(result => {
console.log(result) console.log(result)
refreshData.countdown = floGlobals.supernodeConfig.refreshDelay; refreshData.countdown = floGlobals.supernodeConfig
.refreshDelay;
floSupernode.initSupernode(serverPwd, myFloID).then( floSupernode.initSupernode(serverPwd, myFloID).then(
async result => { async result => {
console.log(result) console.log(result)
@ -8653,7 +8898,7 @@ Bitcoin.Util = {
"comment" "comment"
]; ];
var idbObj = {} var idbObj = {}
for( let d of floGlobals.diskList) { for (let d of floGlobals.diskList) {
idbObj[d] = { idbObj[d] = {
indexes: {} indexes: {}
} }
@ -8754,9 +8999,11 @@ Bitcoin.Util = {
compactIDB.writeData("lastTx", result.totalTxs, floGlobals.adminID); compactIDB.writeData("lastTx", result.totalTxs, floGlobals.adminID);
Promise.all(promises).then(results => { Promise.all(promises).then(results => {
readDataFromIDB().then(result => { readDataFromIDB().then(result => {
migrateData(newNodes, delNodes, flag).then(result => { migrateData(newNodes, delNodes, flag).then(
result => {
console.info(result) console.info(result)
resolve("Read Supernode Data from Blockchain") resolve(
"Read Supernode Data from Blockchain")
}).catch(error => reject(error)) }).catch(error => reject(error))
}).catch(error => reject(error)) }).catch(error => reject(error))
}).catch(error => reject(error)) }).catch(error => reject(error))
@ -8773,7 +9020,7 @@ Bitcoin.Util = {
applicationList: "applications" applicationList: "applications"
} }
const readIDB = function(name, obs){ const readIDB = function (name, obs) {
return new Promise((res, rej) => { return new Promise((res, rej) => {
compactIDB.readAllData(obs).then(data => { compactIDB.readAllData(obs).then(data => {
floGlobals[name] = data; floGlobals[name] = data;
@ -8784,7 +9031,7 @@ Bitcoin.Util = {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let promises = [] let promises = []
for(let d in dataList) for (let d in dataList)
promises.push(readIDB(d, dataList[d])) promises.push(readIDB(d, dataList[d]))
Promise.all(promises) Promise.all(promises)
.then(results => resolve("Read data from IDB")) .then(results => resolve("Read data from IDB"))
@ -8841,9 +9088,9 @@ Bitcoin.Util = {
/*Supernode Backup and migration functions*/ /*Supernode Backup and migration functions*/
function connectToAllBackupSupernode(curNode = myFloID, i = 0) { function connectToAllBackupSupernode(curNode = myFloID, i = 0) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (floGlobals.backupNodes.length > i){ if (floGlobals.backupNodes.length > i) {
let rmNodes = floGlobals.backupNodes.splice(i, floGlobals.backupNodes.length); let rmNodes = floGlobals.backupNodes.splice(i, floGlobals.backupNodes.length);
for(node of rmNodes) for (node of rmNodes)
node.wsConn.close(); node.wsConn.close();
} }
if (i >= floGlobals.supernodeConfig.backupDepth) if (i >= floGlobals.supernodeConfig.backupDepth)
@ -8859,7 +9106,7 @@ Bitcoin.Util = {
floGlobals.backupNodes[i] = node floGlobals.backupNodes[i] = node
flag = true; flag = true;
}).catch(error => console.error(error)) }).catch(error => console.error(error))
.finally( _ => { .finally(_ => {
connectToAllBackupSupernode(nxtNode, flag ? i + 1 : i) connectToAllBackupSupernode(nxtNode, flag ? i + 1 : i)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error)) .catch(error => reject(error))
@ -8874,12 +9121,12 @@ Bitcoin.Util = {
console.log("Attempting to connect to backupNode:", nodeID) console.log("Attempting to connect to backupNode:", nodeID)
floSupernode.connect(nodeID).then(node => { floSupernode.connect(nodeID).then(node => {
node.wsConn.onmessage = (evt) => { node.wsConn.onmessage = (evt) => {
if(evt.data === "$-") if (evt.data === "$-")
replaceOfflineBackupNode(nodeID); replaceOfflineBackupNode(nodeID);
} }
node.wsConn.onclose = (evt) => { node.wsConn.onclose = (evt) => {
let i = floGlobals.backupNodes.map(d => d.floID).indexOf(nodeID); let i = floGlobals.backupNodes.map(d => d.floID).indexOf(nodeID);
if(i !== -1) if (i !== -1)
initateBackupWebsocket(nodeID) initateBackupWebsocket(nodeID)
.then(bNode => floGlobals.backupNodes[i] = bNode) .then(bNode => floGlobals.backupNodes[i] = bNode)
.catch(error => replaceOfflineBackupNode(nodeID)) .catch(error => replaceOfflineBackupNode(nodeID))
@ -8904,7 +9151,7 @@ Bitcoin.Util = {
connectToAllBackupSupernode(len == 0 ? offlineNodeID : floGlobals.backupNodes[len - 1], len).then(result => { connectToAllBackupSupernode(len == 0 ? offlineNodeID : floGlobals.backupNodes[len - 1], len).then(result => {
console.log(result) console.log(result)
//inform the newly connected node to store backups of all serving //inform the newly connected node to store backups of all serving
for( let sn of floGlobals.serveList){ for (let sn of floGlobals.serveList) {
var sendData = { var sendData = {
from: myFloID, from: myFloID,
sn_msg: { sn_msg: {
@ -8917,11 +9164,11 @@ Bitcoin.Util = {
floGlobals.backupNodes[len].wsConn.send(JSON.stringify(sendData)) floGlobals.backupNodes[len].wsConn.send(JSON.stringify(sendData))
} }
}).catch(error => console.error(error)) }).catch(error => console.error(error))
.finally ( _ => { .finally(_ => {
if (index === 0) { if (index === 0) {
//start serving the dead node //start serving the dead node
if (floGlobals.backupNodes.length === 0){ if (floGlobals.backupNodes.length === 0) {
for(let sn in floGlobals.supernodes) for (let sn in floGlobals.supernodes)
startBackupServe(sn) startBackupServe(sn)
} }
//inform the immediate next node of the dead to start serving it //inform the immediate next node of the dead to start serving it
@ -8987,7 +9234,7 @@ Bitcoin.Util = {
sn_msg: sn_msg, sn_msg: sn_msg,
sign: floCrypto.signData(JSON.stringify(sn_msg), myPrivKey) sign: floCrypto.signData(JSON.stringify(sn_msg), myPrivKey)
} }
for(let node of floGlobals.backupNodes) for (let node of floGlobals.backupNodes)
node.wsConn.send(JSON.stringify(data)) node.wsConn.send(JSON.stringify(data))
} }
@ -9042,7 +9289,7 @@ Bitcoin.Util = {
function requestBackupData(from, snID) { function requestBackupData(from, snID) {
var promises = [] var promises = []
for(let i in floGlobals.diskList) for (let i in floGlobals.diskList)
promises[i] = compactIDB.searchData(floGlobals.diskList[i], { promises[i] = compactIDB.searchData(floGlobals.diskList[i], {
lastOnly: true lastOnly: true
}, `SN_${snID}`) }, `SN_${snID}`)
@ -9074,7 +9321,7 @@ Bitcoin.Util = {
function indicateSupernodeUp() { function indicateSupernodeUp() {
console.log("Indicating supernode is up") console.log("Indicating supernode is up")
if(floGlobals.backupNodes.length){ if (floGlobals.backupNodes.length) {
//inform all other nodes //inform all other nodes
var data = { var data = {
from: myFloID, from: myFloID,
@ -9085,12 +9332,12 @@ Bitcoin.Util = {
} }
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey) data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey)
let dataStr = JSON.stringify(data) let dataStr = JSON.stringify(data)
for(let sn in floGlobals.supernodes){ for (let sn in floGlobals.supernodes) {
if(sn !== myFloID){ if (sn !== myFloID) {
floSupernode.connect(sn) floSupernode.connect(sn)
.then(node => { .then(node => {
node.wsConn.send(dataStr); node.wsConn.send(dataStr);
console.info('data sent to :'+ sn) console.info('data sent to :' + sn)
node.wsConn.close(); node.wsConn.close();
}).catch(error => console.error(error)) }).catch(error => console.error(error))
} }
@ -9105,8 +9352,9 @@ Bitcoin.Util = {
//request self data from backup //request self data from backup
requestBackupData(floGlobals.backupNodes[0].floID, myFloID) requestBackupData(floGlobals.backupNodes[0].floID, myFloID)
} else { } else {
let nodeList = floSupernode.kBucket.prevNode(myFloID, floSupernode.kBucket.supernodeKBucket.toArray().length-1) let nodeList = floSupernode.kBucket.prevNode(myFloID, floSupernode.kBucket.supernodeKBucket.toArray()
for(sn of nodeList){ .length - 1)
for (sn of nodeList) {
startBackupStore(sn); startBackupStore(sn);
startBackupServe(sn); startBackupServe(sn);
} }
@ -9127,7 +9375,7 @@ Bitcoin.Util = {
//inform the revived node to serve the other applicable dead nodes //inform the revived node to serve the other applicable dead nodes
let iNodes = floSupernode.kBucket.innerNodes(snID, myFloID) let iNodes = floSupernode.kBucket.innerNodes(snID, myFloID)
data.sn_msg.time = Date.now(); data.sn_msg.time = Date.now();
for (let sn of floGlobals.serveList.slice()){ for (let sn of floGlobals.serveList.slice()) {
if (!iNodes.includes(sn) && sn != myFloID) { if (!iNodes.includes(sn) && sn != myFloID) {
data.sn_msg.snID = sn; data.sn_msg.snID = sn;
data.sn_msg.type = "startBackupStore"; data.sn_msg.type = "startBackupStore";
@ -9143,7 +9391,8 @@ Bitcoin.Util = {
if (floGlobals.backupNodes.length < floGlobals.supernodeConfig.backupDepth) { if (floGlobals.backupNodes.length < floGlobals.supernodeConfig.backupDepth) {
//when less supernodes available, just connect to the revived node //when less supernodes available, just connect to the revived node
let nxtNodes = floSupernode.kBucket.nextNode(myFloID, floSupernode.kBucket.supernodeKBucket.toArray().length) let nxtNodes = floSupernode.kBucket.nextNode(myFloID, floSupernode.kBucket.supernodeKBucket
.toArray().length)
var index = floGlobals.backupNodes.length var index = floGlobals.backupNodes.length
for (let i in floGlobals.backupNodes) { for (let i in floGlobals.backupNodes) {
if (snID == floGlobals.backupNodes[i].floID) { //revived node is already connected if (snID == floGlobals.backupNodes[i].floID) { //revived node is already connected
@ -9156,11 +9405,12 @@ Bitcoin.Util = {
} }
if (index !== false) { if (index !== false) {
initateBackupWebsocket(snID).then(result => { initateBackupWebsocket(snID).then(result => {
floGlobals.backupNodes.splice(index, 0, result) // add revived node as backup node floGlobals.backupNodes.splice(index, 0,
result) // add revived node as backup node
//inform node on the list of backups to store //inform node on the list of backups to store
data.sn_msg.time = Date.now(); data.sn_msg.time = Date.now();
data.sn_msg.type = "startBackupStore"; data.sn_msg.type = "startBackupStore";
for(let sn of floGlobals.serveList){ for (let sn of floGlobals.serveList) {
data.sn_msg.snID = sn; data.sn_msg.snID = sn;
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey); data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey);
node.wsConn.send(JSON.stringify(data)) node.wsConn.send(JSON.stringify(data))
@ -9169,7 +9419,8 @@ Bitcoin.Util = {
} }
} else { } else {
//connect to the revived node as backup if needed //connect to the revived node as backup if needed
let nxtNodes = floSupernode.kBucket.nextNode(myFloID, floSupernode.kBucket.supernodeKBucket.toArray() let nxtNodes = floSupernode.kBucket.nextNode(myFloID, floSupernode.kBucket.supernodeKBucket
.toArray()
.length) .length)
var index = false var index = false
for (let i in floGlobals.backupNodes) { for (let i in floGlobals.backupNodes) {
@ -9183,11 +9434,12 @@ Bitcoin.Util = {
console.info(index) console.info(index)
if (index !== false) { if (index !== false) {
initateBackupWebsocket(snID).then(result => { initateBackupWebsocket(snID).then(result => {
floGlobals.backupNodes.splice(index, 0, result) // add revived node as backup node floGlobals.backupNodes.splice(index, 0,
result) // add revived node as backup node
let rmNode = floGlobals.backupNodes.pop() // remove the last extra backup node let rmNode = floGlobals.backupNodes.pop() // remove the last extra backup node
//inform node on the list of backups to store and inform removed node to stop storing //inform node on the list of backups to store and inform removed node to stop storing
data.sn_msg.time = Date.now(); data.sn_msg.time = Date.now();
for(let sn of floGlobals.serveList){ for (let sn of floGlobals.serveList) {
data.sn_msg.snID = sn; data.sn_msg.snID = sn;
data.sn_msg.type = "startBackupStore"; data.sn_msg.type = "startBackupStore";
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey); data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey);
@ -9221,7 +9473,7 @@ Bitcoin.Util = {
var index = floGlobals.serveList.indexOf(snID); var index = floGlobals.serveList.indexOf(snID);
if (index !== -1 && snID !== myFloID) { if (index !== -1 && snID !== myFloID) {
floGlobals.serveList.splice(index, 1); floGlobals.serveList.splice(index, 1);
if(floGlobals.backupNodes.length == floGlobals.supernodeConfig.backupDepth){ if (floGlobals.backupNodes.length == floGlobals.supernodeConfig.backupDepth) {
//indicate the last backup node to stop storing the revived's backup //indicate the last backup node to stop storing the revived's backup
var lastIndex = floGlobals.backupNodes.length - 1 var lastIndex = floGlobals.backupNodes.length - 1
if (lastIndex !== -1) { if (lastIndex !== -1) {
@ -9245,7 +9497,7 @@ Bitcoin.Util = {
if (!floGlobals.storedList.includes(snID)) { if (!floGlobals.storedList.includes(snID)) {
floGlobals.storedList.push(snID) floGlobals.storedList.push(snID)
initIndexedDBforSupernodeDataStorage(snID).then(result => { initIndexedDBforSupernodeDataStorage(snID).then(result => {
if(from) if (from)
requestBackupData(from, snID); requestBackupData(from, snID);
console.warn("BackupStore started for " + snID); console.warn("BackupStore started for " + snID);
}).catch(error => console.error(error)) }).catch(error => console.error(error))
@ -9283,7 +9535,8 @@ Bitcoin.Util = {
}) })
delNodes.forEach(node => { delNodes.forEach(node => {
//split the data to its prev and next nodes //split the data to its prev and next nodes
let KB = floSupernode.kBucket.constructKB(Object.keys(floGlobals let KB = floSupernode.kBucket.constructKB(Object.keys(
floGlobals
.supernodes).concat(node).sort()); .supernodes).concat(node).sort());
let prevNode = floSupernode.kBucket.prevNode(node, 1, KB); let prevNode = floSupernode.kBucket.prevNode(node, 1, KB);
let nextNode = floSupernode.kBucket.nextNode(node, 1, KB); let nextNode = floSupernode.kBucket.nextNode(node, 1, KB);
@ -9296,8 +9549,8 @@ Bitcoin.Util = {
}) })
} }
function intimateNodes(flag){ function intimateNodes(flag) {
if(!flag) //skip intimate if already intimated if (!flag) //skip intimate if already intimated
return; return;
//intimate all nodes that there is change in supernode list //intimate all nodes that there is change in supernode list
var data = { var data = {
@ -9309,8 +9562,8 @@ Bitcoin.Util = {
} }
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey) data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), myPrivKey)
let dataStr = JSON.stringify(data) let dataStr = JSON.stringify(data)
for(let sn in floGlobals.supernodes){ for (let sn in floGlobals.supernodes) {
if(sn !== myFloID){ if (sn !== myFloID) {
floSupernode.connect(sn) floSupernode.connect(sn)
.then(node => { .then(node => {
node.wsConn.send(dataStr); node.wsConn.send(dataStr);
@ -9320,7 +9573,7 @@ Bitcoin.Util = {
} }
} }
function iniateRefresh(){ function iniateRefresh() {
readSupernodeConfigFromAPI(false) readSupernodeConfigFromAPI(false)
.then(result => console.log(result)) .then(result => console.log(result))
.catch(error => console.error(error)) .catch(error => console.error(error))
@ -9334,7 +9587,8 @@ Bitcoin.Util = {
compactIDB.readAllData(obs, `SN_${snID}`).then(result => { compactIDB.readAllData(obs, `SN_${snID}`).then(result => {
let promises = [] let promises = []
for (let k in result) { for (let k in result) {
if (floSupernode.kBucket.closestNode(result[k].receiverID) === if (floSupernode.kBucket.closestNode(result[k]
.receiverID) ===
toID) { toID) {
var data = { var data = {
from: myFloID, from: myFloID,
@ -9345,10 +9599,12 @@ Bitcoin.Util = {
value: result[k] value: result[k]
} }
} }
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), data.sign = floCrypto.signData(JSON.stringify(data
.sn_msg),
myPrivKey) myPrivKey)
node.wsConn.send(JSON.stringify(data)); node.wsConn.send(JSON.stringify(data));
promises.push(compactIDB.removeData(obs, k, `SN_${snID}`)) promises.push(compactIDB.removeData(obs, k,
`SN_${snID}`))
} }
} }
Promise.all(promises).then(r => {}).catch(e => {}) Promise.all(promises).then(r => {}).catch(e => {})
@ -9393,7 +9649,8 @@ Bitcoin.Util = {
compactIDB.readAllData(obs, `SN_${snID}`).then(result => { compactIDB.readAllData(obs, `SN_${snID}`).then(result => {
let promises = [] let promises = []
for (let k in result) { for (let k in result) {
if (floSupernode.kBucket.closestNode(result[k].receiverID) === if (floSupernode.kBucket.closestNode(result[k]
.receiverID) ===
prev) { prev) {
var data = { var data = {
from: myFloID, from: myFloID,
@ -9404,7 +9661,8 @@ Bitcoin.Util = {
value: result[k] value: result[k]
} }
} }
data.sign = floCrypto.signData(JSON.stringify(data.sn_msg), data.sign = floCrypto.signData(JSON.stringify(data
.sn_msg),
myPrivKey) myPrivKey)
node.wsConn.send(JSON.stringify(data)); node.wsConn.send(JSON.stringify(data));
} else } else