From 3ef0330758d1c15dce92d2f87e5343a05446300c Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 1 Mar 2019 16:50:20 +0530 Subject: [PATCH 1/9] fixed nearest supernode discovery issue --- supernode/index.html | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 88adc94..c36ddc1 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -36349,10 +36349,10 @@ `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - #!#supernodesPubKeys=02B2D2F40EC5BC9D336BAF14017D629B3A96892D5E86095923A50A734E2364FB34, + #!#supernodesPubKeys=02598B9BDBC74C4364EB9EB2D0B2E70B27FF9B28B59F708F8C3B41B351C1DE2F8A,03998939E5E2F93A0648B16F481BE4A9299BCBF0CFAA7F25C716D9A5C80B20DFFC, #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oJeYebjgWV4Hszj5oP7sfXcj1U98P5M6q4"}, - "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oH47fmrVEbSDcoXJG28BQZ4kzUpD9VTM6U"}}`; + "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"ofo48uKuhoepiv6k7QbDgsPxrFUMipqmUh"}}`; let floAssetsArray = RMAssets.split('#!#'); @@ -36570,11 +36570,18 @@ let currentNodeBucketId = localbitcoinplusplus.kademlia .floIdToKbucketId("FLO_TEST", flo_addr); - let nearestSupernode = KBucket.closest(currentNodeBucketId, 1); + let nearestSupernode = KBucket.closest(currentNodeBucketId); + + let supernodeSeedsArray = Object.values(supernodeSeedsObj).map(seed=>seed.kbucketId); + + nearestSupernodeAddressId = nearestSupernode + .filter(suSeed=>supernodeSeedsArray.includes(suSeed.data.id)) + .filter(suSeed=>suSeed.data.id !== flo_addr) + .map(suSeed=>suSeed.data); + + let nearestSupernodeAddress = Object.values(supernodeSeedsObj) + .filter(seed=>seed.kbucketId==nearestSupernodeAddressId[0].id) - nearestSupernodeAddress = Object.values(supernodeSeedsObj).filter(seed=> - nearestSupernode[0].data.id == seed.kbucketId); - seedContactArray.transport = { host: nearestSupernodeAddress[0].ip, port: nearestSupernodeAddress[0].port, @@ -39495,8 +39502,7 @@ "Please Enter a valid FLO private key if you have any. Else leave blank." ); - if (user_pvt_key.trim() == "" || user_pvt_key.length < 1) user_pvt_key = - null; + if (user_pvt_key.trim() == "" || user_pvt_key.length < 1) user_pvt_key = null; let newKeys = RM_WALLET.generateFloKeys(user_pvt_key); if (typeof newKeys == 'object' && newKeys.privateKeyWIF.length > 0 && @@ -39842,14 +39848,22 @@ break; case "send_back_shamirs_secret_supernode_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - res) { - let send_pvtkey_req = RM_RPC + readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val) + .then(function (res) { + if (typeof res=="string") { + let send_pvtkey_req = RM_RPC .send_rpc .call(this, "retrieve_shamirs_secret_supernode_pvtkey", { private_key_chunk: res }); - doSend(send_pvtkey_req); + doSend(send_pvtkey_req); + return; + } + // Supernode does not have this user's private key shares. Request shares from others + let currentNodeBucketId = localbitcoinplusplus.kademlia + .floIdToKbucketId("FLO_TEST", flo_addr); + let nearestSupernode = KBucket.closest(currentNodeBucketId, 1); + }); } break; @@ -40763,8 +40777,7 @@ var rm_configs = localbitcoinplusplus.actions.fetch_configs(async function (...fetch_configs_res) { showMessage(`Connecting to Supernode server. Please wait...`); window.bitjs = []; // Launch bitjs - localbitcoinplusplus.master_configurations.tradableAsset1.map(asset => bitjslib( - asset)); + localbitcoinplusplus.master_configurations.tradableAsset1.map(asset => bitjslib(asset)); kickInit(); }); } catch (error) { From f90b804cc0f1204f0dd84ed8b597212ca7f875c1 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 4 Mar 2019 15:11:32 +0530 Subject: [PATCH 2/9] added loading local db data into ui before connecting supernode --- supernode/index.html | 493 +++++++++++++++++++++---------------------- 1 file changed, 246 insertions(+), 247 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index c36ddc1..b3d1e7d 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -36545,12 +36545,10 @@ return Crypto.util.bytesToBase64(pubKeyBytes); }, getSupernodeSeed: function (flo_addr, flo_pub_key) { - return new Promise((resolve, reject) => { - const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; - if (typeof supernodeSeeds !== "object") throw new Error( - "Failed to get supernode seeds."); - let supernodeSeedsObj = JSON.parse(supernodeSeeds); - + return new Promise(async (resolve, reject) => { + + let nearestSupernodeAddress = await localbitcoinplusplus.kademlia.determineMySupernode(flo_addr); + const contactId = localbitcoinplusplus.kademlia.newBase64DiscoverId(flo_pub_key); const seedContactArray = { @@ -36562,6 +36560,44 @@ }, }; + seedContactArray.transport = { + host: nearestSupernodeAddress[0].ip, + port: nearestSupernodeAddress[0].port, + id: nearestSupernodeAddress[0].kbucketId + } + + const nodeDiscoveryOptions = { + seeds: seedContactArray + } + + const kdiscover = new tristanDiscover(nodeDiscoveryOptions); + + try { + let supernodeAddressUrl = `ws://${kdiscover.seeds.transport.host}:${kdiscover.seeds.transport.port}`; + resolve(supernodeAddressUrl); + } catch (error) { + reject(error); + } + }); + }, + isNodePresentInMyKbucket: function(flo_id) { + return new Promise((resolve, reject)=>{ + let kArray = KBucket.toArray(); + let kArrayFloIds = kArray.map(k=>k.data.id); + if (kArrayFloIds.includes(flo_id)) { + resolve(true); + } else { + reject(false); + } + }); + }, + determineMySupernode: function(flo_addr) { + return new Promise((resolve, reject)=>{ + const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; + if (typeof supernodeSeeds !== "object") reject( + "Failed to get supernode seeds."); + let supernodeSeedsObj = JSON.parse(supernodeSeeds); + Object.entries(supernodeSeedsObj).map(seedObj=>{ localbitcoinplusplus.kademlia.addNewUserNodeInKbucket( "FLO_TEST", seedObj[1].kbucketId, @@ -36581,28 +36617,14 @@ let nearestSupernodeAddress = Object.values(supernodeSeedsObj) .filter(seed=>seed.kbucketId==nearestSupernodeAddressId[0].id) - - seedContactArray.transport = { - host: nearestSupernodeAddress[0].ip, - port: nearestSupernodeAddress[0].port, - id: nearestSupernodeAddress[0].kbucketId - } - const nodeDiscoveryOptions = { - seeds: seedContactArray + if (nearestSupernodeAddress.length>0) { + resolve(nearestSupernodeAddress); + } else { + reject(false); } - - const kdiscover = new tristanDiscover(nodeDiscoveryOptions); - - try { - let supernodeAddressUrl = `ws://${kdiscover.seeds.transport.host}:${kdiscover.seeds.transport.port}`; - console.log(supernodeAddressUrl); - resolve(supernodeAddressUrl); - } catch (error) { - reject(error); - } - }); - }, + }) + } } @@ -36769,6 +36791,166 @@ } + + + @@ -41424,117 +41611,9 @@ })(); - - - From f2bf6d2eafc02101345cb91e7c11d10d0c6c144d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 9 Mar 2019 21:23:21 +0530 Subject: [PATCH 3/9] fixed private key build up issue, multiple ws and idb connections --- supernode/index.html | 26896 +---------------------------------------- 1 file changed, 562 insertions(+), 26334 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index b3d1e7d..592354e 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -9636,26266 +9636,7 @@ } - - + @@ -36349,10 +10090,10 @@ `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - #!#supernodesPubKeys=02598B9BDBC74C4364EB9EB2D0B2E70B27FF9B28B59F708F8C3B41B351C1DE2F8A,03998939E5E2F93A0648B16F481BE4A9299BCBF0CFAA7F25C716D9A5C80B20DFFC, + #!#supernodesPubKeys=03692E641440795B6279F548C7156775EB624CC8A27FDA94C5E3B8945EC94DE1F1,02F22822D5E887ABBDA3D5E3A51574C547FEAAC00BF01185AA56858D4C9B00334F, #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, - #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oJeYebjgWV4Hszj5oP7sfXcj1U98P5M6q4"}, - "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"ofo48uKuhoepiv6k7QbDgsPxrFUMipqmUh"}}`; + #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oURVEZQ6sPT8mwDVTGiBVPqJYqjctXYfF3"}, + "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oapBngvTbcNCSfQfzJ9RS1QYfb4ppSQ9KQ"}}`; let floAssetsArray = RMAssets.split('#!#'); @@ -36544,40 +10285,40 @@ let pubKeyBytes = Crypto.util.hexToBytes(pubKey); return Crypto.util.bytesToBase64(pubKeyBytes); }, - getSupernodeSeed: function (flo_addr, flo_pub_key) { + updateClosestSupernodeSeeds: function(flo_addr) { + return new Promise(async (resolve, reject) => { + let nearestSupernodeAddresslist = await localbitcoinplusplus.kademlia.determineClosestSupernode(flo_addr); + await removeAllinDB('myClosestSupernodes'); + nearestSupernodeAddresslist.map((nearestSupernodeAddress, index)=>{ + updateinDB('myClosestSupernodes', { + id: index+1, + ip: nearestSupernodeAddress.ip, + port: nearestSupernodeAddress.port, + trader_flo_address: nearestSupernodeAddress.kbucketId + }).then(res=>showMessage(`INFO: Updated closest supernodes list successfully.`)); + }); + }); + }, + getSupernodeSeed: function (flo_addr) { return new Promise(async (resolve, reject) => { - let nearestSupernodeAddress = await localbitcoinplusplus.kademlia.determineMySupernode(flo_addr); - - const contactId = localbitcoinplusplus.kademlia.newBase64DiscoverId(flo_pub_key); - - const seedContactArray = { - id: contactId, // Base64 encoding - data: { - publicKey: flo_pub_key, - floId: flo_addr, - msg: `Hello from ${flo_addr}!` - }, - }; - - seedContactArray.transport = { - host: nearestSupernodeAddress[0].ip, - port: nearestSupernodeAddress[0].port, - id: nearestSupernodeAddress[0].kbucketId + let nearestSupernodeAddresslist = await readAllDB('myClosestSupernodes'); + if (nearestSupernodeAddresslist.length<1) { + nearestSupernodeAddresslist = await this.updateClosestSupernodeSeeds(flo_addr); } + //let supernodeAddressUrls = []; - const nodeDiscoveryOptions = { - seeds: seedContactArray - } - - const kdiscover = new tristanDiscover(nodeDiscoveryOptions); + // nearestSupernodeAddresslist.map(nearestSupernodeAddress=>{ + // try { + // supernodeAddressUrls.push(`ws://${nearestSupernodeAddress.ip}:${nearestSupernodeAddress.port}`); + // return supernodeAddressUrls; + // } catch (error) { + // reject(error); + // } + // }); - try { - let supernodeAddressUrl = `ws://${kdiscover.seeds.transport.host}:${kdiscover.seeds.transport.port}`; - resolve(supernodeAddressUrl); - } catch (error) { - reject(error); - } + //resolve(supernodeAddressUrls); + resolve(nearestSupernodeAddresslist); }); }, isNodePresentInMyKbucket: function(flo_id) { @@ -36591,7 +10332,7 @@ } }); }, - determineMySupernode: function(flo_addr) { + determineClosestSupernode: function(flo_addr) { return new Promise((resolve, reject)=>{ const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; if (typeof supernodeSeeds !== "object") reject( @@ -36606,20 +10347,16 @@ let currentNodeBucketId = localbitcoinplusplus.kademlia .floIdToKbucketId("FLO_TEST", flo_addr); - let nearestSupernode = KBucket.closest(currentNodeBucketId); - - let supernodeSeedsArray = Object.values(supernodeSeedsObj).map(seed=>seed.kbucketId); - - nearestSupernodeAddressId = nearestSupernode - .filter(suSeed=>supernodeSeedsArray.includes(suSeed.data.id)) - .filter(suSeed=>suSeed.data.id !== flo_addr) - .map(suSeed=>suSeed.data); - - let nearestSupernodeAddress = Object.values(supernodeSeedsObj) - .filter(seed=>seed.kbucketId==nearestSupernodeAddressId[0].id) + let nearestSupernode = KBucket.closest(currentNodeBucketId, 4); + let nearestSupernodeIds = nearestSupernode.map(f=>f.data.id); + let supernodeSeedsArray = Object.values(supernodeSeedsObj) + .filter(seed=>nearestSupernodeIds.includes(seed.kbucketId)) + .sort(function(a, b){ + return nearestSupernodeIds.indexOf(a.kbucketId) - nearestSupernodeIds.indexOf(b.kbucketId); + }); - if (nearestSupernodeAddress.length>0) { - resolve(nearestSupernodeAddress); + if (supernodeSeedsArray.length>0) { + resolve(supernodeSeedsArray); } else { reject(false); } @@ -36768,14 +10505,14 @@ // This function is only useful when sender and receiver are both online. // If receiver is not online he might never get the message - messageBroadcasting: function (message, flo_id) { + messageBroadcasting: function (message, flo_id, rpc_subject="messageBroadcasting") { readDB('userPublicData', flo_id).then((res) => { pubKey = res.trader_flo_pubKey; let foo = localbitcoinplusplus.encrypt.encryptMessage(message, pubKey); const RM_RPC = new localbitcoinplusplus.rpc; let bar = RM_RPC .send_rpc - .call(this, "messageBroadcasting", foo); + .call(this, rpc_subject, foo); doSend(bar); }); }, @@ -39676,9 +13413,12 @@ function kickInit() { output = document.getElementById("output_div"); const RM_WALLET = new localbitcoinplusplus.wallets; + const BACKUP_DB = {}; + const backUpSupernodesWS = localbitcoinplusplus.backupWS = []; return new Promise(resolve => { readDB("localbitcoinUser", "00-01").then(async function (idbData) { + if (typeof idbData.myLocalFLOPublicKey == "undefined" || idbData.myLocalFLOPublicKey .trim() == '') { let user_pvt_key = prompt( @@ -39696,10 +13436,9 @@ updateinDB("localbitcoinUser", localbitcoinplusplusObj, "00-01"); wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed( - localbitcoinplusplusObj.myLocalFLOAddress, - localbitcoinplusplusObj.myLocalFLOPublicKey); + localbitcoinplusplusObj.myLocalFLOAddress); - await startWebSocket(wsUri); + await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); // Add new user node in Kademlia addDB('kBucketStore', { @@ -39723,6 +13462,22 @@ RM_WALLET.distributeShamirsSecretShares(newKeys.privateKeyWIF) .then(() => privateKeyBuilder()); + // Connect with backup supernodes + wsUri.filter((uri, index)=>{ + if(index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplusObj.myLocalFLOPublicKey)) { + return uri; + } + }).map((uri, index)=>{ + console.log(uri); + backUpSupernodesWS[index] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); + backUpSupernodesWS[index].connectWS(); + + let dbname = `su_backup_${uri.trader_flo_address}`; + BACKUP_DB[uri.trader_flo_address] = new newBackupDB(dbname); + BACKUP_DB[uri.trader_flo_address].createNewDB(); + }); + resolve(true); return; @@ -39733,15 +13488,61 @@ } } - wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress, - idbData.myLocalFLOPublicKey); + wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); + + // Connect with primary supernodes + startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); - resolve(startWebSocket(wsUri)); + // Connect with backup supernodes + wsUri.filter((uri, index)=>{ + if(index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(idbData.myLocalFLOPublicKey)) { + return uri; + } + }).map((uri, index)=>{ + console.log(uri); + backUpSupernodesWS[index] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); + backUpSupernodesWS[index].connectWS(); + + let dbname = `su_backup_${uri.trader_flo_address}`; + BACKUP_DB[uri.trader_flo_address] = new newBackupDB(dbname); + BACKUP_DB[uri.trader_flo_address].createNewDB(); + }); + + resolve(true); }); }); } + const backupSupernodesWebSocketObject = localbitcoinplusplus.backupWS = function(ws_url) { + this.ws_url = ws_url; + this.ws_connection = null; + } + backupSupernodesWebSocketObject.prototype = { + + handle_backup_server_messages(evt) { + var response = evt.data; + console.log('backup response: '+response); + }, + + connectWS() { + this.ws_connection = new WebSocket(this.ws_url); + this.ws_connection.onopen = function (evt) { + showMessage(`Connected to backup Supernode sever: ${this.ws_url}.`); + }.bind(this); + this.ws_connection.onclose = function (evt) { + showMessage(`Disconnected to backup Supernode sever: ${this.ws_url}.`); + }.bind(this); + this.ws_connection.onmessage = function (evt) { + this.handle_backup_server_messages(evt); + }.bind(this); + this.ws_connection.onerror = function (evt) { + console.error(evt); + }; + }, + } + function startWebSocket(wsUri) { return new Promise((resolve, reject) => { websocket = new WebSocket(wsUri); @@ -39763,12 +13564,12 @@ function onOpen(evt) { loadExternalFiles(); dataBaseUIOperations(); - showMessage(`Connected successfully to Supernode: ${wsUri}.`); + showMessage(`Connected successfully to Supernode: ws://${wsUri[0].ip}.${wsUri[0].port}`); writeToScreen("CONNECTED"); } function onClose(evt) { - showMessage(`Disconnected to Supernode sever: ${wsUri}.`); + showMessage(`Disconnected to Supernode sever: ws://${wsUri[0].ip}.${wsUri[0].port}`); writeToScreen("DISCONNECTED"); } @@ -40035,7 +13836,7 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val) .then(function (res) { - if (typeof res=="string") { + if (typeof res=="object") { let send_pvtkey_req = RM_RPC .send_rpc .call(this, "retrieve_shamirs_secret_supernode_pvtkey", { @@ -40044,11 +13845,6 @@ doSend(send_pvtkey_req); return; } - // Supernode does not have this user's private key shares. Request shares from others - let currentNodeBucketId = localbitcoinplusplus.kademlia - .floIdToKbucketId("FLO_TEST", flo_addr); - let nearestSupernode = KBucket.closest(currentNodeBucketId, 1); - }); } break; @@ -40471,6 +14267,92 @@ } break; + case "supernode_to_supernode_backup_request": + + // RM_RPC.filter_legit_requests(function (is_valid_request) { + // if (is_valid_request === true) { + let data = res_obj.params[0]; + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", + "crypto_balances", "cash_balances", "userPublicData" + ]; + localbitcoinplusplus.actions.get_sharable_db_data(tableArray) + .then(function (su_db_data) { + su_db_data.trader_flo_address = data.trader_flo_address; + + let msg_sha256 = Crypto.SHA256(JSON.stringify(su_db_data)); + + localbitcoinplusplus.encrypt + .messageBroadcasting(msg_sha256, data.trader_flo_address, + "supernode_to_supernode_backup_response"); + + // if (typeof su_db_data == "object") { + // su_db_data.trader_flo_address = data.trader_flo_address; + // let server_sync_response = RM_RPC + // .send_rpc + // .call(this, "supernode_to_supernode_backup_response", + // su_db_data); + // doSend(server_sync_response); + // } + }) + // } + // }) + break; + + case "supernode_to_supernode_backup_response": + console.log(res_obj.params[0]); + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let su_db_data = res_obj.params[0]; + + let db_data = localbitcoinplusplus.encrypt.decryptMessage(su_db_data.secret, su_db_data.senderPublicKeyString); + console.log(db_data); + return; + + if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || + su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + ) return false; + + // const BACKUP_DB = new newBackupDB(); + // BACKUP_DB.createNewDB(); + + (async function () { + for (let tableStoreName in su_db_data) { + // skip loop if the property is from prototype + if (tableStoreName == 'trader_flo_address' || !su_db_data.hasOwnProperty( + tableStoreName)) continue; + + try { + let obj = su_db_data[tableStoreName]; + if (["crypto_balances", "cash_balances", "userPublicData"].includes( + tableStoreName)) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await BACKUP_DB.backup_updateinDB(tableStoreName, obj[prop], obj[ + prop].trader_flo_address); + } + } + } else { + let resdbdata = await BACKUP_DB.backup_removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await BACKUP_DB.backup_addDB(resdbdata, obj[prop]); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + + } + break; + case "messageBroadcasting": console.log(res_obj); try { @@ -40799,7 +14681,17 @@ unique: false }); } - + if (!db.objectStoreNames.contains('myClosestSupernodes')) { + var objectStore = db.createObjectStore("myClosestSupernodes", { + keyPath: 'id' + }); + objectStore.createIndex('trader_flo_address', 'trader_flo_address', { + unique: true + }); + objectStore.createIndex('ip', 'ip', { + unique: false + }); + } } function readDB(tablename, id) { @@ -40933,6 +14825,319 @@ } + + + - + + @@ -10069,12 +10069,21 @@ // btcTradeMargin is tolerable difference between Crypto trader should deposit and cryptos he actually deposited RMAssets = `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 - #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - #!#supernodesPubKeys=03692E641440795B6279F548C7156775EB624CC8A27FDA94C5E3B8945EC94DE1F1,02F22822D5E887ABBDA3D5E3A51574C547FEAAC00BF01185AA56858D4C9B00334F, + #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, + 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, - #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oURVEZQ6sPT8mwDVTGiBVPqJYqjctXYfF3"}, - "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oapBngvTbcNCSfQfzJ9RS1QYfb4ppSQ9KQ"}}`; + #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"127.0.0.1","port":"9001","kbucketId":"oZxHcbSf1JC8t5GjutopWYXs7C6Fe9p7ps"}, + "ranchimall2":{"ip":"127.0.0.1","port":"9002","kbucketId":"oTWjPupy3Z7uMdPcu5uXd521HBkcsLuSuM"}, + "ranchimall3":{"ip":"127.0.0.1","port":"9003","kbucketId":"odYA6KagmbokSh9GY7yAfeTUZRtZLwecY1"}}`; + // RMAssets = + // `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, + // #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 + // #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + // #!#supernodesPubKeys=03692E641440795B6279F548C7156775EB624CC8A27FDA94C5E3B8945EC94DE1F1,02F22822D5E887ABBDA3D5E3A51574C547FEAAC00BF01185AA56858D4C9B00334F, + // #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, + // #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oURVEZQ6sPT8mwDVTGiBVPqJYqjctXYfF3"}, + // "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oapBngvTbcNCSfQfzJ9RS1QYfb4ppSQ9KQ"}}`; let floAssetsArray = RMAssets.split('#!#'); @@ -10086,7 +10095,7 @@ let k = assets_string.split('='); if (k[1].indexOf(',') > 0) { k[1] = k[1].split(',') - .map(val => !isNaN(val) ? parseFloat(val) : val) + .map(val => !isNaN(val) ? parseFloat(val) : val.trim()) .filter(v => ![null, "", undefined, NaN].includes(v)); } else if (!isNaN(k[1])) { k[1] = parseFloat(k[1]); @@ -10196,7 +10205,7 @@ t += ``; }); - t += ` `; + t += ``; modalWindow(t); } @@ -10847,14 +10856,39 @@ } return false; }, + manually_assign_my_private_key: function() { + readDB('localbitcoinUser', '00-01').then(usr=>{ + if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) { + const RM_WALLET = new localbitcoinplusplus.wallets; + const pk_manual = prompt("Please enter your private key: "); + let gen_new_keys = RM_WALLET.generateFloKeys(pk_manual); + if (gen_new_keys.address==usr.myLocalFLOAddress) { + //localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY = gen_new_keys.privateKeyWIF; + Object.defineProperty(localbitcoinplusplus.wallets, 'MY_SUPERNODE_PRIVATE_KEY', { + value: gen_new_keys.privateKeyWIF, + writable: false, + configurable: false, + enumerable: false + }); + return true; + } else { + let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; + showMessage(mes); + throw new Error(mes); + } + } + }).catch(e=>{ + let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; + showMessage(mes); + throw new Error(mes); + }); + }, rebuild_my_private_key: function (transactionKey) { const RM_WALLET = new localbitcoinplusplus.wallets; let my_pvt_key = RM_WALLET.rebuild_private_key(MY_PRIVATE_KEY_SHAMIRS_SHARES, transactionKey); - if (typeof my_pvt_key == "undefined") { - showMessage(`WARNING: Failed to create your private keys.`); - throw new Error(`Failed to create your private keys.`); - } + if (typeof my_pvt_key == "undefined") return this.manually_assign_my_private_key(); + Object.defineProperty(localbitcoinplusplus.wallets, 'MY_SUPERNODE_PRIVATE_KEY', { value: my_pvt_key, writable: false, @@ -13445,7 +13479,7 @@ localbitcoinplusplusObj.myLocalFLOAddress = newKeys.address; localbitcoinplusplusObj.myLocalFLOPublicKey = newKeys.pubKeyHex; - // launch KBucekts + // launch KBuckets launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket(newKeys.address); if (!launchKBuckects) { @@ -13709,7 +13743,7 @@ writeToScreen("DISCONNECTED"); } - function onMessage(evt) { + async function onMessage(evt) { var response = evt.data; var res_pos = response.indexOf('{'); if (res_pos >= 0) { @@ -13717,7 +13751,12 @@ try { var res_obj = JSON.parse(res); - if (typeof res_obj.method !== undefined) { + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid: ", isIncomingMessageValid); + + if (!isIncomingMessageValid) return; + + if (typeof res_obj.method !== "undefined") { let response_from_sever; const RM_WALLET = new localbitcoinplusplus.wallets; @@ -13995,24 +14034,37 @@ }); doSend(send_pvtkey_req); return; + } else { + let send_pvtkey_req = RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_supernode_pvtkey", ""); + doSend(send_pvtkey_req); + return; } }); } break; case "retrieve_shamirs_secret_supernode_pvtkey": + if(typeof retrieve_pvtkey_counter=="undefined") retrieve_pvtkey_counter = 0; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof localbitcoinplusplus.wallets.supernode_transaction_key == "object") { + let share = res_obj.params[0].private_key_chunk.privateKeyChunks; if (typeof share !== "undefined" && !MY_PRIVATE_KEY_SHAMIRS_SHARES.includes(share)) { MY_PRIVATE_KEY_SHAMIRS_SHARES.push(share); } if (MY_PRIVATE_KEY_SHAMIRS_SHARES.length == 5) { RM_WALLET.rebuild_my_private_key(localbitcoinplusplus.wallets.supernode_transaction_key); - return; + } + } else { + if (retrieve_pvtkey_counter>5 && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "undefined") { + RM_WALLET.manually_assign_my_private_key(); + return; } } + retrieve_pvtkey_counter++; break; case "send_back_shamirs_secret_btc_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -14529,6 +14581,10 @@ ); break; + case "backup_server_sync_response": + console.log(res_obj); + break; + default: break; } @@ -14546,10 +14602,128 @@ } function doSend(message) { - writeToScreen("SENT: " + message); - websocket.send(message); + + const request_array = [ + 'update_external_file_request', + 'send_back_shamirs_secret_supernode_pvtkey', + 'addNewKbucketNode', + 'sync_with_supernode', + 'add_user_public_data' + ]; + + let finalMessage = message; + + const msgObj = JSON.parse(message); + + if (!request_array.includes(msgObj.method)) { + const RM_WALLET = new localbitcoinplusplus.wallets; + + if (typeof message !== "string") { + message = JSON.stringify(message); + } + const message256hash = Crypto.SHA256(message); + + if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") + throw new Error(`Private key could not be found.`); + + const nodeSignedMessage = RM_WALLET.sign(message256hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); + + msgObj.nodeMessage256hash = message256hash; + msgObj.nodeSignedMessage = nodeSignedMessage; + msgObj.nodePubKey = localbitcoinplusplus.wallets.my_local_flo_public_key; + + finalMessage = JSON.stringify(msgObj); + } + + writeToScreen("SENT: " + finalMessage); + websocket.send(finalMessage); } + function validateIncomingMessage(message) { + return new Promise((resolve, reject)=>{ + if(message.length <1) { + showMessage(`WARNING: The incoming websocket message on was empty.`); + reject(false)}; + const request_array = [ + 'update_external_file_request', + 'send_back_shamirs_secret_supernode_pvtkey', + 'addNewKbucketNode', + 'sync_with_supernode', + 'add_user_public_data' + ]; + + try { + const msgObj = JSON.parse(message); + + if (request_array.includes(msgObj.method)) resolve(true); + + const getFloId = bitjs.FLO_TEST.pubkey2address(msgObj.nodePubKey); + + // Check if the public key belongs to real sender + if (getFloId !== msgObj.globalParams.senderFloId) { + showMessage(`Sender FLO address did not match signer FLO address.`); + reject(false) + } + const initialMsgObj = { + jsonrpc:msgObj.jsonrpc, + id:msgObj.id, + method:msgObj.method, + params:msgObj.params, + globalParams:msgObj.globalParams, + } + + const initialMsgObjStr = JSON.stringify(initialMsgObj); + console.log(initialMsgObjStr); + + const initialMsgObjStrHash = Crypto.SHA256(initialMsgObjStr); + console.log(initialMsgObjStrHash); + + const RM_WALLET = new localbitcoinplusplus.wallets; + if (RM_WALLET.verify(initialMsgObjStrHash, msgObj.nodeSignedMessage, msgObj.nodePubKey)) { + resolve(true); + } else { + showMessage(`WARNING: Incoming Websocket message verification failed.`) + reject(false); + } + + } catch (error) { + reject(error); + } + }) + } + + // function doSendToBackupServers(message) { + // try { + // const supernodesFloAddrList = localbitcoinplusplus.master_configurations.supernodesPubKeys + // .map(fid=>bitjs.FLO_TEST.pubkey2address(fid)); + + // const messageObject = JSON.parse(message) + + // if(!supernodesFloAddrList.includes(messageObject.globalParams.senderFloId)) return; + + // if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") + // throw new Error(`Private key could not be found.`); + + // const RM_WALLET = localbitcoinplusplus.wallets; + + // const supernodeSignedMessage = RM_WALLET.sign(message, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); + + // messageObject.supernodeSignedMessage = supernodeSignedMessage; + // messageObject.supernodePubKey = localbitcoinplusplus.wallets.my_local_flo_public_key; + // messageObject.messageForOnlySupernodes = true; + // messageObject.method = `backup_${messageObject.method}`; + + // const messageString = JSON.stringify(messageObject); + + // supernodesFloAddrList.map(flo_id=>localbitcoinplusplus.encrypt + // .messageBroadcasting(messageString, flo_id, messageObject.method)); + + // } catch (error) { + // console.error(error); + // } + + // } + function writeToScreen(message) { // var pre = document.createElement("p"); // pre.style.wordWrap = "break-word"; @@ -14683,7 +14857,7 @@ var db; const DBName = "localbitcoinDB"; - var request = window.indexedDB.open(DBName, 1); + const request = window.indexedDB.open(DBName, 1); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -15413,26 +15587,8 @@ txKey[0][0]; resolve(true); } else { - readDB('localbitcoinUser', '00-01').then(usr=>{ - if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) { - const RM_WALLET = new localbitcoinplusplus.wallets; - const pk_manual = prompt("Please enter your private key: "); - let gen_new_keys = RM_WALLET.generateFloKeys(pk_manual); - if (gen_new_keys.address==usr.myLocalFLOAddress) { - localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY = gen_new_keys.privateKeyWIF; - resolve(true); - } else { - let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; - showMessage(mes); - reject(mes); - } - } - }).catch(e=>{ - let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; - showMessage(mes); - reject(mes); - }); - + const RM_WALLET = new localbitcoinplusplus.wallets; + RM_WALLET.manually_assign_my_private_key(); } }) } diff --git a/supernode/websocket_chat b/supernode/websocket_chat index c882df30f722eb3013245b73f4ff734fde0b1d3a..a51368cf0e056be1caee388a76a97549a53c1d0a 100755 GIT binary patch delta 59 zcmV-B0L1^;j1Sn153qy+6s&b;I7x#Xx`6S_qqG%gSjW0ST!WYbx0nI}udo3#w@9-A R!*BsHhYTbFw+ti$Orj3L7sLPn delta 59 zcmV-B0L1^;j1Sn153qy+6v;L;6Uif}%uO&;R%V%w&^Fy~!Go9rx0nI}udo3yw@9-A R!*BsGhYTbFw+ti$OrrD`7eoL6 diff --git a/supernode/websocket_chat.c b/supernode/websocket_chat.c index d0c42b8..084e547 100644 --- a/supernode/websocket_chat.c +++ b/supernode/websocket_chat.c @@ -6,7 +6,7 @@ #include "mongoose.h" static sig_atomic_t s_signal_received = 0; -static const char *s_http_port = "9000"; +static const char *s_http_port = "9001"; static struct mg_serve_http_opts s_http_server_opts; static void signal_handler(int sig_num) { From c1f950a3e99ea45b984875a16b972d7c2dc4d73b Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 27 Mar 2019 21:03:30 +0530 Subject: [PATCH 8/9] fixed kbucket errors --- supernode/index.html | 378 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 322 insertions(+), 56 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index a0b53c0..4abf163 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10328,8 +10328,7 @@ restoreSupernodeKBucket: function() { return new Promise((resolve, reject)=>{ const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; - if (typeof supernodeSeeds !== "object") reject( - "Failed to get supernode seeds."); + if (typeof supernodeSeeds !== "object") reject("Failed to get supernode seeds."); let supernodeSeedsObj = JSON.parse(supernodeSeeds); Object.entries(supernodeSeedsObj).map(seedObj=>{ @@ -10340,7 +10339,7 @@ }, updateClosestSupernodeSeeds: function(flo_addr) { return new Promise(async (resolve, reject) => { - let nearestSupernodeAddresslist = await localbitcoinplusplus.kademlia.determineClosestSupernode(flo_addr); + let nearestSupernodeAddresslist = await localbitcoinplusplus.kademlia.addClosestSupernodeInDB(flo_addr); await removeAllinDB('myClosestSupernodes'); nearestSupernodeAddresslist.map((nearestSupernodeAddress, index)=>{ updateinDB('myClosestSupernodes', { @@ -10358,7 +10357,7 @@ if (nearestSupernodeAddresslist.length<1) { nearestSupernodeAddresslist = await this.updateClosestSupernodeSeeds(flo_addr); } - this.restoreSupernodeKBucket(flo_addr, "FLO_TEST", supernodeKBucket); + //this.restoreSupernodeKBucket(flo_addr, "FLO_TEST", supernodeKBucket); resolve(nearestSupernodeAddresslist); }); }, @@ -10372,12 +10371,36 @@ reject(false); } }); + }, + determineClosestSupernode: function(flo_addr, KB=supernodeKBucket, n=1) { + return new Promise((resolve, reject)=>{ + let msg = ``; + if (typeof KB !== "object") { + msg = `ERROR: Supernode KBucket not found.`; + showMessage(msg); + reject(msg); + return false; + } + + try { + let isFloIdUint8 = flo_addr instanceof Uint8Array; + if (!isFloIdUint8) { + flo_addr = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_addr); + } + const closestSupernode = KB.closest(flo_addr, n); + resolve(closestSupernode); + return true; + } catch (error) { + showMessage(error); + reject(error); + return false; + } + }) }, - determineClosestSupernode: function(flo_addr, KB=KBucket) { + addClosestSupernodeInDB: function(flo_addr, KB=KBucket) { return new Promise((resolve, reject)=>{ const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; - if (typeof supernodeSeeds !== "object") reject( - "Failed to get supernode seeds."); + if (typeof supernodeSeeds !== "object") reject("Failed to get supernode seeds."); let supernodeSeedsObj = JSON.parse(supernodeSeeds); Object.entries(supernodeSeedsObj).map(seedObj=>{ @@ -10561,6 +10584,7 @@ transmitMessageToMiddleMan: function (dataToBeSentToReceiver, receiverFloAddress) { const RM_RPC = new localbitcoinplusplus.rpc; + dataToBeSentToReceiver.sender_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; let bar = RM_RPC .send_rpc .call(this, "MessageForMiddleman", dataToBeSentToReceiver); @@ -10863,24 +10887,23 @@ const pk_manual = prompt("Please enter your private key: "); let gen_new_keys = RM_WALLET.generateFloKeys(pk_manual); if (gen_new_keys.address==usr.myLocalFLOAddress) { - //localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY = gen_new_keys.privateKeyWIF; Object.defineProperty(localbitcoinplusplus.wallets, 'MY_SUPERNODE_PRIVATE_KEY', { value: gen_new_keys.privateKeyWIF, writable: false, configurable: false, enumerable: false }); - return true; + Promise.resolve(true); } else { let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; showMessage(mes); - throw new Error(mes); + Promise.reject(mes); } } }).catch(e=>{ let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; showMessage(mes); - throw new Error(mes); + Promise.reject(mes); }); }, rebuild_my_private_key: function (transactionKey) { @@ -10893,7 +10916,7 @@ value: my_pvt_key, writable: false, configurable: false, - enumerable: true + enumerable: false }); }, rebuild_private_key: function (private_key_shamirs_shares, transactionKey) { @@ -10986,7 +11009,8 @@ return Promise.resolve(true); } - } + }, + } @@ -11029,8 +11053,15 @@ if (!karr_floIds.includes(flo_id)) { return callback(false); } + + localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) + .then(my_closest_su=>{ + if (user_keys.address === my_closest_su[0].data.id) { + return callback(true); + } + }); } - return callback(true); + return callback(false); } } } @@ -13500,10 +13531,19 @@ showMessage(`INFO: Added Supernode Id ${d.trader_flo_address} to KBucket.`); }); + localbitcoinplusplus.kademlia.restoreSupernodeKBucket(); + await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); RM_WALLET.distributeShamirsSecretShares(newKeys.privateKeyWIF) - .then(() => privateKeyBuilder()); + .then(() => privateKeyBuilder()) + // .finally(()=>{ + // if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY=='string' + // && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length>0) { + // loadExternalFiles(); + // dataBaseUIOperations(); + // } + // }); // Connect with backup supernodes wsUri.filter((uri, index)=>{ @@ -13549,9 +13589,17 @@ showMessage(`INFO: Added Supernode Id ${d.trader_flo_address} to KBucket.`); }); + localbitcoinplusplus.kademlia.restoreSupernodeKBucket(); + // Connect with primary supernodes startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); + // rebuild private key + await privateKeyBuilder(); + + //loadExternalFiles(); + //dataBaseUIOperations(); + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wsUri[0].trader_flo_address; // Connect with backup supernodes @@ -13582,7 +13630,7 @@ } backupSupernodesWebSocketObject.prototype = { - handle_backup_server_messages(evt) { + async handle_backup_server_messages(evt) { var response = evt.data; console.log('backup response: '+response); @@ -13590,9 +13638,13 @@ if (res_pos >= 0) { var res = response.substr(res_pos); try { + + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid (Backup): ", isIncomingMessageValid); + var res_obj = JSON.parse(res); - if (typeof res_obj.method !== undefined) { + if (typeof res_obj.method !== "undefined") { let response_from_sever; const RM_WALLET = new localbitcoinplusplus.wallets; @@ -13688,6 +13740,220 @@ }); } break; + + case "trade_buy_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let buyOrders_data = res_obj.params[0]; + + if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" && + localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + buyOrders_data.supernodePubKey)) { + let isDataSignedBySuperNode = RM_WALLET + .verify(buyOrders_data.data_hash, buyOrders_data.supernode_sign, + buyOrders_data.supernodePubKey); + if (isDataSignedBySuperNode === true) { + + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + // Add buy order + backup_server_db_instance.backup_addDB("buyOrders", buyOrders_data).then(() => { + showMessage(`Your buy order is placed successfully.`); + }); + } + } + } + break; + case "trade_sell_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let sellOrders_data = res_obj.params[0]; + if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" && + localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + sellOrders_data + .supernodePubKey)) { + let isDataSignedBySuperNode = RM_WALLET + .verify(sellOrders_data.data_hash, sellOrders_data.supernode_sign, + sellOrders_data.supernodePubKey); + if (isDataSignedBySuperNode === true) { + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + // Add buy order + backup_server_db_instance.backup_addDB("sellOrders", sellOrders_data).then(() => { + showMessage(`Your sell order is placed successfully.`); + });; + } + } + } + break; + + case "deposit_asset_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj + .params[0].data == "object") { + let resp = res_obj.params[0]; + if (RM_WALLET + .verify(resp.data.depositDataHash, resp.data.order_validator_sign, resp.data.order_validator_public_key) + ) { + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + backup_server_db_instance.backup_addDB('deposit', resp.data); + if (typeof resp.withdrawer_data == "object") { + backup_server_db_instance.backup_updateinDB("withdraw_cash", resp.withdrawer_data, resp.withdrawer_data.trader_flo_address); + } + backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then(function (user) { + if (typeof user == "object" && user.myLocalFLOAddress == resp.data.trader_flo_address) { + let counterTraderAccountAddress = + `

Please pay the amount to following address:

+

${resp.msg}

`; + showMessage(counterTraderAccountAddress); + modalWindow(counterTraderAccountAddress); + } + }); + } + } + break; + + case "withdrawal_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if (RM_WALLET + .verify(res_obj.params[0].withdrawDataHash, res_obj.params[0].order_validator_sign, + res_obj.params[0].order_validator_public_key)) { + + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + backup_server_db_instance.backup_addDB('withdraw_cash', res_obj.params[0]).then(() => { + showMessage(`Your cash withdrawal request is placed successfully.`); + }); + } + } + break; + + case "cancel_trade": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let cancel_request = res_obj.params[0]; + if (cancel_request.job == "cancel_trade_request") { + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + backup_server_db_instance.backup_readDB("userPublicData", cancel_request.trader_flo_address).then((trader_data) => { + if (typeof trader_data.trader_flo_address !== "string" || typeof trader_data + .trader_flo_pubKey !== "string") { + err_msg="ERROR: Failed to cancel the trade. User is unknown."; + showMessage(err_msg); + throw new Error(err_msg); + } + tradeDB = cancel_request.trade_type == "buy" ? "buyOrders" : + "sellOrders"; + if (RM_WALLET + .verify(cancel_request.trade_id, cancel_request.signed_trade_id, + trader_data.trader_flo_pubKey)) { + backup_server_db_instance.backup_removeinDB(tradeDB, cancel_request.trade_id) + .then((id) => showMessage(`Trade Id ${id} deleted.`)); + } else { + showMessage( + `Failed to verify trade for trade id ${cancel_request.trade_id}` + ); + } + }) + } else { + showMessage("Failed to cancel trade."); + } + } + break; + + case "update_all_withdraw_cash_depositor_claim": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let depositor_claim_response_object = res_obj.params[0]; + let update_withdraw_cash_obj_data_res = { + depositor_claim: depositor_claim_response_object.depositor_claim + }; + let update_withdraw_cash_obj_data_res_str = JSON.stringify( + update_withdraw_cash_obj_data_res); + let depositor_claim_response_data_hash = Crypto.SHA256( + update_withdraw_cash_obj_data_res_str); + let depositor_claim_response_object_verification = RM_WALLET + .verify(depositor_claim_response_data_hash, depositor_claim_response_object.sign, + depositor_claim_response_object.publicKey); + + if ((depositor_claim_response_data_hash == depositor_claim_response_object.hash) && + (depositor_claim_response_object_verification == true)) { + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + backup_server_db_instance.backup_updateinDB('withdraw_cash', depositor_claim_response_object.depositor_claim, + depositor_claim_response_object.depositor_claim.id); + return true; + } + return false; + } + break; + + case "update_all_deposit_withdraw_success": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let withdraw_success_response = res_obj.params[0]; + let update_cash_balance_obj_res = { + depositor_cash_data: withdraw_success_response.depositor_cash_data + } + let update_cash_balance_obj_res_str = JSON.stringify(update_cash_balance_obj_res); + let update_cash_balance_obj_res_hash = Crypto.SHA256( + update_cash_balance_obj_res_str); + let update_cash_balance_obj_res_verification = RM_WALLET + .verify(update_cash_balance_obj_res_hash, withdraw_success_response.sign, + withdraw_success_response.publicKey); + + if ((update_cash_balance_obj_res_hash == withdraw_success_response.hash) && + update_cash_balance_obj_res_verification == true) { + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[su_backup_db_data.trader_flo_address]; + + if(typeof backup_server_db_instance !== "object") { + let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; + showMessage(backup_db_error_msg); + throw new Error(backup_db_error_msg); + }; + + backup_server_db_instance.backup_updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); + backup_server_db_instance.backup_updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); + backup_server_db_instance.backup_removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data + .trader_flo_address); + backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + return true; + } + return false; + } + break; + } } } catch(e) { @@ -13732,8 +13998,6 @@ } function onOpen(evt) { - loadExternalFiles(); - dataBaseUIOperations(); showMessage(`Connected successfully to Supernode: ws://${wsUri[0].ip}.${wsUri[0].port}`); writeToScreen("CONNECTED"); } @@ -14047,6 +14311,7 @@ case "retrieve_shamirs_secret_supernode_pvtkey": if(typeof retrieve_pvtkey_counter=="undefined") retrieve_pvtkey_counter = 0; + let runUIFunc = false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof localbitcoinplusplus.wallets.supernode_transaction_key == "object") { @@ -14057,13 +14322,23 @@ } if (MY_PRIVATE_KEY_SHAMIRS_SHARES.length == 5) { RM_WALLET.rebuild_my_private_key(localbitcoinplusplus.wallets.supernode_transaction_key); + runUIFunc = true; } } else { - if (retrieve_pvtkey_counter>5 && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "undefined") { + if (retrieve_pvtkey_counter==10 + && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "undefined" + ) { RM_WALLET.manually_assign_my_private_key(); - return; + runUIFunc = true; + retrieve_pvtkey_counter++; } } + if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY=='string' + && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length>0 && runUIFunc==true) { + loadExternalFiles(); + dataBaseUIOperations(); + return; + } retrieve_pvtkey_counter++; break; case "send_back_shamirs_secret_btc_pvtkey": @@ -14574,7 +14849,7 @@ break; case "MessageForMiddleman": - RM_RPC.filter_legit_requests(trade_balance_res.trade_infos.buyer_flo_id, + RM_RPC.filter_legit_requests(dataToBeSentToReceiver.sender_flo_address, function (is_valid_request) { console.log(is_valid_request); } @@ -14603,13 +14878,9 @@ function doSend(message) { - const request_array = [ - 'update_external_file_request', - 'send_back_shamirs_secret_supernode_pvtkey', - 'addNewKbucketNode', - 'sync_with_supernode', - 'add_user_public_data' - ]; + const request_array = ['send_back_shamirs_secret_supernode_pvtkey', + 'retrieve_shamirs_secret_supernode_pvtkey', + 'store_shamirs_secret_pvtkey_shares']; let finalMessage = message; @@ -14624,7 +14895,7 @@ const message256hash = Crypto.SHA256(message); if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") - throw new Error(`Private key could not be found.`); + throw new Error(`Private key could not be found.`); const nodeSignedMessage = RM_WALLET.sign(message256hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); @@ -14644,18 +14915,14 @@ if(message.length <1) { showMessage(`WARNING: The incoming websocket message on was empty.`); reject(false)}; - const request_array = [ - 'update_external_file_request', - 'send_back_shamirs_secret_supernode_pvtkey', - 'addNewKbucketNode', - 'sync_with_supernode', - 'add_user_public_data' - ]; + const request_array = ['send_back_shamirs_secret_supernode_pvtkey', + 'retrieve_shamirs_secret_supernode_pvtkey', + 'store_shamirs_secret_pvtkey_shares']; try { const msgObj = JSON.parse(message); - if (request_array.includes(msgObj.method)) resolve(true); + if (request_array.includes(msgObj.method)) return resolve(true); const getFloId = bitjs.FLO_TEST.pubkey2address(msgObj.nodePubKey); @@ -15585,11 +15852,13 @@ }); const TRANSACTION_KEY = localbitcoinplusplus.wallets.supernode_transaction_key = txKey[0][0]; - resolve(true); } else { const RM_WALLET = new localbitcoinplusplus.wallets; - RM_WALLET.manually_assign_my_private_key(); + await RM_WALLET.manually_assign_my_private_key(); + loadExternalFiles(); + dataBaseUIOperations(); } + resolve(true); }) } @@ -15600,9 +15869,6 @@ const RM_TRADE = new localbitcoinplusplus.trade; const RM_RPC = new localbitcoinplusplus.rpc; - // rebuild private key - privateKeyBuilder(); - try { readDB("localbitcoinUser", "00-01").then(async function (idbData) { // Declare the user flo address @@ -15617,21 +15883,21 @@ { id: MY_LOCAL_FLO_ADDRESS }); // restore k-bucket - const dbObj = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", KBucket); - const dbObjSuKB = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", supernodeKBucket); + // const dbObj = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", KBucket); + // const dbObjSuKB = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", supernodeKBucket); - if (typeof dbObj=="object") { - let addNewKNode = localbitcoinplusplus.rpc.prototype - .send_rpc - .call(this, "addNewKbucketNode", { - newKbucketNode: dbObj - }); - console.log(addNewKNode); + // if (typeof dbObj=="object") { + // let addNewKNode = localbitcoinplusplus.rpc.prototype + // .send_rpc + // .call(this, "addNewKbucketNode", { + // newKbucketNode: dbObj + // }); + // console.log(addNewKNode); - doSend(addNewKNode); - } else { - console.warn(`Failed to restore kBucket.`); - } + // doSend(addNewKNode); + // } else { + // console.warn(`Failed to restore kBucket.`); + // } readDB('userPublicData', MY_LOCAL_FLO_ADDRESS).then(function ( pubic_data_response) { From 3231b23506ca4cf12a15834bad7a239fef11a29a Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 28 Mar 2019 15:04:16 +0530 Subject: [PATCH 9/9] fixed kbucket errors --- supernode/index.html | 83 +++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 4abf163..183b165 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10315,7 +10315,12 @@ readAllDB('kBucketStore') .then(dbObject => { if (typeof dbObject=="object") { - dbObject.map(dbObj=>{ + let su_flo_addr_array = localbitcoinplusplus.master_configurations.supernodesPubKeys + .map(pubk=>bitjs.FLO_TEST.pubkey2address(pubk)); + // Prevent supernode to re-added in kbucket + dbObject + .filter(f=>!su_flo_addr_array.includes(f.data.id)) + .map(dbObj=>{ this.addNewUserNodeInKbucket(blockchain, flo_addr, dbObj.data, KB); }); } else { @@ -11060,12 +11065,14 @@ return callback(true); } }); - } - return callback(false); + } else { + return callback(false); + } } } + } else { + return callback(false); } - return callback(false); }, async receive_rpc_response(request) { @@ -14723,13 +14730,25 @@ case "addNewKbucketNode": try { - const newKbucketObjectArr = res_obj.params[0]; - newKbucketObjectArr.newKbucketNode.map(newKbucketObject=>{ - newKbucketObject_id_array = Object.values(newKbucketObject.id); - newKbucketObject_idu8 = new Uint8Array(newKbucketObject_id_array); - localbitcoinplusplus.kademlia.addNewUserNodeInKbucketAndDB("FLO_TEST", - newKbucketObject_idu8, newKbucketObject.data); - }); + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su=>{ + if (localbitcoinplusplus.wallets.my_local_flo_address !== my_closest_su[0].data.id) return; + + const newKbucketObjectObj = res_obj.params[0]; + if (typeof newKbucketObjectObj.newKbucketNode == "object") { + newKbucketObject = newKbucketObjectObj.newKbucketNode; + + newKbucketObject_id_array = Object.values(newKbucketObject.id); + newKbucketObject_idu8 = new Uint8Array(newKbucketObject_id_array); + localbitcoinplusplus.kademlia.addNewUserNodeInKbucketAndDB("FLO_TEST", + newKbucketObject_idu8, newKbucketObject.data); + } else { + let mss = `WARNING: Failed to add ${res_obj.globalParams.senderFloId} to KBucket.`; + showMessage(mss) + console.warn(mss); + } + }); + } catch (error) { console.error(error); } @@ -15877,27 +15896,29 @@ const MY_LOCAL_FLO_PUBLIC_KEY = localbitcoinplusplus.wallets.my_local_flo_public_key = idbData.myLocalFLOPublicKey; - // add/update yourself in your kbucket - await localbitcoinplusplus.kademlia.addNewUserNodeInKbucketAndDB( - "FLO_TEST", MY_LOCAL_FLO_ADDRESS, - { id: MY_LOCAL_FLO_ADDRESS }); - // restore k-bucket - // const dbObj = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", KBucket); - // const dbObjSuKB = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", supernodeKBucket); - - // if (typeof dbObj=="object") { - // let addNewKNode = localbitcoinplusplus.rpc.prototype - // .send_rpc - // .call(this, "addNewKbucketNode", { - // newKbucketNode: dbObj - // }); - // console.log(addNewKNode); - - // doSend(addNewKNode); - // } else { - // console.warn(`Failed to restore kBucket.`); - // } + const dbObj = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", KBucket); + + // Send your id to Supernode kbucket + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + let kbuck = localbitcoinplusplus.kademlia.floIdToKbucketId("FLO_TEST", MY_LOCAL_FLO_ADDRESS); + readDB('kBucketStore', kbuck).then(userKBData=>{ + if(typeof userKBData == "undefined") { + msf = `WARNING: Failed to determine KBucket Id and hence failed to send Kbucket Id to Supernode.` + showMessage(msf) + throw new Error(msf) + }; + let addNewKNode = localbitcoinplusplus.rpc.prototype + .send_rpc + .call(this, "addNewKbucketNode", { + newKbucketNode: userKBData + }); + console.log(addNewKNode); + + doSend(addNewKNode); + }) + } readDB('userPublicData', MY_LOCAL_FLO_ADDRESS).then(function ( pubic_data_response) {