Merge pull request #5 from sairajzero/master

This commit is contained in:
Sai Raj 2020-01-31 22:05:26 +05:30 committed by GitHub
commit f20b028e3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -7615,7 +7615,7 @@ Bitcoin.Util = {
privKey: key.getBitcoinWalletImportFormat() privKey: key.getBitcoinWalletImportFormat()
} }
} catch (e) { } catch (e) {
console.log(e); console.error(e);
} }
}, },
@ -7652,7 +7652,7 @@ Bitcoin.Util = {
else else
return false; return false;
} catch (e) { } catch (e) {
console.log(e); console.error(e);
} }
}, },
@ -7742,7 +7742,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));
@ -7960,7 +7960,7 @@ Bitcoin.Util = {
let kArrayFloIds = KB.toArray().map(k => k.floID); let kArrayFloIds = KB.toArray().map(k => k.floID);
var innerNodes = [] var innerNodes = []
if(kArrayFloIds.includes(flo_addr1) && kArrayFloIds.includes(flo_addr2)){ if(kArrayFloIds.includes(flo_addr1) && kArrayFloIds.includes(flo_addr2)){
for(var i = kArrayFloIds.indexOf(flo_addr1); i!= flo_addr2; i++){ for(var i = kArrayFloIds.indexOf(flo_addr1) + 1; kArrayFloIds[i]!= flo_addr2; i++){
if(i >= kArrayFloIds.length) if(i >= kArrayFloIds.length)
i = -1 i = -1
else else
@ -7977,7 +7977,7 @@ Bitcoin.Util = {
let kArrayFloIds = KB.toArray().map(k => k.floID); let kArrayFloIds = KB.toArray().map(k => k.floID);
var outterNodes = [] var outterNodes = []
if(kArrayFloIds.includes(flo_addr1) && kArrayFloIds.includes(flo_addr2)){ if(kArrayFloIds.includes(flo_addr1) && kArrayFloIds.includes(flo_addr2)){
for(var i = kArrayFloIds.indexOf(flo_addr2); i!= flo_addr1; i++){ for(var i = kArrayFloIds.indexOf(flo_addr2) + 1; kArrayFloIds[i]!= flo_addr1; i++){
if(i >= kArrayFloIds.length) if(i >= kArrayFloIds.length)
i = -1 i = -1
else else
@ -8135,13 +8135,13 @@ Bitcoin.Util = {
console.log('Disconnected from supernode websocket!'); console.log('Disconnected from supernode websocket!');
floSupernode.initSupernode(serverPwd, myFloID) floSupernode.initSupernode(serverPwd, myFloID)
.then(result => console.log(result)) .then(result => console.log(result))
.catch(error => console.log(error)) .catch(error => console.error(error))
}); });
//Event fired when connection error with supernode websocket //Event fired when connection error with supernode websocket
reactor.registerEvent('supernode_error'); reactor.registerEvent('supernode_error');
reactor.addEventListener('supernode_error', function (event) { reactor.addEventListener('supernode_error', function (event) {
console.log('Error! Unable to connect supernode websocket!'); console.error('Error! Unable to connect supernode websocket!');
}); });
//Event fired when received admin messages from WSS //Event fired when received admin messages from WSS
@ -8169,9 +8169,9 @@ Bitcoin.Util = {
} }
compactIDB.searchData( floGlobals.diskList.includes(request.application) ? request.application : floGlobals.defaultDisk, filterOptions, `SN_${closestNode[0]}`) compactIDB.searchData( floGlobals.diskList.includes(request.application) ? request.application : floGlobals.defaultDisk, filterOptions, `SN_${closestNode[0]}`)
.then(result => floSupernode.supernodeClientWS.send(`${requestor} ${JSON.stringify(result)}`)) .then(result => floSupernode.supernodeClientWS.send(`${requestor} ${JSON.stringify(result)}`))
.catch(error => console.log(error)) .catch(error => console.error(error))
} }
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} catch (error) { } catch (error) {
console.log(error.message) console.log(error.message)
} }
@ -8202,7 +8202,7 @@ Bitcoin.Util = {
compactIDB.addData(floGlobals.diskList.includes(value.application) ? value.application:floGlobals.defaultDisk , value ,key,`SN_${closestNode[0]}`) compactIDB.addData(floGlobals.diskList.includes(value.application) ? value.application:floGlobals.defaultDisk , value ,key,`SN_${closestNode[0]}`)
reactor.dispatchEvent("send_backup",{ key:key, value:value, snfloID: closestNode[0]}) reactor.dispatchEvent("send_backup",{ key:key, value:value, snfloID: closestNode[0]})
} }
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}else if(data.from in floGlobals.supernodes) }else if(data.from in floGlobals.supernodes)
reactor.dispatchEvent("backup_message_event", data) reactor.dispatchEvent("backup_message_event", data)
} catch (error) { } catch (error) {
@ -8343,26 +8343,34 @@ Bitcoin.Util = {
}); });
}, },
searchData: function (obsName, patternEval, dbName = this.dbName) { searchData: function (obsName, options = {}, dbName = this.dbName) {
return new Promise((resolve, reject) => { options.lowerKey = options.atKey || options.lowerKey || 0
this.openDB(dbName).then(db => { options.upperKey = options.atKey || options.upperKey || false
var obs = db.transaction(obsName, "readonly").objectStore(obsName); options.patternEval = options.patternEval || ((k,v) => {return true})
var filteredResult = {} options.lastOnly = options.lastOnly || false
let curReq = obs.openCursor(); return new Promise((resolve, reject) => {
curReq.onsuccess = (evt) => { this.openDB(dbName).then(db => {
var cursor = evt.target.result; var obs = db.transaction(obsName, "readonly").objectStore(obsName);
if (cursor) { var filteredResult = {}
if (patternEval(cursor.primaryKey, cursor.value)) let curReq = obs.openCursor(
filteredResult[cursor.primaryKey] = cursor.value; options.upperKey ? IDBKeyRange.bound(options.lowerKey,options.upperKey) : IDBKeyRange.lowerBound(options.lowerKey),
cursor.continue(); options.lastOnly ? "prev":"next" );
} else curReq.onsuccess = (evt) => {
resolve(filteredResult); var cursor = evt.target.result;
} if (cursor) {
curReq.onerror = (evt) => reject( if (options.patternEval(cursor.primaryKey, cursor.value)){
`Search unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`); filteredResult[cursor.primaryKey] = cursor.value;
db.close(); options.lastOnly ? resolve(filteredResult) : cursor.continue();
}).catch(error => reject(error)); }else
}); cursor.continue();
} else
resolve(filteredResult);
}
curReq.onerror = (evt) => reject(
`Search unsuccessful [${evt.target.error.name}] ${evt.target.error.message}`);
db.close();
}).catch(error => reject(error));
});
} }
} }
</script> </script>
@ -8393,13 +8401,13 @@ Bitcoin.Util = {
console.log(result) console.log(result)
await sleep(2000) await sleep(2000)
reactor.dispatchEvent("indicate_supernode_up",myFloID) reactor.dispatchEvent("indicate_supernode_up",myFloID)
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
function getCredentials(){ function getCredentials(){
@ -8432,7 +8440,7 @@ Bitcoin.Util = {
console.log(floID) console.log(floID)
alert(`Supernode floID: ${floID}`) alert(`Supernode floID: ${floID}`)
}catch(error){ }catch(error){
console.log(error) console.error(error)
return reject("Invalid Private Key") return reject("Invalid Private Key")
} }
var threshold = floCrypto.randInt(10,20) var threshold = floCrypto.randInt(10,20)
@ -8567,8 +8575,8 @@ Bitcoin.Util = {
console.log(result) console.log(result)
autoDeleteStoredData() autoDeleteStoredData()
.then(result => console.log(result)) .then(result => console.log(result))
.catch(error => console.log(error)) .catch(error => console.error(error))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
function autoDeleteStoredData(){ function autoDeleteStoredData(){
@ -8584,7 +8592,7 @@ Bitcoin.Util = {
var promise = new Promise((res,rej) => { var promise = new Promise((res,rej) => {
compactIDB.searchData(floGlobals.defaultDisk,filterOptions,`SN_${floGlobals.storedList[i]}`).then(results => { compactIDB.searchData(floGlobals.defaultDisk,filterOptions,`SN_${floGlobals.storedList[i]}`).then(results => {
for(key in results) for(key in results)
if(!floGlobals.applicationList.includes(results[key].application) || !floGlobals.appSubAdmins[results[key].application].includes(results[key].senderID)) if(!(results[key].application in floGlobals.applicationList) || !floGlobals.appSubAdmins[results[key].application].includes(results[key].senderID))
compactIDB.removeData(floGlobals.defaultDisk, key, `SN_${floGlobals.storedList[i]}`) compactIDB.removeData(floGlobals.defaultDisk, key, `SN_${floGlobals.storedList[i]}`)
res(`Auto-delete successful for SN_${floGlobals.storedList[i]} from ${deleteStart} to ${deleteEnd}`) res(`Auto-delete successful for SN_${floGlobals.storedList[i]} from ${deleteStart} to ${deleteEnd}`)
}).catch(error => rej(error)) }).catch(error => rej(error))
@ -8648,6 +8656,7 @@ Bitcoin.Util = {
for(app in floGlobals.applicationList){ for(app in floGlobals.applicationList){
var promise = new Promise((res,rej) => { var promise = new Promise((res,rej) => {
compactIDB.readData("appSubAdmins", app).then(subAdmins => { compactIDB.readData("appSubAdmins", app).then(subAdmins => {
if(!Array.isArray(subAdmins)) subAdmins = []
compactIDB.readData("lastTx",floGlobals.applicationList[app]).then(lastTx => { compactIDB.readData("lastTx",floGlobals.applicationList[app]).then(lastTx => {
floBlockchainAPI.readData(floGlobals.applicationList[app],{ignoreOld:lastTx,sentOnly:true,pattern:app}).then(result => { floBlockchainAPI.readData(floGlobals.applicationList[app],{ignoreOld:lastTx,sentOnly:true,pattern:app}).then(result => {
for(var i = result.data.length-1; i>=0; i--){ for(var i = result.data.length-1; i>=0; i--){
@ -8656,8 +8665,8 @@ Bitcoin.Util = {
subAdmins = subAdmins.filter(x => !content.removeSubAdmin.includes(x)); subAdmins = subAdmins.filter(x => !content.removeSubAdmin.includes(x));
if(Array.isArray(content.addSubAdmin)) if(Array.isArray(content.addSubAdmin))
subAdmins = subAdmins.concat(content.addSubAdmin) subAdmins = subAdmins.concat(content.addSubAdmin)
} }
compactIDB.writeData("lastTx", result.totalTxs, floGlobals.adminID); compactIDB.writeData("lastTx", result.totalTxs, floGlobals.applicationList[app]);
compactIDB.writeData("appSubAdmins", subAdmins, app) compactIDB.writeData("appSubAdmins", subAdmins, app)
.then(result => res(app)) .then(result => res(app))
.catch(error => rej(error)) .catch(error => rej(error))
@ -8702,10 +8711,10 @@ Bitcoin.Util = {
initateBackupWebsocket(backupNodeID) initateBackupWebsocket(backupNodeID)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => { .catch(error => {
console.log(error) console.error(error)
floSupernode.kBucket.getNextSupernode(backupNodeID).then(nextNode => { floSupernode.kBucket.getNextSupernode(backupNodeID).then(nextNode => {
connectToBackupSupernode(nextNode[0]).then(result => resolve(result)) connectToBackupSupernode(nextNode[0]).then(result => resolve(result))
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}) })
}) })
} }
@ -8713,7 +8722,7 @@ Bitcoin.Util = {
function initateBackupWebsocket(backupNodeID){ function initateBackupWebsocket(backupNodeID){
return new Promise((resolve,reject) => { return new Promise((resolve,reject) => {
try{ try{
console.log(backupNodeID) console.log("Attempting to connect to backupNode:", backupNodeID)
var backupNode = { var backupNode = {
floID: backupNodeID, floID: backupNodeID,
wsConn: new WebSocket("wss://" + floGlobals.supernodes[backupNodeID].uri + "/ws") wsConn: new WebSocket("wss://" + floGlobals.supernodes[backupNodeID].uri + "/ws")
@ -8753,7 +8762,7 @@ Bitcoin.Util = {
initateBackupWebsocket(backupNodeID) initateBackupWebsocket(backupNodeID)
.then(result => console.log(result)) .then(result => console.log(result))
.catch(error =>{ .catch(error =>{
console.log(error) console.error(error)
reactor.dispatchEvent("backup_node_offline",backupNodeID); reactor.dispatchEvent("backup_node_offline",backupNodeID);
}) })
}) })
@ -8769,7 +8778,7 @@ Bitcoin.Util = {
reactor.addEventListener("backup_node_offline", function (offlineNodeID) { reactor.addEventListener("backup_node_offline", function (offlineNodeID) {
console.log("backup_node_offline"); console.log("backup_node_offline");
//remove offline node and add the immediate next available node //remove offline node and add the immediate next available node
var index = floGlobals.backupNodes.indexOf(offlineNodeID); var index = floGlobals.backupNodes.map(d => d.floID).indexOf(offlineNodeID);
if (index !== -1) floGlobals.backupNodes.splice(index, 1); if (index !== -1) floGlobals.backupNodes.splice(index, 1);
//connect to next node available //connect to next node available
var len = floGlobals.backupNodes.length var len = floGlobals.backupNodes.length
@ -8802,7 +8811,7 @@ Bitcoin.Util = {
floGlobals.backupNodes[0].wsConn.send(JSON.stringify(sendData2)) floGlobals.backupNodes[0].wsConn.send(JSON.stringify(sendData2))
} }
}).catch(error => { }).catch(error => {
console.log(error) console.error(error)
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)
@ -8824,6 +8833,40 @@ Bitcoin.Util = {
}) })
}) })
reactor.registerEvent("backup_message_event");
reactor.addEventListener("backup_message_event", function (data) {
console.log("backup_message_event");
if(floCrypto.verifySign(JSON.stringify(data.backupMsg), data.sign, floGlobals.supernodes[data.from].pubKey)){
//Backup event messages (most crucial part)
switch(data.backupMsg.type){
case "backupData":
reactor.dispatchEvent("store_backup_data", data.backupMsg)
break;
case "supernodeUp":
reactor.dispatchEvent("supernode_back_online", data.backupMsg.snfloID)
break;
case "startBackupServe":
reactor.dispatchEvent("start_backup_serve", data.backupMsg.snfloID)
break;
case "stopBackupServe":
reactor.dispatchEvent("stop_backup_serve", data.backupMsg.snfloID)
break;
case "startBackupStore":
reactor.dispatchEvent("start_backup_store", {from:data.from, snfloID:data.backupMsg.snfloID})
break;
case "stopBackupStore":
reactor.dispatchEvent("stop_backup_store", data.backupMsg.snfloID)
break;
case "dataRequest":
reactor.dispatchEvent("send_stored_backup", {from:data.from, snfloID:data.backupMsg.snfloID, lowerKey:data.backupMsg.lowerKey})
break;
default:
console.log(data.backupMsg)
}
}
})
reactor.registerEvent("send_message_to_backup_nodes"); reactor.registerEvent("send_message_to_backup_nodes");
reactor.addEventListener("send_message_to_backup_nodes", function (backupMsg) { reactor.addEventListener("send_message_to_backup_nodes", function (backupMsg) {
console.log("send_message_to_backup_nodes"); console.log("send_message_to_backup_nodes");
@ -8891,10 +8934,10 @@ Bitcoin.Util = {
//send stored backuped data to the requestor node //send stored backuped data to the requestor node
if(floGlobals.storedList.includes(event.snfloID)){ if(floGlobals.storedList.includes(event.snfloID)){
try{ try{
var requestorWS = new WebSocket("wss://" + floGlobals.supernodes[event.from].uri + "/ws") floGlobals.diskList.forEach(obs => {
requestorWS.onopen = (evt) => { compactIDB.searchData(obs, {lowerKey: event.lowerKey[obs]}, `SN_${event.snfloID}`).then(result => {
floGlobals.diskList.forEach(obs => { var requestorWS = new WebSocket("wss://" + floGlobals.supernodes[event.from].uri + "/ws")
compactIDB.searchData(obs, {lowerKey: event.lowerKey[obs]}, `SN_${event.snfloID}`).then(result => { requestorWS.onopen = (evt) => {
for(k in result){ for(k in result){
var sendData = { var sendData = {
from: myFloID, from: myFloID,
@ -8908,52 +8951,18 @@ Bitcoin.Util = {
sendData.sign = floCrypto.signData(JSON.stringify(sendData.backupMsg), myPrivKey) sendData.sign = floCrypto.signData(JSON.stringify(sendData.backupMsg), myPrivKey)
requestorWS.send(JSON.stringify(sendData)) requestorWS.send(JSON.stringify(sendData))
} }
}).catch(error => console.log(error)) }
}) requestorWS.onmessage = (evt) => console.log(evt.data);
} requestorWS.onclose = (evt) => console.log("Disconnected from " + event.from);
requestorWS.onmessage = (evt) => console.log(evt.data); requestorWS.onerror = (evt) => console.log("Error connecting to " + event.from);
requestorWS.onclose = (evt) => console.log("Disconnected from " + event.from); }).catch(error => console.error(error))
requestorWS.onerror = (evt) => console.log("Error connecting to " + event.from); })
}catch(error){ }catch(error){
console.log(error.message) console.log(error.message)
} }
} }
}) })
reactor.registerEvent("backup_message_event");
reactor.addEventListener("backup_message_event", function (data) {
console.log("backup_message_event");
if(floCrypto.verifySign(JSON.stringify(data.backupMsg), data.sign, floGlobals.supernodes[data.from].pubKey)){
//Backup event messages (most crucial part)
switch(data.backupMsg.type){
case "backupData":
reactor.dispatchEvent("store_backup_data", data.backupMsg)
break;
case "supernodeUp":
reactor.dispatchEvent("supernode_back_online", data.backupMsg.snfloID)
break;
case "startBackupServe":
reactor.dispatchEvent("start_backup_serve", data.backupMsg.snfloID)
break;
case "stopBackupServe":
reactor.dispatchEvent("stop_backup_serve", data.backupMsg.snfloID)
break;
case "startBackupStore":
reactor.dispatchEvent("start_backup_store", {from:data.from, snfloID:data.backupMsg.snfloID})
break;
case "stopBackupStore":
reactor.dispatchEvent("stop_backup_store", data.backupMsg.snfloID)
break;
case "dataRequest":
reactor.dispatchEvent("send_stored_backup", {from:data.from, snfloID:data.backupMsg.snfloID, lowerKey:data.backupMsg.lowerKey})
break;
default:
console.log(data.backupMsg)
}
}
})
reactor.registerEvent("request_data"); reactor.registerEvent("request_data");
reactor.addEventListener("request_data", function (event) { reactor.addEventListener("request_data", function (event) {
console.log("request_data"); console.log("request_data");
@ -8980,7 +8989,7 @@ Bitcoin.Util = {
reactor.addEventListener("store_backup_data", function (data) { reactor.addEventListener("store_backup_data", function (data) {
console.log("store_backup_data"); console.log("store_backup_data");
//store received backup data //store received backup data
if(floGlobals.storedList.includes(data.backupMsg.snfloID)){ if(floGlobals.storedList.includes(data.snfloID)){
compactIDB.addData( compactIDB.addData(
floGlobals.diskList.includes(data.value.application) ? data.value.application:floGlobals.defaultDisk, floGlobals.diskList.includes(data.value.application) ? data.value.application:floGlobals.defaultDisk,
data.value, data.key, `SN_${data.snfloID}` data.value, data.key, `SN_${data.snfloID}`
@ -9010,13 +9019,14 @@ Bitcoin.Util = {
reactor.registerEvent("supernode_back_online"); reactor.registerEvent("supernode_back_online");
reactor.addEventListener("supernode_back_online", function (snfloID) { reactor.addEventListener("supernode_back_online", function (snfloID) {
console.log("supernode_back_online"); console.log("supernode_back_online");
if(floGlobals.serveList.includes(snfloID)){ if(floGlobals.serveList.includes(snfloID)){
//stop serving the revived node //stop serving the revived node
reactor.dispatchEvent("stop_backup_serve", snfloID) reactor.dispatchEvent("stop_backup_serve", snfloID)
//inform the revived node to serve the other applicable dead nodes //inform the revived node to serve the other applicable dead nodes
floSupernode.kBucket.getInnerNodes(snfloID, myFloID).then(innerNodes => { floSupernode.kBucket.getInnerNodes(snfloID, myFloID).then(innerNodes => {
for(var i=0; i < floGlobals.serveList.length; i++) for(var i=0; i < floGlobals.serveList.length; i++){
if(!innerNodes.includes(floGlobals.serveList[i])){ if(!innerNodes.includes(floGlobals.serveList[i]) && floGlobals.serveList[i] != myFloID){
var backupMsg = { var backupMsg = {
type: "startBackupServe", type: "startBackupServe",
snfloID: floGlobals.serveList[i], snfloID: floGlobals.serveList[i],
@ -9026,8 +9036,10 @@ Bitcoin.Util = {
reactor.dispatchEvent("stop_backup_serve", floGlobals.serveList[i]) reactor.dispatchEvent("stop_backup_serve", floGlobals.serveList[i])
i--; //reduce iterator as an element is removed i--; //reduce iterator as an element is removed
} }
}) }
}).catch(error => console.error(error))
} }
if(floGlobals.storedList.includes(snfloID)){ if(floGlobals.storedList.includes(snfloID)){
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
@ -9046,9 +9058,9 @@ Bitcoin.Util = {
if(index !== false){ if(index !== false){
initateBackupWebsocket(snfloID).then(result => { initateBackupWebsocket(snfloID).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
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
}).catch(error => console.log(error)) }).catch(error => console.error(error))
}else{ }else{
var lastBackup = floGlobals.storedList.pop() var lastBackup = floGlobals.storedList.pop()
//inform the revived node to store the backup //inform the revived node to store the backup
@ -9082,9 +9094,9 @@ Bitcoin.Util = {
initateBackupWebsocket(snfloID).then(result => { initateBackupWebsocket(snfloID).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
floGlobals.backupNodes.pop() // remove the last extra backup node floGlobals.backupNodes.pop() // remove the last extra backup node
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
}) })
@ -9140,7 +9152,7 @@ Bitcoin.Util = {
floGlobals.storedList.push(event.snfloID) floGlobals.storedList.push(event.snfloID)
initIndexedDBforSupernodeDataStorage(event.snfloID).then(result => { initIndexedDBforSupernodeDataStorage(event.snfloID).then(result => {
reactor.dispatchEvent("request_data",{holder:event.from, snfloID:event.snfloID}) reactor.dispatchEvent("request_data",{holder:event.from, snfloID:event.snfloID})
}).catch(error => console.log(error)) }).catch(error => console.error(error))
} }
}) })