From 45fd896620bb7914997b387be50722aaf4f17a01 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 10 Apr 2019 21:26:15 +0530 Subject: [PATCH 01/95] added code to add kbucket of other supernodes --- supernode/index.html | 168 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 33 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index ac1830d..2f0ed0c 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -9635,7 +9635,8 @@ btc_mainnet: "https://blockexplorer.com", btc_testnet: "https://testnet.blockexplorer.com", flo_mainnet: "https://livenet.flocha.in", - flo_testnet: "https://testnet.flocha.in" + flo_testnet: "http://ranchimall1.duckdns.org:8080" + //flo_testnet: "https://testnet.flocha.in" }, writable: false, configurable: false, @@ -10048,7 +10049,7 @@ if (request.status >= 200 && request.status < 400) { data.txs.forEach(tx => { - if (typeof tx !== undefined && typeof tx.floData == 'string' && tx.floData + if (typeof tx !== "undefined" && typeof tx.floData == 'string' && tx.floData .length > 0) { callback(tx.floData); } @@ -10255,6 +10256,22 @@ } }) }, + launchSupernodesKBucket: function() { + localbitcoinplusplus.master_configurations.supernodesPubKeys.map(pubKey=>{ + return new Promise((resolve, reject)=>{ + try { + let flo_id = bitjs.FLO_TEST.pubkey2address(pubKey); + let kname = `SKBucket_${pubKey}`; + const KBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_id) + const kbOptions = { localNodeId: KBucketId } + window[kname] = new BuildKBucket(kbOptions); + resolve(true); + } catch (error) { + reject(error); + } + }) + }) + }, addContact: function (id, data, KB=KBucket) { const contact = { id: id, @@ -10273,15 +10290,20 @@ return {decodedId:decodedId, data:data}; }, addNewUserNodeInKbucketAndDB: function (blockchain, address, data, KB=KBucket) { + let closestSupernodePubKey = localbitcoinplusplus.master_configurations + .supernodesPubKeys.filter(j=>bitjs.FLO_TEST.pubkey2address(j)==data.id); + let kbuck = this.addNewUserNodeInKbucket(blockchain, address, data, KB); readDB('kBucketStore', kbuck.decodedId).then(kres=>{ if (typeof kres=="object") { kres.data = data; + kres.primary_supernode_flo_public_key = closestSupernodePubKey[0] } else { kbuckObj={ id: kbuck.decodedId, vectorClock: 0, data: kbuck.data, + primary_supernode_flo_public_key: closestSupernodePubKey[0], last_updated_on: + new Date(), } kres = kbuckObj; @@ -10292,6 +10314,20 @@ return Promise.resolve(kbuck); }); }, + addFullKBDataInKBucketAndDB: function(full_data, KB) { + let userKBId = ''; + let isFloIdUint8 = full_data.id instanceof Uint8Array; + if (!isFloIdUint8) { + userKBId = this.floIdToKbucketId('FLO_TEST', full_data.data.id); + this.addContact(userKBId, full_data.data, KB); + full_data.id = userKBId; + } else { + this.addContact(full_data.id, full_data.data, KB); + } + updateinDB('kBucketStore', full_data) + .then(ms=>showMessage(`INFO: Added/Updated a node in DB.`)) + .catch(e=>{showMessage(`ERROR: Failed to add a node in DB.`)}); + }, floIdToKbucketId: function (blockchain, address) { const decodedId = this.decodeBase58Address(blockchain, address); const nodeIdBigInt = new BigInteger(decodedId, 16); @@ -12776,17 +12812,19 @@ sendTransaction(crypto_type, utxo_addr, utxo_addr_wif, receiver_address, receiving_amount, receiving_amount_currency = null, change_adress, callback) { let blockchain_explorer; - let divDecimal = 1; if (crypto_type == "BTC") { blockchain_explorer = localbitcoinplusplus.server.btc_mainnet; } else if (crypto_type == "BTC_TEST") { blockchain_explorer = localbitcoinplusplus.server.btc_testnet; } else if (crypto_type == "FLO") { blockchain_explorer = localbitcoinplusplus.server.flo_mainnet; - divDecimal = 100000000; } else if (crypto_type == "FLO_TEST") { blockchain_explorer = localbitcoinplusplus.server.flo_testnet; - divDecimal = 100000000; + } + + if(typeof blockchain_explorer !== "string") { + showMessage(`WARNING: Please select cryptocurrency/fiat value from select bar.`); + return false; } let url = `${blockchain_explorer}/api/addr/${utxo_addr}/utxo`; @@ -12818,7 +12856,7 @@ for (var key in utxo_list) { if (utxo_list[key].confirmations > 0) { var obj = utxo_list[key]; - sum += obj.satoshis / divDecimal; + sum += obj.amount; if (btc_eq_receiving_amount <= sum) { trx.addinput(obj.txid, obj.vout, obj.scriptPubKey); @@ -12829,9 +12867,7 @@ } } - //sum = parseFloat(sum / 100000000).toFixed(8); - - let change_amount = sum - btc_eq_receiving_amount - 0.00006060; + let change_amount = sum - btc_eq_receiving_amount - 0.00016800; trx.addoutput(receiver_address, btc_eq_receiving_amount); trx.addoutput(change_adress, change_amount); @@ -13617,7 +13653,7 @@ // launch KBucekts launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket(idbData.myLocalFLOAddress); - + if (!launchKBuckects) { const kmsg = `ERROR: Failed to build KBuckets. System cannot proceed further.`; showMessage(kmsg); @@ -13755,9 +13791,10 @@ break; case "server_sync_response": - if (typeof res_obj.params == "object" - && typeof res_obj.params[0] == "object") { + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; let su_backup_db_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; @@ -13806,11 +13843,14 @@ })(); }); - } + break; case "trade_buy_request_response": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let trade_buy_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(trade_buy_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; @@ -13844,7 +13884,10 @@ }); break; case "trade_sell_request_response": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let trade_sell_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(trade_buy_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -13875,7 +13918,10 @@ break; case "deposit_asset_request_response": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let deposit_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" @@ -13911,7 +13957,10 @@ break; case "withdrawal_request_response": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let withdrawal_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -13936,7 +13985,10 @@ break; case "cancel_trade": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let cancel_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(cancel_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -13978,7 +14030,10 @@ break; case "update_all_withdraw_cash_depositor_claim": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let withdraw_caim_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(withdraw_caim_res_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -14014,7 +14069,10 @@ break; case "update_all_deposit_withdraw_success": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let update_deposit_withdraw_claim_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(update_deposit_withdraw_claim_data.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -14051,7 +14109,10 @@ }); break; case "requestSupernodesToRemoveAUserFloIdFromTheirKBucket": - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let removeUserFromKBData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(removeUserFromKBData.trader_flo_address, function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -14065,6 +14126,38 @@ } }); break; + case "requestSupernodesKBucketData": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let reqSuKBData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(reqSuKBData.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request) return false; + if(typeof res_obj.globalParams.senderFloId !=="string") return; + let sender = res_obj.globalParams.senderFloId; + readAllDB('kBucketStore') + .then(myKBData=>{ + myKBData.receiver_flo_address = sender; + let sendBackMySupernodeKBucket = localbitcoinplusplus.rpc.prototype + .send_rpc + .call(this, "SupernodesKBucketDataResponse", myKBData); + doSend(sendBackMySupernodeKBucket); + }) + } + ); + break; + case "SupernodesKBucketDataResponse": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const reqSuKBResponseData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(reqSuKBResponseData.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request) return false; + reqSuKBResponseData.map(kd=> { + let kb = window[`SKBucket_${kd.primary_supernode_flo_public_key}`]; + localbitcoinplusplus.kademlia.addFullKBDataInKBucketAndDB(kd, kb)}) + }); + } + break; case "link_My_Local_IP_To_My_Flo_Id": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const req_params = res_obj.params[0]; @@ -14289,7 +14382,7 @@ async function onMessage(evt) { var response = evt.data; - + writeToScreen('RESPONSE: ' + response + ''); // If the message is about leaving of a node determine its FLO Id // and fire respective events let isItANodeLeavingMessage = response.search(`\\-- left`); @@ -15038,15 +15131,9 @@ newKbucketObject_id_array = Object.values(newKbucketObject.id); newKbucketObject_idu8 = new Uint8Array(newKbucketObject_id_array); - if (localbitcoinplusplus.wallets.my_local_flo_address !== my_closest_su[0].data.id) { - // User is connected to backup supernode - localbitcoinplusplus.kademlia.addNewUserNodeInKbucket("FLO_TEST", + + localbitcoinplusplus.kademlia.addNewUserNodeInKbucketAndDB("FLO_TEST", newKbucketObject_idu8, newKbucketObject.data); - } else { - // User is connected to primary supernode - localbitcoinplusplus.kademlia.addNewUserNodeInKbucketAndDB("FLO_TEST", - newKbucketObject_idu8, newKbucketObject.data); - } let removeRedundantKNode = localbitcoinplusplus.rpc.prototype .send_rpc @@ -15236,7 +15323,6 @@ return; } } - writeToScreen('RESPONSE: ' + evt.data + ''); } function onError(evt) { @@ -15452,6 +15538,7 @@ id: null, vectorClock: 0, data: null, + primary_supernode_flo_public_key: null, last_updated_on: null, } @@ -15470,7 +15557,7 @@ var db; const DBName = "localbitcoinDB"; - const request = window.indexedDB.open(DBName, 3); + const request = window.indexedDB.open(DBName, 4); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -15617,7 +15704,11 @@ if (!db.objectStoreNames.contains('kBucketStore')) { var objectStore = db.createObjectStore('kBucketStore', { keyPath: "id" - }) + }); + objectStore.createIndex('primary_supernode_flo_public_key' + , 'primary_supernode_flo_public_key', { + unique: false + }); } if (!db.objectStoreNames.contains('messages_table')) { var objectStore = db.createObjectStore("messages_table", { @@ -16247,6 +16338,17 @@ // restore k-bucket const dbObj = await localbitcoinplusplus.kademlia.restoreKbucket(MY_LOCAL_FLO_ADDRESS, "FLO_TEST", KBucket); + + // launch supernode kbucket + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { + // Build Supernodes KBuckets + launchSupernodesKBuckects = await localbitcoinplusplus.kademlia.launchSupernodesKBucket(); + // Request other supernodes KBucket data + let requestSupernodeKBData = localbitcoinplusplus.rpc.prototype + .send_rpc + .call(this, "requestSupernodesKBucketData", {}); + doSend(requestSupernodeKBData); + } // Send your id to Supernode kbucket if (!localbitcoinplusplus.master_configurations.supernodesPubKeys From 5a3a061e297ba12b9fbc91a40ffeb9e832b703d7 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 17 Apr 2019 20:22:45 +0530 Subject: [PATCH 02/95] modified supernode kbucket according to a common master flo id --- supernode/index.html | 2685 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 2613 insertions(+), 72 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 2f0ed0c..9404cb8 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -9634,9 +9634,9 @@ value: { btc_mainnet: "https://blockexplorer.com", btc_testnet: "https://testnet.blockexplorer.com", - flo_mainnet: "https://livenet.flocha.in", - flo_testnet: "http://ranchimall1.duckdns.org:8080" - //flo_testnet: "https://testnet.flocha.in" + flo_mainnet: "http://flosight.duckdns.org", + //flo_testnet: "http://testnet-flosight.duckdns.org" + flo_testnet: "https://testnet.flocha.in" }, writable: false, configurable: false, @@ -10069,7 +10069,8 @@ // remove this line later // 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, + `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 + #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, @@ -10154,6 +10155,7 @@ localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); deposit_withdraw_user_claim_obj.userPubKey = localbitcoinplusplus.wallets.my_local_flo_public_key; + deposit_withdraw_user_claim_obj.trader_flo_address = localbitcoinplusplus.wallets.my_; deposit_withdraw_user_claim_obj.hash = deposit_withdraw_user_claim_hash; deposit_withdraw_user_claim_obj.sign = deposit_withdraw_user_claim_sign; @@ -10246,17 +10248,25 @@ launchKBucket: function(flo_id) { return new Promise((resolve, reject)=>{ try { - const KBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_id) + const KBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_id); const kbOptions = { localNodeId: KBucketId } window.KBucket = new BuildKBucket(kbOptions); - window.supernodeKBucket = new BuildKBucket(kbOptions); + + const master_flo_pubKey = localbitcoinplusplus.master_configurations.masterFLOPubKey; + const master_flo_addr = bitjs.FLO_TEST.pubkey2address(master_flo_pubKey); + if(typeof master_flo_pubKey !== "string") return reject(false); + const SuKBucketId = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', master_flo_addr); + const SukbOptions = { localNodeId: SuKBucketId } + window.supernodeKBucket = new BuildKBucket(SukbOptions); + resolve(true); } catch (error) { reject(error); } - }) + }); }, launchSupernodesKBucket: function() { + localbitcoinplusplus.master_configurations.supernodesPubKeys.map(pubKey=>{ return new Promise((resolve, reject)=>{ try { @@ -10426,10 +10436,10 @@ } }); }, - determineClosestSupernode: function(flo_addr, KB=supernodeKBucket, n=1) { + determineClosestSupernode: function(flo_addr, n=1, KB=supernodeKBucket) { return new Promise((resolve, reject)=>{ let msg = ``; - if (typeof KB !== "object") { + if (typeof supernodeKBucket !== "object") { msg = `ERROR: Supernode KBucket not found.`; showMessage(msg); reject(msg); @@ -10441,7 +10451,7 @@ if (!isFloIdUint8) { flo_addr = localbitcoinplusplus.kademlia.floIdToKbucketId('FLO_TEST', flo_addr); } - const closestSupernode = KB.closest(flo_addr, n); + const closestSupernode = supernodeKBucket.closest(flo_addr, n); resolve(closestSupernode); return true; } catch (error) { @@ -10633,7 +10643,10 @@ const RM_RPC = new localbitcoinplusplus.rpc; let bar = RM_RPC .send_rpc - .call(this, rpc_subject, {data: data, receiver_flo_address: flo_id}); + .call(this, rpc_subject, {data: data, + receiver_flo_address: flo_id, + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address + }); doSend(bar); }); }, @@ -10641,6 +10654,7 @@ transmitMessageToMiddleMan: function (dataToBeSentToReceiver, receiverFloAddress) { const RM_RPC = new localbitcoinplusplus.rpc; dataToBeSentToReceiver.sender_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; + dataToBeSentToReceiver.trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address let bar = RM_RPC .send_rpc .call(this, "MessageForMiddleman", dataToBeSentToReceiver); @@ -11058,15 +11072,24 @@ const RM_RPC = new localbitcoinplusplus.rpc; let store_pvtkey_req = RM_RPC .send_rpc - .call(this, "store_shamirs_secret_pvtkey_shares", - shares); - doSend(store_pvtkey_req); + .call(this, "store_shamirs_secret_pvtkey_shares", shares); + localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) + .then(my_closest_su=>{ + store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return store_pvtkey_req; + }).then((store_pvtkey_req)=>doSend(store_pvtkey_req)) }); return Promise.resolve(true); - } }, + getSupernodePublicKeyFromFloId: function(flo_id='') { + let su_arr = localbitcoinplusplus.master_configurations.supernodesPubKeys + .map(s=>[s, bitjs.FLO_TEST.pubkey2address(s)]) + .filter(f=>f[1]==flo_id); + + return su_arr[0]; + }, } @@ -11092,7 +11115,7 @@ request.globalParams.receiverFloId = params[0].receiver_flo_address; } - return request.toString(); + return request.toString(); }, filter_legit_requests: function (flo_id=null, callback) { @@ -11203,7 +11226,7 @@ let server_response = RM_RPC .send_rpc .call(this, "supernode_message", { - "trader_flo_id": respective_trader_id, + "trader_flo_address": respective_trader_id, "receiver_flo_address": respective_trader_id, "server_msg": request.response }); @@ -11230,7 +11253,7 @@ let server_response = RM_RPC .send_rpc .call(this, "supernode_message", { - "trader_flo_id": respective_trader_id, + "trader_flo_address": respective_trader_id, "receiver_flo_address": respective_trader_id, "server_msg": server_msg }); @@ -11439,6 +11462,7 @@ data: receivedTradeInfo }; deposit_response_object.receiver_flo_address = params.trader_flo_address; + deposit_response_object.trader_flo_address = params.trader_flo_address; let deposit_request_response = RM_RPC @@ -11487,7 +11511,12 @@ "store_shamirs_secret_pvtkey_shares", shares ); - doSend(store_pvtkey_req); + + localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) + .then(my_closest_su=>{ + store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return store_pvtkey_req; + }).then(store_pvtkey_req=>doSend(store_pvtkey_req)) }); if (typeof localbitcoinplusplus @@ -11552,6 +11581,7 @@ msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, data: receivedTradeInfo, receiver_flo_address: params.trader_flo_address, + trader_flo_address: params.trader_flo_address, }; let deposit_request_response = @@ -11637,8 +11667,7 @@ updateinDB( "deposit", receivedTradeInfo, - receivedTradeInfo - .trader_flo_address + receivedTradeInfo.trader_flo_address ); let withdrawer_bank_account = withdrawer.receivinAddress; @@ -11650,6 +11679,7 @@ data: receivedTradeInfo, withdrawer_data: withdrawer, receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, }; let @@ -11678,6 +11708,7 @@ msg: `Plese send the money to following bank address: "System determined bank".`, data: receivedTradeInfo, receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, }; let deposit_request_response = @@ -11919,19 +11950,9 @@ vbl .deposited_btc_address ).then( - function ( - res - ) { - let - retrieve_pvtkey_req_id = - res[ - 0 - ] - .id; - res - [ - 0 - ] + function (res) { + let retrieve_pvtkey_req_id = res[0].id; + res[0] .btc_private_key_shamirs_id .map( bpks => { @@ -11947,10 +11968,12 @@ withdraw_id: vbl.withdraw_id } ); - doSend - ( - retrieve_pvtkey_req - ); + localbitcoinplusplus.kademlia + .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address) + .then(my_closest_su=>{ + retrieve_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return retrieve_pvtkey_req; + }).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); } ); }); @@ -12070,6 +12093,8 @@ // return back the response to client withdraw_request_db_object.receiver_flo_address = params.trader_flo_address; + withdraw_request_db_object.trader_flo_address = + params.trader_flo_address; let withdrawal_request_response = RM_RPC.send_rpc @@ -12077,9 +12102,7 @@ "withdrawal_request_response", withdraw_request_db_object ); - doSend( - withdrawal_request_response - ); + doSend(withdrawal_request_response); return true; } catch (error) { console.log(error); @@ -12253,10 +12276,7 @@ "updateUserCryptoBalanceRequest", updateUserCryptoBalanceObject ); - doSend - ( - updateUserCryptoBalanceRequestObject - ); + doSend(updateUserCryptoBalanceRequestObject); } ) @@ -12403,6 +12423,1273 @@ return request.toString(); // return to client }, + async backup_receive_rpc_response(request) { + var request = JSON.parse(request); + var params = request.params[0]; + var method = request.method; + + if (typeof params == "object" && typeof method == "string") { + + const RM_WALLET = new localbitcoinplusplus.wallets; + const RM_TRADE = new localbitcoinplusplus.trade; + const RM_RPC = new localbitcoinplusplus.rpc; + + let respective_trader_id = ''; + if (typeof params.trader_flo_address == "string") respective_trader_id = params.trader_flo_address; + request.response = {}; + let err_msg; + + if (method=="sync_with_supernode") { + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { + if (is_valid_request === true && params.job == + "SYNC_MY_LOCAL_DB_WITH_SUPERNODE_DB" && params.trader_flo_address.length > + 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) { + if (typeof su_db_data == "object") { + su_db_data.trader_flo_address = params.trader_flo_address; + su_db_data.receiver_flo_address = params.trader_flo_address; + let server_sync_response = RM_RPC + .send_rpc + .call(this, "server_sync_response", + su_db_data); + doSend(server_sync_response); + } + }); + } + }); + } + + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { + if (is_valid_request !== true) return false; + + try { + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + const my_closest_su_list = localbitcoinplusplus.kademlia.determineClosestSupernode(params.trader_flo_address); + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + // CHECK HERE IF USER IS INDULGED IN ANY MORE TRADE. IF TRUE RETURN ERROR + await backup_server_db_instance.backup_readAllDB("deposit").then(function (res) { + if (typeof res == "object" && res.length > 0) { + let canUserTrade = res.map(function (user) { + return respective_trader_id == user.trader_flo_address; + }); + if (canUserTrade.includes(true)) { + request.response = + `Trader id ${respective_trader_id} is not clear for trade currently. + You must finish your previous pending orders to qualify again to trade.`; + + const RM_RPC = new localbitcoinplusplus.rpc; + let server_response = RM_RPC + .send_rpc + .call(this, "supernode_message", { + "trader_flo_address": respective_trader_id, + "receiver_flo_address": respective_trader_id, + "server_msg": request.response + }); + doSend(server_response); + showMessage(request.response); + throw new Error(request.response); + return false; + } + } + }); + + // Check if user id is in deposit or withdraw. If true prevent him from trading + await backup_server_db_instance.backup_readAllDB('withdraw_cash').then(function (res) { + if (typeof res == "object") { + let check_deposit_withdraw_id_array = res.filter(f => f.status === 2) + .map(m => { + if (m.trader_flo_address == respective_trader_id || m.deposit_withdraw_id_array == + respective_trader_id) { + let server_msg = + `Trader id ${respective_trader_id} is not clear for trade currently. + You must finish your previous pending deposit/withdraw action to qualify again to trade.`; + + const RM_RPC = new localbitcoinplusplus.rpc; + let server_response = RM_RPC + .send_rpc + .call(this, "supernode_message", { + "trader_flo_address": respective_trader_id, + "receiver_flo_address": respective_trader_id, + "server_msg": server_msg + }); + doSend(server_response); + showMessage(server_msg); + throw new Error( + "User has not finished previous pending actions." + ); + } + }); + } + }); + } catch (error) { + throw new Error(error); + } + }); + + switch (method) { + case "trade_buy": + + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { + if (is_valid_request !== true) return false; + await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, + params.currency); + let trade_margin = await RM_TRADE.getAssetTradeAndWithdrawLimit( + params.trader_flo_address, params.product, params.currency); + if (typeof trade_margin.remaining_crypto_credit == "number" && + typeof trade_margin.remaining_fiat_credit == "number") { + if (trade_margin.remaining_fiat_credit > 0 && trade_margin.remaining_fiat_credit >= + params.buy_price) { + request.response = RM_TRADE.trade_buy.call(this, + ...request.params, + function (supernode_signed_res) { + supernode_signed_res.receiver_flo_address = params.trader_flo_address; + if (typeof supernode_signed_res == "object") { + let buy_request_response = RM_RPC + .send_rpc + .call(this, + "trade_buy_request_response", + supernode_signed_res); + doSend(buy_request_response); + // Init trading + RM_TRADE.createTradePipes(params.currency); + return true; + } + }); + } else { + err_msg = `Trade Margin Check Failed: You can only trade upto ${params.currency} ${trade_margin.remaining_fiat_credit}.`; + showMessage(err_msg); + throw new Error(err_msg); + } + } else { + err_msg = "Invalid trade margin figures."; + showMessage(err_msg); + throw new Error(err_msg); + } + + }); + break; + case "trade_sell": + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { + if (is_valid_request !== true) return false; + await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, + params.currency); + let trade_margin = await RM_TRADE.getAssetTradeAndWithdrawLimit( + params.trader_flo_address, params.product, params.currency); + if (typeof trade_margin.remaining_crypto_credit == "number" && + typeof trade_margin.remaining_fiat_credit == "number") { + let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash(params.buy_price); + if (trade_margin.remaining_crypto_credit > 0 && trade_margin.remaining_crypto_credit >= + eqCrypto) { + request.response = RM_TRADE.trade_sell.call( + this, ...request.params, + function (supernode_signed_res) { + if (typeof supernode_signed_res == "object") { + supernode_signed_res.receiver_flo_address = params.trader_flo_address; + let sell_request_response = RM_RPC + .send_rpc + .call(this, + "trade_sell_request_response", + supernode_signed_res); + doSend(sell_request_response); + // Init trading + RM_TRADE.createTradePipes(params.currency); + return true; + } + } + ); + } else { + err_msg = `WARNING: Trade Margin Check Failed: + You can only trade upto ${params.currency} ${trade_margin.remaining_fiat_credit}.`; + + showMessage(err_msg); + throw new Error(err_msg); + } + } else { + err_msg = "Invalid trade margin figures."; + showMessage(err_msg); + throw new Error(err_msg); + } + }); + break; + case "sync_with_supernode": + // already processed above + break; + case "deposit_asset_request": + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { + + if (is_valid_request !== true) return false; + + // This code will only run for supernodes + if (typeof params.product !== "undefined" && + (localbitcoinplusplus.master_configurations.tradableAsset1.includes( + params.product) || + localbitcoinplusplus.master_configurations.tradableAsset2.includes( + params.product)) && + typeof params.depositing_amount !== "undefined" && + localbitcoinplusplus.master_configurations.tradableAsset2.includes( + params.currency) && + typeof localbitcoinplusplus.master_configurations.validTradingAmount !== + 'undefined' && + localbitcoinplusplus.master_configurations.validTradingAmount.includes( + parseFloat(params.depositing_amount)) && + typeof params.trader_flo_address == "string" && + params.trader_flo_address.length > 0 + ) { + RM_WALLET.getUserPublicKey(params.trader_flo_address, + async function (requester_public_key) { + if (requester_public_key == undefined || + requester_public_key == null) { + err_msg = 'Failed to get public key of the user.'; + showMessage(err_msg); + throw new Error(err_msg); + } + params.depositor_public_key = requester_public_key; + + await RM_TRADE.resolve_current_crypto_price_in_fiat( + params.product, params.currency); + + if (localbitcoinplusplus.master_configurations.tradableAsset1 + .includes(params.product)) { + + let generate_btc_keys_for_requester = RM_WALLET + .generateFloKeys(null, params.product); + + params.id = helper_functions.unique_id(); + params.status = 1; + params.btc_address = + generate_btc_keys_for_requester.address; + + params.bitcoinToBePaid = RM_TRADE.calculateCryptoEquivalentOfCash( + params.depositing_amount, params.currency, + params.product); + + let receivedTradeInfo = { ...params }; + + if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == + "undefined") { + err_msg = 'Failed to determine Super node signing key.'; + showMessage(err_msg); + throw new Error(err_msg); + } + + backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( + function (su_data) { + if (typeof su_data == "object" && + typeof su_data.myLocalFLOPublicKey == + "string" && + su_data.myLocalFLOPublicKey.length > + 0 && + localbitcoinplusplus.master_configurations + .supernodesPubKeys + .includes(su_data.myLocalFLOPublicKey) + ) { + + let receivedTradeInfoHash = + Crypto.SHA256(JSON.stringify(receivedTradeInfo)); + + receivedTradeInfo["depositDataHash"] = receivedTradeInfoHash; + receivedTradeInfo["order_validator_sign"] = + RM_WALLET.sign(receivedTradeInfoHash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + receivedTradeInfo["order_validator_public_key"] = su_data.myLocalFLOPublicKey; + + try { + const this_btc_pvt_key = + generate_btc_keys_for_requester.privateKeyWIF; + const this_btc_tx_key = + Crypto.util.randomBytes(64); + const + this_btc_pvt_key_shamirs_secret = + RM_WALLET.createShamirsSecretShares(this_btc_pvt_key, 10, 5); + if (typeof this_btc_pvt_key_shamirs_secret == + "object" && + this_btc_pvt_key_shamirs_secret + .length > 0) { + backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); + + // Send the address to the requester + let + deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, + data: receivedTradeInfo + }; + deposit_response_object.receiver_flo_address = params.trader_flo_address; + deposit_response_object.trader_flo_address = params.trader_flo_address; + let + deposit_request_response = + RM_RPC + .send_rpc + .call(this, + "deposit_asset_request_response", + deposit_response_object + ); + doSend(deposit_request_response); + + let + this_btc_pvt_key_shamirs_secret_array = + this_btc_pvt_key_shamirs_secret + .map(chunks => { + let + chunk_ids = + Crypto.util + .bytesToHex( + Crypto + .util + .randomBytes( + 64 + )); + let + chunk_array = { + "id": chunk_ids, + "privateKeyChunks": Crypto + .AES + .encrypt( + chunks, + this_btc_tx_key + ) + }; + return chunk_array; + }); + + // Send chunks of private keys to other supernodes + this_btc_pvt_key_shamirs_secret_array + .map(shares => { + let + store_pvtkey_req = + RM_RPC + .send_rpc + .call( + this, + "store_shamirs_secret_pvtkey_shares", + shares + ); + + localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) + .then(my_closest_su=>{ + store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return store_pvtkey_req; + }).then(store_pvtkey_req=>doSend(store_pvtkey_req)) + }); + + if (typeof localbitcoinplusplus + .wallets.my_local_flo_address == + "string" && + typeof localbitcoinplusplus + .wallets.my_local_flo_public_key == + "string" && + typeof localbitcoinplusplus + .master_configurations + .supernodesPubKeys == + "object" && + localbitcoinplusplus + .master_configurations + .supernodesPubKeys.includes( + localbitcoinplusplus + .wallets.my_local_flo_public_key + )) { + try { + let + this_btc_pvt_key_shamirs_secret__id_array = + this_btc_pvt_key_shamirs_secret_array + .map(i => i.id); + let + btc_private_key_shamirs_id = + this_btc_pvt_key_shamirs_secret__id_array; + let + supernode_transaction_key = + this_btc_tx_key; + const + system_btc_reserves_private_keys_object = { + id: helper_functions + .unique_id(), + product: params + .product, + btc_address: params + .btc_address, + balance: null, + trader_flo_address: params + .trader_flo_address, + btc_private_key_shamirs_id: btc_private_key_shamirs_id, + supernode_transaction_key: supernode_transaction_key + } + backup_server_db_instance.backup_addDB( + "system_btc_reserves_private_keys", + system_btc_reserves_private_keys_object + ); + } catch (error) { + throw new Error( error); + } + } + return true; + } + } catch (error) { + throw new Error(error); + } + + // Send the address to the requester + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, + data: receivedTradeInfo, + receiver_flo_address: params.trader_flo_address, + trader_flo_address: params.trader_flo_address, + }; + + let deposit_request_response = + RM_RPC.send_rpc + .call(this, + "deposit_asset_request_response", + deposit_response_object + ); + doSend(deposit_request_response); + return true; + } + }); + + return false; + + } else if (!localbitcoinplusplus.master_configurations + .tradableAsset1.includes(params.product)) { + params.id = helper_functions.unique_id(); + params.status = 1; + // IMPORTANT - If deposit is a fiat make sure product and currency are both same + params.currency = params.product; + let receivedTradeInfo = { ...params }; + + backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( + function (su_data) { + if (typeof su_data == "object" && + typeof su_data.myLocalFLOPublicKey == + "string" && + su_data.myLocalFLOPublicKey.length > + 0 && + localbitcoinplusplus.master_configurations + .supernodesPubKeys + .includes(su_data.myLocalFLOPublicKey) + ) { + let receivedTradeInfoHash = + Crypto.SHA256(JSON.stringify( + receivedTradeInfo)); + + receivedTradeInfo[ + "depositDataHash"] = + receivedTradeInfoHash; + receivedTradeInfo[ + "order_validator_sign"] = + RM_WALLET.sign( + receivedTradeInfoHash, + localbitcoinplusplus.wallets + .MY_SUPERNODE_PRIVATE_KEY + ); + receivedTradeInfo[ + "order_validator_public_key" + ] = su_data.myLocalFLOPublicKey; + + // YOU NEED TO DETERMINE A BANK ACCOUNT HERE IF NO ONE IS WITHDRAWING + try { + backup_server_db_instance.backup_addDB("deposit", + receivedTradeInfo); + backup_server_db_instance.backup_readDBbyIndex( + "withdraw_cash", + "status", 1).then( + function ( + withdrawers_list + ) { + if (typeof withdrawers_list == + "object") { + if ( + withdrawers_list.length > 0) { + withdrawers_list.filter( + wd => wd.currency == + params.currency).map( + function (withdrawer) { + if ( + withdrawer.withdraw_amount == + params.depositing_amount && + withdrawer.currency == + params.currency + ) { + withdrawer.status = 2; // A depositor has been asked to deposit money + withdrawer.depositor_found_at = + new Date(); + withdrawer.depositor_flo_id = receivedTradeInfo.trader_flo_address; + backup_server_db_instance.backup_updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); + + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account + backup_server_db_instance.backup_updateinDB( + "deposit", + receivedTradeInfo, + receivedTradeInfo.trader_flo_address + ); + + let withdrawer_bank_account = withdrawer.receivinAddress; + + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Plese send the money to following bank address: "${withdrawer_bank_account}"`, + data: receivedTradeInfo, + withdrawer_data: withdrawer, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, + }; + + let + deposit_request_response = + RM_RPC.send_rpc.call( + this, + "deposit_asset_request_response", + deposit_response_object + ); + + doSend(deposit_request_response); + return true; + } else { + err_msg = "Deposit request failed: We could not find a withdrawer."; + showMessage(err_msg); + throw new Error(err_msg); + } + } + ); + } else { + //No one is withdrawing so provide your bank details + let + deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Plese send the money to following bank address: "System determined bank".`, + data: receivedTradeInfo, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, + }; + let + deposit_request_response = + RM_RPC + .send_rpc + .call( + this, + "deposit_asset_request_response", + deposit_response_object + ); + + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account + updateinDB + ( + "deposit", + receivedTradeInfo, + receivedTradeInfo + .trader_flo_address + ); + + doSend(deposit_request_response); + return true; + } + } + }); + } catch (error) { + err_msg = "Deposit request failed: We could not find a withdrawer. Come again later."; + showMessage(err_msg); + throw new Error(err_msg); + } + + } + }); + } + }); + + } else { + err_msg = "deposit asset request error"; + showMessage(err_msg); + throw new Error(err_msg); + } + }); + break; + case "withdraw_request_method": + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { + + if (is_valid_request !== true) return false; + + if (typeof params.product !== "undefined" && + (localbitcoinplusplus.master_configurations.tradableAsset1.includes( + params.product) || + localbitcoinplusplus.master_configurations.tradableAsset2.includes( + params.currency)) && + typeof params.withdrawing_amount !== "undefined" && + typeof localbitcoinplusplus.master_configurations.validTradingAmount !== + 'undefined' && + localbitcoinplusplus.master_configurations.validTradingAmount.includes( + parseFloat(params.withdrawing_amount)) && + typeof params.trader_flo_address == "string" && params.trader_flo_address + .length > 0 && + typeof params.receivinAddress == "string" && params.receivinAddress + .length > + 0 && typeof params.currency == "string" + ) { + await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, + params.currency); + let trade_margin = await RM_TRADE.getAssetTradeAndWithdrawLimit( + params.trader_flo_address, params.product, params.currency + ); + + if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( + params.product)) { + let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( + params.withdrawing_amount); + if (trade_margin.remaining_crypto_credit < 0 && + trade_margin.remaining_crypto_credit < eqCrypto) { + err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` + showMessage(err_msg); + throw new Error(err_msg); + } + } else { + if (trade_margin.remaining_fiat_credit < 0 && trade_margin.remaining_fiat_credit < + params.withdrawing_amount) { + err_msg = `Insufficient fiat balance to withdraw. You can withdraw upto: ${params.currency} ${trade_margin.remaining_fiat_credit}`; + showMessage(err_msg); + throw new Error(err_msg); + } + } + + params.id = helper_functions.unique_id(); + params.status = 1; + if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( + params.product)) { + // Check how much cryptos the user can withdraw + let withdrawer_btc_id = + `${params.trader_flo_address}_${params.product}`; + backup_server_db_instance.backup_readDB("crypto_balances", withdrawer_btc_id).then(function ( + btc_balance_res) { + if (typeof btc_balance_res == "object" && + typeof btc_balance_res + .trader_flo_address == "string" && + btc_balance_res.crypto_balance > 0) { + let withdrawer_btc_balance = parseFloat( + btc_balance_res.crypto_balance); + let withdrawing_btc_amount_in_cash = + parseFloat(params.withdrawing_amount); + if (!localbitcoinplusplus.master_configurations + .tradableAsset2.includes(params.currency) + ) { + err_msg = "Invalid or unsupported currency."; + showMessage(err_msg); + throw new Error(err_msg); + } + let eqBTC = RM_TRADE.calculateCryptoEquivalentOfCash( + withdrawing_btc_amount_in_cash, + params.currency, params.product); + eqBTC = parseFloat(eqBTC).toFixed(8); + let withdrawer_new_btc_balance = + withdrawer_btc_balance - eqBTC; + if (withdrawer_new_btc_balance > 0 && + withdrawer_btc_balance > 0 && + withdrawing_btc_amount_in_cash > 0 && + eqBTC > 0 && eqBTC <= + withdrawer_btc_balance) { + + // Now details of Bitcoins can be sent to withdrawer + + /**************************************************************************** + ***********IMPORTANT: CHANGE RECEIVING ADDRESS TO BTC THAN FLO HERE********** + ***********AND DO SOMETHING ABOUT PRIVATE KEY BELOW************************** + ****************************************************************************/ + let sum_total_btc = 0; + let valid_utxo_list = []; + let receiverBTCAddress = params.receivinAddress + .trim(); + + backup_server_db_instance.backup_readAllDB("deposit").then(function ( + deposit_list) { + if (typeof deposit_list == + "object" && + deposit_list.length > 0 + ) { + deposit_list = + deposit_list.filter( + deposits => + deposits.status == + 2 && + localbitcoinplusplus + .master_configurations + .tradableAsset1 + .includes( + deposits.product + ) && + params.product == + deposits.product + ); + for (const dl in + deposit_list) { + if (deposit_list.hasOwnProperty( + dl)) { + const deposit_dl = + deposit_list[ + dl]; + sum_total_btc += + parseFloat( + deposit_dl + .bitcoinToBePaid + ); + + if (eqBTC <= + sum_total_btc + ) { + valid_utxo_list + .push( + deposit_dl + ); + break; + } else { + valid_utxo_list + .push( + deposit_dl + ); + } + } + } + let valid_btc_list = + valid_utxo_list.map( + deposit_arr => { + deposit_arr + .status = + 3 // Deposited Bitcoin is under process + backup_server_db_instance.backup_updateinDB( + "deposit", + deposit_arr, + deposit_arr + .trader_flo_address + ); + + // save the address and id in a table + let + withdraw_id = + helper_functions + .unique_id(); + const + withdraw_btc_order_object = { + id: withdraw_id, + trader_flo_address: params + .trader_flo_address, + utxo_addr: deposit_arr + .btc_address, + receiverBTCAddress: params + .receivinAddress, + receiverBTCEquivalentInCash: withdrawing_btc_amount_in_cash, + currency: params + .currency, + product: params + .product, + change_adress: deposit_arr + .btc_address, + timestamp: + new Date() + } + backup_server_db_instance.backup_addDB( + 'withdraw_btc', + withdraw_btc_order_object + ); + return { + withdraw_id: withdraw_id, + deposited_btc_address: deposit_arr + .btc_address + }; + }); + + // doSend btc_private_key_shamirs_id from system_btc_reserves_private_keys + valid_btc_list.map(vbl => { + readDBbyIndex + ( + 'system_btc_reserves_private_keys', + 'btc_address', + vbl + .deposited_btc_address + ).then( + function (res) { + let retrieve_pvtkey_req_id = res[0].id; + res[0] + .btc_private_key_shamirs_id + .map( + bpks => { + let + retrieve_pvtkey_req = + RM_RPC + .send_rpc + .call( + this, + "send_back_shamirs_secret_btc_pvtkey", { + retrieve_pvtkey_req_id: retrieve_pvtkey_req_id, + chunk_val: bpks, + withdraw_id: vbl.withdraw_id + } + ); + localbitcoinplusplus.kademlia + .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address) + .then(my_closest_su=>{ + retrieve_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return retrieve_pvtkey_req; + }).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); + } + ); + }); + }); + + } + }); + + } else { + err_msg = `Withdrawal request failed: You are trying to withdraw more Bitcoins than you have.`; + showMessage(err_msg); + throw new Error(err_msg); + + // Return error to the requester + return { + error: true, + method: "withdrawal_request_response", + data: "Withdrawal request failed: You are trying to withdraw more Bitcoins than you have." + }; + } + } else { + err_msg = + `Withdrawal request failed: You don't seem to have any Bitcoin balance in the system yet. + Please buy some Bitcoins to withdraw.`; + showMessage(err_msg); + + // Return error to the requester + return { + error: true, + method: "withdrawal_request_response", + data: `Withdrawal request failed: You don't seem to have any Bitcoin balance in the system yet. + Please buy some Bitcoins to withdraw.` + }; + } + }); + } else if (!localbitcoinplusplus.master_configurations.tradableAsset1 + .includes(params.product)) { + // Check if there's no already a withdraw cash order of this user + /*ONLY DELETE A WITHDRAW ORDER WHEN A DEPOSITOR HAS CONFIRMED DEPOSIT + AND RECEIVER HAS CONFIRMED WITHDRAW*/ + + // Check how much Cash user can withdraw + const trader_cash_id = + `${params.trader_flo_address}_${params.currency}`; + backup_server_db_instance.backup_readDB("cash_balances", trader_cash_id).then(function ( + cash_balances_res) { + if (typeof cash_balances_res == "object" && + typeof cash_balances_res + .trader_flo_address == "string" && + typeof cash_balances_res.cash_balance == + "number" && + cash_balances_res.cash_balance > 0) { + let withdrawer_cash_balance = parseFloat( + cash_balances_res.cash_balance); + let withdrawing_cash_amount = parseFloat( + params.withdrawing_amount); + let bank_details = params.receivinAddress.trim(); + + if (withdrawer_cash_balance > 0 && + withdrawing_cash_amount > 0 && + withdrawer_cash_balance >= + withdrawing_cash_amount) { + // Add it to cash withdrawal table + let withdraw_request_db_object = { + id: helper_functions.unique_id(), + trader_flo_address: params.trader_flo_address, + withdraw_amount: withdrawing_cash_amount, + currency: params.currency, + receivinAddress: bank_details, + status: 1, // withdraw request called + } + + backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( + function ( + su_data) { + if (typeof su_data == + "object" && + typeof su_data.myLocalFLOPublicKey == + "string" && + su_data.myLocalFLOPublicKey + .length > + 0 && + localbitcoinplusplus.master_configurations + .supernodesPubKeys.includes( + su_data.myLocalFLOPublicKey + )) { + + let + withdraw_request_db_object_hash = + Crypto.SHA256(JSON.stringify( + withdraw_request_db_object + )); + withdraw_request_db_object + ["withdrawDataHash"] = + withdraw_request_db_object_hash; + withdraw_request_db_object + [ + "order_validator_sign" + ] = + RM_WALLET + .sign( + withdraw_request_db_object_hash, + localbitcoinplusplus + .wallets.MY_SUPERNODE_PRIVATE_KEY + ); + withdraw_request_db_object + [ + "order_validator_public_key" + ] = su_data.myLocalFLOPublicKey; + + try { + // add the request to supernode db + backup_server_db_instance.backup_addDB( + "withdraw_cash", + withdraw_request_db_object + ); + // return back the response to client + withdraw_request_db_object.receiver_flo_address = + params.trader_flo_address; + withdraw_request_db_object.trader_flo_address = + params.trader_flo_address; + let + withdrawal_request_response = + RM_RPC.send_rpc + .call(this, + "withdrawal_request_response", + withdraw_request_db_object + ); + doSend(withdrawal_request_response); + return true; + } catch (error) { + console.log(error); + } + } + }); + + } else { + // Return error to the requester + err_msg = "Withdrawal request failed: You are trying to withdraw more cash than you have in localbitcoinplusplus account."; + showMessage(err_msg); + throw new Error(err_msg); + } + } + }); + } else { + err_msg = "withdraw request error"; + showMessage(err_msg); + throw new Error(err_msg); + } + } + }); + break; + + case "retrieve_shamirs_secret_btc_pvtkey": + RM_RPC.filter_legit_backup_requests(null, function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (typeof params.btc_private_key_array !== "string" || typeof params.retrieve_pvtkey_req_id !== + "string") return false; + + let btc_private_key_str = params.btc_private_key_array; + let retrieve_pvtkey_req_id = params.retrieve_pvtkey_req_id; + let withdraw_id = params.withdraw_id; + + try { + let btc_private_key_object = JSON.parse(btc_private_key_str); + let btc_pk_shares_array = btc_private_key_object.map(pkChunks => { + if (typeof pkChunks.private_key_chunk !== "undefined") + return pkChunks.private_key_chunk.privateKeyChunks; + }).filter(val => val !== undefined); + console.log(btc_pk_shares_array); + + backup_server_db_instance.backup_readDB('withdraw_btc', withdraw_id).then(function (withdraw_res) { + if (typeof withdraw_res == "object") { + backup_server_db_instance.backup_readDB('system_btc_reserves_private_keys', + retrieve_pvtkey_req_id).then(async function ( + btc_reserves) { + if (typeof btc_reserves == "object") { + + // Ideally this line should never run. + if (btc_reserves.product !== + withdraw_res.product) throw new Error( + "Mismatch of assets in withdrawal request." + ); + + await RM_TRADE.resolve_current_crypto_price_in_fiat( + withdraw_res.product, + withdraw_res.currency); + const EqCryptoWd = RM_TRADE.calculateCryptoEquivalentOfCash( + withdraw_res.receiverBTCEquivalentInCash, + withdraw_res.currency, + withdraw_res.product); + EqCryptoWd = parseFloat(EqCryptoWd); + + let transaction_key = + btc_reserves.supernode_transaction_key; + if (transaction_key.length > 0) { + let btc_private_key = + RM_WALLET.rebuild_private_key( + btc_pk_shares_array, + transaction_key); + //console.log(btc_private_key); + + RM_TRADE.sendTransaction( + withdraw_res.product, + withdraw_res.utxo_addr, + btc_private_key, + withdraw_res.receiverBTCAddress, + withdraw_res.receiverBTCEquivalentInCash, + withdraw_res.currency, + withdraw_res.change_adress, + async function (res) { + console.log( + res + ); + if (typeof res == + "string" && + res.length > + 0) { + try { + let + resp_obj = + JSON + .parse( + res + ); + let + resp_txid = + resp_obj + .txid + .result || + resp_obj + .txid; + let + msg = + `Transaction Id for your withdrawn crypto asset: ${resp_txid}`; + + backup_server_db_instance.backup_readDB + ( + 'crypto_balances', + withdraw_res + .id + ) + .then( + res_bal => { + btc_eq_receiving_amount + = + parseFloat( + btc_eq_receiving_amount + ) + .toFixed( + 8 + ); + res_bal + .crypto_balance -= + EqCryptoWd; + backup_server_db_instance.backup_updateinDB + ( + 'crypto_balances', + res_bal, + withdraw_res + .id + ) + .then( + res_obj => { + const + res_obj_str = + JSON + .stringify( + res_obj + ); + const + res_obj_hash = + Crypto + .SHA256( + res_obj_str + ); + const + res_obj_sign = + RM_WALLET + .sign( + res_obj_hash, + localbitcoinplusplus + .wallets + .MY_SUPERNODE_PRIVATE_KEY + ); + + const + updateUserCryptoBalanceObject = { + updatedBTCBalanceObject: res_bal, + updatedBTCBalanceObjectSign: res_obj_sign, + trader_flo_address: withdraw_res.trader_flo_address, + receiver_flo_address: withdraw_res.trader_flo_address, + } + + const + updateUserCryptoBalanceRequestObject = + RM_RPC + .send_rpc( + "updateUserCryptoBalanceRequest", + updateUserCryptoBalanceObject + ); + doSend(updateUserCryptoBalanceRequestObject); + + } + ) + + } + ); + } catch ( + error + ) { + console.warn(error); + showMessage(error); + } + } + + // Check if there's BTC left in deposited BTC. If yes update its status to 2 else delete it + + /*********************************************************************************************************************************** + *******************CHECK ACTUAL BTC BALANCE HERE THROUGH AN API AND UPDATE DEPOSIT TABLE**************************************************** + ************************************************************************************************************************************/ + + backup_server_db_instance.backup_readDBbyIndex + ( + 'deposit', + 'btc_address', + withdraw_res + .utxo_addr + ).then( + function ( + deposit_arr_resp + ) { + if ( + typeof deposit_arr_resp == + "object" + ) { + deposit_arr_resp + .map( + deposit_arr => { + deposit_arr + .bitcoinToBePaid -= + EqCryptoWd; + + if ( + deposit_arr + .bitcoinToBePaid > + 0 + ) { + // update deposits in db + deposit_arr + .status = + 2; // UTXO ready to be used again + backup_server_db_instance.backup_updateinDB + ( + "deposit", + deposit_arr, + deposit_arr + .trader_flo_address + ); + + } else { + // delete entry in deposits in db + backup_server_db_instance.backup_removeinDB + ( + "deposit", + deposit_arr + .trader_flo_address + ); + } + } + ); + return true; + } + }); + + }); + } + } + }); + } + }); + + } catch (error) { + throw new Error(error); + } + + }); + break; + + case "superNodeSignedAddUserPublicData": + if (typeof params == "object" && typeof params.data == "object") { + RM_RPC.filter_legit_backup_requests(params.data.trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (typeof params.su_pubKey == "string" && localbitcoinplusplus + .master_configurations.supernodesPubKeys.includes(params.su_pubKey)) { + let res_data_obj = { + trader_flo_address: params.data.trader_flo_address, + trader_flo_pubKey: params.data.trader_flo_pubKey, + trader_status: params.data.trader_status, + timestamp: params.data.timestamp + }; + let res_data_hash = Crypto.SHA256(JSON.stringify(res_data_obj)); + let res_data_verification = RM_WALLET + .verify(res_data_hash, params.sign, params.su_pubKey); + if ((res_data_verification == true) && res_data_hash == params.data_hash) { + backup_server_db_instance.backup_addDB('userPublicData', params.data); + return true; + } + } + }); + } + break; + + case "update_external_file_server_response": + if (typeof params == "object") { + if (params.filename == "UPDATE_ALL_FILES") { + let file_details_str = JSON.stringify(params.file_updated); + if (RM_WALLET.verify(file_details_str, + params.server_sign, params.server_pubkey)) { + params.file_updated.map(new_file => { + backup_server_db_instance.backup_updateinDB("external_files", new_file); + createScript(new_file.filename, new_file.content); + }); + return true; + } + } else { + let file_details_string = JSON.stringify(params.file_updated); + if (RM_WALLET.verify(file_details_string, + params.server_sign, params.server_pubkey)) { + backup_server_db_instance.backup_updateinDB("external_files", params.file_updated); + createScript(params.file_updated.filename, params.file_updated.content); + return true; + } + } + showMessage(`WARNING: Failed to update external files from server.`); + } + break; + + default: + showMessage("WARNING: Unknown method called for execution."); + break; + } + } + return request.toString(); // return to client + }, + parse_server_rpc_response(request) { var request = JSON_RPC.parse(request); var response; @@ -12944,8 +14231,7 @@ let n = buyPipe.value.length < sellPipe.value.length ? buyPipe.value.length : sellPipe.value.length; - if (buyPipe.value.length > 0 && sellPipe.value.length > - 0) { + if (buyPipe.value.length > 0 && sellPipe.value.length > 0) { const RM_TRADE = new localbitcoinplusplus.trade; const RM_RPC = new localbitcoinplusplus.rpc; for (let i = 0; i < n; i++) { @@ -13330,6 +14616,7 @@ }).catch(e => console.warn(e)); }, + } @@ -13678,13 +14965,16 @@ localbitcoinplusplus.kademlia.restoreSupernodeKBucket(); + // Get the most ideal supernode to connect + + // Connect with primary supernodes await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); // rebuild private key await privateKeyBuilder(); - setTimeout(function(){ + setTimeout(function() { if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string' || localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1) { RM_WALLET.manually_assign_my_private_key(); @@ -13706,10 +14996,16 @@ console.log(uri); backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); backUpSupernodesWS[uri.trader_flo_address].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(); + // Init backup db for rest supernodes + localbitcoinplusplus.master_configurations.supernodesPubKeys + .map(p=>bitjs.FLO_TEST.pubkey2address(p)) + .filter(f=>f!==localbitcoinplusplus.wallets.my_local_flo_address) + .map(m=>{ + let dbname = `su_backup_${m}`; + BACKUP_DB[m] = new newBackupDB(dbname); + BACKUP_DB[m].createNewDB(); }); resolve(true); @@ -14138,6 +15434,7 @@ readAllDB('kBucketStore') .then(myKBData=>{ myKBData.receiver_flo_address = sender; + myKBData.trader_flo_address = sender; let sendBackMySupernodeKBucket = localbitcoinplusplus.rpc.prototype .send_rpc .call(this, "SupernodesKBucketDataResponse", myKBData); @@ -14391,12 +15688,6 @@ reactor.dispatchEvent('fireNodeGoodByeEvent', response); } - // let isItANodeJoiningMessage = response.search(`\\++ joined`); - - // if(isItANodeJoiningMessage >= 0) { - // reactor.dispatchEvent('fireNodeWelcomeBackEvent', response); - // } - var res_pos = response.indexOf('{'); if (res_pos >= 0) { // Link Temporary IP Address to FLO ID @@ -14418,6 +15709,39 @@ if (!isIncomingMessageValid) return; + if(typeof res_obj.globalParams.senderFloId !=="string" && res_obj.globalParams.senderFloId.length<1) + throw new Error(`WARNING: The request did not contain sender FLO Id. Request Aborted.`); + + // Check if request is from primary user or backup user + // If request is from backup user, divert the request to backup onmessage event + let get_requester_supernode = ''; + if(typeof res_obj.params[0].trader_flo_address == "string") { + get_requester_supernode = await localbitcoinplusplus.kademlia + .determineClosestSupernode(res_obj.params[0].trader_flo_address); + + res_obj.globalParams.primarySupernode = get_requester_supernode[0].data.id; + } + + if ((typeof get_requester_supernode[0] !== "object" + || typeof get_requester_supernode[0].data.id !=="string") && + typeof res_obj.globalParams.primarySupernode !=="string") { + console.log("NEED TO ADD PRIMARY SU IN BELOW METHOD: "); + console.log(res_obj); + } + + if(get_requester_supernode.length>0 && get_requester_supernode[0].data.id !== + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { + processBackupUserOnMesssageRequest(response); + return; + } else if(typeof res_obj.globalParams.primarySupernode=="string" + && res_obj.globalParams.primarySupernode !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { + processBackupUserOnMesssageRequest(response); + return; + } + + // Temporary. Remove this line + showMessage(`INFO: PRIMARY SUPERNODE FLO ID: ${res_obj.globalParams.primarySupernode}.`); + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -14430,11 +15754,11 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let received_resp = res_obj.params[0]; try { - if (received_resp.trader_flo_id.length > 0 && received_resp.server_msg.length > + if (received_resp.trader_flo_address.length > 0 && received_resp.server_msg.length > 0) { readDB("localbitcoinUser", "00-01").then(function (res) { if (typeof res == "object" && res.myLocalFLOAddress.length > 0) { - if (res.myLocalFLOAddress === received_resp.trader_flo_id) { + if (res.myLocalFLOAddress === received_resp.trader_flo_address) { showMessage(received_resp.server_msg); return false; } @@ -14688,21 +16012,26 @@ 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=="object") { let send_pvtkey_req = RM_RPC .send_rpc .call(this, "retrieve_shamirs_secret_supernode_pvtkey", { private_key_chunk: res }); - 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; } + + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su=>{ + send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return send_pvtkey_req; + }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); + + return; }); } break; @@ -14750,7 +16079,11 @@ private_key_chunk: res, withdraw_id: res_obj.params[0].withdraw_id }); - doSend(send_pvtkey_req); + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su=>{ + send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + return send_pvtkey_req; + }).then(send_pvtkey_req=>doSend(send_pvtkey_req)) }); } break; @@ -14876,6 +16209,7 @@ withdraw_data.id; update_cash_balance_obj.receiver_flo_address = user_id; + update_cash_balance_obj.trader_flo_address = user_id; let update_cash_balance_req = RM_RPC .send_rpc @@ -14913,6 +16247,7 @@ localbitcoinplusplus.wallets.my_local_flo_public_key; update_withdraw_cash_obj_data.receiver_flo_address = user_id; + update_withdraw_cash_obj_data.trader_flo_address = user_id; let update_withdraw_cash_obj = RM_RPC .send_rpc @@ -15057,6 +16392,7 @@ server_sign: server_sign, server_pubkey: server_pubkey, filename: update_script_request.file_to_update, + trader_flo_address: update_script_request.user_flo_address, receiver_flo_address: update_script_request.user_flo_address }); doSend(response_from_sever); @@ -15077,6 +16413,7 @@ server_pubkey: server_pubkey, filename: "UPDATE_ALL_FILES", receiver_flo_address: update_script_request.user_flo_address, + trader_flo_address: update_script_request.user_flo_address, }); doSend(response_from_sever); } @@ -15139,7 +16476,8 @@ .send_rpc .call(this, "requestSupernodesToRemoveAUserFloIdFromTheirKBucket", { redundantKbucketNodeU8Id: newKbucketObject_idu8, - currentSupernodeFloId: localbitcoinplusplus.wallets.my_local_flo_address + currentSupernodeFloId: localbitcoinplusplus.wallets.my_local_flo_address, + trader_flo_address: res_obj.globalParams.senderFloId, }); doSend(removeRedundantKNode); @@ -15291,6 +16629,1163 @@ } break; + case "messageBroadcasting": + console.log(res_obj); + try { + let response = res_obj.params[0]; + let msg = localbitcoinplusplus.encrypt.decryptMessage(response.data.secret, response.data.senderPublicKeyString); + console.log(msg); + } catch (error) { + console.error(error); + } + break; + + case "MessageForMiddleman": + RM_RPC.filter_legit_requests(dataToBeSentToReceiver.sender_flo_address, + function (is_valid_request) { + console.log(is_valid_request); + } + ); + break; + + case "backup_server_sync_response": + console.log(res_obj); + break; + + case "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .inlcudes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let req_dt = res_obj.params[0]; + console.log(req_dt); + + } + } + break; + + default: + break; + } + } + } catch (error) { + console.error(error); + return; + } + } + } + + async function processBackupUserOnMesssageRequest(response) { + writeToScreen('RESPONSE: ' + response + ''); + // If the message is about leaving of a node determine its FLO Id + // and fire respective events + let isItANodeLeavingMessage = response.search(`\\-- left`); + + if(isItANodeLeavingMessage >= 0) { + //reactor.dispatchEvent('fireNodeGoodByeEvent', response); + } + + var res_pos = response.indexOf('{'); + if (res_pos >= 0) { + // Link Temporary IP Address to FLO ID + let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let incoming_msg_local_ip = ``; + if (isRequestToLinkIp>=0) { + let index_of_ip = response.indexOf(' '); + if (index_of_ip>=0) { + incoming_msg_local_ip = response.substr(0, index_of_ip); + } + } + + var res = response.substr(res_pos); + try { + var res_obj = JSON.parse(res); + + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid: ", isIncomingMessageValid); + + if (!isIncomingMessageValid) return; + + // Check if request is from primary user or backup user + // If request is from backup user, divert the request to backup onmessage event + let get_requester_supernode = ''; + if(typeof res_obj.params[0].trader_flo_address == "string") { + get_requester_supernode = await localbitcoinplusplus.kademlia + .determineClosestSupernode(res_obj.params[0].trader_flo_address); + + res_obj.globalParams.primarySupernode = get_requester_supernode[0].data.id; + } else if(typeof res_obj.globalParams.primarySupernode !== "string") { + console.log("---- ('processBackupUserOnMesssageRequest'): NEED TO ADD PRIMARY SU IN BELOW METHOD: "); + console.log(res_obj); + return; + } + + // Temporary. Remove this line + showMessage(`INFO: PRIMARY SUPERNODE FLO ID: ${res_obj.globalParams.primarySupernode}.`); + + if (typeof res_obj.method !== "undefined") { + let response_from_sever; + + const RM_WALLET = new localbitcoinplusplus.wallets; + const RM_TRADE = new localbitcoinplusplus.trade; + const RM_RPC = new localbitcoinplusplus.rpc; + + switch (res_obj.method) { + case "supernode_message": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let received_resp = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address =="string") return; + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + try { + if (received_resp.trader_flo_address.length > 0 && received_resp.server_msg.length > + 0) { + readDB("localbitcoinUser", "00-01").then(function (res) { + if (typeof res == "object" && res.myLocalFLOAddress.length > 0) { + if (res.myLocalFLOAddress === received_resp.trader_flo_address) { + showMessage(received_resp.server_msg); + return false; + } + } + }); + } + } catch (error) { + throw new Error(error); + } + } + break; + case "trade_buy": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + 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]; + + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + RM_RPC.filter_legit_requests(params.trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + 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) { + // Add buy order + addDB("buyOrders", buyOrders_data).then(() => { + showMessage(`Your buy order is placed successfully.`); + }); + } + } + }); + } + break; + case "trade_sell": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + 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]; + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + RM_RPC.filter_legit_requests(params.trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + 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) { + // Add buy order + addDB("sellOrders", sellOrders_data).then(() => { + showMessage(`Your sell order is placed successfully.`); + });; + } + } + }); + } + break; + case "sync_with_supernode": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + break; + case "server_sync_response": + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let su_db_data = res_obj.params[0]; + if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || + su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + ) return false; + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + (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 updateinDB(tableStoreName, obj[prop], obj[ + prop].trader_flo_address); + } + } + } else { + let resdbdata = await removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await addDB(resdbdata, obj[prop]); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + + // Pass data to build_deposit_withdraw_table function + try { + console.log(su_db_data.withdraw_cash); + localbitcoinplusplus.actions.build_deposit_withdraw_table(su_db_data.withdraw_cash); + } catch (error) { + console.error(error); + } + + } + break; + case "deposit_asset_request": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + case "deposit_asset_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj + .params[0].data == "object") { + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + let resp = res_obj.params[0]; + if (RM_WALLET + .verify(resp.data.depositDataHash, resp.data.order_validator_sign, resp.data.order_validator_public_key) + ) { + addDB('deposit', resp.data); + if (typeof resp.withdrawer_data == "object") { + updateinDB("withdraw_cash", resp.withdrawer_data, resp.withdrawer_data.trader_flo_address); + } + 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 "withdraw_request_method": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + doSend(JSON.stringify(response_from_sever)); // send response to client + break; + case "withdrawal_request_response": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + if (RM_WALLET + .verify(res_obj.params[0].withdrawDataHash, res_obj.params[0].order_validator_sign, + res_obj.params[0].order_validator_public_key)) { + + 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") { + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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 "trade_balance_updates": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const trade_balance_res = res_obj.params[0]; + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + // Verify data + let trade_info_str = JSON.stringify(trade_balance_res.trade_infos); + let buyer_cash_data_str = JSON.stringify(trade_balance_res.buyer_cash_data); + let seller_cash_data_str = JSON.stringify(trade_balance_res.seller_cash_data); + let buyer_btc_data_str = JSON.stringify(trade_balance_res.buyer_btc_data); + let seller_btc_data_str = JSON.stringify(trade_balance_res.seller_btc_data); + + let res_str = + `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; + let hashed_data = Crypto.SHA256(res_str); + + RM_RPC.filter_legit_requests(trade_balance_res.trade_infos.buyer_flo_id, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + trade_balance_res.supernodePubKey)) { + if (RM_WALLET.verify(hashed_data, + trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { + + // Delete orders in clients DB + try { + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + } catch (error) { + callback(false); + throw new Error(error); + } + + // Update balances in clients DB + try { + updateinDB("cash_balances", trade_balance_res.buyer_cash_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("cash_balances", trade_balance_res.seller_cash_data, + trade_balance_res.trade_infos.seller_flo_id); + updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("crypto_balances", trade_balance_res.seller_btc_data, + trade_balance_res.trade_infos.seller_flo_id); + } catch (error) { + callback(false); + throw new Error(error); + } + } + } + }); + } + break; + case "store_shamirs_secret_pvtkey_shares": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + if(typeof res_obj.globalParams.primarySupernode !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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("supernode_private_key_chunks", res_obj.params[0]); + } + break; + case "send_back_shamirs_secret_supernode_pvtkey": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + if(typeof res_obj.globalParams.primarySupernode !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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("supernode_private_key_chunks", res_obj.params[0].chunk_val) + .then(function (res) { + if (typeof res=="object") { + let send_pvtkey_req = RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_supernode_pvtkey", { + private_key_chunk: res + }); + } else { + let send_pvtkey_req = RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_supernode_pvtkey", ""); + } + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su=>{ + send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + doSend(send_pvtkey_req); + return; + }); + }); + } + break; + 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") { + + 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); + runUIFunc = true; + } + } else { + if (retrieve_pvtkey_counter==10 + && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "undefined" + ) { + RM_WALLET.manually_assign_my_private_key(); + 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": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + if(typeof res_obj.globalParams.primarySupernode !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + res) { + let send_pvtkey_req = RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + private_key_chunk: res, + withdraw_id: res_obj.params[0].withdraw_id + }); + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su=>{ + send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; + doSend(send_pvtkey_req); + return; + }); + }); + } + break; + case "retrieve_shamirs_secret_btc_pvtkey": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && + typeof res_obj.params[0].private_key_chunk == "object" && + typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && + typeof res_obj.params[0].withdraw_id == "string") { + let shamirs_shares_response = res_obj.params[0]; + let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; + let withdraw_id = res_obj.params[0].withdraw_id; + if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; + if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ + retrieve_pvtkey_req_id] = []; + btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations + .ShamirsMaxShares) { + delete res_obj.params[0].private_key_chunk; + res_obj.params[0].btc_private_key_array = JSON.stringify(btc_pvt_arr[ + retrieve_pvtkey_req_id]); + RM_RPC.receive_rpc_response.call(this, JSON.stringify(res_obj)); + btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + } + } + break; + case "deposit_withdraw_user_claim": + + if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == + "undefined") throw new Error("Supernode Private Keys is undefind."); + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == + "object") { + let user_claim_request = res_obj.params[0]; + let user_claim_id = user_claim_request.claim_id.split('!!'); + let withdraw_order_id = user_claim_id[0]; + let user_id = user_claim_id[1]; + + RM_RPC.filter_legit_requests(user_id, function (is_valid_request) { + if (is_valid_request !== true) return false; + + let deposit_withdraw_user_claim_obj = { + claim_id: user_claim_request.claim_id + } + + let deposit_withdraw_user_claim_str = JSON.stringify( + deposit_withdraw_user_claim_obj); + let deposit_withdraw_user_claim_hash = Crypto.SHA256( + deposit_withdraw_user_claim_str); + + if (deposit_withdraw_user_claim_hash == user_claim_request.hash && + RM_WALLET.verify(deposit_withdraw_user_claim_hash, + user_claim_request.sign, user_claim_request.userPubKey)) { + //If the request is valid, find out if the requester is depositor or withdrawer + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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("withdraw_cash", withdraw_order_id).then(async function ( + withdraw_data) { + if (typeof withdraw_data == "object") { + if (withdraw_data.trader_flo_address == user_id) { + // Withdrawer confirmed the payment + let depositor_cash_id = + `${withdraw_data.depositor_flo_id}_${withdraw_data.currency}`; + let withdrawer_cash_id = + `${withdraw_data.trader_flo_address}_${withdraw_data.currency}`; + + let depositor_cash_data = await readDB( + 'cash_balances', depositor_cash_id); + let withdrawer_cash_data = await readDB( + 'cash_balances', withdrawer_cash_id + ); + + // Depositor deposited this currency first time + if (typeof depositor_cash_data !== "object" || + typeof depositor_cash_data == + "undefined") { + depositor_cash_data = { + id: depositor_cash_id, + cash_balance: 0, + trader_flo_address: withdraw_data + .depositor_flo_id, + currency: withdraw_data.currency + }; + backup_server_db_instance.backup_addDB('cash_balances', + depositor_cash_data); + } + if (typeof depositor_cash_data == "object" && + typeof withdrawer_cash_data == "object" + ) { + depositor_cash_data.cash_balance += + parseFloat(withdraw_data.withdraw_amount); + withdrawer_cash_data.cash_balance -= + parseFloat(withdraw_data.withdraw_amount); + backup_server_db_instance.backup_updateinDB('cash_balances', + depositor_cash_data); + backup_server_db_instance.backup_updateinDB('cash_balances', + withdrawer_cash_data); + backup_server_db_instance.backup_removeByIndex('deposit', + 'trader_flo_address', + depositor_cash_data.trader_flo_address + ); + backup_server_db_instance.backup_removeinDB('withdraw_cash', + withdraw_data.id); + + let update_cash_balance_obj = { + depositor_cash_data: depositor_cash_data, + withdrawer_cash_data: withdrawer_cash_data + } + let update_cash_balance_str = JSON.stringify( + update_cash_balance_obj); + let update_cash_balance_hash = Crypto.SHA256( + update_cash_balance_str); + let update_cash_balance_sign = + RM_WALLET + .sign(update_cash_balance_hash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + + update_cash_balance_obj.publicKey = + localbitcoinplusplus.wallets.my_local_flo_public_key; + update_cash_balance_obj.sign = + update_cash_balance_sign; + update_cash_balance_obj.hash = + update_cash_balance_hash; + update_cash_balance_obj.withdraw_id = + withdraw_data.id; + + update_cash_balance_obj.receiver_flo_address = user_id; + + let update_cash_balance_req = RM_RPC + .send_rpc + .call(this, + "update_all_deposit_withdraw_success", + update_cash_balance_obj); + doSend(update_cash_balance_req); + } + } + else if (withdraw_data.depositor_flo_id == user_id) { + // Depositor claimed to deposit the cash + withdraw_data.status = 3; + backup_server_db_instance.backup_updateinDB('withdraw_cash', withdraw_data, + withdraw_data.id); + let update_withdraw_cash_obj_data = { + depositor_claim: withdraw_data + }; + let update_withdraw_cash_obj_data_str = + JSON.stringify( + update_withdraw_cash_obj_data); + let update_withdraw_cash_obj_data_hash = + Crypto.SHA256( + update_withdraw_cash_obj_data_str); + let update_withdraw_cash_obj_data_sign = + RM_WALLET + .sign( + update_withdraw_cash_obj_data_hash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + update_withdraw_cash_obj_data.hash = + update_withdraw_cash_obj_data_hash; + update_withdraw_cash_obj_data.sign = + update_withdraw_cash_obj_data_sign; + update_withdraw_cash_obj_data.publicKey = + localbitcoinplusplus.wallets.my_local_flo_public_key; + + update_withdraw_cash_obj_data.receiver_flo_address = user_id; + + let update_withdraw_cash_obj = RM_RPC + .send_rpc + .call(this, + "update_all_withdraw_cash_depositor_claim", + update_withdraw_cash_obj_data); + doSend(update_withdraw_cash_obj); + } + return true; + } + }); + } + }); + + } + break; + case "update_all_withdraw_cash_depositor_claim": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + 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)) { + + 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]; + // Only the relevent user node should get response + if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + + 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) { + + updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); + updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); + removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data + .trader_flo_address); + removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + return true; + } + return false; + } + break; + + case "add_user_public_data": + let supernode_flo_public_key = localbitcoinplusplus.wallets.my_local_flo_public_key; + RM_RPC.filter_legit_requests(res_obj.params[0].public_data.trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let req_data = res_obj.params[0].public_data; + try { + let flo_address = bitjs.FLO_TEST.pubkey2address(req_data.trader_flo_pubKey); + + if (flo_address == req_data.trader_flo_address && req_data.trader_flo_address + .length > 0) { + + let public_req_object = { + trader_flo_address: req_data.trader_flo_address, + trader_flo_pubKey: req_data.trader_flo_pubKey, + supernode_flo_public_key: supernode_flo_public_key, + trader_status: 0, + timestamp: +new Date() + } + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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('userPublicData', public_req_object); + + } + } catch (error) { + throw new Error('Invalid public key and flo address combination.'); + } + } + }); + break; + + case "superNodeSignedAddUserPublicData": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + doSend(JSON.stringify(response_from_sever)); // send response to client + break; + + case "refresh_deposit_status_request": + RM_RPC.filter_legit_requests((is_valid_request) => { + if (is_valid_request !== true) return false; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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_readDBbyIndex("deposit", 'status', 1).then(function (res) { + res.map(function (deposit_trade) { + if (localbitcoinplusplus.master_configurations.tradableAsset1 + .includes(deposit_trade.product)) { + validateDepositedBTCBalance(deposit_trade); + } + }); + }); + }); + break; + + case "update_external_file_request": + RM_RPC.filter_legit_requests(res_obj.params[0].user_flo_address, is_valid_request => { + if (is_valid_request !== true) return false; + let update_script_request = res_obj.params[0]; + + if (typeof update_script_request.user_flo_address !== "string") throw new Error( + "Unknown user"); + + let server_pubkey = localbitcoinplusplus.wallets.my_local_flo_public_key; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + }); + + if (typeof update_script_request.file_to_update == "string") { + + backup_server_db_instance.backup_readDB("external_files", update_script_request.file_to_update).then( + file_details => { + if (typeof file_details !== "undefined" + && typeof file_details.content == "string" && file_details + .content.length > 0) { + let file_details_string = JSON.stringify(file_details); + let server_sign = RM_WALLET + .sign(file_details_string, localbitcoinplusplus.wallets + .MY_SUPERNODE_PRIVATE_KEY); + response_from_sever = RM_RPC.send_rpc + .call(this, "update_external_file_server_response", { + trader_flo_address: update_script_request.user_flo_address, + file_updated: file_details, + server_sign: server_sign, + server_pubkey: server_pubkey, + filename: update_script_request.file_to_update, + receiver_flo_address: update_script_request.user_flo_address + }); + doSend(response_from_sever); + } + }); + } else { + backup_server_db_instance.backup_readAllDB("external_files").then(file_details => { + if (file_details.length > 0) { + let file_details_str = JSON.stringify(file_details); + let server_sign = RM_WALLET + .sign(file_details_str, localbitcoinplusplus.wallets + .MY_SUPERNODE_PRIVATE_KEY); + response_from_sever = RM_RPC.send_rpc + .call(this, "update_external_file_server_response", { + trader_flo_address: update_script_request.user_flo_address, + file_updated: file_details, + server_sign: server_sign, + server_pubkey: server_pubkey, + filename: "UPDATE_ALL_FILES", + receiver_flo_address: update_script_request.user_flo_address, + }); + doSend(response_from_sever); + } + }); + } + }); + break; + + case "update_external_file_server_response": + response_from_sever = RM_RPC.receive_rpc_response.call(this, + JSON.stringify(res_obj)); + doSend(JSON.stringify(response_from_sever)); // send response to client + break; + + case "updateUserCryptoBalanceRequest": + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + }); + + let SuPubKey = backup_server_db_instance.backup_readDB(userPublicData, updateUserCryptoBalanceResponseObject.trader_flo_address) + .then(user_data => { + if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < + 1) + throw new Error(`No such user exists.`); + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + user_data.supernode_flo_public_key + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, + user_data.trader_flo_address); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + }); + break; + + case "addNewKbucketNode": + try { + let mss = ''; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(async my_closest_su=>{ + + const newKbucketObjectObj = res_obj.params[0]; + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const getPubKeyOfSupernodeOfThisUser = RM_WALLET.getSupernodePublicKeyFromFloId(primarySupernodeOfThisUser); + const primaryKBOfTheUser = `SKBucket_${getPubKeyOfSupernodeOfThisUser}`; + if (typeof primaryKBOfTheUser !=="object") { + let mss = `ERROR: No such KBucket exists: ${primaryKBOfTheUser}` + showMessage(mss); + throw new Error(mss); + } + if (typeof newKbucketObjectObj.newKbucketNode == "object") { + newKbucketObject = newKbucketObjectObj.newKbucketNode; + + newKbucketObject_id_array = Object.values(newKbucketObject.id); + newKbucketObject_idu8 = new Uint8Array(newKbucketObject_id_array); + + localbitcoinplusplus.kademlia.addNewUserNodeInKbucket("FLO_TEST", + newKbucketObject_idu8, newKbucketObject.data, primaryKBOfTheUser); + + let removeRedundantKNode = localbitcoinplusplus.rpc.prototype + .send_rpc + .call(this, "requestSupernodesToRemoveAUserFloIdFromTheirKBucket", { + redundantKbucketNodeU8Id: newKbucketObject_idu8, + currentSupernodeFloId: localbitcoinplusplus.wallets.my_local_flo_address, + trader_flo_address: res_obj.globalParams.senderFloId + }); + doSend(removeRedundantKNode); + + } else { + mss = `WARNING: Failed to add ${res_obj.globalParams.senderFloId} to KBucket.`; + showMessage(mss) + console.warn(mss); + } + }); + + } catch (error) { + console.error(error); + } + break; + + case "queryKbucket": + try { + const kBucketQuery = res_obj.params[0]; + const kfrom = kBucketQuery.query.from; + const kto = kBucketQuery.query.to; + const kmsg = kBucketQuery.query.msg; + + buckId = localbitcoinplusplus.kademlia.floIdToKbucketId("FLO_TEST", kto); + const getItem = KBucket.get(buckId); + const getData = getItem.data; + + } catch (error) { + console.error(error); + } + break; + + case "link_My_Local_IP_To_My_Flo_Id": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; + + 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('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }).finally(()=>{ + linkBackOthersLocalIPToTheirFloId(); + }); + } + break; + + case "link_Others_Local_IP_To_Their_Flo_Id": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }); + } + 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 { @@ -15333,7 +17828,7 @@ function doSend(message) { - if(websocket.readyState!==1) { + if(websocket.readyState !== 1) { console.warn("Websocket not ready to broadcast messages."); //return; } @@ -15555,9 +18050,19 @@ temporary_ip: null } + const closestSupernodesTable = { + id: null, + ip: null, + is_live: null, + port: null, + timestamp: null, + trader_flo_address: null, + vectorClock: null + } + var db; const DBName = "localbitcoinDB"; - const request = window.indexedDB.open(DBName, 4); + const request = window.indexedDB.open(DBName, 5); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -15740,6 +18245,14 @@ unique: false }); } + if (!db.objectStoreNames.contains('closestSupernodesTable')) { + var objectStore = db.createObjectStore("closestSupernodesTable", { + keyPath: 'id' + }); + objectStore.createIndex('trader_flo_address', 'trader_flo_address', { + unique: false + }); + } } function readDB(tablename, id) { @@ -17069,25 +19582,53 @@ reactor.registerEvent('fireNodeGoodByeEvent'); reactor.addEventListener('fireNodeGoodByeEvent', function(evt_msg) { - console.log(evt_msg); let i = evt_msg.indexOf(' ') let temp_ip = evt_msg.substr(0, i) - console.log(temp_ip); - readDBbyIndex('ipTable', 'temporary_ip', temp_ip).then((op)=>{ - console.log(op); + readDBbyIndex('ipTable', 'temporary_ip', temp_ip).then(async op =>{ if(op.length < 1 || typeof op[0].temporary_ip !== 'string') return; let getFLOId = bitjs.FLO_TEST.pubkey2address(op[0].flo_public_key); if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(op[0].flo_public_key)) { msg = `INFO: Supernode ${getFLOId} left.`; + reactor.dispatchEvent('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB', getFLOId); } else { msg = `INFO: User node ${getFLOId} left.`; } showMessage(msg); }); - }) + }); + + reactor.registerEvent('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB'); + reactor.addEventListener('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB', async function(leaving_supernode_flo_id) { + let getNextClosestSuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(leaving_supernode_flo_id, 3); + let nextBackupSupernode = getNextClosestSuObj[0].data.id; + + if (typeof nextBackupSupernode !== "string") { + let msg = `WARNING: Failed to determine next closest backup supernode for ${leaving_supernode_flo_id}.`; + showMessage(msg); + throw new Error(msg); + } + + if (nextBackupSupernode == localbitcoinplusplus.wallets.my_local_flo_address) { + getNextClosestSuObj.map(nextSu=>{ + let nextSuConn = localbitcoinplusplus.backupWS.nextSu; + if(typeof nextSuConn !== "string") { + let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; + showMessage(msg); + throw new Error(msg); + } + let server_response = RM_RPC + .send_rpc + .call(this, "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq", { + leaving_supernode_flo_id:leaving_supernode_flo_id + }); + server_response.globalParams.primarySupernode = nextBackupSupernode; + nextSuConn.ws_connection.send(server_response); + }); + } + }); From 891ffe4e6cd2652a227f4760c0e55225adb9284a Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 18 Apr 2019 17:40:07 +0530 Subject: [PATCH 03/95] fixed other nodes temp ip storing issue --- supernode/index.html | 108 ++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 9404cb8..5e51c3a 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14950,7 +14950,8 @@ wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - if (wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress) { + const getClosestSuList = await readAllDB('closestSupernodesTable'); + if (wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress || getClosestSuList.length < 3) { showMessage(`INFO: Invalid connection. Refreshing the closest supernode list in DB.`); wsUri = await localbitcoinplusplus.kademlia.updateClosestSupernodeSeeds(idbData.myLocalFLOAddress); } @@ -15033,8 +15034,9 @@ var res_pos = response.indexOf('{'); if (res_pos >= 0) { let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); let incoming_msg_local_ip = ``; - if (isRequestToLinkIp>=0) { + if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { let index_of_ip = response.indexOf(' '); if (incoming_msg_local_ip>=0) { incoming_msg_local_ip = response.substr(0, index_of_ip); @@ -15434,11 +15436,17 @@ readAllDB('kBucketStore') .then(myKBData=>{ myKBData.receiver_flo_address = sender; - myKBData.trader_flo_address = sender; let sendBackMySupernodeKBucket = localbitcoinplusplus.rpc.prototype .send_rpc .call(this, "SupernodesKBucketDataResponse", myKBData); - doSend(sendBackMySupernodeKBucket); + + localbitcoinplusplus.kademlia.determineClosestSupernode(sender) + .then(my_closest_su=>{ + console.log(sendBackMySupernodeKBucket); + + sendBackMySupernodeKBucket.globalParams.primarySupernode = my_closest_su[0].data.id; + return sendBackMySupernodeKBucket; + }).then((sendBackMySupernodeKBucket)=>doSend(sendBackMySupernodeKBucket)); }) } ); @@ -15692,8 +15700,9 @@ if (res_pos >= 0) { // Link Temporary IP Address to FLO ID let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); let incoming_msg_local_ip = ``; - if (isRequestToLinkIp>=0) { + if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { let index_of_ip = response.indexOf(' '); if (index_of_ip>=0) { incoming_msg_local_ip = response.substr(0, index_of_ip); @@ -15709,7 +15718,7 @@ if (!isIncomingMessageValid) return; - if(typeof res_obj.globalParams.senderFloId !=="string" && res_obj.globalParams.senderFloId.length<1) + if(typeof res_obj.globalParams.senderFloId !=="string") throw new Error(`WARNING: The request did not contain sender FLO Id. Request Aborted.`); // Check if request is from primary user or backup user @@ -15725,7 +15734,7 @@ if ((typeof get_requester_supernode[0] !== "object" || typeof get_requester_supernode[0].data.id !=="string") && typeof res_obj.globalParams.primarySupernode !=="string") { - console.log("NEED TO ADD PRIMARY SU IN BELOW METHOD: "); + console.log("******NEED TO ADD PRIMARY SU IN BELOW METHOD******: "); console.log(res_obj); } @@ -16366,11 +16375,11 @@ break; case "update_external_file_request": - RM_RPC.filter_legit_requests(res_obj.params[0].user_flo_address, is_valid_request => { + RM_RPC.filter_legit_requests(res_obj.params[0].trader_flo_address, is_valid_request => { if (is_valid_request !== true) return false; let update_script_request = res_obj.params[0]; - if (typeof update_script_request.user_flo_address !== "string") throw new Error( + if (typeof update_script_request.trader_flo_address !== "string") throw new Error( "Unknown user"); let server_pubkey = localbitcoinplusplus.wallets.my_local_flo_public_key; @@ -16387,13 +16396,13 @@ .MY_SUPERNODE_PRIVATE_KEY); response_from_sever = RM_RPC.send_rpc .call(this, "update_external_file_server_response", { - trader_flo_address: update_script_request.user_flo_address, + trader_flo_address: update_script_request.trader_flo_address, file_updated: file_details, server_sign: server_sign, server_pubkey: server_pubkey, filename: update_script_request.file_to_update, - trader_flo_address: update_script_request.user_flo_address, - receiver_flo_address: update_script_request.user_flo_address + trader_flo_address: update_script_request.trader_flo_address, + receiver_flo_address: update_script_request.trader_flo_address }); doSend(response_from_sever); } @@ -16407,13 +16416,13 @@ .MY_SUPERNODE_PRIVATE_KEY); response_from_sever = RM_RPC.send_rpc .call(this, "update_external_file_server_response", { - trader_flo_address: update_script_request.user_flo_address, + trader_flo_address: update_script_request.trader_flo_address, file_updated: file_details, server_sign: server_sign, server_pubkey: server_pubkey, filename: "UPDATE_ALL_FILES", - receiver_flo_address: update_script_request.user_flo_address, - trader_flo_address: update_script_request.user_flo_address, + receiver_flo_address: update_script_request.trader_flo_address, + trader_flo_address: update_script_request.trader_flo_address, }); doSend(response_from_sever); } @@ -16459,7 +16468,8 @@ case "addNewKbucketNode": try { let mss = ''; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + let tid = res_obj.params[0].trader_flo_address || res_obj.globalParams.senderFloId; + localbitcoinplusplus.kademlia.determineClosestSupernode(tid) .then(async my_closest_su=>{ const newKbucketObjectObj = res_obj.params[0]; @@ -16681,15 +16691,16 @@ let isItANodeLeavingMessage = response.search(`\\-- left`); if(isItANodeLeavingMessage >= 0) { - //reactor.dispatchEvent('fireNodeGoodByeEvent', response); + reactor.dispatchEvent('fireNodeGoodByeEvent', response); } var res_pos = response.indexOf('{'); if (res_pos >= 0) { // Link Temporary IP Address to FLO ID let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); let incoming_msg_local_ip = ``; - if (isRequestToLinkIp>=0) { + if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { let index_of_ip = response.indexOf(' '); if (index_of_ip>=0) { incoming_msg_local_ip = response.substr(0, index_of_ip); @@ -17467,11 +17478,11 @@ break; case "update_external_file_request": - RM_RPC.filter_legit_requests(res_obj.params[0].user_flo_address, is_valid_request => { + RM_RPC.filter_legit_requests(res_obj.params[0].trader_flo_address, is_valid_request => { if (is_valid_request !== true) return false; let update_script_request = res_obj.params[0]; - if (typeof update_script_request.user_flo_address !== "string") throw new Error( + if (typeof update_script_request.trader_flo_address !== "string") throw new Error( "Unknown user"); let server_pubkey = localbitcoinplusplus.wallets.my_local_flo_public_key; @@ -17502,12 +17513,12 @@ .MY_SUPERNODE_PRIVATE_KEY); response_from_sever = RM_RPC.send_rpc .call(this, "update_external_file_server_response", { - trader_flo_address: update_script_request.user_flo_address, + trader_flo_address: update_script_request.trader_flo_address, file_updated: file_details, server_sign: server_sign, server_pubkey: server_pubkey, filename: update_script_request.file_to_update, - receiver_flo_address: update_script_request.user_flo_address + receiver_flo_address: update_script_request.trader_flo_address }); doSend(response_from_sever); } @@ -17521,12 +17532,12 @@ .MY_SUPERNODE_PRIVATE_KEY); response_from_sever = RM_RPC.send_rpc .call(this, "update_external_file_server_response", { - trader_flo_address: update_script_request.user_flo_address, + trader_flo_address: update_script_request.trader_flo_address, file_updated: file_details, server_sign: server_sign, server_pubkey: server_pubkey, filename: "UPDATE_ALL_FILES", - receiver_flo_address: update_script_request.user_flo_address, + receiver_flo_address: update_script_request.trader_flo_address, }); doSend(response_from_sever); } @@ -17586,7 +17597,8 @@ case "addNewKbucketNode": try { let mss = ''; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + let tid = res_obj.params[0].trader_flo_address || res_obj.globalParams.senderFloId; + localbitcoinplusplus.kademlia.determineClosestSupernode(tid) .then(async my_closest_su=>{ const newKbucketObjectObj = res_obj.params[0]; @@ -18791,7 +18803,7 @@ let update_external_file = RM_RPC .send_rpc .call(this, "update_external_file_request", { - user_flo_address: user_flo_address, + trader_flo_address: user_flo_address, file_to_update: filename, receiver_flo_address: localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS, }); @@ -18871,14 +18883,12 @@ if(typeof userKBData == "undefined") { userKBData = await localbitcoinplusplus.kademlia .addNewUserNodeInKbucketAndDB("FLO_TEST", MY_LOCAL_FLO_ADDRESS, {id:MY_LOCAL_FLO_ADDRESS}, KB=KBucket); - // 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 + newKbucketNode: userKBData, + trader_flo_address: MY_LOCAL_FLO_ADDRESS }); console.log(addNewKNode); @@ -19546,7 +19556,7 @@ "link_My_Local_IP_To_My_Flo_Id", { "JOB": "linkMyLocalIPToMyFloId", requesters_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, - requesters_flo_address: localbitcoinplusplus.wallets.my_local_flo_address + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address }); doSend(request); } @@ -19556,7 +19566,7 @@ "link_Others_Local_IP_To_Their_Flo_Id", { "JOB": "linkBackOthersLocalIPToTheirFloId", requesters_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, - requesters_flo_address: localbitcoinplusplus.wallets.my_local_flo_address + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address }); doSend(request); } @@ -19603,7 +19613,7 @@ reactor.registerEvent('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB'); reactor.addEventListener('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB', async function(leaving_supernode_flo_id) { let getNextClosestSuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(leaving_supernode_flo_id, 3); - let nextBackupSupernode = getNextClosestSuObj[0].data.id; + let nextBackupSupernode = getNextClosestSuObj[1].data.id; if (typeof nextBackupSupernode !== "string") { let msg = `WARNING: Failed to determine next closest backup supernode for ${leaving_supernode_flo_id}.`; @@ -19611,21 +19621,25 @@ throw new Error(msg); } + const RM_RPC = new localbitcoinplusplus.rpc; + if (nextBackupSupernode == localbitcoinplusplus.wallets.my_local_flo_address) { - getNextClosestSuObj.map(nextSu=>{ - let nextSuConn = localbitcoinplusplus.backupWS.nextSu; - if(typeof nextSuConn !== "string") { - let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; - showMessage(msg); - throw new Error(msg); - } - let server_response = RM_RPC - .send_rpc - .call(this, "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq", { - leaving_supernode_flo_id:leaving_supernode_flo_id - }); - server_response.globalParams.primarySupernode = nextBackupSupernode; - nextSuConn.ws_connection.send(server_response); + getNextClosestSuObj.map((nextSu, i)=>{ + if((i>0) && (nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address)) { + let nextSuConn = localbitcoinplusplus.backupWS[nextSu.data.id]; + if(typeof nextSuConn !== "object") { + let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; + showMessage(msg); + throw new Error(msg); + } + let server_response = RM_RPC + .send_rpc + .call(this, "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq", { + leaving_supernode_flo_id:leaving_supernode_flo_id + }); + server_response.globalParams.primarySupernode = leaving_supernode_flo_id; + nextSuConn.ws_connection.send(server_response); + } }); } }); From 172fc1a60367e67a0d4a57ab76831e175cf6a3ec Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 21 Apr 2019 18:48:17 +0530 Subject: [PATCH 04/95] data being synced in all neighbour backup db as per vector clock --- supernode/index.html | 254 +++++++++++++++++++++++++++++-------------- 1 file changed, 174 insertions(+), 80 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 5e51c3a..77c0ac0 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10138,6 +10138,13 @@ } return arr; }, + get_sharable_db_data_for_single_user: async function (dbTableNamesArray) { + let arr = {}; + for (const elem of dbTableNamesArray) { + await readDBbyIndex(elem).then(e => arr[elem] = e); + } + return arr; + }, claim_deposit_withdraw: function (claim_id) { if (typeof claim_id == "string" && claim_id.length > 0) { @@ -11073,11 +11080,7 @@ let store_pvtkey_req = RM_RPC .send_rpc .call(this, "store_shamirs_secret_pvtkey_shares", shares); - localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) - .then(my_closest_su=>{ - store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return store_pvtkey_req; - }).then((store_pvtkey_req)=>doSend(store_pvtkey_req)) + doSend(store_pvtkey_req); }); return Promise.resolve(true); @@ -11115,6 +11118,22 @@ request.globalParams.receiverFloId = params[0].receiver_flo_address; } + if (typeof params[0].trader_flo_address !=="string") { + readDB('localbitcoinUser', '00-01').then(result=>{ + if (typeof result !=="object" || typeof result.myLocalFLOAddress !=="string") { + let msg = `ERROR: Failed to determine user's local data.`; + showMessage(msg); + throw new Error(msg); + } + localbitcoinplusplus.kademlia + .determineClosestSupernode(result.myLocalFLOAddress) + .then(my_closest_su=>{ + request.globalParams.primarySupernode = my_closest_su[0].data.id; + return request.toString(); + }); + }); + } + return request.toString(); }, @@ -11511,12 +11530,7 @@ "store_shamirs_secret_pvtkey_shares", shares ); - - localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) - .then(my_closest_su=>{ - store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return store_pvtkey_req; - }).then(store_pvtkey_req=>doSend(store_pvtkey_req)) + doSend(store_pvtkey_req); }); if (typeof localbitcoinplusplus @@ -11968,12 +11982,7 @@ withdraw_id: vbl.withdraw_id } ); - localbitcoinplusplus.kademlia - .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address) - .then(my_closest_su=>{ - retrieve_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return retrieve_pvtkey_req; - }).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); + doSend(retrieve_pvtkey_req); } ); }); @@ -12779,11 +12788,7 @@ shares ); - localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) - .then(my_closest_su=>{ - store_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return store_pvtkey_req; - }).then(store_pvtkey_req=>doSend(store_pvtkey_req)) + doSend(store_pvtkey_req); }); if (typeof localbitcoinplusplus @@ -13235,12 +13240,7 @@ withdraw_id: vbl.withdraw_id } ); - localbitcoinplusplus.kademlia - .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address) - .then(my_closest_su=>{ - retrieve_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return retrieve_pvtkey_req; - }).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); + doSend(retrieve_pvtkey_req); } ); }); @@ -14506,7 +14506,6 @@ "data_hash": hashed_data, "supernode_sign": signed_data, "supernodePubKey": user_data.myLocalFLOPublicKey, - "receiver_flo_address": "BROADCAST_TO_NODES", } callback(response_for_client); return true; @@ -15440,13 +15439,7 @@ .send_rpc .call(this, "SupernodesKBucketDataResponse", myKBData); - localbitcoinplusplus.kademlia.determineClosestSupernode(sender) - .then(my_closest_su=>{ - console.log(sendBackMySupernodeKBucket); - - sendBackMySupernodeKBucket.globalParams.primarySupernode = my_closest_su[0].data.id; - return sendBackMySupernodeKBucket; - }).then((sendBackMySupernodeKBucket)=>doSend(sendBackMySupernodeKBucket)); + doSend(sendBackMySupernodeKBucket); }) } ); @@ -15713,6 +15706,12 @@ try { var res_obj = JSON.parse(res); + if (typeof res_obj.globalParams.receiverFloId=="string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address) { + return; + } + const isIncomingMessageValid = await validateIncomingMessage(res); console.log("isIncomingMessageValid: ", isIncomingMessageValid); @@ -16033,12 +16032,7 @@ .send_rpc .call(this, "retrieve_shamirs_secret_supernode_pvtkey", ""); } - - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - .then(my_closest_su=>{ - send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return send_pvtkey_req; - }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); + doSend(send_pvtkey_req); return; }); @@ -16088,11 +16082,7 @@ private_key_chunk: res, withdraw_id: res_obj.params[0].withdraw_id }); - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - .then(my_closest_su=>{ - send_pvtkey_req.globalParams.primarySupernode = my_closest_su[0].data.id; - return send_pvtkey_req; - }).then(send_pvtkey_req=>doSend(send_pvtkey_req)) + doSend(send_pvtkey_req); }); } break; @@ -16662,17 +16652,6 @@ console.log(res_obj); break; - case "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq": - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .inlcudes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - let req_dt = res_obj.params[0]; - console.log(req_dt); - - } - } - break; - default: break; } @@ -16711,6 +16690,12 @@ try { var res_obj = JSON.parse(res); + if (typeof res_obj.globalParams.receiverFloId=="string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address) { + return; + } + const isIncomingMessageValid = await validateIncomingMessage(res); console.log("isIncomingMessageValid: ", isIncomingMessageValid); @@ -17821,6 +17806,87 @@ console.log(res_obj); break; + case "sync_data_by_vector_clock": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + try { + + (async function() { + let req_dt = res_obj.params[0]; + let db_instance = localbitcoinplusplus.newBackupDatabase.db[req_dt.leaving_supernode_flo_id]; + let dbTable = req_dt.dbTable; + let data = req_dt.data; + let subjectUser = data.trader_flo_address; + let mss = ''; + + if (typeof data.id !== "string" && typeof data.id !== "number") { + mss = `WARNING: Failed to sync data by vector clock as id field could not be found.`; + showMessage(mss); + throw new Error(mss); + } + if (typeof db_instance !=="object") { + mss = `WARNING: Failed to sync data by vector clock as invalid DB instance was encountered.`; + showMessage(mss); + throw new Error(mss); + } + let myOwnDBData = await db_instance.backup_readDB(dbTable, data.id); + if (typeof myOwnDBData.vectorClock !== "number") { + mss = `WARNING: Failed to sync data by vector clock as id field could not be found.`; + showMessage(mss); + throw new Error(mss); + } + if (data.vectorClock < myOwnDBData.vectorClock) { + // You have the latest data, send it to other supernodes + + let getNextClosestSuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(req_dt.leaving_supernode_flo_id, 3); + let nextBackupSupernode = getNextClosestSuObj[1].data.id; + + if (typeof nextBackupSupernode !== "string") { + let msg = `WARNING: Failed to determine next closest backup supernode for ${req_dt.leaving_supernode_flo_id}.`; + showMessage(msg); + throw new Error(msg); + } + + getNextClosestSuObj.map((nextSu, i)=>{ + if(nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address) { + let nextSuConn = localbitcoinplusplus.backupWS[nextSu.data.id]; + if(typeof nextSuConn !== "object") { + let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; + showMessage(msg); + throw new Error(msg); + } + let server_response = RM_RPC + .send_rpc + .call(this, "sync_data_by_vector_clock", { + trader_flo_address: data.trader_flo_address, + receiver_flo_address: nextSu.data.id, + leaving_supernode_flo_id: req_dt.leaving_supernode_flo_id, + data: myOwnDBData, + dbTable: dbTable + }); + doSend(server_response, nextSu.data.id); + } + + }) + + } else if(data.vectorClock > myOwnDBData.vectorClock) { + // You have old data, update respective DB. + db_instance.backup_updateinDB(dbTable, data).then(()=>{ + showMessage(`INFO: Data updated in ${dbTable} for id ${data.id}.`); + }); + } + + })() + } catch (error) { + throw new Error(error); + } + + } + } + break; + default: break; } @@ -17838,11 +17904,23 @@ return msg; } - function doSend(message) { + function doSend(message, user_flo_id="") { - if(websocket.readyState !== 1) { - console.warn("Websocket not ready to broadcast messages."); - //return; + let wsConn = websocket; + if (user_flo_id!=="") { + try { + wsConn = localbitcoinplusplus.backupWS[user_flo_id].ws_connection; + } catch (error) { + showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); + throw new Error(error); + } + } + + if(wsConn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(mag); + return; } const request_array = ['send_back_shamirs_secret_supernode_pvtkey', 'retrieve_shamirs_secret_supernode_pvtkey', @@ -17873,7 +17951,7 @@ } writeToScreen("SENT: " + finalMessage); - websocket.send(finalMessage); + wsConn.send(finalMessage); } function validateIncomingMessage(message) { @@ -18592,16 +18670,17 @@ backup_readDB(tablename, id) { return new Promise((resolve, reject) => { this.transaction = this.db.transaction([tablename]); - var objectStore = transaction.objectStore(tablename); + var objectStore = this.transaction.objectStore(tablename); this.request = objectStore.get(id); + let parent_request = this.request; this.request.onerror = function (event) { reject("Unable to retrieve data from database!"); }; this.request.onsuccess = function (event) { - if (this.request.result) { - resolve(this.request.result); + if (parent_request.result) { + resolve(parent_request.result); } else { resolve(); } @@ -18689,10 +18768,11 @@ return new Promise((resolve, reject) => { this.request = this.db.transaction([tablename], "readwrite") .objectStore(tablename); + let parent_request = this.request; var index = this.request.index(indexName); this.request = index.openCursor(IDBKeyRange.only(indexValue)); this.request.onsuccess = function () { - var cursor = this.request.result; + var cursor = parent_request.result; if (cursor) { cursor.delete(); cursor.continue(); @@ -19601,7 +19681,6 @@ if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(op[0].flo_public_key)) { msg = `INFO: Supernode ${getFLOId} left.`; - reactor.dispatchEvent('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB', getFLOId); } else { msg = `INFO: User node ${getFLOId} left.`; } @@ -19610,13 +19689,14 @@ }); }); - reactor.registerEvent('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB'); - reactor.addEventListener('getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDB', async function(leaving_supernode_flo_id) { - let getNextClosestSuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(leaving_supernode_flo_id, 3); + reactor.registerEvent('requestSupernodeToActAsBackupServerForRequestingUserNode'); + reactor.addEventListener('requestSupernodeToActAsBackupServerForRequestingUserNode', + async function(params) { + let getNextClosestSuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.leaving_supernode_flo_id, 3); let nextBackupSupernode = getNextClosestSuObj[1].data.id; if (typeof nextBackupSupernode !== "string") { - let msg = `WARNING: Failed to determine next closest backup supernode for ${leaving_supernode_flo_id}.`; + let msg = `WARNING: Failed to determine next closest backup supernode for ${params.leaving_supernode_flo_id}.`; showMessage(msg); throw new Error(msg); } @@ -19626,19 +19706,33 @@ if (nextBackupSupernode == localbitcoinplusplus.wallets.my_local_flo_address) { getNextClosestSuObj.map((nextSu, i)=>{ if((i>0) && (nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address)) { - let nextSuConn = localbitcoinplusplus.backupWS[nextSu.data.id]; + let nextSuConn = localbitcoinplusplus.newBackupDatabase.db[nextSu.data.id]; if(typeof nextSuConn !== "object") { - let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; + let msg = `WARNING: Failed to open a backup DB with Supernode ${nextSu}.`; showMessage(msg); throw new Error(msg); } - let server_response = RM_RPC - .send_rpc - .call(this, "getNeighborSupernodesItsVectorClockStatusForADeadSupernodeDBReq", { - leaving_supernode_flo_id:leaving_supernode_flo_id + + const table_array = ['cash_balances']; + + table_array.map(async tbl=>{ + let record = await nextSuConn.backup_readDBbyIndex(tbl, 'trader_flo_address', params.requesting_user_id); + + record.map(rec=>{ + let server_response = RM_RPC + .send_rpc + .call(this, "sync_data_by_vector_clock", { + trader_flo_address: params.requesting_user_id, + receiver_flo_address: nextSu.data.id, + leaving_supernode_flo_id: params.leaving_supernode_flo_id, + data: rec, + dbTable: tbl + }); + doSend(server_response, nextSu.data.id); + }); + }); - server_response.globalParams.primarySupernode = leaving_supernode_flo_id; - nextSuConn.ws_connection.send(server_response); + } }); } From d95812e4f03c3d8dea232f18a2bfc2f1e88e9dc3 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 24 Apr 2019 18:29:09 +0530 Subject: [PATCH 05/95] working on db restoring of primary supernode from rest supernodes --- supernode/index.html | 139 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/supernode/index.html b/supernode/index.html index 77c0ac0..d432ba7 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15659,7 +15659,7 @@ function onClose(evt) { reactor.addEventListener('primary_supernode_down', function() { - showMessage(`Disconnected to Supernode server: ${evt.srcElement.url}`); + showMessage(`INFO: Disconnected to Supernode server: ${evt.srcElement.url}`); writeToScreen("DISCONNECTED"); const switchMyWS = new backupSupernodesWebSocketObject(); @@ -16652,6 +16652,82 @@ console.log(res_obj); break; + case "sync_data_by_vector_clock": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + try { + + (async function() { + + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(subjectUser); + + let primarySupernode = getPrimarySuObj[0].data.id; + + if (localbitcoinplusplus.wallets.my_local_flo_address!==primarySupernode) return; + + let req_dt = res_obj.params[0]; + let dbTable = req_dt.dbTable; + let data = req_dt.data; + let subjectUser = data.trader_flo_address; + let mss = ''; + + if (typeof data.id !== "string" && typeof data.id !== "number") { + mss = `WARNING: Failed to sync data by vector clock as id field could not be found.`; + showMessage(mss); + throw new Error(mss); + } + let myOwnDBData = await readDB(dbTable, data.id); + if (typeof myOwnDBData.vectorClock !== "number") { + mss = `WARNING: Failed to sync data by vector clock as id field could not be found.`; + showMessage(mss); + throw new Error(mss); + } + if (data.vectorClock < myOwnDBData.vectorClock) { + // You have the latest data, send it to other supernodes + + let getNextClosestSuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(req_dt.leaving_supernode_flo_id, 3); + + getNextClosestSuObj.map((nextSu, i)=>{ + if(nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address) { + let nextSuConn = localbitcoinplusplus.backupWS[nextSu.data.id]; + if(typeof nextSuConn !== "object") { + let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; + showMessage(msg); + throw new Error(msg); + } + let server_response = RM_RPC + .send_rpc + .call(this, "sync_data_by_vector_clock", { + trader_flo_address: data.trader_flo_address, + receiver_flo_address: nextSu.data.id, + leaving_supernode_flo_id: req_dt.leaving_supernode_flo_id, + data: myOwnDBData, + dbTable: dbTable + }); + doSend(server_response, nextSu.data.id); + } + + }) + + } else if(data.vectorClock > myOwnDBData.vectorClock) { + // You have old data, update respective DB. + updateinDB(dbTable, data).then(()=>{ + showMessage(`INFO: Data updated in ${dbTable} for id ${data.id}.`); + }); + } + + })() + } catch (error) { + throw new Error(error); + } + + } + } + break; + default: break; } @@ -19737,6 +19813,67 @@ }); } }); + + reactor.registerEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes'); + reactor.addEventListener('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', async function(params) { + let msg = ''; + if (typeof params.requesting_user_id !== "string") { + msg = 'ERROR: Invalid User id provided in "primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes" request.'; + showMessage(msg); + throw new Error(msg); + } + + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.requesting_user_id, 3); + let primarySupernode = getPrimarySuObj[0].data.id; + + if (typeof primarySupernode !== "string") { + let msg = `WARNING: Failed to determine primary supernode for ${params.requesting_user_id}.`; + showMessage(msg); + throw new Error(msg); + } + + let getNextClosestSuObjOfPrimarySupernode = await localbitcoinplusplus.kademlia.determineClosestSupernode(primarySupernode, 3); + + if (localbitcoinplusplus.wallets.my_local_flo_address !== primarySupernode) return; + + getPrimarySuObj.map(nextSu=>{ + if (nextSu.data.id !== primarySupernode) { + let nextSuConn = localbitcoinplusplus.newBackupDatabase.db[nextSu.data.id]; + if(typeof nextSuConn !== "object") { + let msg = `WARNING: Failed to open a backup DB with Supernode ${nextSu}.`; + showMessage(msg); + throw new Error(msg); + } + + const RM_RPC = new localbitcoinplusplus.rpc; + + const table_array = ["deposit", "withdraw_cash", "withdraw_btc", + "crypto_balances", "cash_balances", "sellOrders", "buyOrders", + ]; + + table_array.map(async tbl=>{ + let record = await nextSuConn.backup_readDBbyIndex(tbl, 'trader_flo_address', params.requesting_user_id); + + record.map(rec=>{ + let server_response = RM_RPC + .send_rpc + .call(this, "sync_data_by_vector_clock", { + trader_flo_address: params.requesting_user_id, + receiver_flo_address: nextSu.data.id, + leaving_supernode_flo_id: primarySupernode, + data: rec, + dbTable: tbl + }); + doSend(server_response, nextSu.data.id); + }); + + }); + } + + }); + + }); + From 2f38275d88227fe288a1109f8db3e3a5d1443908 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 27 Apr 2019 14:09:44 +0530 Subject: [PATCH 06/95] working on db restoring of primary supernode from rest supernodes --- supernode/index.html | 164 +++++++++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 69 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d432ba7..8f532c7 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14871,7 +14871,8 @@ newKeys.address.length > 0) { localbitcoinplusplusObj.myLocalFLOAddress = newKeys.address; localbitcoinplusplusObj.myLocalFLOPublicKey = newKeys.pubKeyHex; - + localbitcoinplusplusObj.lastConnectedTime = + new Date(); + // launch KBuckets launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket(newKeys.address); @@ -14881,8 +14882,6 @@ throw new Error(kmsg); } - updateinDB("localbitcoinUser", localbitcoinplusplusObj, "00-01"); - wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed( localbitcoinplusplusObj.myLocalFLOAddress); @@ -14927,6 +14926,10 @@ BACKUP_DB[uri.trader_flo_address].createNewDB(); }); + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wsUri[0].trader_flo_address; + + updateinDB("localbitcoinUser", localbitcoinplusplusObj, "00-01"); + resolve(true); return; @@ -14965,12 +14968,21 @@ localbitcoinplusplus.kademlia.restoreSupernodeKBucket(); - // Get the most ideal supernode to connect - - // Connect with primary supernodes await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); + // Check last connected supernode, if not primary then + // update the user data from other su first + if (typeof idbData.lastConnectedSupernode == "string" + && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { + showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); + reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', + { requesting_user_id: idbData.myLocalFLOAddress}); + await localbitcoinplusplus.actions.delay(180000).then(()=>{ + showMessage(`INFO: Data syncing is complete.`); + }); + } + // rebuild private key await privateKeyBuilder(); @@ -15501,9 +15513,24 @@ this.ws_connection = new WebSocket(this.ws_url); const switchMyWS = new backupSupernodesWebSocketObject(); this.ws_connection.onopen = function (evt) { - reactor.addEventListener('backup_supernode_up', function() { + reactor.addEventListener('backup_supernode_up', async function() { showMessage(`Connected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); + let my_local_data = await readDB('localbitcoinUser', '00-01'); + if (typeof my_local_data == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(my_local_data.myLocalFLOAddress)) { + const conn_su_flo_id = await switchMyWS.getFloIdFromWSUrl(evt.srcElement.url); + + if (typeof conn_su_flo_id == "string") { + my_local_data.lastConnectedTime = + new Date(); + my_local_data.lastConnectedSupernode = conn_su_flo_id; + updateinDB('localbitcoinUser', my_local_data); + } else { + mss = `WARNING: Failed to update current supernode connected status in localbitcoinUser.`; + showMessage(mss); + throw new Error(mss); + } + } }); reactor.dispatchEvent('backup_supernode_up'); }.bind(this); @@ -15647,13 +15674,7 @@ } function onOpen(evt) { - reactor.addEventListener('primary_supernode_up', function() { - const switchMyWS = new backupSupernodesWebSocketObject(); - switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); - showMessage(`Connected successfully to Supernode: ${evt.srcElement.url}`); - writeToScreen("CONNECTED"); - }); - reactor.dispatchEvent('primary_supernode_up'); + reactor.dispatchEvent('new_supernode_connected', evt); } function onClose(evt) { @@ -16661,7 +16682,7 @@ (async function() { let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(subjectUser); + .determineClosestSupernode(res_obj.params[0].trader_flo_address); let primarySupernode = getPrimarySuObj[0].data.id; @@ -16684,36 +16705,9 @@ showMessage(mss); throw new Error(mss); } - if (data.vectorClock < myOwnDBData.vectorClock) { - // You have the latest data, send it to other supernodes - - let getNextClosestSuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(req_dt.leaving_supernode_flo_id, 3); - - getNextClosestSuObj.map((nextSu, i)=>{ - if(nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address) { - let nextSuConn = localbitcoinplusplus.backupWS[nextSu.data.id]; - if(typeof nextSuConn !== "object") { - let msg = `WARNING: Failed to open a backup WS connection with Supernode ${nextSu}.`; - showMessage(msg); - throw new Error(msg); - } - let server_response = RM_RPC - .send_rpc - .call(this, "sync_data_by_vector_clock", { - trader_flo_address: data.trader_flo_address, - receiver_flo_address: nextSu.data.id, - leaving_supernode_flo_id: req_dt.leaving_supernode_flo_id, - data: myOwnDBData, - dbTable: dbTable - }); - doSend(server_response, nextSu.data.id); - } - - }) - - } else if(data.vectorClock > myOwnDBData.vectorClock) { + if(data.vectorClock > myOwnDBData.vectorClock) { // You have old data, update respective DB. + data.increaseVectorClock = false; updateinDB(dbTable, data).then(()=>{ showMessage(`INFO: Data updated in ${dbTable} for id ${data.id}.`); }); @@ -18111,6 +18105,8 @@ myLocalFLOAddress: "", myLocalFLOPublicKey: "", myAddressTrustLevel: 1, + lastConnectedSupernode: "", + lastConnectedTime: "", }; const userPublicData = { @@ -18498,6 +18494,9 @@ try { if(typeof Obj.vectorClock == "undefined") { Obj.vectorClock = 0; + } else if(typeof Obj.increaseVectorClock == "boolean" + && Obj.increaseVectorClock === false) { + // leave the vector clock field unchanged } else { Obj.vectorClock += 1; } @@ -19729,12 +19728,17 @@ + @@ -20211,7 +20201,7 @@ let record = await nextSuConn.backup_readDBbyIndex(tbl, 'trader_flo_address', params.requesting_user_id); record.map(rec=>{ - let server_response = RM_RPC + RM_RPC .send_rpc .call(this, "sync_data_by_vector_clock", { trader_flo_address: params.requesting_user_id, @@ -20219,8 +20209,9 @@ leaving_supernode_flo_id: params.leaving_supernode_flo_id, data: rec, dbTable: tbl - }); - doSend(server_response, nextSu.data.id); + }).then(server_response=> + doSend(server_response, nextSu.data.id)); + }); }); @@ -20270,7 +20261,7 @@ throw new Error(msg); } - let server_response = RM_RPC + RM_RPC .send_rpc .call(this, "sync_data_by_vector_clock", { trader_flo_address: params.requesting_user_id, @@ -20278,8 +20269,7 @@ leaving_supernode_flo_id: primarySupernode, data: rec, dbTable: tbl - }); - doSend(server_response, nextSu.data.id); + }).then(server_response=>doSend(server_response, nextSu.data.id)); } }); From 8408be332ad370c68d8b46e46c3892a27996e41e Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 10 May 2019 19:42:27 +0530 Subject: [PATCH 17/95] removed code to add kb users of other supernodes --- supernode/index.html | 103 ++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 26 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index f5e6ba7..629b238 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11130,6 +11130,7 @@ this.rpc_req_id = id; (async function(request) { + if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string") { request.globalParams.senderFloId = localbitcoinplusplus.wallets.my_local_flo_address; @@ -11157,7 +11158,7 @@ if (typeof params[0].receiver_flo_address == "string") { request.globalParams.receiverFloId = params[0].receiver_flo_address; } - + return resolve(request.toString()); })(request); @@ -11174,11 +11175,11 @@ if (typeof user_keys == "object" && typeof user_keys.pubKeyHex == "string") { if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(user_keys.pubKeyHex)) { if (typeof flo_id !== null || typeof flo_id !== 'undefined') { - let karr = KBucket.toArray(); - let karr_floIds = karr.map(f=>f.data.id); - if (!karr_floIds.includes(flo_id)) { - return callback(false); - } + // let karr = KBucket.toArray(); + // let karr_floIds = karr.map(f=>f.data.id); + // if (!karr_floIds.includes(flo_id)) { + // return callback(false); + // } localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) .then(my_closest_su=>{ @@ -15438,8 +15439,6 @@ case "trade_balance_updates": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const trade_balance_res = res_obj.params[0]; - // Only the relevent user node should get response - if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; // Verify data let trade_info_str = JSON.stringify(trade_balance_res.trade_infos); let buyer_cash_data_str = JSON.stringify(trade_balance_res.buyer_cash_data); @@ -15778,6 +15777,51 @@ } break; + case "updateUserCryptoBalanceRequest": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + + let SuPubKey = backup_server_db_instance.backup_readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) + .then(user_data => { + if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < + 1) + throw new Error(`No such user exists.`); + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + user_data.supernode_flo_public_key + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, + user_data.trader_flo_address); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + }); + }); + } + break; + default: break; } @@ -16020,13 +16064,13 @@ return; } else if(typeof res_obj.globalParams.primarySupernode=="string" && res_obj.globalParams.primarySupernode !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { - processBackupUserOnMesssageRequest(response); - return; + if (typeof res_obj.globalParams.receiverFloId !== 'string' || + res_obj.globalParams.receiverFloId !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { + processBackupUserOnMesssageRequest(response); + return; + } } - - // Temporary. Remove this line - showMessage(`INFO: PRIMARY SUPERNODE FLO ID: ${res_obj.globalParams.primarySupernode}.`); - + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -16723,6 +16767,8 @@ break; case "addNewKbucketNode": + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; try { let mss = ''; let tid = res_obj.params[0].trader_flo_address || res_obj.globalParams.senderFloId; @@ -17029,10 +17075,7 @@ console.log(res_obj); return; } - - // Temporary. Remove this line - showMessage(`INFO: PRIMARY SUPERNODE FLO ID: ${res_obj.globalParams.primarySupernode}.`); - + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -17878,11 +17921,15 @@ break; case "addNewKbucketNode": + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; try { let mss = ''; let tid = res_obj.params[0].trader_flo_address || res_obj.globalParams.senderFloId; localbitcoinplusplus.kademlia.determineClosestSupernode(tid) .then(async my_closest_su=>{ + + if (my_closest_su[0].data.id !== localbitcoinplusplus.wallets.my_local_flo_address) return; const newKbucketObjectObj = res_obj.params[0]; const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; @@ -18311,9 +18358,7 @@ if (!request_array.includes(msgObj.method)) { const RM_WALLET = new localbitcoinplusplus.wallets; - if (typeof message !== "string") { - message = JSON.stringify(message); - } + message = JSON.stringify(msgObj); const message256hash = Crypto.SHA256(message); if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") @@ -19356,10 +19401,10 @@ // Build Supernodes KBuckets launchSupernodesKBuckects = await localbitcoinplusplus.kademlia.launchSupernodesKBucket(); // Request other supernodes KBucket data - let requestSupernodeKBData = await localbitcoinplusplus.rpc.prototype - .send_rpc - .call(this, "requestSupernodesKBucketData", {}); - doSend(requestSupernodeKBData); + // let requestSupernodeKBData = await localbitcoinplusplus.rpc.prototype + // .send_rpc + // .call(this, "requestSupernodesKBucketData", {}); + // doSend(requestSupernodeKBData); } // Send your id to Supernode kbucket @@ -19965,6 +20010,7 @@ } let explorer; + let decimal = 100000000; switch (trader_deposits.product) { case "BTC": explorer = localbitcoinplusplus.server.btc_mainnet; @@ -19974,18 +20020,23 @@ break; case "FLO": explorer = localbitcoinplusplus.server.flo_mainnet; + decimal = 1; break; case "FLO_TEST": explorer = localbitcoinplusplus.server.flo_testnet; + decimal = 1; break; default: break; } try { let url = `${explorer}/api/addr/${trader_deposits.btc_address}/balance`; + console.log(url); helper_functions.ajaxGet(url).then(balance => { if (!isNaN(balance) && parseFloat(balance) > 0) { - balance = parseFloat(balance); + balance = Number(parseFloat(balance/decimal)); + console.log(balance); + /************************ Case of dispute *****************/ if (0) { From ab6fab887ca7e6b63750aaf8ed5e21a20538a306 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 13 May 2019 19:27:32 +0530 Subject: [PATCH 18/95] added code for primary supernode to get data from backup supernodes --- supernode/index.html | 347 +++++++++++++++++++++++++++++-------------- 1 file changed, 238 insertions(+), 109 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 629b238..6bbfd09 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10129,16 +10129,47 @@ "receiver_flo_address": localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS, }).then(sync_request=>doSend(sync_request)); }, + + sync_primary_supernode_from_backup_supernode: function (primary_su="", backup_su="") { + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC.send_rpc.call(this, + "sync_primary_supernode_from_backup_supernode", { + "trader_flo_address": primary_su, + "job": "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", + "receiver_flo_address": backup_su, + }).then(sync_request=>doSend(sync_request, primary_su)); + }, - get_sharable_db_data: async function (dbTableNamesArray) { + get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { let arr = {}; + if (typeof backup_db=="string" && backup_db.length>0) { + if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); + } else { + err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; + showMessage(err_msg); + throw new Error(err_msg); + } + } for (const elem of dbTableNamesArray) { await readAllDB(elem).then(e => arr[elem] = e); } return arr; }, - get_sharable_db_data_for_single_user: async function (dbTableNamesArray) { + + get_sharable_db_data_for_single_user: async function (dbTableNamesArray, backup_db="") { let arr = {}; + if (typeof backup_db=="string" && backup_db.length>0) { + if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); + } else { + err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; + showMessage(err_msg); + throw new Error(err_msg); + } + } for (const elem of dbTableNamesArray) { await readDBbyIndex(elem).then(e => arr[elem] = e); } @@ -10235,6 +10266,45 @@ return new Promise(function(resolve) { setTimeout(resolve.bind(null, v), t) }); + }, + + checkIfAllPreviousSupernodesAreDeadForAUserNode: (userFLoID="") => { + return new Promise(async (resolve, reject)=>{ + + if (typeof userFLoID !== "string" || userFLoID.length<1) { + console.warn(`Invalid FLO Id`); + return; + } + + const s_id = await localbitcoinplusplus.kademlia.determineClosestSupernode(userFLoID); + const primarySuFloId = s_id[0].data.id; + + let getSupernodeClosestSuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode("", 3, supernodeKBucket, primarySuFloId); + + let promises = []; + let leaving_supernode_flo_id = ""; + + for (let index = 0; index < getSupernodeClosestSuObj.length; index++) { + const element = getSupernodeClosestSuObj[index]; + if (element.data.id==localbitcoinplusplus.wallets.my_local_flo_address) break; + promises.push(readDBbyIndex('myClosestSupernodes', 'trader_flo_address', element.data.id)); + leaving_supernode_flo_id = element.data.id; + } + + Promise.all(promises).then(cs=>{ + let isPreviousSupernodesLive = cs.map((su_status, index)=> + (typeof su_status[index] !== "object" || su_status[index].is_live == true ) + ); + + if (!isPreviousSupernodesLive.includes(true)) { + resolve(true); // Every previous supernode is dead + } else { + resolve(false); // At least one previous supernode is alive + } + }).catch(e=>reject(e)); + }); + } } @@ -11175,16 +11245,17 @@ if (typeof user_keys == "object" && typeof user_keys.pubKeyHex == "string") { if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(user_keys.pubKeyHex)) { if (typeof flo_id !== null || typeof flo_id !== 'undefined') { - // let karr = KBucket.toArray(); - // let karr_floIds = karr.map(f=>f.data.id); - // if (!karr_floIds.includes(flo_id)) { - // return callback(false); - // } - - localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id) + localbitcoinplusplus.kademlia.determineClosestSupernode(flo_id, 4) .then(my_closest_su=>{ if (user_keys.address === my_closest_su[0].data.id) { return callback(true); + } else { + let su_arr = my_closest_su.map(m=>m.data.id); + if(su_arr.includes(flo_id)) { + return callback(true); + } else { + return callback(false); + } } }); } else { @@ -12452,6 +12523,17 @@ request.response = {}; let err_msg; + if(typeof params.trader_flo_address !="string") return; + const my_closest_su_list = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.trader_flo_address); + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + if (method=="sync_with_supernode") { RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { if (is_valid_request === true && params.job == @@ -12477,22 +12559,36 @@ }); } + if (method=="sync_primary_supernode_from_backup_supernode") { + // params.trader_flo_address -> primary supernode flo id + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { + if (is_valid_request === true && params.job == + "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > + 0) { + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + + localbitcoinplusplus.actions.get_sharable_db_data(tableArray, params.trader_flo_address).then( + function (su_db_data) { + if (typeof su_db_data == "object") { + su_db_data.trader_flo_address = params.trader_flo_address; + su_db_data.receiver_flo_address = params.trader_flo_address; + RM_RPC + .send_rpc + .call(this, "sync_primary_supernode_from_backup_supernode_response", + su_db_data) + .then(server_sync_response=> + doSend(server_sync_response)); + } + }); + } + }); + } + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { if (is_valid_request !== true) return false; try { - - if(typeof params.trader_flo_address !="string") return; - const my_closest_su_list = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.trader_flo_address); - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - // CHECK HERE IF USER IS INDULGED IN ANY MORE TRADE. IF TRUE RETURN ERROR + // CHECK HERE IF USER IS INDULGED IN ANY MORE TRADE. IF TRUE RETURN ERROR await backup_server_db_instance.backup_readAllDB("deposit").then(function (res) { if (typeof res == "object" && res.length > 0) { let canUserTrade = res.filter(function (user) { @@ -15086,11 +15182,16 @@ if (typeof idbData.lastConnectedSupernode == "string" && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', - { requesting_user_id: idbData.myLocalFLOAddress}); - await localbitcoinplusplus.actions.delay(180000).then(()=>{ - showMessage(`INFO: Data syncing is complete.`); + + // Get data for deposits and withdraw from last (currently alive) backup supernode + readAllDB('myClosestSupernodes').then(cs=>{ + for (let index = cs.length; index > 0; index--) { + const element = cs[index]; + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(primarySupernode, getPrimarySuObj[element].data.id); + } }); + } // rebuild private key @@ -15691,42 +15792,7 @@ } }); break; - - case "send_back_shamirs_secret_supernode_pvtkey": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - if(typeof res_obj.globalParams.senderFloId !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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("supernode_private_key_chunks", res_obj.params[0].chunk_val) - .then(function (res) { - let send_pvtkey_req = null; - if (typeof res=="object") { - RM_RPC - .send_rpc - .call(this, "retrieve_shamirs_secret_supernode_pvtkey", { - private_key_chunk: res - }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - } else { - RM_RPC - .send_rpc - .call(this, "retrieve_shamirs_secret_supernode_pvtkey", "") - .then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - } - }); - }) - } - break; - + case "send_back_shamirs_secret_btc_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -15948,6 +16014,7 @@ if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string' || localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1) ) { + const RM_WALLET = new localbitcoinplusplus.wallets; RM_WALLET.manually_assign_my_private_key(); loadExternalFiles(); dataBaseUIOperations(); @@ -15989,6 +16056,7 @@ } function onOpen(evt) { + localbitcoinplusplus.amIreadyToServePrimaryUsers = false; reactor.dispatchEvent('new_supernode_connected', evt); } @@ -16231,7 +16299,6 @@ case "withdraw_request_method": response_from_sever = RM_RPC.receive_rpc_response.call(this, JSON.stringify(res_obj)); - //doSend(JSON.stringify(response_from_sever)); // send response to client break; case "withdrawal_request_response": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -17013,6 +17080,99 @@ } break; + case "sync_primary_supernode_from_backup_supernode": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, + JSON.stringify(res_obj)); + } + break; + + case "sync_primary_supernode_from_backup_supernode_response": + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let su_db_data = res_obj.params[0]; + if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || + su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + ) return false; + + (async function () { + let i = 0; + for (let tableStoreName in su_db_data) { + i++; + if (i==su_db_data.length-2) { + // Get data for crypto and fiat balances based on vector clock from all backup supernodes + reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', + { requesting_user_id: idbData.myLocalFLOAddress}); + await localbitcoinplusplus.actions.delay(180000).then(()=>{ + showMessage(`INFO: Balance syncing is complete.`); + + localbitcoinplusplus.amIreadyToServePrimaryUsers = true; + + const RM_RPC = new localbitcoinplusplus.rpc; + + // Method 1: Inform user nodes they can now trade + RM_RPC + .send_rpc + .call(this, "supernode_message", { + "trader_flo_address": respective_trader_id, + "receiver_flo_address": "", // message for all + "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, + }).thn(server_response=>doSend(server_response)); + + // Method 2: Now inform all backup supernodes you are back and request to stop serving your users + // RM_RPC + // .send_rpc + // .call(this, "update_supernode_status", { + // trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + // trader_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, + // su_status: true, + // }).then(server_response=> + // doSend(server_response, nextSu.data.id)); + + }); + } + // skip loop if the property is from prototype + if (tableStoreName == 'trader_flo_address' + || tableStoreName == 'receiver_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 updateinDB(tableStoreName, obj[prop], obj[ + prop].trader_flo_address).then(()=>{ + showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); + }); + } + } + } else { + let resdbdata = await removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await addDB(resdbdata, obj[prop]).then(()=>{ + showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); + }); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + } + break; + default: break; } @@ -17075,7 +17235,18 @@ console.log(res_obj); return; } + + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions + .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); + console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); + + if (ifAllPrevSuAreDead !== true) { + console.log(res_obj); + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) + return; + } + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -17777,10 +17948,11 @@ break; case "refresh_deposit_status_request": - RM_RPC.filter_legit_backup_requests((is_valid_request) => { + if(typeof res_obj.params[0].trader_flo_address !="string") return; + RM_RPC.filter_legit_backup_requests(res_obj.params[0].trader_flo_address, + function(is_valid_request) { if (is_valid_request !== true) return false; - if(typeof res_obj.params[0].trader_flo_address !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) .then(my_closest_su_list=>{ const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; @@ -20157,7 +20329,6 @@ reactor.registerEvent('backup_supernode_down'); reactor.registerEvent('fireNodeWelcomeBackEvent'); reactor.registerEvent('fireNodeGoodByeEvent'); - reactor.registerEvent('requestNextBackupSupernodeToSyncDataBeforeActingAsBackupSupernodeNode'); reactor.registerEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { @@ -20231,47 +20402,6 @@ }); }); - reactor.addEventListener('requestNextBackupSupernodeToSyncDataBeforeActingAsBackupSupernodeNode', - async function(params) { - const RM_RPC = new localbitcoinplusplus.rpc; - - getNextClosestSuObj.map((nextSu, i)=>{ - if((i>0) && (nextSu.data.id !==localbitcoinplusplus.wallets.my_local_flo_address)) { - let nextSuConn = localbitcoinplusplus.newBackupDatabase.db[nextSu.data.id]; - if(typeof nextSuConn !== "object") { - let msg = `WARNING: Failed to open a backup DB with Supernode ${nextSu}.`; - showMessage(msg); - throw new Error(msg); - } - - const table_array = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "sellOrders", "buyOrders", - ]; - - table_array.map(async tbl=>{ - let record = await nextSuConn.backup_readDBbyIndex(tbl, 'trader_flo_address', params.requesting_user_id); - - record.map(rec=>{ - RM_RPC - .send_rpc - .call(this, "sync_data_by_vector_clock", { - trader_flo_address: params.requesting_user_id, - receiver_flo_address: nextSu.data.id, - leaving_supernode_flo_id: params.leaving_supernode_flo_id, - data: rec, - dbTable: tbl - }).then(server_response=> - doSend(server_response, nextSu.data.id)); - - }); - - }); - - } - }); - - }); - reactor.addEventListener('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', async function(params) { let msg = ''; if (typeof params.requesting_user_id !== "string") { @@ -20295,9 +20425,7 @@ const RM_RPC = new localbitcoinplusplus.rpc; - const table_array = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "sellOrders", "buyOrders", - ]; + const table_array = ["crypto_balances", "cash_balances"]; table_array.map(async tbl=>{ let record = await readDBbyIndex(tbl, 'trader_flo_address', params.requesting_user_id); @@ -20330,6 +20458,7 @@ }); + From 701db7da42d232eeec1c4faccd53d5743489abe3 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 14 May 2019 21:12:01 +0530 Subject: [PATCH 19/95] fixed db functions for primary and backup db --- supernode/index.html | 247 +++++++++++++++++++------------------------ 1 file changed, 111 insertions(+), 136 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 6bbfd09..3f1c2ec 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10143,9 +10143,10 @@ get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { let arr = {}; if (typeof backup_db=="string" && backup_db.length>0) { + let _readAllDB = readAllDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); + _readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -10153,17 +10154,18 @@ } } for (const elem of dbTableNamesArray) { - await readAllDB(elem).then(e => arr[elem] = e); + await _readAllDB(elem).then(e => arr[elem] = e); } return arr; }, get_sharable_db_data_for_single_user: async function (dbTableNamesArray, backup_db="") { let arr = {}; + let _readDBbyIndex = readDBbyIndex; if (typeof backup_db=="string" && backup_db.length>0) { if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); + _readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -10171,7 +10173,7 @@ } } for (const elem of dbTableNamesArray) { - await readDBbyIndex(elem).then(e => arr[elem] = e); + await _readDBbyIndex(elem).then(e => arr[elem] = e); } return arr; }, @@ -13924,16 +13926,12 @@ } if (typeof backup_db=="string" && backup_db.length>0) { + let _addDB = addDB; + let _readDB = readDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); + _addDB = foreign_db.backup_addDB.bind(foreign_db); + _readDB = foreign_db.backup_readDB.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -13947,7 +13945,7 @@ //Check buyer's fiat balance const trader_cash_id = `${params.trader_flo_address}_${params.currency}`; - readDB("cash_balances", trader_cash_id).then(function (res) { + _readDB("cash_balances", trader_cash_id).then(function (res) { if (typeof res !== "undefined" && typeof res.cash_balance == "number" && !isNaN(res.cash_balance)) { let buyer_cash_balance = parseFloat(res.cash_balance); let buy_price_btc = parseFloat(params.buy_price); @@ -13965,7 +13963,7 @@ let res_btc; // supernode data query - readDB('localbitcoinUser', '00-01').then(function (user_data) { + _readDB('localbitcoinUser', '00-01').then(function (user_data) { if (typeof user_data == "object" && typeof localbitcoinplusplus.wallets .MY_SUPERNODE_PRIVATE_KEY == "string" && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY @@ -13985,7 +13983,7 @@ params["supernodePubKey"] = user_data.myLocalFLOPublicKey; params["status"] = 1; - addDB("buyOrders", params); + _addDB("buyOrders", params); // Send data for further action callback(params); @@ -14029,16 +14027,12 @@ } if (typeof backup_db=="string" && backup_db.length>0) { + let _addDB = addDB; + let _readDB = readDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); + _addDB = foreign_db.backup_addDB.bind(foreign_db); + _readDB = foreign_db.backup_readDB.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -14052,7 +14046,7 @@ // Check crypto balance of the seller let seller_btc_id = `${params.trader_flo_address}_${params.product}`; - readDB("crypto_balances", seller_btc_id).then(function (res) { + _readDB("crypto_balances", seller_btc_id).then(function (res) { if (typeof res !== "undefined" && typeof res.trader_flo_address == "string" && res.trader_flo_address .length > 0 && res.crypto_balance > 0) { let seller_btc_balance = parseFloat(res.crypto_balance); @@ -14069,7 +14063,7 @@ } // supernode data query - readDB('localbitcoinUser', '00-01').then(function (user_data) { + _readDB('localbitcoinUser', '00-01').then(function (user_data) { if (typeof user_data == "object" && typeof localbitcoinplusplus.wallets .MY_SUPERNODE_PRIVATE_KEY == "string" && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY @@ -14088,7 +14082,7 @@ params["supernodePubKey"] = user_data.myLocalFLOPublicKey; params["status"] = 1; - addDB("sellOrders", params); + _addDB("sellOrders", params); callback(params); } @@ -14345,16 +14339,10 @@ /*Finds the best buy sell id match for a trade*/ createTradePipes(trading_currency = "USD", backup_db="") { if (typeof backup_db=="string" && backup_db.length>0) { + let _readAllDB = readAllDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); + _readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -14362,11 +14350,11 @@ } } try { - readAllDB("sellOrders").then(function (sellOrdersList) { + _readAllDB("sellOrders").then(function (sellOrdersList) { if (sellOrdersList.length > 0) { sellOrdersList = sellOrdersList.filter(sellOrder => sellOrder.currency == trading_currency); - readAllDB("buyOrders").then(function (buyOrdersList) { + _readAllDB("buyOrders").then(function (buyOrdersList) { if (buyOrdersList.length > 0) { buyOrdersList = buyOrdersList.filter(buyOrder => buyOrder.currency == trading_currency); @@ -14425,16 +14413,24 @@ }, launchTrade(buyPipeObj, sellPipeObj, callback, backup_db="") { if (typeof backup_db=="string" && backup_db.length>0) { + let _addDB = addDB; + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; + let _readAllDB = readAllDB; + let _updateinDB = updateinDB; + let _removeinDB = removeinDB; + let _removeByIndex = removeByIndex; + let _removeAllinDB = removeAllinDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); + _addDB = foreign_db.backup_addDB.bind(foreign_db); + _readDB = foreign_db.backup_readDB.bind(foreign_db); + _readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); + _readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); + _updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); + _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); + _removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); + _removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -14451,7 +14447,7 @@ let err_msg; // Check buyer's cash balance const buyer_cash_id = `${buyPipeObj.trader_flo_address}_${buyPipeObj.currency}`; - readDB("cash_balances", buyer_cash_id).then(function (buyPipeCashRes) { + _readDB("cash_balances", buyer_cash_id).then(function (buyPipeCashRes) { if (typeof buyPipeCashRes == "object" && typeof buyPipeCashRes.cash_balance == "number") { let buyer_cash_balance = parseFloat(buyPipeCashRes.cash_balance); @@ -14471,7 +14467,7 @@ // Check seller's crypto balance let seller_btc_id = `${sellPipeObj.trader_flo_address}_${sellPipeObj.product}`; - readDB("crypto_balances", seller_btc_id).then(function (sellPipeBTCRes) { + _readDB("crypto_balances", seller_btc_id).then(function (sellPipeBTCRes) { if (typeof sellPipeBTCRes == "object" && typeof sellPipeBTCRes.crypto_balance == "number") { let seller_btc_balance = Number(parseFloat(sellPipeBTCRes.crypto_balance) @@ -14493,7 +14489,7 @@ let buyerBTCResponseObject; let buyer_btc_id = `${buyPipeObj.trader_flo_address}_${buyPipeObj.product}`; - readDB("crypto_balances", buyPipeObj.trader_flo_address).then( + _readDB("crypto_balances", buyPipeObj.trader_flo_address).then( function (buyPipeBTCRes) { if (typeof buyPipeBTCRes == "object" && typeof buyPipeBTCRes .crypto_balance == "number") { @@ -14526,7 +14522,7 @@ let sellerCashResponseObject; const seller_cash_id = `${sellPipeObj.trader_flo_address}_${buyPipeObj.currency}`; - readDB("cash_balances", seller_cash_id).then( + _readDB("cash_balances", seller_cash_id).then( function (sellPipeCashRes) { if (typeof sellPipeCashRes == "object" && typeof sellPipeCashRes @@ -14566,7 +14562,7 @@ } // supernode data query - readDB('localbitcoinUser', '00-01') + _readDB('localbitcoinUser', '00-01') .then( function (user_data) { if (typeof user_data == @@ -14578,11 +14574,11 @@ .length > 0) { // Delete orders try { - removeinDB( + _removeinDB( "buyOrders", buyPipeObj .id); - removeinDB( + _removeinDB( "sellOrders", sellPipeObj .id); @@ -14594,25 +14590,25 @@ // Update balances try { - updateinDB( + _updateinDB( "cash_balances", buyerCashResponseObject, buyPipeObj .trader_flo_address ); - updateinDB( + _updateinDB( "cash_balances", sellerCashResponseObject, sellPipeObj .trader_flo_address ); - updateinDB( + _updateinDB( "crypto_balances", buyerBTCResponseObject, buyPipeObj .trader_flo_address ); - updateinDB( + _updateinDB( "crypto_balances", sellerBTCResponseObject, sellPipeObj @@ -14729,16 +14725,12 @@ getAssetTradeAndWithdrawLimit(flo_id, crypto, fiat, backup_db="") { if (typeof backup_db=="string" && backup_db.length>0) { + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); + _readDB = foreign_db.backup_readDB.bind(foreign_db); + _readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); } else { err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; showMessage(err_msg); @@ -14751,15 +14743,15 @@ let user_crypto_id = `${flo_id}_${crypto}`; let user_fiat_id = `${flo_id}_${fiat}`; - const user_balance_crypto_promise = readDB("crypto_balances", user_crypto_id); - const user_balance_fiat_promise = readDB("cash_balances", user_fiat_id); - const user_sell_orders_promise = readDBbyIndex("sellOrders", "trader_flo_address", flo_id) + const user_balance_crypto_promise = _readDB("crypto_balances", user_crypto_id); + const user_balance_fiat_promise = _readDB("cash_balances", user_fiat_id); + const user_sell_orders_promise = _readDBbyIndex("sellOrders", "trader_flo_address", flo_id) .then((res) => res.filter(resp => resp.currency == fiat && resp.product == crypto)); - const user_buy_orders_promise = readDBbyIndex("buyOrders", "trader_flo_address", flo_id) + const user_buy_orders_promise = _readDBbyIndex("buyOrders", "trader_flo_address", flo_id) .then((res) => res.filter(resp => resp.currency == fiat && resp.product == crypto)); - const user_fiat_withdraw_request_promise = readDBbyIndex("withdraw_cash", "trader_flo_address", + const user_fiat_withdraw_request_promise = _readDBbyIndex("withdraw_cash", "trader_flo_address", flo_id); - const user_crypto_withdraw_request_promise = readDBbyIndex("withdraw_btc", "trader_flo_address", + const user_crypto_withdraw_request_promise = _readDBbyIndex("withdraw_btc", "trader_flo_address", flo_id); return Promise.all([user_balance_crypto_promise, user_balance_fiat_promise, @@ -15160,7 +15152,7 @@ wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - const getClosestSuList = await readAllDB('closestSupernodesTable'); + const getClosestSuList = await readAllDB('myClosestSupernodes'); if (wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress || getClosestSuList.length < 3) { showMessage(`INFO: Invalid connection. Refreshing the closest supernode list in DB.`); wsUri = await localbitcoinplusplus.kademlia.updateClosestSupernodeSeeds(idbData.myLocalFLOAddress); @@ -17236,15 +17228,18 @@ return; } - let ifAllPrevSuAreDead = await localbitcoinplusplus.actions + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); - console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); + console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - if (ifAllPrevSuAreDead !== true) { - console.log(res_obj); - showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) - return; + if (ifAllPrevSuAreDead !== true) { + console.log(res_obj); + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) + return; + } } if (typeof res_obj.method !== "undefined") { @@ -18049,22 +18044,9 @@ doSend(JSON.stringify(response_from_sever)); // send response to client break; - case "updateUserCryptoBalanceRequest": + case "updateUserCryptoBalanceRequest": let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - - let SuPubKey = backup_server_db_instance.backup_readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) + let SuPubKey = readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) .then(user_data => { if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < 1) @@ -18076,7 +18058,7 @@ user_data.supernode_flo_public_key ); if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, + updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, user_data.trader_flo_address); if (localbitcoinplusplus.wallets.my_local_flo_address == updateUserCryptoBalanceResponseObject.trader_flo_address) { @@ -18088,8 +18070,6 @@ showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); } }); - }); - break; case "addNewKbucketNode": @@ -18191,25 +18171,11 @@ let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); if(typeof flo_addr_for_pubkey !== "string") return; if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; - - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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('ipTable', { - 'flo_public_key': req_params.requesters_pub_key, - 'temporary_ip': incoming_msg_local_ip - }).then((ipRes)=>{ - reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); - }); + updateinDB('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); }); } break; @@ -19257,11 +19223,22 @@ unique: false }); } - if (!db.objectStoreNames.contains('ipTable')) { - var objectStore = db.createObjectStore("ipTable", { + if (!this.db.objectStoreNames.contains('ipTable')) { + var objectStore = this.db.createObjectStore("ipTable", { keyPath: 'flo_public_key' }); } + if (!this.db.objectStoreNames.contains('myClosestSupernodes')) { + var objectStore = this.db.createObjectStore("myClosestSupernodes", { + keyPath: 'id' + }); + objectStore.createIndex('trader_flo_address', 'trader_flo_address', { + unique: true + }); + objectStore.createIndex('ip', 'ip', { + unique: false + }); + } }.bind(this) @@ -20163,23 +20140,21 @@ if (!localbitcoinplusplus.master_configurations.tradableAsset1 .includes(trader_deposits.product)) return false; - if (typeof backup_db=="string" && backup_db.length>0) { - if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { - const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - addDB = foreign_db.backup_addDB.bind(foreign_db); - readDB = foreign_db.backup_readDB.bind(foreign_db); - readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); - readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); - updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); - removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - removeByIndex = foreign_db.backup_removeByIndex.bind(foreign_db); - removeAllinDB = foreign_db.backup_removeAllinDB.bind(foreign_db); - } else { - err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; - showMessage(err_msg); - throw new Error(err_msg); + if (typeof backup_db=="string" && backup_db.length>0) { + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; + let _updateinDB = updateinDB; + if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + _readDB = foreign_db.backup_readDB.bind(foreign_db); + _readDBbyIndex = foreign_db.backup_readDBbyIndex.bind(foreign_db); + _updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); + } else { + err_msg = `WARNING: Invalid Backup DB Instance Id: ${backup_db}.`; + showMessage(err_msg); + throw new Error(err_msg); + } } - } let explorer; let decimal = 100000000; @@ -20223,14 +20198,14 @@ //Deposit successful. Update user balance and status to 2. Its Private key can be // now given to a random trader trader_deposits.status = 2; - updateinDB("deposit", trader_deposits, trader_deposits.trader_flo_address); + _updateinDB("deposit", trader_deposits, trader_deposits.trader_flo_address); - readDBbyIndex('system_btc_reserves_private_keys', 'btc_address', trader_deposits.btc_address) + _readDBbyIndex('system_btc_reserves_private_keys', 'btc_address', trader_deposits.btc_address) .then(function (reserve_res) { if (typeof reserve_res == "object") { reserve_res.map(reserves => { reserves.balance = balance; - updateinDB('system_btc_reserves_private_keys', reserves, + _updateinDB('system_btc_reserves_private_keys', reserves, reserves.id); }); } @@ -20244,14 +20219,14 @@ crypto_balance: balance, crypto_currency: trader_deposits.product } - readDB('crypto_balances', trader_depositor_cash_id).then(function (res_btc_balances) { + _readDB('crypto_balances', trader_depositor_cash_id).then(function (res_btc_balances) { if (typeof res_btc_balances == "object" && typeof res_btc_balances.result == "object" && typeof res_btc_balances.crypto_balance == "number") { updatedCryptobalances.crypto_balance += parseFloat(res_btc_balances .crypto_balance); } // Update crypto balance of user in crypto_balances - updateinDB("crypto_balances", updatedCryptobalances, trader_deposits.btc_address) + _updateinDB("crypto_balances", updatedCryptobalances, trader_deposits.btc_address) .then(updatedBTCBalanceObject => { const RM_WALLET = new localbitcoinplusplus.wallets; From cff3ef5b18c1b4450ea765e08c883f72dd1efd5a Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 15 May 2019 14:09:14 +0530 Subject: [PATCH 20/95] fixed db functions for primary and backup db --- supernode/index.html | 114 ++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 62 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 3f1c2ec..c51c453 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10142,8 +10142,8 @@ get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { let arr = {}; + let _readAllDB = readAllDB; if (typeof backup_db=="string" && backup_db.length>0) { - let _readAllDB = readAllDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); @@ -13907,6 +13907,8 @@ }, trade_buy(params, callback, backup_db="") { let err_msg; + let _addDB = addDB; + let _readDB = readDB; for (var key in params) { if (params.hasOwnProperty(key)) { if (typeof key == undefined || key.trim() == "" || key == null) { @@ -13926,8 +13928,6 @@ } if (typeof backup_db=="string" && backup_db.length>0) { - let _addDB = addDB; - let _readDB = readDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _addDB = foreign_db.backup_addDB.bind(foreign_db); @@ -14008,6 +14008,8 @@ }, trade_sell(params, callback, backup_db="") { let err_msg; + let _addDB = addDB; + let _readDB = readDB; for (var key in params) { if (params.hasOwnProperty(key)) { if (typeof key == "undefined" || key.trim() == "" || key == null) { @@ -14027,8 +14029,6 @@ } if (typeof backup_db=="string" && backup_db.length>0) { - let _addDB = addDB; - let _readDB = readDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _addDB = foreign_db.backup_addDB.bind(foreign_db); @@ -14338,8 +14338,8 @@ }, /*Finds the best buy sell id match for a trade*/ createTradePipes(trading_currency = "USD", backup_db="") { + let _readAllDB = readAllDB; if (typeof backup_db=="string" && backup_db.length>0) { - let _readAllDB = readAllDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _readAllDB = foreign_db.backup_readAllDB.bind(foreign_db); @@ -14412,15 +14412,15 @@ } }, launchTrade(buyPipeObj, sellPipeObj, callback, backup_db="") { + let _addDB = addDB; + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; + let _readAllDB = readAllDB; + let _updateinDB = updateinDB; + let _removeinDB = removeinDB; + let _removeByIndex = removeByIndex; + let _removeAllinDB = removeAllinDB; if (typeof backup_db=="string" && backup_db.length>0) { - let _addDB = addDB; - let _readDB = readDB; - let _readDBbyIndex = readDBbyIndex; - let _readAllDB = readAllDB; - let _updateinDB = updateinDB; - let _removeinDB = removeinDB; - let _removeByIndex = removeByIndex; - let _removeAllinDB = removeAllinDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _addDB = foreign_db.backup_addDB.bind(foreign_db); @@ -14673,20 +14673,23 @@ .wallets.MY_SUPERNODE_PRIVATE_KEY ); - let - response_for_client = { - "trade_infos": trade_infos, - "buyer_cash_data": buyerCashResponseObject, - "seller_cash_data": sellerCashResponseObject, - "buyer_btc_data": buyerBTCResponseObject, - "seller_btc_data": sellerBTCResponseObject, - "data_hash": hashed_data, - "supernode_sign": signed_data, - "supernodePubKey": user_data.myLocalFLOPublicKey, - "trader_flo_address": buyPipeObj.trader_flo_address, - } - callback(response_for_client); - return true; + localbitcoinplusplus.kademlia.determineClosestSupernode(buyPipeObj.trader_flo_address) + .then(getPrimarySuObj=>{ + let response_for_client = { + "trade_infos": trade_infos, + "buyer_cash_data": buyerCashResponseObject, + "seller_cash_data": sellerCashResponseObject, + "buyer_btc_data": buyerBTCResponseObject, + "seller_btc_data": sellerBTCResponseObject, + "data_hash": hashed_data, + "supernode_sign": signed_data, + "supernodePubKey": user_data.myLocalFLOPublicKey, + "trader_flo_address": getPrimarySuObj[0].data.id, + } + callback(response_for_client); + return true; + }); + } }); }); @@ -14723,10 +14726,9 @@ }, getAssetTradeAndWithdrawLimit(flo_id, crypto, fiat, backup_db="") { - + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; if (typeof backup_db=="string" && backup_db.length>0) { - let _readDB = readDB; - let _readDBbyIndex = readDBbyIndex; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _readDB = foreign_db.backup_readDB.bind(foreign_db); @@ -17478,8 +17480,6 @@ case "trade_balance_updates": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const trade_balance_res = res_obj.params[0]; - // Only the relevent user node should get response - if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; // Verify data let trade_info_str = JSON.stringify(trade_balance_res.trade_infos); let buyer_cash_data_str = JSON.stringify(trade_balance_res.buyer_cash_data); @@ -17491,7 +17491,7 @@ `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; let hashed_data = Crypto.SHA256(res_str); - RM_RPC.filter_legit_requests(trade_balance_res.trade_infos.buyer_flo_id, + RM_RPC.filter_legit_backup_requests(trade_balance_res.trade_infos.buyer_flo_id, function (is_valid_request) { if (is_valid_request !== true) return false; @@ -18138,30 +18138,21 @@ break; case "link_My_Local_IP_To_My_Flo_Id": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const req_params = res_obj.params[0]; - if(typeof req_params.requesters_pub_key !== "string") return; - let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); - if(typeof flo_addr_for_pubkey !== "string") return; - if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; - - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; - - 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('ipTable', { - 'flo_public_key': req_params.requesters_pub_key, - 'temporary_ip': incoming_msg_local_ip - }).then((ipRes)=>{ - reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); - }).finally(()=>{ - linkBackOthersLocalIPToTheirFloId(); - }); - } + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + updateinDB('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }).finally(()=>{ + linkBackOthersLocalIPToTheirFloId(); + }); + } break; case "link_Others_Local_IP_To_Their_Flo_Id": @@ -20139,11 +20130,10 @@ ) return false; if (!localbitcoinplusplus.master_configurations.tradableAsset1 .includes(trader_deposits.product)) return false; - + let _readDB = readDB; + let _readDBbyIndex = readDBbyIndex; + let _updateinDB = updateinDB; if (typeof backup_db=="string" && backup_db.length>0) { - let _readDB = readDB; - let _readDBbyIndex = readDBbyIndex; - let _updateinDB = updateinDB; if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; _readDB = foreign_db.backup_readDB.bind(foreign_db); From 9e8e2587d5a058c327d69ba0b5ab8c12ba3207ac Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 16 May 2019 16:49:14 +0530 Subject: [PATCH 21/95] added code for Primary supernode to sync data from backup supernodes --- supernode/index.html | 148 +++++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 53 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index c51c453..13d98ac 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10137,7 +10137,7 @@ "trader_flo_address": primary_su, "job": "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", "receiver_flo_address": backup_su, - }).then(sync_request=>doSend(sync_request, primary_su)); + }).then(sync_request=>doSend(sync_request, backup_su)); }, get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { @@ -12579,7 +12579,7 @@ .call(this, "sync_primary_supernode_from_backup_supernode_response", su_db_data) .then(server_sync_response=> - doSend(server_sync_response)); + doSend(server_sync_response, params.trader_flo_address)); } }); } @@ -15177,15 +15177,16 @@ && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - // Get data for deposits and withdraw from last (currently alive) backup supernode - readAllDB('myClosestSupernodes').then(cs=>{ - for (let index = cs.length; index > 0; index--) { - const element = cs[index]; - localbitcoinplusplus.actions - .sync_primary_supernode_from_backup_supernode(primarySupernode, getPrimarySuObj[element].data.id); - } - }); - + // Get data for deposits and withdraw starting from first (and currently alive) backup supernode + // readAllDB('myClosestSupernodes').then(cs=>{ + // // for (let index = cs.length; index > 0; index--) { + + // }); + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(idbData.myLocalFLOAddress, 3); + for (let index = 1; index <= cs.length-1; index++) { + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(getPrimarySuObj[0].data.id, getPrimarySuObj[index].data.id); + } } // rebuild private key @@ -15314,10 +15315,12 @@ let su_backup_db_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.receiverFloId); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15377,7 +15380,9 @@ buyOrders_data.supernodePubKey); if (isDataSignedBySuperNode === true) { - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15402,8 +15407,10 @@ .verify(sellOrders_data.data_hash, sellOrders_data.supernode_sign, sellOrders_data.supernodePubKey); if (isDataSignedBySuperNode === true) { - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; - + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; showMessage(backup_db_error_msg); @@ -15424,7 +15431,7 @@ || typeof res_obj.params[0] !== "object") return; let deposit_res_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].data == "object") { @@ -15432,8 +15439,9 @@ 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[res_obj.globalParams.senderFloId]; - + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; showMessage(backup_db_error_msg); @@ -15463,14 +15471,17 @@ || typeof res_obj.params[0] !== "object") return; let withdrawal_res_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; 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[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(withdrawal_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15491,12 +15502,15 @@ || typeof res_obj.params[0] !== "object") return; let cancel_res_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(cancel_res_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; 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[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(cancel_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15546,7 +15560,7 @@ let hashed_data = Crypto.SHA256(res_str); RM_RPC.filter_legit_backup_requests(trade_balance_res.trade_infos.buyer_flo_id, - function (is_valid_request) { + async function (is_valid_request) { if (is_valid_request !== true) return false; if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( @@ -15554,7 +15568,10 @@ if (RM_WALLET.verify(hashed_data, trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(trade_balance_res.trade_infos.buyer_flo_id); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15596,7 +15613,7 @@ || typeof res_obj.params[0] !== "object") return; let withdraw_caim_res_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(withdraw_caim_res_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let depositor_claim_response_object = res_obj.params[0]; @@ -15613,7 +15630,10 @@ 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[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(withdraw_caim_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -15635,7 +15655,7 @@ || typeof res_obj.params[0] !== "object") return; let update_deposit_withdraw_claim_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(update_deposit_withdraw_claim_data.trader_flo_address, - function (is_valid_request) { + async function (is_valid_request) { if(!is_valid_request) return false; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let withdraw_success_response = res_obj.params[0]; @@ -15651,7 +15671,10 @@ 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[res_obj.globalParams.senderFloId]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(update_deposit_withdraw_claim_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; @@ -17074,14 +17097,6 @@ } break; - case "sync_primary_supernode_from_backup_supernode": - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, - JSON.stringify(res_obj)); - } - break; - case "sync_primary_supernode_from_backup_supernode_response": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -17094,10 +17109,10 @@ let i = 0; for (let tableStoreName in su_db_data) { i++; - if (i==su_db_data.length-2) { + if (i==Object.keys(su_db_data).length-2) { // Get data for crypto and fiat balances based on vector clock from all backup supernodes reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', - { requesting_user_id: idbData.myLocalFLOAddress}); + { requesting_user_id: localbitcoinplusplus.wallets.my_local_flo_address}); await localbitcoinplusplus.actions.delay(180000).then(()=>{ showMessage(`INFO: Balance syncing is complete.`); @@ -17108,11 +17123,12 @@ // Method 1: Inform user nodes they can now trade RM_RPC .send_rpc - .call(this, "supernode_message", { + .call(this, "reconnect_with_another_supernode", { "trader_flo_address": respective_trader_id, "receiver_flo_address": "", // message for all + "ws_url": websocket.url, "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, - }).thn(server_response=>doSend(server_response)); + }).then(server_response=>doSend(server_response)); // Method 2: Now inform all backup supernodes you are back and request to stop serving your users // RM_RPC @@ -17129,8 +17145,7 @@ // skip loop if the property is from prototype if (tableStoreName == 'trader_flo_address' || tableStoreName == 'receiver_flo_address' - || !su_db_data.hasOwnProperty( - tableStoreName)) continue; + || !su_db_data.hasOwnProperty(tableStoreName)) continue; try { let obj = su_db_data[tableStoreName]; @@ -17167,6 +17182,23 @@ } break; + case "reconnect_with_another_supernode": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let su_db_data = res_obj.params[0]; + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC.filter_legit_requests(su_db_data.trader_flo_address, + async function (is_valid_request) { + if (is_valid_request!==true) return; + if (websocket.readyState === WebSocket.OPEN) { + websocket.close(); + await startWebSocket(su_db_data.ws_url); + showMssage(`INFO: ${su_db_data.server_msg}`); + } + } + ); + } + break; + default: break; } @@ -17230,17 +17262,19 @@ return; } - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - let ifAllPrevSuAreDead = await localbitcoinplusplus.actions - .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); - - console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); + if (res_obj.method !== "sync_primary_supernode_from_backup_supernode") { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions + .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); + + console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - if (ifAllPrevSuAreDead !== true) { - console.log(res_obj); - showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) - return; + if (ifAllPrevSuAreDead !== true) { + console.log(res_obj); + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) + return; + } } } @@ -18441,6 +18475,14 @@ } break; + case "sync_primary_supernode_from_backup_supernode": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, + JSON.stringify(res_obj)); + } + break; + default: break; } From cb00785ab6f091ebca42e75f72b5a4c3a757cc79 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 18 May 2019 18:27:58 +0530 Subject: [PATCH 22/95] fixed issues on having left-right supernodes --- supernode/index.html | 454 +++++++++++++++++++++++++++++-------------- 1 file changed, 311 insertions(+), 143 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 13d98ac..114c9da 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10072,12 +10072,24 @@ `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + #!#MaxBackups=3 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, + 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB, + 026FCC6CFF6EB3A39E54BEB6E13FC2F02C3A93F4767AA80E49E7E876443F95AE5F,029CDB29270DC5087EF4903E8C2364552C62E935FBAA1A96AB53CC5791C7EF2067, + 022EC1D090960D9EFFFC60FDC34AB97A8395A5F6D1326DD1B1380BD9F6E31981CA,037C623A8D31DB751F666A1D2C65EC8996C5978348CEEE8566F480708D4A6335AB, + 032871A74D2DDA9D0DE7135F58B5BD2D7F679D2CCA20EA7909466D1A6912DF4022 #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, #!#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"}}`; + "ranchimall3":{"ip":"127.0.0.1","port":"9003","kbucketId":"odYA6KagmbokSh9GY7yAfeTUZRtZLwecY1"}, + "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, + "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}, + "ranchimall6":{"ip":"127.0.0.1","port":"9006","kbucketId":"oV1wCeWca3VawbBTfUGKA7Vd368PATnKAx"}, + "ranchimall7":{"ip":"127.0.0.1","port":"9007","kbucketId":"oSqFZePXibNJqeiboTYmmaqqVkd6esDUfZ"}, + "ranchimall8":{"ip":"127.0.0.1","port":"9008","kbucketId":"odUQekfMPsZV3ocneFW8SNSZADFtx9xUtm"}, + "ranchimall9":{"ip":"127.0.0.1","port":"9009","kbucketId":"oLYeoBfXWxKkUmRxhn1pcmJWtTu5kZoUJq"}, + "ranchimall10":{"ip":"127.0.0.1","port":"9010","kbucketId":"oJJe8wkADkCT28BMLkyf79fqBZeoF21cXL"}}`; // 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 @@ -10139,6 +10151,17 @@ "receiver_flo_address": backup_su, }).then(sync_request=>doSend(sync_request, backup_su)); }, + + sync_backup_supernode_from_backup_supernode: function (requester="", receiver="", flo_addr_of_backup="") { + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC.send_rpc.call(this, + "sync_backup_supernode_from_backup_supernode", { + "trader_flo_address": flo_addr_of_backup, + "job": "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", + "receiver_flo_address": receiver, + "requester_flo_id": requester + }).then(sync_request=>doSend(sync_request, receiver)); + }, get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { let arr = {}; @@ -12585,6 +12608,33 @@ } }); } + + if (method=="sync_backup_supernode_from_backup_supernode") { + // params.trader_flo_address -> primary supernode flo id + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { + if (is_valid_request === true && params.job == + "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > + 0) { + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + + let rec_flo_id = (params.receiver_flo_address==params.trader_flo_address) ? "" : params.trader_flo_address; + + localbitcoinplusplus.actions.get_sharable_db_data(tableArray, rec_flo_id).then( + function (su_db_data) { + if (typeof su_db_data == "object") { + su_db_data.trader_flo_address = params.trader_flo_address; + su_db_data.receiver_flo_address = params.requester_flo_id; + RM_RPC + .send_rpc + .call(this, "sync_backup_supernode_from_backup_supernode_response", + su_db_data) + .then(server_sync_response=> + doSend(server_sync_response, params.trader_flo_address)); + } + }); + } + }); + } RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { if (is_valid_request !== true) return false; @@ -15114,12 +15164,12 @@ // Connect with backup supernodes wsUri.filter((uri, index)=>{ - if(index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + if(index>0 && index<=localbitcoinplusplus.master_configurations.MaxBackups + && localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplusObj.myLocalFLOPublicKey)) { return uri; } }).map((uri, index)=>{ - console.log(uri); backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); backUpSupernodesWS[uri.trader_flo_address].connectWS(); @@ -15173,20 +15223,37 @@ // Check last connected supernode, if not primary then // update the user data from other su first - if (typeof idbData.lastConnectedSupernode == "string" - && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { - showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - - // Get data for deposits and withdraw starting from first (and currently alive) backup supernode - // readAllDB('myClosestSupernodes').then(cs=>{ - // // for (let index = cs.length; index > 0; index--) { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { + if (typeof idbData.lastConnectedSupernode == "string" + && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { + showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - // }); - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(idbData.myLocalFLOAddress, 3); - for (let index = 1; index <= cs.length-1; index++) { - localbitcoinplusplus.actions - .sync_primary_supernode_from_backup_supernode(getPrimarySuObj[0].data.id, getPrimarySuObj[index].data.id); - } + // Get data for deposits and withdraw starting from first (and currently alive) backup supernode + let closestSuNodes = await readAllDB('myClosestSupernodes'); + let firstAliveBackupFloIdForPrimarySupernode; + + for (let index = 1; index <= closestSuNodes.length-1; index++) { + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { + firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); + } + } + + // Update backup db as well for all supernodes you're serving as backup + for (let index = 1; index <= closestSuNodes.length-1; index++) { + let firstAliveBackupFloIdForBackupSupernode; + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + } else { + // it will ask backup from backup su next closest + console.info(`da daa`); + } + } + } } // rebuild private key @@ -15210,7 +15277,8 @@ // Connect with backup supernodes wsUri.filter((uri, index)=>{ - if(index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + if(index>0 && index<=localbitcoinplusplus.master_configurations.MaxBackups + && localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(idbData.myLocalFLOPublicKey)) { return uri; } @@ -15243,6 +15311,7 @@ backupSupernodesWebSocketObject.prototype = { async handle_backup_server_messages(evt) { + var response = evt.data; writeToScreen('backup response: '+response); @@ -15367,23 +15436,50 @@ break; - case "trade_buy_request_response": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let buyOrders_data = res_obj.params[0]; + case "trade_buy_request_response": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let buyOrders_data = res_obj.params[0]; - if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" && - localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - buyOrders_data.supernodePubKey)) { + 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) { + + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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(buyOrders_data.data_hash, buyOrders_data.supernode_sign, - buyOrders_data.supernodePubKey); + .verify(sellOrders_data.data_hash, sellOrders_data.supernode_sign, + sellOrders_data.supernodePubKey); if (isDataSignedBySuperNode === true) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); const primarySupernode = getPrimarySuObj[0].data.id; const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - + if(typeof backup_server_db_instance !== "object") { let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; showMessage(backup_db_error_msg); @@ -15391,111 +15487,84 @@ }; // Add buy order - backup_server_db_instance.backup_addDB("buyOrders", buyOrders_data).then(() => { - showMessage(`Your buy order is placed successfully.`); + backup_server_db_instance.backup_addDB("sellOrders", sellOrders_data).then(() => { + showMessage(`Your sell 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) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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); - }; + break; + + case "deposit_asset_request_response": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let deposit_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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) + ) { + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + 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") return; - let deposit_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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) - ) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - 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); + 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; + }); + break; - case "withdrawal_request_response": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let withdrawal_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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)) { + case "withdrawal_request_response": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let withdrawal_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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)) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(withdrawal_res_data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(withdrawal_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - 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); - }; + 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.`); - }); + backup_server_db_instance.backup_addDB('withdraw_cash', res_obj.params[0]).then(() => { + showMessage(`Your cash withdrawal request is placed successfully.`); + }); + } } - } - }); - break; + }); + break; case "cancel_trade": if (typeof res_obj.params !== "object" @@ -15949,7 +16018,7 @@ reactor.dispatchEvent('backup_supernode_down'); }.bind(this); this.ws_connection.onmessage = function (evt) { - this.handle_backup_server_messages(evt); + //this.handle_backup_server_messages(evt); }.bind(this); this.ws_connection.onerror = function (evt) { console.error(evt); @@ -16154,6 +16223,8 @@ processBackupUserOnMesssageRequest(response); return; } + localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); + return; } if (typeof res_obj.method !== "undefined") { @@ -17181,6 +17252,72 @@ })(); } break; + + case "sync_backup_supernode_from_backup_supernode_response": + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let su_db_data = res_obj.params[0]; + // if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || + // su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + // ) return false; + + (async function () { + let i = 0; + for (let tableStoreName in su_db_data) { + i++; + if (i==Object.keys(su_db_data).length-2) { + // Get data for crypto and fiat balances based on vector clock from all backup supernodes + // reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', + // { requesting_user_id: localbitcoinplusplus.wallets.my_local_flo_address}); + // await localbitcoinplusplus.actions.delay(180000).then(()=>{ + // showMessage(`INFO: Balance syncing is complete.`); + + localbitcoinplusplus.amIreadyToServePrimaryUsers = true; + + //}); + } + // skip loop if the property is from prototype + if (tableStoreName == 'trader_flo_address' + || tableStoreName == 'receiver_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 localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + .backup_updateinDB(tableStoreName, obj[prop], obj[prop] + .trader_flo_address).then(()=>{ + showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); + }); + } + } + } else { + let resdbdata = await localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + .backup_removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + .backup_addDB(resdbdata, obj[prop]).then(()=>{ + showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); + }); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + } + break; case "reconnect_with_another_supernode": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -17262,7 +17399,8 @@ return; } - if (res_obj.method !== "sync_primary_supernode_from_backup_supernode") { + if (res_obj.method !== "sync_primary_supernode_from_backup_supernode" + || res_obj.method !== "sync_backup_supernode_from_backup_supernode") { if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { let ifAllPrevSuAreDead = await localbitcoinplusplus.actions @@ -17272,7 +17410,8 @@ if (ifAllPrevSuAreDead !== true) { console.log(res_obj); - showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`) + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); + localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); return; } } @@ -18482,6 +18621,14 @@ JSON.stringify(res_obj)); } break; + + case "sync_backup_supernode_from_backup_supernode": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, + JSON.stringify(res_obj)); + } + break; default: break; @@ -18502,22 +18649,6 @@ function doSend(message, user_flo_id="") { - let wsConn = websocket; - if (user_flo_id!=="") { - try { - wsConn = localbitcoinplusplus.backupWS[user_flo_id].ws_connection; - } catch (error) { - showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); - throw new Error(error); - } - } - - if(wsConn.readyState !== 1) { - let msg = "WARNING: Websocket not ready to broadcast messages."; - showMessage(msg); - console.warn(msg); - return; - } const request_array = ['send_back_shamirs_secret_supernode_pvtkey', 'retrieve_shamirs_secret_supernode_pvtkey', 'store_shamirs_secret_pvtkey_shares']; @@ -18533,7 +18664,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(`WARNING: Private key could not be found.`); const nodeSignedMessage = RM_WALLET.sign(message256hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); @@ -18543,9 +18674,46 @@ finalMessage = JSON.stringify(msgObj); } + + // The message is for a specific supernode only + if (user_flo_id!=="" && user_flo_id.length>0) { + try { + wsConn = localbitcoinplusplus.backupWS[user_flo_id].ws_connection; + if(wsConn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(msg); + return; + } + wsConn.send(finalMessage); + } catch (error) { + showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); + throw new Error(error); + } + + } else { + // The message is for usernodes and all backup supernodes + try { + websocket.send(finalMessage); + + localbitcoinplusplus.backupWS.map(ws_conn=>{ + if(ws_conn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(msg); + return; + } + ws_conn.send(finalMessage); + }); + + } catch(error) { + showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); + throw new Error(error); + } + } writeToScreen("SENT: " + finalMessage); - wsConn.send(finalMessage); + } function validateIncomingMessage(message) { From 28f8aeabf2cce8e925195856ec4ee52837a423b0 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 19 May 2019 19:52:57 +0530 Subject: [PATCH 23/95] fixed doSend function --- supernode/index.html | 104 ++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 114c9da..44b2e62 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10072,24 +10072,39 @@ `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - #!#MaxBackups=3 + #!#MaxBackups=2 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, - 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB, - 026FCC6CFF6EB3A39E54BEB6E13FC2F02C3A93F4767AA80E49E7E876443F95AE5F,029CDB29270DC5087EF4903E8C2364552C62E935FBAA1A96AB53CC5791C7EF2067, - 022EC1D090960D9EFFFC60FDC34AB97A8395A5F6D1326DD1B1380BD9F6E31981CA,037C623A8D31DB751F666A1D2C65EC8996C5978348CEEE8566F480708D4A6335AB, - 032871A74D2DDA9D0DE7135F58B5BD2D7F679D2CCA20EA7909466D1A6912DF4022 + 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, #!#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"}, - "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, - "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}, - "ranchimall6":{"ip":"127.0.0.1","port":"9006","kbucketId":"oV1wCeWca3VawbBTfUGKA7Vd368PATnKAx"}, - "ranchimall7":{"ip":"127.0.0.1","port":"9007","kbucketId":"oSqFZePXibNJqeiboTYmmaqqVkd6esDUfZ"}, - "ranchimall8":{"ip":"127.0.0.1","port":"9008","kbucketId":"odUQekfMPsZV3ocneFW8SNSZADFtx9xUtm"}, - "ranchimall9":{"ip":"127.0.0.1","port":"9009","kbucketId":"oLYeoBfXWxKkUmRxhn1pcmJWtTu5kZoUJq"}, - "ranchimall10":{"ip":"127.0.0.1","port":"9010","kbucketId":"oJJe8wkADkCT28BMLkyf79fqBZeoF21cXL"}}`; + "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}}`; + + // RMAssets = + // `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 + // #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, + // #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + // #!#MaxBackups=2 + // #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, + // 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, + // 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB, + // 026FCC6CFF6EB3A39E54BEB6E13FC2F02C3A93F4767AA80E49E7E876443F95AE5F,029CDB29270DC5087EF4903E8C2364552C62E935FBAA1A96AB53CC5791C7EF2067, + // 022EC1D090960D9EFFFC60FDC34AB97A8395A5F6D1326DD1B1380BD9F6E31981CA,037C623A8D31DB751F666A1D2C65EC8996C5978348CEEE8566F480708D4A6335AB, + // 032871A74D2DDA9D0DE7135F58B5BD2D7F679D2CCA20EA7909466D1A6912DF4022 + // #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, + // #!#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"}, + // "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, + // "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}, + // "ranchimall6":{"ip":"127.0.0.1","port":"9006","kbucketId":"oV1wCeWca3VawbBTfUGKA7Vd368PATnKAx"}, + // "ranchimall7":{"ip":"127.0.0.1","port":"9007","kbucketId":"oSqFZePXibNJqeiboTYmmaqqVkd6esDUfZ"}, + // "ranchimall8":{"ip":"127.0.0.1","port":"9008","kbucketId":"odUQekfMPsZV3ocneFW8SNSZADFtx9xUtm"}, + // "ranchimall9":{"ip":"127.0.0.1","port":"9009","kbucketId":"oLYeoBfXWxKkUmRxhn1pcmJWtTu5kZoUJq"}, + // "ranchimall10":{"ip":"127.0.0.1","port":"9010","kbucketId":"oJJe8wkADkCT28BMLkyf79fqBZeoF21cXL"}}`; + // 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 @@ -10305,7 +10320,8 @@ const primarySuFloId = s_id[0].data.id; let getSupernodeClosestSuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode("", 3, supernodeKBucket, primarySuFloId); + .determineClosestSupernode("", localbitcoinplusplus.master_configurations.MaxBackups, + supernodeKBucket, primarySuFloId); let promises = []; let leaving_supernode_flo_id = ""; @@ -15205,7 +15221,7 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { const getClosestSuList = await readAllDB('myClosestSupernodes'); - if (wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress || getClosestSuList.length < 3) { + if (wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress || getClosestSuList.length < localbitcoinplusplus.master_configurations.MaxBackups) { showMessage(`INFO: Invalid connection. Refreshing the closest supernode list in DB.`); wsUri = await localbitcoinplusplus.kademlia.updateClosestSupernodeSeeds(idbData.myLocalFLOAddress); } @@ -15340,6 +15356,10 @@ var res_obj = JSON.parse(res); + // Only supernodes are allowed to go below + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) return; + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -17380,6 +17400,25 @@ return; } + if (res_obj.method !== "sync_primary_supernode_from_backup_supernode" + || res_obj.method !== "sync_backup_supernode_from_backup_supernode") { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions + .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); + + console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); + + if (ifAllPrevSuAreDead !== true) { + console.log(res_obj); + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); + localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); + return; + } + } + } + const isIncomingMessageValid = await validateIncomingMessage(res); console.log("isIncomingMessageValid: ", isIncomingMessageValid); @@ -17398,24 +17437,6 @@ console.log(res_obj); return; } - - if (res_obj.method !== "sync_primary_supernode_from_backup_supernode" - || res_obj.method !== "sync_backup_supernode_from_backup_supernode") { - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - let ifAllPrevSuAreDead = await localbitcoinplusplus.actions - .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); - - console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - - if (ifAllPrevSuAreDead !== true) { - console.log(res_obj); - showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); - localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); - return; - } - } - } if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -18696,15 +18717,18 @@ try { websocket.send(finalMessage); - localbitcoinplusplus.backupWS.map(ws_conn=>{ - if(ws_conn.readyState !== 1) { - let msg = "WARNING: Websocket not ready to broadcast messages."; - showMessage(msg); - console.warn(msg); - return; + for (const key in localbitcoinplusplus.backupWS) { + if (localbitcoinplusplus.backupWS.hasOwnProperty(key)) { + const ws_conn = localbitcoinplusplus.backupWS[key].ws_connection; + if(ws_conn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(msg); + break; + } + ws_conn.send(finalMessage); } - ws_conn.send(finalMessage); - }); + } } catch(error) { showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); From 77435c2b2d031451eb7099677af5a83a3e1235a2 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 20 May 2019 19:22:54 +0530 Subject: [PATCH 24/95] fixed ip and user data recording in backup db --- supernode/index.html | 1456 +++++++++++++++++++++--------------------- 1 file changed, 743 insertions(+), 713 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 44b2e62..c2c9ed7 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15326,685 +15326,6 @@ } backupSupernodesWebSocketObject.prototype = { - async handle_backup_server_messages(evt) { - - var response = evt.data; - writeToScreen('backup response: '+response); - - let isItANodeLeavingMessage = response.search(`\\-- left`); - - if(isItANodeLeavingMessage >= 0) { - reactor.dispatchEvent('fireNodeGoodByeEvent', response); - } - - var res_pos = response.indexOf('{'); - if (res_pos >= 0) { - let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); - let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); - let incoming_msg_local_ip = ``; - if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { - let index_of_ip = response.indexOf(' '); - if (incoming_msg_local_ip>=0) { - incoming_msg_local_ip = response.substr(0, index_of_ip); - } - } - var res = response.substr(res_pos); - try { - - const isIncomingMessageValid = await validateIncomingMessage(res); - console.log("isIncomingMessageValid (Backup): ", isIncomingMessageValid); - - var res_obj = JSON.parse(res); - - // Only supernodes are allowed to go below - if (!localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(res_obj.nodePubKey)) return; - - if (typeof res_obj.method !== "undefined") { - let response_from_sever; - - const RM_WALLET = new localbitcoinplusplus.wallets; - const RM_TRADE = new localbitcoinplusplus.trade; - const RM_RPC = new localbitcoinplusplus.rpc; - - switch (res_obj.method) { - case "give_me_your_backup": - if (typeof res_obj.params == "object" - && typeof res_obj.params[0] == "object") { - let received_resp = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(received_resp.trader_flo_address, - function (is_valid_request) { - if(!is_valid_request || received_resp.JOB!=="BACKUP_SERVER_REQUEST") return; - const requester_supernode_pubkey = received_resp.requesters_pub_key; - const requester_supernode_flo_address = received_resp.trader_flo_address; - - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" - ]; - localbitcoinplusplus.actions.get_sharable_db_data(tableArray).then( - function (su_db_data) { - if (typeof su_db_data == "object") { - su_db_data.trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; - su_db_data.receiver_flo_address = requester_supernode_flo_address; - RM_RPC - .send_rpc - .call(this, "backup_server_sync_response", - su_db_data) - .then(server_sync_response=>doSend(server_sync_response)); - } - }); - - }); - } - break; - - case "server_sync_response": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let su_backup_db_data = res_obj.params[0]; - - RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.receiverFloId); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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); - }; - - (async function () { - for (let tableStoreName in su_backup_db_data) { - // skip loop if the property is from prototype - if (tableStoreName == 'trader_flo_address' || !su_backup_db_data.hasOwnProperty( - tableStoreName)) continue; - - try { - let obj = su_backup_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_server_db_instance.backup_updateinDB(tableStoreName, - obj[prop], obj[prop].trader_flo_address); - } - } - } else { - let resdbdata = await backup_server_db_instance.backup_removeAllinDB(tableStoreName); - if (resdbdata !== false) { - if (obj.length > 0) { - for (var prop in obj) { - if (!obj.hasOwnProperty(prop)) continue; - await backup_server_db_instance.backup_addDB(resdbdata, obj[prop]); - } - } - } - } - - } catch (error) { - console.log(error); - } - } - })(); - - }); - - break; - - case "trade_buy_request_response": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - 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) { - - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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") return; - let deposit_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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) - ) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - 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") return; - let withdrawal_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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)) { - - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(withdrawal_res_data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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") return; - let cancel_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(cancel_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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") { - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(cancel_res_data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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 "trade_balance_updates": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const trade_balance_res = res_obj.params[0]; - // Verify data - let trade_info_str = JSON.stringify(trade_balance_res.trade_infos); - let buyer_cash_data_str = JSON.stringify(trade_balance_res.buyer_cash_data); - let seller_cash_data_str = JSON.stringify(trade_balance_res.seller_cash_data); - let buyer_btc_data_str = JSON.stringify(trade_balance_res.buyer_btc_data); - let seller_btc_data_str = JSON.stringify(trade_balance_res.seller_btc_data); - - let res_str = - `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; - let hashed_data = Crypto.SHA256(res_str); - - RM_RPC.filter_legit_backup_requests(trade_balance_res.trade_infos.buyer_flo_id, - async function (is_valid_request) { - if (is_valid_request !== true) return false; - - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - trade_balance_res.supernodePubKey)) { - if (RM_WALLET.verify(hashed_data, - trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { - - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(trade_balance_res.trade_infos.buyer_flo_id); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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); - }; - - // Delete orders in clients DB - try { - backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); - } catch (error) { - callback(false); - throw new Error(error); - } - - // Update balances in clients DB - try { - backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); - backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); - backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); - backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); - } catch (error) { - callback(false); - throw new Error(error); - } - } - } - }); - } - break; - - case "update_all_withdraw_cash_depositor_claim": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let withdraw_caim_res_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(withdraw_caim_res_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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)) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(withdraw_caim_res_data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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") return; - let update_deposit_withdraw_claim_data = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(update_deposit_withdraw_claim_data.trader_flo_address, - async function (is_valid_request) { - if(!is_valid_request) return false; - 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) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia - .determineClosestSupernode(update_deposit_withdraw_claim_data.trader_flo_address); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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; - case "requestSupernodesToRemoveAUserFloIdFromTheirKBucket": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let removeUserFromKBData = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(removeUserFromKBData.trader_flo_address, - function (is_valid_request) { - if(!is_valid_request) return false; - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const removeKBReq = res_obj.params[0]; - const currentSupernodeFloIdOfUser = removeKBReq.currentSupernodeFloId; - if(localbitcoinplusplus.wallets.my_local_flo_address == currentSupernodeFloIdOfUser) return; - const userKbucketObject_id_array = Object.values(removeKBReq.redundantKbucketNodeU8Id); - const userKBId = new Uint8Array(userKbucketObject_id_array); - KBucket.remove(userKBId); - return true; - } - }); - break; - case "requestSupernodesKBucketData": - if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; - let reqSuKBData = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(reqSuKBData.trader_flo_address, - function (is_valid_request) { - if(!is_valid_request) return false; - if(typeof res_obj.globalParams.senderFloId !=="string") return; - let sender = res_obj.globalParams.senderFloId; - readAllDB('kBucketStore') - .then(myKBData=>{ - myKBData.receiver_flo_address = sender; - - localbitcoinplusplus.rpc.prototype - .send_rpc - .call(this, "SupernodesKBucketDataResponse", myKBData) - .then(sendBackMySupernodeKBucket=> - doSend(sendBackMySupernodeKBucket)); - }) - } - ); - break; - case "SupernodesKBucketDataResponse": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const reqSuKBResponseData = res_obj.params[0]; - RM_RPC.filter_legit_backup_requests(reqSuKBResponseData.trader_flo_address, - function (is_valid_request) { - if(!is_valid_request) return false; - reqSuKBResponseData.map(kd=> { - let kb = window[`SKBucket_${kd.primary_supernode_flo_public_key}`]; - localbitcoinplusplus.kademlia.addFullKBDataInKBucketAndDB(kd, kb)}) - }); - } - break; - case "link_My_Local_IP_To_My_Flo_Id": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const req_params = res_obj.params[0]; - if(typeof req_params.requesters_pub_key !== "string") return; - let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); - if(typeof flo_addr_for_pubkey !== "string") return; - if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; - updateinDB('ipTable', { - 'flo_public_key': req_params.requesters_pub_key, - 'temporary_ip': incoming_msg_local_ip - }).then((ipRes)=>{ - reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); - }).finally(()=>{ - linkBackOthersLocalIPToTheirFloId(); - }); - } - break; - case "link_Others_Local_IP_To_Their_Flo_Id": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const req_params = res_obj.params[0]; - if(typeof req_params.requesters_pub_key !== "string") return; - let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); - if(typeof flo_addr_for_pubkey !== "string") return; - if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; - updateinDB('ipTable', { - 'flo_public_key': req_params.requesters_pub_key, - 'temporary_ip': incoming_msg_local_ip - }).then((ipRes)=>{ - reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); - }); - } - break; - - case "add_user_public_data": - let supernode_flo_public_key = localbitcoinplusplus.wallets.my_local_flo_public_key; - RM_RPC.filter_legit_backup_requests(res_obj.params[0].trader_flo_address, - function (is_valid_request) { - if (is_valid_request !== true) return false; - - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - let req_data = res_obj.params[0]; - try { - let flo_address = bitjs.FLO_TEST.pubkey2address(req_data.trader_flo_pubKey); - - if (flo_address == req_data.trader_flo_address && req_data.trader_flo_address - .length > 0) { - - let public_req_object = { - trader_flo_address: req_data.trader_flo_address, - trader_flo_pubKey: req_data.trader_flo_pubKey, - supernode_flo_public_key: supernode_flo_public_key, - trader_status: 0, - timestamp: +new Date() - } - - addDB('userPublicData', public_req_object); - - } - } catch (error) { - throw new Error('Invalid public key and flo address combination.'); - } - } - }); - break; - - case "send_back_shamirs_secret_btc_pvtkey": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - if(typeof res_obj.globalParams.senderFloId !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - res) { - RM_RPC - .send_rpc - .call(this, "retrieve_shamirs_secret_btc_pvtkey", { - retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, - private_key_chunk: res, - withdraw_id: res_obj.params[0].withdraw_id, - receiver_flo_address: res_obj.globalParams.senderFloId, - }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - }); - }); - } - break; - - case "store_shamirs_secret_pvtkey_shares": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - delete res_obj.params[0].trader_flo_address; - backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); - }); - } - break; - - case "updateUserCryptoBalanceRequest": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - - let SuPubKey = backup_server_db_instance.backup_readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) - .then(user_data => { - if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < - 1) - throw new Error(`No such user exists.`); - let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, - user_data.supernode_flo_public_key - ); - if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, - user_data.trader_flo_address); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserCryptoBalanceResponseObject.trader_flo_address) { - displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); - } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); - } - }); - }); - } - break; - - default: - break; - } - - } - } catch(e) { - console.warn(e); - } - } - }, - connectWS() { this.ws_connection = new WebSocket(this.ws_url); const switchMyWS = new backupSupernodesWebSocketObject(); @@ -16039,6 +15360,13 @@ }.bind(this); this.ws_connection.onmessage = function (evt) { //this.handle_backup_server_messages(evt); + let response = evt.data; + let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); + let incoming_msg_local_ip = ``; + if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { + handle_backup_server_messages(response); + } }.bind(this); this.ws_connection.onerror = function (evt) { console.error(evt); @@ -16243,7 +15571,7 @@ processBackupUserOnMesssageRequest(response); return; } - localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); + handle_backup_server_messages(response); return; } @@ -16822,6 +16150,12 @@ } addDB('userPublicData', public_req_object); + + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "add_user_public_data", public_req_object) + .then(add_user_public_data_req=>doSend(add_user_public_data_req)); } } catch (error) { @@ -17394,35 +16728,11 @@ try { var res_obj = JSON.parse(res); - if (typeof res_obj.globalParams.receiverFloId=="string" - && res_obj.globalParams.receiverFloId !== - localbitcoinplusplus.wallets.my_local_flo_address) { - return; - } - - if (res_obj.method !== "sync_primary_supernode_from_backup_supernode" - || res_obj.method !== "sync_backup_supernode_from_backup_supernode") { - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - - let ifAllPrevSuAreDead = await localbitcoinplusplus.actions - .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); - - console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - - if (ifAllPrevSuAreDead !== true) { - console.log(res_obj); - showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); - localbitcoinplusplus.backupWS.prototype.handle_backup_server_messages(response); - return; - } - } - } - - const isIncomingMessageValid = await validateIncomingMessage(res); - console.log("isIncomingMessageValid: ", isIncomingMessageValid); - - if (!isIncomingMessageValid) return; + // if (typeof res_obj.globalParams.receiverFloId=="string" + // && res_obj.globalParams.receiverFloId !== + // localbitcoinplusplus.wallets.my_local_flo_address) { + // return; + // } // Check if request is from primary user or backup user // If request is from backup user, divert the request to backup onmessage event @@ -17437,7 +16747,35 @@ console.log(res_obj); return; } - + + if (res_obj.method !== "sync_primary_supernode_from_backup_supernode" + && res_obj.method !== "sync_backup_supernode_from_backup_supernode" + && res_obj.method !== "link_My_Local_IP_To_My_Flo_Id" + && res_obj.method !== "link_Others_Local_IP_To_Their_Flo_Id" + //&& res_obj.method !== "add_user_public_data" + ) { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions + .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); + + console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); + + if (ifAllPrevSuAreDead !== true) { + console.log(res_obj); + showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); + handle_backup_server_messages(response); + return; + } + } + } + + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid: ", isIncomingMessageValid); + + if (!isIncomingMessageValid) return; + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -18662,6 +18000,699 @@ } } + async function handle_backup_server_messages(response) { + + //var response = evt.data; + writeToScreen('backup response: '+response); + + let isItANodeLeavingMessage = response.search(`\\-- left`); + + if(isItANodeLeavingMessage >= 0) { + reactor.dispatchEvent('fireNodeGoodByeEvent', response); + } + + var res_pos = response.indexOf('{'); + if (res_pos >= 0) { + let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); + let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); + let incoming_msg_local_ip = ``; + if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { + let index_of_ip = response.indexOf(' '); + if (incoming_msg_local_ip>=0) { + incoming_msg_local_ip = response.substr(0, index_of_ip); + } + } + var res = response.substr(res_pos); + try { + + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid (Backup): ", isIncomingMessageValid); + + var res_obj = JSON.parse(res); + + // Only supernodes are allowed to go below + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) return; + + if (typeof res_obj.method !== "undefined") { + let response_from_sever; + + const RM_WALLET = new localbitcoinplusplus.wallets; + const RM_TRADE = new localbitcoinplusplus.trade; + const RM_RPC = new localbitcoinplusplus.rpc; + + switch (res_obj.method) { + case "give_me_your_backup": + if (typeof res_obj.params == "object" + && typeof res_obj.params[0] == "object") { + let received_resp = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(received_resp.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request || received_resp.JOB!=="BACKUP_SERVER_REQUEST") return; + const requester_supernode_pubkey = received_resp.requesters_pub_key; + const requester_supernode_flo_address = received_resp.trader_flo_address; + + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", + "crypto_balances", "cash_balances", "userPublicData" + ]; + localbitcoinplusplus.actions.get_sharable_db_data(tableArray).then( + function (su_db_data) { + if (typeof su_db_data == "object") { + su_db_data.trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; + su_db_data.receiver_flo_address = requester_supernode_flo_address; + RM_RPC + .send_rpc + .call(this, "backup_server_sync_response", + su_db_data) + .then(server_sync_response=>doSend(server_sync_response)); + } + }); + + }); + } + break; + + case "server_sync_response": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let su_backup_db_data = res_obj.params[0]; + + RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.receiverFloId); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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); + }; + + (async function () { + for (let tableStoreName in su_backup_db_data) { + // skip loop if the property is from prototype + if (tableStoreName == 'trader_flo_address' || !su_backup_db_data.hasOwnProperty( + tableStoreName)) continue; + + try { + let obj = su_backup_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_server_db_instance.backup_updateinDB(tableStoreName, + obj[prop], obj[prop].trader_flo_address); + } + } + } else { + let resdbdata = await backup_server_db_instance.backup_removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await backup_server_db_instance.backup_addDB(resdbdata, obj[prop]); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + + }); + + break; + + case "trade_buy_request_response": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + 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) { + + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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) { + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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") return; + let deposit_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(deposit_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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) + ) { + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(resp.data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + 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") return; + let withdrawal_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(withdrawal_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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)) { + + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(withdrawal_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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") return; + let cancel_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(cancel_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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") { + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(cancel_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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 "trade_balance_updates": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const trade_balance_res = res_obj.params[0]; + // Verify data + let trade_info_str = JSON.stringify(trade_balance_res.trade_infos); + let buyer_cash_data_str = JSON.stringify(trade_balance_res.buyer_cash_data); + let seller_cash_data_str = JSON.stringify(trade_balance_res.seller_cash_data); + let buyer_btc_data_str = JSON.stringify(trade_balance_res.buyer_btc_data); + let seller_btc_data_str = JSON.stringify(trade_balance_res.seller_btc_data); + + let res_str = + `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; + let hashed_data = Crypto.SHA256(res_str); + + RM_RPC.filter_legit_backup_requests(trade_balance_res.trade_infos.buyer_flo_id, + async function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + trade_balance_res.supernodePubKey)) { + if (RM_WALLET.verify(hashed_data, + trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { + + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(trade_balance_res.trade_infos.buyer_flo_id); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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); + }; + + // Delete orders in clients DB + try { + backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + } catch (error) { + callback(false); + throw new Error(error); + } + + // Update balances in clients DB + try { + backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.buyer_cash_data, + trade_balance_res.trade_infos.buyer_flo_id); + backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.seller_cash_data, + trade_balance_res.trade_infos.seller_flo_id); + backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, + trade_balance_res.trade_infos.buyer_flo_id); + backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.seller_btc_data, + trade_balance_res.trade_infos.seller_flo_id); + } catch (error) { + callback(false); + throw new Error(error); + } + } + } + }); + } + break; + + case "update_all_withdraw_cash_depositor_claim": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let withdraw_caim_res_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(withdraw_caim_res_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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)) { + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(withdraw_caim_res_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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") return; + let update_deposit_withdraw_claim_data = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(update_deposit_withdraw_claim_data.trader_flo_address, + async function (is_valid_request) { + if(!is_valid_request) return false; + 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) { + let getPrimarySuObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(update_deposit_withdraw_claim_data.trader_flo_address); + const primarySupernode = getPrimarySuObj[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; + + 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; + case "requestSupernodesToRemoveAUserFloIdFromTheirKBucket": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let removeUserFromKBData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(removeUserFromKBData.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request) return false; + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const removeKBReq = res_obj.params[0]; + const currentSupernodeFloIdOfUser = removeKBReq.currentSupernodeFloId; + if(localbitcoinplusplus.wallets.my_local_flo_address == currentSupernodeFloIdOfUser) return; + const userKbucketObject_id_array = Object.values(removeKBReq.redundantKbucketNodeU8Id); + const userKBId = new Uint8Array(userKbucketObject_id_array); + KBucket.remove(userKBId); + return true; + } + }); + break; + case "requestSupernodesKBucketData": + if (typeof res_obj.params !== "object" + || typeof res_obj.params[0] !== "object") return; + let reqSuKBData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(reqSuKBData.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request) return false; + if(typeof res_obj.globalParams.senderFloId !=="string") return; + let sender = res_obj.globalParams.senderFloId; + readAllDB('kBucketStore') + .then(myKBData=>{ + myKBData.receiver_flo_address = sender; + + localbitcoinplusplus.rpc.prototype + .send_rpc + .call(this, "SupernodesKBucketDataResponse", myKBData) + .then(sendBackMySupernodeKBucket=> + doSend(sendBackMySupernodeKBucket)); + }) + } + ); + break; + case "SupernodesKBucketDataResponse": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const reqSuKBResponseData = res_obj.params[0]; + RM_RPC.filter_legit_backup_requests(reqSuKBResponseData.trader_flo_address, + function (is_valid_request) { + if(!is_valid_request) return false; + reqSuKBResponseData.map(kd=> { + let kb = window[`SKBucket_${kd.primary_supernode_flo_public_key}`]; + localbitcoinplusplus.kademlia.addFullKBDataInKBucketAndDB(kd, kb)}) + }); + } + break; + case "link_My_Local_IP_To_My_Flo_Id": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + updateinDB('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }).finally(()=>{ + linkBackOthersLocalIPToTheirFloId(); + }); + } + break; + case "link_Others_Local_IP_To_Their_Flo_Id": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + updateinDB('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }); + } + break; + + case "add_user_public_data": + let supernode_flo_public_key = localbitcoinplusplus.wallets.my_local_flo_public_key; + RM_RPC.filter_legit_backup_requests(res_obj.params[0].trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let req_data = res_obj.params[0]; + try { + let flo_address = bitjs.FLO_TEST.pubkey2address(req_data.trader_flo_pubKey); + + if (flo_address == req_data.trader_flo_address && req_data.trader_flo_address + .length > 0) { + + let public_req_object = { + trader_flo_address: req_data.trader_flo_address, + trader_flo_pubKey: req_data.trader_flo_pubKey, + supernode_flo_public_key: supernode_flo_public_key, + trader_status: 0, + timestamp: +new Date() + } + + addDB('userPublicData', public_req_object); + + localbitcoinplusplus.kademlia.determineClosestSupernode(req_data.trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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('userPublicData', public_req_object); + }); + + } + } catch (error) { + throw new Error('Invalid public key and flo address combination.'); + } + } + }); + break; + + case "send_back_shamirs_secret_btc_pvtkey": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + if(typeof res_obj.globalParams.senderFloId !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + res) { + RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + private_key_chunk: res, + withdraw_id: res_obj.params[0].withdraw_id, + receiver_flo_address: res_obj.globalParams.senderFloId, + }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); + }); + }); + } + break; + + case "store_shamirs_secret_pvtkey_shares": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + delete res_obj.params[0].trader_flo_address; + backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); + }); + } + break; + + case "updateUserCryptoBalanceRequest": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + + let SuPubKey = backup_server_db_instance.backup_readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) + .then(user_data => { + if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < + 1) + throw new Error(`No such user exists.`); + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + user_data.supernode_flo_public_key + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, + user_data.trader_flo_address); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + }); + }); + } + break; + + default: + break; + } + + } + } catch(e) { + console.warn(e); + } + } + } + + function onError(evt) { let msg = `ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`; showMessage(msg); @@ -19811,9 +19842,8 @@ trader_flo_address: MY_LOCAL_FLO_ADDRESS, trader_flo_pubKey: MY_LOCAL_FLO_PUBLIC_KEY, trader_status: 0, - timestamp: +new Date(), - receiver_flo_address: localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS - }).then(add_user_public_data_req=>doSend(add_user_public_data_req)) + timestamp: +new Date() + }).then(add_user_public_data_req=>doSend(add_user_public_data_req)); } }); From 6b5565f806f46a7e4f967916593f7fb2a34688f2 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 21 May 2019 19:20:00 +0530 Subject: [PATCH 25/95] added code for adding user data from handle_backup_request and backup to backup sync --- supernode/index.html | 142 ++++++++++++++++++++++++++++++++----------- 1 file changed, 105 insertions(+), 37 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index c2c9ed7..b94bb69 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10075,12 +10075,13 @@ #!#MaxBackups=2 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, - 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF + 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, #!#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"}, - "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}}`; + "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, + "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}}`; // RMAssets = // `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 @@ -10175,7 +10176,7 @@ "job": "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", "receiver_flo_address": receiver, "requester_flo_id": requester - }).then(sync_request=>doSend(sync_request, receiver)); + }).then(sync_request=>doSend(sync_request, receiver)); }, get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { @@ -15179,19 +15180,19 @@ }); // Connect with backup supernodes - wsUri.filter((uri, index)=>{ + wsUri.map((uri, index)=>{ if(index>0 && index<=localbitcoinplusplus.master_configurations.MaxBackups && localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplusObj.myLocalFLOPublicKey)) { - return uri; + .includes(idbData.myLocalFLOPublicKey)) { + backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); + backUpSupernodesWS[uri.trader_flo_address].connectWS(); + } + if (index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(idbData.myLocalFLOPublicKey)) { + let dbname = `su_backup_${uri.trader_flo_address}`; + BACKUP_DB[uri.trader_flo_address] = new newBackupDB(dbname); + BACKUP_DB[uri.trader_flo_address].createNewDB(); } - }).map((uri, index)=>{ - backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); - backUpSupernodesWS[uri.trader_flo_address].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(); }); localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wsUri[0].trader_flo_address; @@ -15257,7 +15258,7 @@ } // Update backup db as well for all supernodes you're serving as backup - for (let index = 1; index <= closestSuNodes.length-1; index++) { + for (let index = closestSuNodes.length; index > closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { let firstAliveBackupFloIdForBackupSupernode; if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; @@ -15266,9 +15267,19 @@ firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); } else { // it will ask backup from backup su next closest - console.info(`da daa`); + for (let j = index; j <= index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + const nextBKSu = closestSuNodes[j].trader_flo_address; + if (nextBKSu !== idbData.myLocalFLOAddress + && closestSuNodes[index].is_live==true + && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[j].trader_flo_address); + } + } } } + } } @@ -15292,26 +15303,19 @@ localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wsUri[0].trader_flo_address; // Connect with backup supernodes - wsUri.filter((uri, index)=>{ - if(index>0 && index<=localbitcoinplusplus.master_configurations.MaxBackups + wsUri.map((uri, index)=>{ + if(index>0 && index<=localbitcoinplusplus.master_configurations.MaxBackups && localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(idbData.myLocalFLOPublicKey)) { - return uri; + backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); + backUpSupernodesWS[uri.trader_flo_address].connectWS(); + } + if (index>0 && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(idbData.myLocalFLOPublicKey)) { + let dbname = `su_backup_${uri.trader_flo_address}`; + BACKUP_DB[uri.trader_flo_address] = new newBackupDB(dbname); + BACKUP_DB[uri.trader_flo_address].createNewDB(); } - }).map((uri, index)=>{ - console.log(uri); - backUpSupernodesWS[uri.trader_flo_address] = new backupSupernodesWebSocketObject(`ws://${uri.ip}:${uri.port}`); - backUpSupernodesWS[uri.trader_flo_address].connectWS(); - }); - - // Init backup db for rest supernodes - localbitcoinplusplus.master_configurations.supernodesPubKeys - .map(p=>bitjs.FLO_TEST.pubkey2address(p)) - .filter(f=>f!==localbitcoinplusplus.wallets.my_local_flo_address) - .map(m=>{ - let dbname = `su_backup_${m}`; - BACKUP_DB[m] = new newBackupDB(dbname); - BACKUP_DB[m].createNewDB(); }); resolve(true); @@ -15359,7 +15363,6 @@ reactor.dispatchEvent('backup_supernode_down'); }.bind(this); this.ws_connection.onmessage = function (evt) { - //this.handle_backup_server_messages(evt); let response = evt.data; let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); @@ -15367,6 +15370,22 @@ if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { handle_backup_server_messages(response); } + var res_pos = response.indexOf('{'); + if (res_pos >= 0) { + var res = response.substr(res_pos); + let res_obj = JSON.parse(res); + if (res_obj.method==="add_user_public_data") { + handle_backup_server_messages(response); + } + if (res_obj.method==="sync_backup_supernode_from_backup_supernode") { + // if (localbitcoinplusplus.master_configurations.supernodesPubKeys + // .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + // response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, + // JSON.stringify(res_obj)); + // } + onMessage(response); + } + } }.bind(this); this.ws_connection.onerror = function (evt) { console.error(evt); @@ -16154,7 +16173,7 @@ const RM_RPC = new localbitcoinplusplus.rpc; RM_RPC .send_rpc - .call(this, "add_user_public_data", public_req_object) + .call(this, "add_user_public_data_inBackup_db", public_req_object) .then(add_user_public_data_req=>doSend(add_user_public_data_req)); } @@ -17983,7 +18002,10 @@ case "sync_backup_supernode_from_backup_supernode": if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && typeof res_obj.globalParams.receiverFloId == "string" + && localbitcoinplusplus.wallets.my_local_flo_address == res_obj.globalParams.receiverFloId + ) { response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, JSON.stringify(res_obj)); } @@ -18585,9 +18607,55 @@ } }); break; + + case "add_user_public_data_inBackup_db": + RM_RPC.filter_legit_backup_requests(res_obj.params[0].trader_flo_address, + function (is_valid_request) { + if (is_valid_request !== true) return false; + + let supernode_flo_public_key = localbitcoinplusplus.wallets.my_local_flo_public_key; + + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + let req_data = res_obj.params[0]; + try { + let flo_address = bitjs.FLO_TEST.pubkey2address(req_data.trader_flo_pubKey); + + if (flo_address == req_data.trader_flo_address && req_data.trader_flo_address + .length > 0) { + + let public_req_object = { + trader_flo_address: req_data.trader_flo_address, + trader_flo_pubKey: req_data.trader_flo_pubKey, + supernode_flo_public_key: supernode_flo_public_key, + trader_status: 0, + timestamp: +new Date() + } + + addDB('userPublicData', public_req_object); + + localbitcoinplusplus.kademlia.determineClosestSupernode(req_data.trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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('userPublicData', public_req_object); + }); + + } + } catch (error) { + throw new Error('Invalid public key and flo address combination.'); + } + } + }); + break; case "send_back_shamirs_secret_btc_pvtkey": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { if(typeof res_obj.globalParams.senderFloId !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) @@ -20559,7 +20627,7 @@ reactor.registerEvent('fireNodeWelcomeBackEvent'); reactor.registerEvent('fireNodeGoodByeEvent'); reactor.registerEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes'); - + reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); if(localbitcoinplusplus.master_configurations.supernodesPubKeys From 915c2d7cd41b5d9663f537824599b76389b366b7 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 22 May 2019 16:14:19 +0530 Subject: [PATCH 26/95] fixed minor issues in primary operations --- supernode/index.html | 320 +++++++++++++++++++++---------------------- 1 file changed, 154 insertions(+), 166 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index b94bb69..0323614 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15796,6 +15796,7 @@ } break; case "trade_balance_updates": + if(!localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(res_obj.nodePubKey)) return; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const trade_balance_res = res_obj.params[0]; // Verify data @@ -15809,40 +15810,35 @@ `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; let hashed_data = Crypto.SHA256(res_str); - RM_RPC.filter_legit_requests(trade_balance_res.trade_infos.buyer_flo_id, - function (is_valid_request) { - if (is_valid_request !== true) return false; + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + trade_balance_res.supernodePubKey)) { + if (RM_WALLET.verify(hashed_data, + trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { + // Delete orders in clients DB + try { + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + } catch (error) { + callback(false); + throw new Error(error); + } - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - trade_balance_res.supernodePubKey)) { - if (RM_WALLET.verify(hashed_data, - trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { - // Delete orders in clients DB - try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); - } catch (error) { - callback(false); - throw new Error(error); - } - - // Update balances in clients DB - try { - updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); - updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); - updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); - updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); - } catch (error) { - callback(false); - throw new Error(error); - } + // Update balances in clients DB + try { + updateinDB("cash_balances", trade_balance_res.buyer_cash_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("cash_balances", trade_balance_res.seller_cash_data, + trade_balance_res.trade_infos.seller_flo_id); + updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("crypto_balances", trade_balance_res.seller_btc_data, + trade_balance_res.trade_infos.seller_flo_id); + } catch (error) { + callback(false); + throw new Error(error); } } - }); + } } break; case "store_shamirs_secret_pvtkey_shares": @@ -16267,31 +16263,27 @@ break; case "updateUserCryptoBalanceRequest": - let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - let SuPubKey = readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) - .then(user_data => { - if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < - 1) - throw new Error(`No such user exists.`); - let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, - user_data.supernode_flo_public_key - ); - if (isBalanceLegit) { - updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, - user_data.trader_flo_address); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserCryptoBalanceResponseObject.trader_flo_address) { - displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); - } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); } - }); + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } break; case "addNewKbucketNode": @@ -17029,6 +17021,7 @@ } break; case "trade_balance_updates": + if(!localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(res_obj.nodePubKey)) return; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const trade_balance_res = res_obj.params[0]; // Verify data @@ -17042,60 +17035,57 @@ `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; let hashed_data = Crypto.SHA256(res_str); - RM_RPC.filter_legit_backup_requests(trade_balance_res.trade_infos.buyer_flo_id, - function (is_valid_request) { - if (is_valid_request !== true) return false; - - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( trade_balance_res.supernodePubKey)) { - if (RM_WALLET.verify(hashed_data, - trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { + if (RM_WALLET.verify(hashed_data, + trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { - // Delete orders in clients DB - try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); - } catch (error) { - callback(false); - throw new Error(error); - } + // Delete orders in clients DB + try { + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + } catch (error) { + callback(false); + throw new Error(error); + } - // Update balances in clients DB - try { - updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); - updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); - updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); - updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); - } catch (error) { - callback(false); - throw new Error(error); - } + // Update balances in clients DB + try { + updateinDB("cash_balances", trade_balance_res.buyer_cash_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("cash_balances", trade_balance_res.seller_cash_data, + trade_balance_res.trade_infos.seller_flo_id); + updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, + trade_balance_res.trade_infos.buyer_flo_id); + updateinDB("crypto_balances", trade_balance_res.seller_btc_data, + trade_balance_res.trade_infos.seller_flo_id); + } catch (error) { + callback(false); + throw new Error(error); } } - }); + } } break; case "store_shamirs_secret_pvtkey_shares": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - delete res_obj.params[0].trader_flo_address; - backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); - }); + 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); + }; + delete res_obj.params[0].trader_flo_address; + backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); + }); + } } break; case "send_back_shamirs_secret_supernode_pvtkey": @@ -17596,31 +17586,29 @@ break; case "updateUserCryptoBalanceRequest": - let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - let SuPubKey = readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) - .then(user_data => { - if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < - 1) - throw new Error(`No such user exists.`); - let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, - user_data.supernode_flo_public_key - ); - if (isBalanceLegit) { - updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, - user_data.trader_flo_address); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserCryptoBalanceResponseObject.trader_flo_address) { - displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); - } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, + updateUserCryptoBalanceResponseObject.trader_flo_address); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); } - }); + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } + break; case "addNewKbucketNode": @@ -18165,7 +18153,7 @@ buyOrders_data.supernodePubKey); if (isDataSignedBySuperNode === true) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(buyOrders_data.trader_flo_address); const primarySupernode = getPrimarySuObj[0].data.id; const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; @@ -18192,7 +18180,7 @@ .verify(sellOrders_data.data_hash, sellOrders_data.supernode_sign, sellOrders_data.supernodePubKey); if (isDataSignedBySuperNode === true) { - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj[0].trader_flo_address); + let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(sellOrders_data.trader_flo_address); const primarySupernode = getPrimarySuObj[0].data.id; const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; @@ -18331,6 +18319,8 @@ break; case "trade_balance_updates": + + if(!localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(res_obj.nodePubKey)) return; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { const trade_balance_res = res_obj.params[0]; // Verify data @@ -18705,49 +18695,47 @@ break; case "updateUserCryptoBalanceRequest": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + + let updateUserCryptoBalanceResponseObject = res_obj.params[0]; + console.log(res_obj.params[0]); + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - 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); - }; + 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); + }; - let SuPubKey = backup_server_db_instance.backup_readDB('userPublicData', updateUserCryptoBalanceResponseObject.trader_flo_address) - .then(user_data => { - if (typeof user_data !== "object" || user_data.supernode_flo_public_key.length < - 1) - throw new Error(`No such user exists.`); - let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, - user_data.supernode_flo_public_key - ); - if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject, - user_data.trader_flo_address); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserCryptoBalanceResponseObject.trader_flo_address) { - displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); + let updateUserCryptoBalanceResponseString = JSON.stringify( + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("crypto_balances", updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserCryptoBalanceResponseObject.trader_flo_address) { + displayBalances(updateUserCryptoBalanceResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); - } - }); - }); - } - break; + }); + } + } + + break; default: break; From 8d43e33e8ef8728b48266fd0f5a7137ea6973e5d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 26 May 2019 12:25:54 +0530 Subject: [PATCH 27/95] fixed node availability status --- supernode/index.html | 151 ++++++++++++++++++++++++++++++++----------- 1 file changed, 113 insertions(+), 38 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 0323614..b822f0e 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10522,7 +10522,7 @@ ip: nearestSupernodeAddress.ip, port: nearestSupernodeAddress.port, trader_flo_address: nearestSupernodeAddress.kbucketId, - is_live: true + is_live: null }).then(updatedClosestSupernodes=>{ readAllDB('myClosestSupernodes').then(nearestSupernodeAddresslist=>{ showMessage(`INFO: Updated closest supernodes list successfully.`); @@ -15258,7 +15258,7 @@ } // Update backup db as well for all supernodes you're serving as backup - for (let index = closestSuNodes.length; index > closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { + for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { let firstAliveBackupFloIdForBackupSupernode; if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; @@ -15267,7 +15267,7 @@ firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); } else { // it will ask backup from backup su next closest - for (let j = index; j <= index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + for (let j = index-1; j >= index-localbitcoinplusplus.master_configurations.MaxBackups; j--) { const nextBKSu = closestSuNodes[j].trader_flo_address; if (nextBKSu !== idbData.myLocalFLOAddress && closestSuNodes[index].is_live==true @@ -15364,6 +15364,12 @@ }.bind(this); this.ws_connection.onmessage = function (evt) { let response = evt.data; + + let isItANodeLeavingMessage = response.search(`\\-- left`); + if(isItANodeLeavingMessage >= 0) { + reactor.dispatchEvent('fireNodeGoodByeEvent', response); + } + let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); let isRequestToLinkOthersIp = response.search("link_Others_Local_IP_To_Their_Flo_Id"); let incoming_msg_local_ip = ``; @@ -15385,6 +15391,12 @@ // } onMessage(response); } + if (res_obj.method==="is_node_alive_request" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && (res_obj.params[0].receiver_flo_address == localbitcoinplusplus.wallets.my_local_flo_address)) { + reactor.dispatchEvent('nodeIsAlive', res_obj); + } } }.bind(this); this.ws_connection.onerror = function (evt) { @@ -15409,7 +15421,13 @@ }, async updateSupernodeAvailabilityStatus(ws_url, status) { - const disconnected_su_flo_id = await this.getFloIdFromWSUrl(ws_url); + let disconnected_su_flo_id = ''; + try { + disconnected_su_flo_id = await this.getFloIdFromWSUrl(ws_url); + } catch(e) { + disconnected_su_flo_id = ws_url; // Input is a FLO Id not url + } + const get_disconnected_su_details_list = await readDBbyIndex('myClosestSupernodes', 'trader_flo_address', disconnected_su_flo_id); const get_disconnected_su_details = get_disconnected_su_details_list[0]; if(typeof get_disconnected_su_details !== "object") { @@ -15519,7 +15537,7 @@ async function onMessage(evt) { var response = evt.data; - writeToScreen('RESPONSE: ' + response + ''); + console.log('RESPONSE: ' + response); // If the message is about leaving of a node determine its FLO Id // and fire respective events let isItANodeLeavingMessage = response.search(`\\-- left`); @@ -16342,21 +16360,21 @@ break; case "link_My_Local_IP_To_My_Flo_Id": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - const req_params = res_obj.params[0]; - if(typeof req_params.requesters_pub_key !== "string") return; - let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); - if(typeof flo_addr_for_pubkey !== "string") return; - if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; - updateinDB('ipTable', { - 'flo_public_key': req_params.requesters_pub_key, - 'temporary_ip': incoming_msg_local_ip - }).then((ipRes)=>{ - reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); - }).finally(()=>{ - linkBackOthersLocalIPToTheirFloId(); - }); - } + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + const req_params = res_obj.params[0]; + if(typeof req_params.requesters_pub_key !== "string") return; + let flo_addr_for_pubkey = bitjs.FLO_TEST.pubkey2address(req_params.requesters_pub_key); + if(typeof flo_addr_for_pubkey !== "string") return; + if(flo_addr_for_pubkey !== res_obj.globalParams.senderFloId) return; + updateinDB('ipTable', { + 'flo_public_key': req_params.requesters_pub_key, + 'temporary_ip': incoming_msg_local_ip + }).then((ipRes)=>{ + reactor.dispatchEvent('fireNodeWelcomeBackEvent', ipRes); + }).finally(()=>{ + linkBackOthersLocalIPToTheirFloId(); + }); + } break; case "link_Others_Local_IP_To_Their_Flo_Id": @@ -16701,6 +16719,13 @@ } break; + case "is_node_alive_request": + if(localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + reactor.dispatchEvent('nodeIsAlive', res_obj); + } + break; + default: break; } @@ -16713,7 +16738,7 @@ } async function processBackupUserOnMesssageRequest(response) { - writeToScreen('RESPONSE: ' + response + ''); + console.log('processBackupUserOnMesssageRequest RESPONSE: ' + response); // If the message is about leaving of a node determine its FLO Id // and fire respective events let isItANodeLeavingMessage = response.search(`\\-- left`); @@ -17999,6 +18024,13 @@ } break; + case "is_node_alive_request": + if(localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + reactor.dispatchEvent('nodeIsAlive', res_obj); + } + break; + default: break; } @@ -18013,7 +18045,7 @@ async function handle_backup_server_messages(response) { //var response = evt.data; - writeToScreen('backup response: '+response); + console.log('backup response: '+response); let isItANodeLeavingMessage = response.search(`\\-- left`); @@ -18748,7 +18780,6 @@ } } - function onError(evt) { let msg = `ERROR: Websocket Connection to ${evt.srcElement.url} returned error.`; showMessage(msg); @@ -18823,7 +18854,7 @@ } } - writeToScreen("SENT: " + finalMessage); + console.log("SENT: " + finalMessage); } @@ -18876,14 +18907,6 @@ }) } - function writeToScreen(message) { - // var pre = document.createElement("p"); - // pre.style.wordWrap = "break-word"; - // pre.innerHTML = message; - //output.appendChild(pre); - console.log(message); - } - /* Websocket Code Ends Here*/ @@ -19921,6 +19944,9 @@ // Upload files to DB uploadFileToDB(); + // Get the node cuurent active status + reactor.dispatchEvent("get_node_status_request"); + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( MY_LOCAL_FLO_PUBLIC_KEY)) { localbitcoinplusplus.master_configurations.tradableAsset1.forEach(function ( @@ -20615,15 +20641,22 @@ reactor.registerEvent('fireNodeWelcomeBackEvent'); reactor.registerEvent('fireNodeGoodByeEvent'); reactor.registerEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes'); + reactor.registerEvent('nodeIsAlive'); + reactor.registerEvent('get_node_status_request'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); + if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(evt.flo_public_key)) { msg = `INFO: Supernode ${getFLOId} joined.`; - } else { - msg = `INFO: User node ${getFLOId} joined.`; - } + + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); + + } else { + msg = `INFO: User node ${getFLOId} joined.`; + } showMessage(msg); }); @@ -20631,7 +20664,7 @@ const switchMyWS = new backupSupernodesWebSocketObject(); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); showMessage(`INFO: Connected successfully to Supernode: ${evt.srcElement.url}`); - writeToScreen("CONNECTED"); + console.log("CONNECTED"); let my_local_data = await readDB('localbitcoinUser', '00-01'); if (typeof my_local_data == "object" @@ -20671,13 +20704,26 @@ reactor.addEventListener('fireNodeGoodByeEvent', function(evt_msg) { let i = evt_msg.indexOf(' ') - let temp_ip = evt_msg.substr(0, i) - + let temp_ip = evt_msg.substr(0, i); + readDBbyIndex('ipTable', 'temporary_ip', temp_ip).then(async op =>{ if(op.length < 1 || typeof op[0].temporary_ip !== 'string') return; let getFLOId = bitjs.FLO_TEST.pubkey2address(op[0].flo_public_key); if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(op[0].flo_public_key)) { + + // Update Node availability status to true/false + readDBbyIndex('myClosestSupernodes', 'trader_flo_address', getFLOId) + .then(cs=>{ + if(cs.length<1) { + console.log(temp_ip, getFLOId); + console.error(`WARNING: Failed to update Supernodes status.`); + return; + } + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(`ws://${cs[0].ip}:${cs[0].port}`, false); + }); + msg = `INFO: Supernode ${getFLOId} left.`; } else { msg = `INFO: User node ${getFLOId} left.`; @@ -20743,6 +20789,35 @@ }); + reactor.addEventListener('nodeIsAlive', function(res_obj) { + try { + if (res_obj.params[0].JOB !== "ARE_YOU_ALIVE") return; + const params=res_obj.params[0]; + if (params.receiver_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(params.trader_flo_address, true); + } catch(e) { + console.warn(e); + } + }); + + reactor.addEventListener('get_node_status_request', function() { + readAllDB('myClosestSupernodes').then(nearestSupernodeAddresslist=>{ + const RM_RPC = new localbitcoinplusplus.rpc; + nearestSupernodeAddresslist.map(f=>{ + if (f.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) { + RM_RPC + .send_rpc + .call(this, "is_node_alive_request", { + JOB: 'ARE_YOU_ALIVE', + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + receiver_flo_address: f.trader_flo_address + }).then(req=>doSend(req)); + } + }); + }); + }); + From 07cea657837319bb204d396863179530b96783fd Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 27 May 2019 16:33:44 +0530 Subject: [PATCH 28/95] changed _readDB to readDB while getting supernode pub key while trade buy, sell, balance updates --- supernode/index.html | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index b822f0e..ed69a43 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14030,7 +14030,7 @@ let res_btc; // supernode data query - _readDB('localbitcoinUser', '00-01').then(function (user_data) { + readDB('localbitcoinUser', '00-01').then(function (user_data) { if (typeof user_data == "object" && typeof localbitcoinplusplus.wallets .MY_SUPERNODE_PRIVATE_KEY == "string" && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY @@ -14130,7 +14130,7 @@ } // supernode data query - _readDB('localbitcoinUser', '00-01').then(function (user_data) { + readDB('localbitcoinUser', '00-01').then(function (user_data) { if (typeof user_data == "object" && typeof localbitcoinplusplus.wallets .MY_SUPERNODE_PRIVATE_KEY == "string" && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY @@ -14629,7 +14629,7 @@ } // supernode data query - _readDB('localbitcoinUser', '00-01') + readDB('localbitcoinUser', '00-01') .then( function (user_data) { if (typeof user_data == @@ -16856,9 +16856,13 @@ // Only the relevent user node should get response if(buyOrders_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; - if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" && - localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - buyOrders_data.supernodePubKey)) { + if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" + // Commented this because it prevents usernode to register data in db + // while a backup supernode sends it any data like trade_buy + + // && localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + // buyOrders_data.supernodePubKey) + ) { let isDataSignedBySuperNode = RM_WALLET .verify(buyOrders_data.data_hash, buyOrders_data.supernode_sign, buyOrders_data.supernodePubKey); @@ -16881,10 +16885,13 @@ // Only the relevent user node should get response if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; - if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" && - localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - sellOrders_data - .supernodePubKey)) { + if (typeof localbitcoinplusplus.master_configurations.supernodesPubKeys == "object" + // Commented this because it prevents usernode to register data in db + // while a backup supernode sends it any data like trade_buy + + // && localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + // sellOrders_data.supernodePubKey) + ) { let isDataSignedBySuperNode = RM_WALLET .verify(sellOrders_data.data_hash, sellOrders_data.supernode_sign, sellOrders_data.supernodePubKey); @@ -17060,8 +17067,8 @@ `${trade_info_str}${buyer_cash_data_str}${seller_cash_data_str}${buyer_btc_data_str}${seller_btc_data_str}`; let hashed_data = Crypto.SHA256(res_str); - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - trade_balance_res.supernodePubKey)) { + // if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + // trade_balance_res.supernodePubKey)) { if (RM_WALLET.verify(hashed_data, trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { @@ -17089,7 +17096,7 @@ throw new Error(error); } } - } + //} } break; case "store_shamirs_secret_pvtkey_shares": @@ -17114,7 +17121,10 @@ } break; case "send_back_shamirs_secret_supernode_pvtkey": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + ) { if(typeof res_obj.globalParams.primarySupernode !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) From a8c94586b71fbf51e4c828b270c04a296bf18ce9 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 28 May 2019 18:53:40 +0530 Subject: [PATCH 29/95] fixed primary backup issues --- supernode/index.html | 225 +++++++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 102 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index ed69a43..9e74199 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10165,7 +10165,13 @@ "trader_flo_address": primary_su, "job": "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", "receiver_flo_address": backup_su, - }).then(sync_request=>doSend(sync_request, backup_su)); + }).then(sync_request=>{ + if (typeof localbitcoinplusplus.backupWS[backup_su]=="object") { + doSend(sync_request, backup_su); + } else { + doSend(sync_request); + } + }); }, sync_backup_supernode_from_backup_supernode: function (requester="", receiver="", flo_addr_of_backup="") { @@ -10176,7 +10182,13 @@ "job": "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB", "receiver_flo_address": receiver, "requester_flo_id": requester - }).then(sync_request=>doSend(sync_request, receiver)); + }).then(sync_request=>{ + if (typeof localbitcoinplusplus.backupWS[receiver]=="object") { + doSend(sync_request, receiver); + } else { + doSend(sync_request); + } + }); }, get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { @@ -12619,7 +12631,7 @@ .call(this, "sync_primary_supernode_from_backup_supernode_response", su_db_data) .then(server_sync_response=> - doSend(server_sync_response, params.trader_flo_address)); + doSend(server_sync_response)); } }); } @@ -15238,51 +15250,6 @@ // Connect with primary supernodes await startWebSocket(`ws://${wsUri[0].ip}:${wsUri[0].port}`); - // Check last connected supernode, if not primary then - // update the user data from other su first - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - if (typeof idbData.lastConnectedSupernode == "string" - && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { - showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - - // Get data for deposits and withdraw starting from first (and currently alive) backup supernode - let closestSuNodes = await readAllDB('myClosestSupernodes'); - let firstAliveBackupFloIdForPrimarySupernode; - - for (let index = 1; index <= closestSuNodes.length-1; index++) { - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { - firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); - } - } - - // Update backup db as well for all supernodes you're serving as backup - for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { - let firstAliveBackupFloIdForBackupSupernode; - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - } else { - // it will ask backup from backup su next closest - for (let j = index-1; j >= index-localbitcoinplusplus.master_configurations.MaxBackups; j--) { - const nextBKSu = closestSuNodes[j].trader_flo_address; - if (nextBKSu !== idbData.myLocalFLOAddress - && closestSuNodes[index].is_live==true - && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[j].trader_flo_address); - } - } - } - } - - } - } - // rebuild private key await privateKeyBuilder(); @@ -15375,6 +15342,7 @@ let incoming_msg_local_ip = ``; if (isRequestToLinkIp>=0 || isRequestToLinkOthersIp>=0) { handle_backup_server_messages(response); + return; } var res_pos = response.indexOf('{'); if (res_pos >= 0) { @@ -15383,19 +15351,17 @@ if (res_obj.method==="add_user_public_data") { handle_backup_server_messages(response); } - if (res_obj.method==="sync_backup_supernode_from_backup_supernode") { - // if (localbitcoinplusplus.master_configurations.supernodesPubKeys - // .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - // response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, - // JSON.stringify(res_obj)); - // } + if (res_obj.method==="sync_backup_supernode_from_backup_supernode" + || res_obj.method==="sync_primary_supernode_from_backup_supernode_response") { onMessage(response); + return; } if (res_obj.method==="is_node_alive_request" && localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) && (res_obj.params[0].receiver_flo_address == localbitcoinplusplus.wallets.my_local_flo_address)) { reactor.dispatchEvent('nodeIsAlive', res_obj); + return; } } }.bind(this); @@ -15536,7 +15502,7 @@ } async function onMessage(evt) { - var response = evt.data; + var response = evt.data || evt; console.log('RESPONSE: ' + response); // If the message is about leaving of a node determine its FLO Id // and fire respective events @@ -16563,39 +16529,7 @@ let i = 0; for (let tableStoreName in su_db_data) { i++; - if (i==Object.keys(su_db_data).length-2) { - // Get data for crypto and fiat balances based on vector clock from all backup supernodes - reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', - { requesting_user_id: localbitcoinplusplus.wallets.my_local_flo_address}); - await localbitcoinplusplus.actions.delay(180000).then(()=>{ - showMessage(`INFO: Balance syncing is complete.`); - - localbitcoinplusplus.amIreadyToServePrimaryUsers = true; - - const RM_RPC = new localbitcoinplusplus.rpc; - - // Method 1: Inform user nodes they can now trade - RM_RPC - .send_rpc - .call(this, "reconnect_with_another_supernode", { - "trader_flo_address": respective_trader_id, - "receiver_flo_address": "", // message for all - "ws_url": websocket.url, - "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, - }).then(server_response=>doSend(server_response)); - - // Method 2: Now inform all backup supernodes you are back and request to stop serving your users - // RM_RPC - // .send_rpc - // .call(this, "update_supernode_status", { - // trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, - // trader_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, - // su_status: true, - // }).then(server_response=> - // doSend(server_response, nextSu.data.id)); - - }); - } + // skip loop if the property is from prototype if (tableStoreName == 'trader_flo_address' || tableStoreName == 'receiver_flo_address' @@ -16628,6 +16562,40 @@ } } + if (i==Object.keys(su_db_data).length-2) { + // Get data for crypto and fiat balances based on vector clock from all backup supernodes + reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', + { requesting_user_id: localbitcoinplusplus.wallets.my_local_flo_address}); + await localbitcoinplusplus.actions.delay(180000).then(()=>{ + showMessage(`INFO: Balance syncing is complete.`); + + localbitcoinplusplus.amIreadyToServePrimaryUsers = true; + + const RM_RPC = new localbitcoinplusplus.rpc; + + // Method 1: Inform user nodes they can now trade + RM_RPC + .send_rpc + .call(this, "reconnect_with_another_supernode", { + "trader_flo_address": su_db_data.trader_flo_address, + //"receiver_flo_address": "", // message for all + "ws_url": websocket.url, + "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, + }).then(server_response=>doSend(server_response)); + + // Method 2: Now inform all backup supernodes you are back and request to stop serving your users + // RM_RPC + // .send_rpc + // .call(this, "update_supernode_status", { + // trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + // trader_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, + // su_status: true, + // }).then(server_response=> + // doSend(server_response, nextSu.data.id)); + + }); + } + } catch (error) { console.log(error); } @@ -18827,14 +18795,16 @@ // The message is for a specific supernode only if (user_flo_id!=="" && user_flo_id.length>0) { try { - wsConn = localbitcoinplusplus.backupWS[user_flo_id].ws_connection; - if(wsConn.readyState !== 1) { - let msg = "WARNING: Websocket not ready to broadcast messages."; - showMessage(msg); - console.warn(msg); - return; + if (typeof localbitcoinplusplus.backupWS[user_flo_id]=="object") { + wsConn = localbitcoinplusplus.backupWS[user_flo_id].ws_connection; + if(wsConn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(msg); + return; + } + wsConn.send(finalMessage); } - wsConn.send(finalMessage); } catch (error) { showMessage(`ERROR: Failed to determine WS connection with ${user_flo_id}.`); throw new Error(error); @@ -18847,14 +18817,16 @@ for (const key in localbitcoinplusplus.backupWS) { if (localbitcoinplusplus.backupWS.hasOwnProperty(key)) { - const ws_conn = localbitcoinplusplus.backupWS[key].ws_connection; - if(ws_conn.readyState !== 1) { - let msg = "WARNING: Websocket not ready to broadcast messages."; - showMessage(msg); - console.warn(msg); - break; + if (typeof localbitcoinplusplus.backupWS[key]=="object") { + const ws_conn = localbitcoinplusplus.backupWS[key].ws_connection; + if(ws_conn.readyState !== 1) { + let msg = "WARNING: Websocket not ready to broadcast messages."; + showMessage(msg); + console.warn(msg); + break; + } + ws_conn.send(finalMessage); } - ws_conn.send(finalMessage); } } @@ -19936,6 +19908,55 @@ } }); + + // Check last connected supernode, if not primary then + // update the user data from other su first + wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { + if (typeof idbData.lastConnectedSupernode == "string" + && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { + showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); + + // Get data for deposits and withdraw starting from first (and currently alive) backup supernode + let closestSuNodes = await readAllDB('myClosestSupernodes'); + let firstAliveBackupFloIdForPrimarySupernode; + + for (let index = 1; index <= closestSuNodes.length-1; index++) { + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { + firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); + } + } + + // Update backup db as well for all supernodes you're serving as backup + for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { + let firstAliveBackupFloIdForBackupSupernode; + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + } else { + // it will ask backup from backup su next closest + for (let j = index-1; j >= index-localbitcoinplusplus.master_configurations.MaxBackups; j--) { + const nextBKSu = closestSuNodes[j].trader_flo_address; + if (nextBKSu !== idbData.myLocalFLOAddress + && closestSuNodes[index].is_live==true + && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[j].trader_flo_address); + } + } + } + } + + } + } + + // Show balances displayBalances(idbData.myLocalFLOAddress); From 7cc25776106e0ef70bfab9d65ed62482612368ac Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 29 May 2019 13:48:52 +0530 Subject: [PATCH 30/95] fixed backup supernodes backup db sync when primary comes back --- supernode/index.html | 128 +++++++++++++++++++++++++++++++++---------- 1 file changed, 99 insertions(+), 29 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 9e74199..f2f68c2 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12580,14 +12580,7 @@ if(typeof params.trader_flo_address !="string") return; const my_closest_su_list = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.trader_flo_address); const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - 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); - }; - + if (method=="sync_with_supernode") { RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { if (is_valid_request === true && params.job == @@ -12658,13 +12651,24 @@ .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) .then(server_sync_response=> - doSend(server_sync_response, params.trader_flo_address)); + doSend(server_sync_response, params.requester_flo_id)); } }); } }); } + let backup_server_db_instance; + if (typeof localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser] == "object") { + backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + } + + 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); + }; + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { if (is_valid_request !== true) return false; @@ -13869,7 +13873,6 @@ break; default: - showMessage("WARNING: Unknown method called for execution."); break; } } @@ -16575,24 +16578,14 @@ // Method 1: Inform user nodes they can now trade RM_RPC - .send_rpc - .call(this, "reconnect_with_another_supernode", { - "trader_flo_address": su_db_data.trader_flo_address, - //"receiver_flo_address": "", // message for all - "ws_url": websocket.url, - "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, - }).then(server_response=>doSend(server_response)); - - // Method 2: Now inform all backup supernodes you are back and request to stop serving your users - // RM_RPC - // .send_rpc - // .call(this, "update_supernode_status", { - // trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, - // trader_pub_key: localbitcoinplusplus.wallets.my_local_flo_public_key, - // su_status: true, - // }).then(server_response=> - // doSend(server_response, nextSu.data.id)); - + .send_rpc + .call(this, "reconnect_with_another_supernode", { + "trader_flo_address": su_db_data.trader_flo_address, + //"receiver_flo_address": "", // message for all + "ws_url": websocket.url, + "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, + }).then(server_response=>doSend(server_response)); + }); } @@ -16606,10 +16599,10 @@ case "sync_backup_supernode_from_backup_supernode_response": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let su_db_data = res_obj.params[0]; // if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || // su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { // ) return false; (async function () { @@ -16694,6 +16687,18 @@ } break; + case "sync_backup_supernode_from_backup_supernode": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && typeof res_obj.globalParams.receiverFloId == "string" + && localbitcoinplusplus.wallets.my_local_flo_address == res_obj.globalParams.receiverFloId + ) { + const RM_RPC = new localbitcoinplusplus.rpc; + response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, + JSON.stringify(res_obj)); + } + break; + default: break; } @@ -18747,6 +18752,71 @@ break; + case "sync_backup_supernode_from_backup_supernode_response": + let su_db_data = res_obj.params[0]; + // if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || + // su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { + // ) return false; + + (async function () { + let i = 0; + for (let tableStoreName in su_db_data) { + i++; + if (i==Object.keys(su_db_data).length-2) { + // Get data for crypto and fiat balances based on vector clock from all backup supernodes + // reactor.dispatchEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes', + // { requesting_user_id: localbitcoinplusplus.wallets.my_local_flo_address}); + // await localbitcoinplusplus.actions.delay(180000).then(()=>{ + // showMessage(`INFO: Balance syncing is complete.`); + + localbitcoinplusplus.amIreadyToServePrimaryUsers = true; + + //}); + } + // skip loop if the property is from prototype + if (tableStoreName == 'trader_flo_address' + || tableStoreName == 'receiver_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 localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] + .backup_updateinDB(tableStoreName, obj[prop], obj[prop] + .trader_flo_address).then(()=>{ + showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); + }); + } + } + } else { + let resdbdata = await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] + .backup_removeAllinDB(tableStoreName); + if (resdbdata !== false) { + if (obj.length > 0) { + for (var prop in obj) { + if (!obj.hasOwnProperty(prop)) continue; + await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] + .backup_addDB(resdbdata, obj[prop]).then(()=>{ + showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); + }); + } + } + } + } + + } catch (error) { + console.log(error); + } + } + })(); + } + break; + default: break; } From 772b516c506410ed152b28a05925924c9c61c680 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 30 May 2019 12:31:18 +0530 Subject: [PATCH 31/95] fixed node live status and removed break from doSend dunction --- supernode/index.html | 90 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 10 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index f2f68c2..c973b24 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15362,8 +15362,29 @@ if (res_obj.method==="is_node_alive_request" && localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) - && (res_obj.params[0].receiver_flo_address == localbitcoinplusplus.wallets.my_local_flo_address)) { - reactor.dispatchEvent('nodeIsAlive', res_obj); + && (res_obj.params[0].receiver_flo_address == + localbitcoinplusplus.wallets.my_local_flo_address)) { + // Register his attendance + reactor.dispatchEvent('nodeIsAlive', res_obj); + // Send your live status to Sender + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "yup_i_am_awake", { + JOB: 'I_AM_ALIVE', + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + receiver_flo_address: res_obj.globalParams.senderFloId + }).then(req=>doSend(req)); + return; + } + + if (res_obj.method=="yup_i_am_awake" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && (res_obj.params[0].receiver_flo_address == + localbitcoinplusplus.wallets.my_local_flo_address)) { + + reactor.dispatchEvent('nodeIsAlive', res_obj); return; } } @@ -15498,6 +15519,12 @@ function onOpen(evt) { localbitcoinplusplus.amIreadyToServePrimaryUsers = false; reactor.dispatchEvent('new_supernode_connected', evt); + readAllDB('myClosestSupernodes').then(sconn=>{ + const switchMyWS = new backupSupernodesWebSocketObject(); + sconn.map((m,i)=>{ + if(i>0) switchMyWS.updateSupernodeAvailabilityStatus(m.trader_flo_address, false); + }); + }); } function onClose(evt) { @@ -16632,7 +16659,7 @@ if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - await localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] .backup_updateinDB(tableStoreName, obj[prop], obj[prop] .trader_flo_address).then(()=>{ showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); @@ -16640,13 +16667,13 @@ } } } else { - let resdbdata = await localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + let resdbdata = await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] .backup_removeAllinDB(tableStoreName); if (resdbdata !== false) { if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - await localbitcoinplusplus.newBackupDatabase.db[trader_flo_address] + await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] .backup_addDB(resdbdata, obj[prop]).then(()=>{ showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); }); @@ -16683,7 +16710,28 @@ case "is_node_alive_request": if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - reactor.dispatchEvent('nodeIsAlive', res_obj); + reactor.dispatchEvent('nodeIsAlive', res_obj); + // Send your live status to Sender + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "yup_i_am_awake", { + JOB: 'I_AM_ALIVE', + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + receiver_flo_address: res_obj.globalParams.senderFloId + }).then(req=>doSend(req)); + } + break; + + case "yup_i_am_awake": + if (res_obj.method=="yup_i_am_awake" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && (res_obj.params[0].receiver_flo_address == + localbitcoinplusplus.wallets.my_local_flo_address)) { + + reactor.dispatchEvent('nodeIsAlive', res_obj); + return; } break; @@ -18010,10 +18058,31 @@ case "is_node_alive_request": if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - reactor.dispatchEvent('nodeIsAlive', res_obj); + reactor.dispatchEvent('nodeIsAlive', res_obj); + // Send your live status to Sender + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "yup_i_am_awake", { + JOB: 'I_AM_ALIVE', + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, + receiver_flo_address: res_obj.globalParams.senderFloId + }).then(req=>doSend(req)); } break; + case "yup_i_am_awake": + if (res_obj.method=="yup_i_am_awake" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && (res_obj.params[0].receiver_flo_address == + localbitcoinplusplus.wallets.my_local_flo_address)) { + + reactor.dispatchEvent('nodeIsAlive', res_obj); + return; + } + break; + default: break; } @@ -18893,9 +18962,9 @@ let msg = "WARNING: Websocket not ready to broadcast messages."; showMessage(msg); console.warn(msg); - break; + } else { + ws_conn.send(finalMessage); } - ws_conn.send(finalMessage); } } } @@ -20892,7 +20961,8 @@ reactor.addEventListener('nodeIsAlive', function(res_obj) { try { - if (res_obj.params[0].JOB !== "ARE_YOU_ALIVE") return; + if (res_obj.params[0].JOB !== "ARE_YOU_ALIVE" + || res_obj.params[0].JOB !== "I_AM_ALIVE") return; const params=res_obj.params[0]; if (params.receiver_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; const switchMyWS = new backupSupernodesWebSocketObject(); From a3adb867ee1278c601bb7ad05cefd4ed95794f1d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 31 May 2019 18:31:04 +0530 Subject: [PATCH 32/95] changed pubkey used in btc shares as backup su than dead primary su --- supernode/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index c973b24..fa97922 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12891,7 +12891,7 @@ throw new Error(err_msg); } - backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( + readDB("localbitcoinUser", "00-01").then( function (su_data) { if (typeof su_data == "object" && typeof su_data.myLocalFLOPublicKey == @@ -13409,7 +13409,7 @@ // doSend btc_private_key_shamirs_id from system_btc_reserves_private_keys valid_btc_list.map(vbl => { - readDBbyIndex + backup_server_db_instance.backup_readDBbyIndex ( 'system_btc_reserves_private_keys', 'btc_address', @@ -16809,7 +16809,7 @@ && res_obj.method !== "sync_backup_supernode_from_backup_supernode" && res_obj.method !== "link_My_Local_IP_To_My_Flo_Id" && res_obj.method !== "link_Others_Local_IP_To_Their_Flo_Id" - //&& res_obj.method !== "add_user_public_data" + && res_obj.method !== "send_back_shamirs_secret_btc_pvtkey" ) { if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { @@ -20728,8 +20728,8 @@ _readDB('crypto_balances', trader_depositor_cash_id).then(function (res_btc_balances) { if (typeof res_btc_balances == "object" && typeof res_btc_balances.result == "object" && typeof res_btc_balances.crypto_balance == "number") { - updatedCryptobalances.crypto_balance += parseFloat(res_btc_balances - .crypto_balance); + updatedCryptobalances.crypto_balance = Number(parseFloat(res_btc_balances + .crypto_balance + updatedCryptobalances.crypto_balance)); } // Update crypto balance of user in crypto_balances _updateinDB("crypto_balances", updatedCryptobalances, trader_deposits.btc_address) From 26ccdfec0f278c20a5d75ea3b222102f797b485e Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 1 Jun 2019 18:55:09 +0530 Subject: [PATCH 33/95] fixed functionality to withdraw crypto when backup supernode is acting supernode --- supernode/index.html | 252 +++++++++++++++++++++++++++---------------- 1 file changed, 161 insertions(+), 91 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index fa97922..8a5abaf 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12568,6 +12568,12 @@ if (typeof params == "object" && typeof method == "string") { + if (typeof params.receiver_flo_address=="string" + && params.receiver_flo_address.length>0) { + if(params.receiver_flo_address + !== localbitcoinplusplus.wallets.my_local_flo_address) return; + } + const RM_WALLET = new localbitcoinplusplus.wallets; const RM_TRADE = new localbitcoinplusplus.trade; const RM_RPC = new localbitcoinplusplus.rpc; @@ -12577,7 +12583,7 @@ request.response = {}; let err_msg; - if(typeof params.trader_flo_address !="string") return; + if(typeof params.trader_flo_address !=="string") return; const my_closest_su_list = await localbitcoinplusplus.kademlia.determineClosestSupernode(params.trader_flo_address); const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; @@ -12659,15 +12665,17 @@ } let backup_server_db_instance; - if (typeof localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser] == "object") { - backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - } + if (method !== "retrieve_shamirs_secret_btc_pvtkey") { + if (typeof localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser] == "object") { + backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + } - 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); - }; + 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); + }; + } RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { if (is_valid_request !== true) return false; @@ -13429,7 +13437,8 @@ "send_back_shamirs_secret_btc_pvtkey", { retrieve_pvtkey_req_id: retrieve_pvtkey_req_id, chunk_val: bpks, - withdraw_id: vbl.withdraw_id + withdraw_id: vbl.withdraw_id, + db_inst: primarySupernodeForThisUser } ).then(retrieve_pvtkey_req=> doSend(retrieve_pvtkey_req)); @@ -13593,6 +13602,10 @@ if (typeof params.btc_private_key_array !== "string" || typeof params.retrieve_pvtkey_req_id !== "string") return false; + backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[params.db_inst]; + + if (typeof backup_server_db_instance !== "object") return; + let btc_private_key_str = params.btc_private_key_array; let retrieve_pvtkey_req_id = params.retrieve_pvtkey_req_id; let withdraw_id = params.withdraw_id; @@ -13621,7 +13634,7 @@ await RM_TRADE.resolve_current_crypto_price_in_fiat( withdraw_res.product, withdraw_res.currency); - const EqCryptoWd = RM_TRADE.calculateCryptoEquivalentOfCash( + let EqCryptoWd = RM_TRADE.calculateCryptoEquivalentOfCash( withdraw_res.receiverBTCEquivalentInCash, withdraw_res.currency, withdraw_res.product); @@ -13670,22 +13683,17 @@ msg = `Transaction Id for your withdrawn crypto asset: ${resp_txid}`; + let withdrawer_crypto_bal_id = `${withdraw_res.trader_flo_address}_${withdraw_res.product}`; backup_server_db_instance.backup_readDB ( 'crypto_balances', - withdraw_res - .id + withdrawer_crypto_bal_id ) .then( res_bal => { - // btc_eq_receiving_amount - // = - // Number(parseFloat( - // btc_eq_receiving_amount - // ) - // .toFixed( - // 8 - // )); + if (typeof res_bal !== "object") { + throw new Error(`FATAL ERROR: Failed to subtract balance of id ${withdrawer_crypto_bal_id} by ${EqCryptoWd}. `); + } res_bal .crypto_balance -= EqCryptoWd; @@ -15351,11 +15359,14 @@ if (res_pos >= 0) { var res = response.substr(res_pos); let res_obj = JSON.parse(res); - if (res_obj.method==="add_user_public_data") { + if (res_obj.method==="add_user_public_data" + || res_obj.method==="retrieve_shamirs_secret_btc_pvtkey" + ) { handle_backup_server_messages(response); + return; } if (res_obj.method==="sync_backup_supernode_from_backup_supernode" - || res_obj.method==="sync_primary_supernode_from_backup_supernode_response") { + || res_obj.method==="sync_primary_supernode_from_backup_supernode_response") { onMessage(response); return; } @@ -15604,6 +15615,7 @@ processBackupUserOnMesssageRequest(response); return; } + handle_backup_server_messages(response); return; } @@ -15923,7 +15935,7 @@ private_key_chunk: res, withdraw_id: res_obj.params[0].withdraw_id, receiver_flo_address: res_obj.globalParams.senderFloId - }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); + }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); }); } break; @@ -16810,6 +16822,8 @@ && res_obj.method !== "link_My_Local_IP_To_My_Flo_Id" && res_obj.method !== "link_Others_Local_IP_To_Their_Flo_Id" && res_obj.method !== "send_back_shamirs_secret_btc_pvtkey" + && res_obj.method !== "send_back_shamirs_secret_supernode_pvtkey" + && res_obj.method !== "store_shamirs_secret_pvtkey_shares" ) { if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { @@ -17124,20 +17138,21 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + // if(typeof res_obj.params[0].trader_flo_address !="string") return; + // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + // .then(my_closest_su_list=>{ + // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - 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); - }; - delete res_obj.params[0].trader_flo_address; - backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); - }); + // 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); + // }; + + // }); + delete res_obj.params[0].trader_flo_address; + addDB("supernode_private_key_chunks", res_obj.params[0]); } } break; @@ -17214,29 +17229,43 @@ case "send_back_shamirs_secret_btc_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - if(typeof res_obj.globalParams.primarySupernode !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + if(typeof res_obj.globalParams.primarySupernode !="string") return; + + // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) + // .then(my_closest_su_list=>{ + // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - 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); - }; + // 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - res) { - RM_RPC - .send_rpc - .call(this, "retrieve_shamirs_secret_btc_pvtkey", { - retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, - private_key_chunk: res, - withdraw_id: res_obj.params[0].withdraw_id, - receiver_flo_address: res_obj.globalParams.senderFloId, - }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - }); + // backup_server_db_instance.backup_readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + // res) { + // RM_RPC + // .send_rpc + // .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + // retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + // private_key_chunk: res, + // withdraw_id: res_obj.params[0].withdraw_id, + // receiver_flo_address: res_obj.globalParams.senderFloId, + // }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); + // }); + // }); + + readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + res) { + RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + private_key_chunk: res, + withdraw_id: res_obj.params[0].withdraw_id, + db_inst: res_obj.params[0].db_inst, + receiver_flo_address: res_obj.globalParams.senderFloId, + }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); }); } break; @@ -18732,28 +18761,42 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { if(typeof res_obj.globalParams.senderFloId !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) + // .then(my_closest_su_list=>{ + // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - 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); - }; + // 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - res) { - RM_RPC - .send_rpc - .call(this, "retrieve_shamirs_secret_btc_pvtkey", { - retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, - private_key_chunk: res, - withdraw_id: res_obj.params[0].withdraw_id, - receiver_flo_address: res_obj.globalParams.senderFloId, - }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - }); + // backup_server_db_instance.backup_readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + // res) { + // RM_RPC + // .send_rpc + // .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + // retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + // private_key_chunk: res, + // withdraw_id: res_obj.params[0].withdraw_id, + // receiver_flo_address: res_obj.globalParams.senderFloId, + // }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); + // }); + // }); + + readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( + res) { + RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_btc_pvtkey", { + retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, + private_key_chunk: res, + withdraw_id: res_obj.params[0].withdraw_id, + receiver_flo_address: res_obj.globalParams.senderFloId, + db_inst: res_obj.params[0].db_inst + }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); }); } break; @@ -18761,23 +18804,50 @@ case "store_shamirs_secret_pvtkey_shares": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ - const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + // if(typeof res_obj.params[0].trader_flo_address !="string") return; + // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + // .then(my_closest_su_list=>{ + // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - 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); - }; - delete res_obj.params[0].trader_flo_address; - backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); - }); + // 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); + // }; + // delete res_obj.params[0].trader_flo_address; + // backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); + // }); + delete res_obj.params[0].trader_flo_address; + addDB("supernode_private_key_chunks", res_obj.params[0]); + } break; + case "retrieve_shamirs_secret_btc_pvtkey": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && + typeof res_obj.params[0].private_key_chunk == "object" && + typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && + typeof res_obj.params[0].withdraw_id == "string") { + let shamirs_shares_response = res_obj.params[0]; + let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; + let withdraw_id = res_obj.params[0].withdraw_id; + if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; + if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ + retrieve_pvtkey_req_id] = []; + btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations + .ShamirsMaxShares) { + delete res_obj.params[0].private_key_chunk; + res_obj.params[0].btc_private_key_array = JSON.stringify(btc_pvt_arr[ + retrieve_pvtkey_req_id]); + res_obj.params[0].trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; + RM_RPC.backup_receive_rpc_response.call(this, JSON.stringify(res_obj)); + btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + } + } + break; + case "updateUserCryptoBalanceRequest": if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { From d8ce4c97450f7be826695e0ea3b433f3e2312d85 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 4 Jun 2019 13:03:57 +0530 Subject: [PATCH 34/95] fixed readtState error --- supernode/index.html | 376 +++++++++++++++++++++++-------------------- 1 file changed, 205 insertions(+), 171 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 8a5abaf..50c821b 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10326,6 +10326,7 @@ if (typeof userFLoID !== "string" || userFLoID.length<1) { console.warn(`Invalid FLO Id`); + reject(`Invalid FLO Id`); return; } @@ -11356,6 +11357,12 @@ request.response = {}; let err_msg; + let recvr_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId; + if (typeof recvr_flo_id == "string" + && recvr_flo_id.length > 0 + && recvr_flo_id !== + localbitcoinplusplus.wallets.my_local_flo_address) return; + if (method=="sync_with_supernode") { RM_RPC.filter_legit_requests(params.trader_flo_address, function (is_valid_request) { if (is_valid_request === true && params.job == @@ -12278,6 +12285,10 @@ if (typeof params.btc_private_key_array !== "string" || typeof params.retrieve_pvtkey_req_id !== "string") return false; + + let rec_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId; + if (typeof rec_flo_id == "undefined" || rec_flo_id !== + localbitcoinplusplus.wallets.my_local_flo_address) return; let btc_private_key_str = params.btc_private_key_array; let retrieve_pvtkey_req_id = params.retrieve_pvtkey_req_id; @@ -12574,6 +12585,12 @@ !== localbitcoinplusplus.wallets.my_local_flo_address) return; } + let recvr_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId; + if (typeof recvr_flo_id == "string" + && recvr_flo_id.length > 0 + && recvr_flo_id !== + localbitcoinplusplus.wallets.my_local_flo_address) return; + const RM_WALLET = new localbitcoinplusplus.wallets; const RM_TRADE = new localbitcoinplusplus.trade; const RM_RPC = new localbitcoinplusplus.rpc; @@ -12610,6 +12627,7 @@ }); } }); + return; } if (method=="sync_primary_supernode_from_backup_supernode") { @@ -12618,7 +12636,8 @@ if (is_valid_request === true && params.job == "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > 0) { - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", + "system_btc_reserves_private_keys"]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray, params.trader_flo_address).then( function (su_db_data) { @@ -12635,6 +12654,7 @@ }); } }); + return; } if (method=="sync_backup_supernode_from_backup_supernode") { @@ -12653,15 +12673,16 @@ su_db_data.trader_flo_address = params.trader_flo_address; su_db_data.receiver_flo_address = params.requester_flo_id; RM_RPC - .send_rpc - .call(this, "sync_backup_supernode_from_backup_supernode_response", - su_db_data) - .then(server_sync_response=> - doSend(server_sync_response, params.requester_flo_id)); + .send_rpc + .call(this, "sync_backup_supernode_from_backup_supernode_response", + su_db_data) + .then(server_sync_response=> + doSend(server_sync_response, params.requester_flo_id)); } }); } }); + return; } let backup_server_db_instance; @@ -12674,74 +12695,75 @@ let backup_db_error_msg = `WARNING: Unknown DB instance. DB Backup failed.`; showMessage(backup_db_error_msg); throw new Error(backup_db_error_msg); - }; - } + }; - RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { - if (is_valid_request !== true) return false; + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { + if (is_valid_request !== true) return false; - try { - // CHECK HERE IF USER IS INDULGED IN ANY MORE TRADE. IF TRUE RETURN ERROR - await backup_server_db_instance.backup_readAllDB("deposit").then(function (res) { - if (typeof res == "object" && res.length > 0) { - let canUserTrade = res.filter(function (user) { - return (respective_trader_id == user.trader_flo_address - && user.status==1); - }); - if (canUserTrade.includes(true)) { - request.response = - `Trader id ${respective_trader_id} is not clear for trade currently. - You must finish your previous pending orders to qualify again to trade.`; - - const RM_RPC = new localbitcoinplusplus.rpc; - RM_RPC - .send_rpc - .call(this, "supernode_message", { - "trader_flo_address": respective_trader_id, - "receiver_flo_address": respective_trader_id, - "server_msg": request.response - }).then(server_response=> - doSend(server_response)); - - showMessage(request.response); - throw new Error(request.response); - return false; - } - } - }); - - // Check if user id is in deposit or withdraw. If true prevent him from trading - await backup_server_db_instance.backup_readAllDB('withdraw_cash').then(function (res) { - if (typeof res == "object") { - let check_deposit_withdraw_id_array = res.filter(f => f.status === 2) - .map(m => { - if (m.trader_flo_address == respective_trader_id || m.deposit_withdraw_id_array == - respective_trader_id) { - let server_msg = - `Trader id ${respective_trader_id} is not clear for trade currently. - You must finish your previous pending deposit/withdraw action to qualify again to trade.`; - - const RM_RPC = new localbitcoinplusplus.rpc; - RM_RPC - .send_rpc - .call(this, "supernode_message", { - "trader_flo_address": respective_trader_id, - "receiver_flo_address": respective_trader_id, - "server_msg": server_msg - }).then(server_response=> - doSend(server_response)); - showMessage(server_msg); - throw new Error( - "User has not finished previous pending actions." - ); - } + try { + // CHECK HERE IF USER IS INDULGED IN ANY MORE TRADE. IF TRUE RETURN ERROR + await backup_server_db_instance.backup_readAllDB("deposit").then(function (res) { + if (typeof res == "object" && res.length > 0) { + let canUserTrade = res.filter(function (user) { + return (respective_trader_id == user.trader_flo_address + && user.status==1); }); - } - }); - } catch (error) { - throw new Error(error); - } - }); + if (canUserTrade.includes(true)) { + request.response = + `Trader id ${respective_trader_id} is not clear for trade currently. + You must finish your previous pending orders to qualify again to trade.`; + + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "supernode_message", { + "trader_flo_address": respective_trader_id, + "receiver_flo_address": respective_trader_id, + "server_msg": request.response + }).then(server_response=> + doSend(server_response)); + + showMessage(request.response); + throw new Error(request.response); + return false; + } + } + }); + + // Check if user id is in deposit or withdraw. If true prevent him from trading + await backup_server_db_instance.backup_readAllDB('withdraw_cash').then(function (res) { + if (typeof res == "object") { + let check_deposit_withdraw_id_array = res.filter(f => f.status === 2) + .map(m => { + if (m.trader_flo_address == respective_trader_id || m.deposit_withdraw_id_array == + respective_trader_id) { + let server_msg = + `Trader id ${respective_trader_id} is not clear for trade currently. + You must finish your previous pending deposit/withdraw action to qualify again to trade.`; + + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC + .send_rpc + .call(this, "supernode_message", { + "trader_flo_address": respective_trader_id, + "receiver_flo_address": respective_trader_id, + "server_msg": server_msg + }).then(server_response=> + doSend(server_response)); + showMessage(server_msg); + throw new Error( + "User has not finished previous pending actions." + ); + } + }); + } + }); + } catch (error) { + throw new Error(error); + } + }); + + } switch (method) { case "trade_buy": @@ -13599,8 +13621,12 @@ RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { if (is_valid_request !== true) return false; - if (typeof params.btc_private_key_array !== "string" || typeof params.retrieve_pvtkey_req_id !== - "string") return false; + if (typeof params.btc_private_key_array !== "string" + || typeof params.retrieve_pvtkey_req_id !== "string") return false; + + let rec_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId; + if (typeof rec_flo_id == "undefined" || rec_flo_id !== + localbitcoinplusplus.wallets.my_local_flo_address) return; backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[params.db_inst]; @@ -13643,11 +13669,10 @@ let transaction_key = btc_reserves.supernode_transaction_key; if (transaction_key.length > 0) { - let btc_private_key = - RM_WALLET.rebuild_private_key( - btc_pk_shares_array, - transaction_key); - //console.log(btc_private_key); + let btc_private_key = RM_WALLET.rebuild_private_key( + btc_pk_shares_array, transaction_key); + console.log(btc_pk_shares_array); + console.log(transaction_key); RM_TRADE.sendTransaction( withdraw_res.product, @@ -13658,30 +13683,12 @@ withdraw_res.currency, withdraw_res.change_adress, async function (res) { - console.log( - res - ); - if (typeof res == - "string" && - res.length > - 0) { + console.log(res); + if (typeof res == "string" && res.length > 0) { try { - let - resp_obj = - JSON - .parse( - res - ); - let - resp_txid = - resp_obj - .txid - .result || - resp_obj - .txid; - let - msg = - `Transaction Id for your withdrawn crypto asset: ${resp_txid}`; + let resp_obj = JSON.parse(res); + let resp_txid = resp_obj.txid.result || resp_obj.txid; + let msg=`Transaction Id for your withdrawn crypto asset: ${resp_txid}`; let withdrawer_crypto_bal_id = `${withdraw_res.trader_flo_address}_${withdraw_res.product}`; backup_server_db_instance.backup_readDB @@ -13694,47 +13701,24 @@ if (typeof res_bal !== "object") { throw new Error(`FATAL ERROR: Failed to subtract balance of id ${withdrawer_crypto_bal_id} by ${EqCryptoWd}. `); } - res_bal - .crypto_balance -= - EqCryptoWd; - backup_server_db_instance.backup_updateinDB - ( - 'crypto_balances', + res_bal.crypto_balance -= EqCryptoWd; + backup_server_db_instance.backup_updateinDB + ('crypto_balances', res_bal, - withdraw_res - .id - ) - .then( - res_obj => { - const - res_obj_str = - JSON - .stringify( - res_obj - ); - const - res_obj_hash = - Crypto - .SHA256( - res_obj_str - ); - const - res_obj_sign = - RM_WALLET - .sign( - res_obj_hash, - localbitcoinplusplus - .wallets - .MY_SUPERNODE_PRIVATE_KEY - ); + withdraw_res.id + ).then(res_obj => { + const res_obj_str = JSON.stringify(res_obj); + const res_obj_hash = Crypto.SHA256(res_obj_str); + const res_obj_sign = RM_WALLET + .sign(res_obj_hash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); - const - updateUserCryptoBalanceObject = { - updatedBTCBalanceObject: res_bal, - updatedBTCBalanceObjectSign: res_obj_sign, - trader_flo_address: withdraw_res.trader_flo_address, - receiver_flo_address: withdraw_res.trader_flo_address, - } + const updateUserCryptoBalanceObject = { + updatedBTCBalanceObject: res_bal, + updatedBTCBalanceObjectSign: res_obj_sign, + trader_flo_address: withdraw_res.trader_flo_address, + receiver_flo_address: withdraw_res.trader_flo_address, + } RM_RPC .send_rpc( @@ -14424,7 +14408,7 @@ throw new Error(error); } } - }).catch(e => console.error(`No balance found in ${utxo_addr}: ${e}`)); + }).catch(e => console.error(`ERROR: Failed to send tx from utxo ${utxo_addr}: ${e}`)); }, /*Finds the best buy sell id match for a trade*/ createTradePipes(trading_currency = "USD", backup_db="") { @@ -15366,7 +15350,8 @@ return; } if (res_obj.method==="sync_backup_supernode_from_backup_supernode" - || res_obj.method==="sync_primary_supernode_from_backup_supernode_response") { + || res_obj.method==="sync_primary_supernode_from_backup_supernode_response" + ) { onMessage(response); return; } @@ -15398,6 +15383,13 @@ reactor.dispatchEvent('nodeIsAlive', res_obj); return; } + + // If you want to send Shamir shares from here write the req code below + if (res_obj.method=="send_back_shamirs_secret_btc_pvtkey") { + console.log(res_obj); + return; + } + } }.bind(this); this.ws_connection.onerror = function (evt) { @@ -15611,7 +15603,10 @@ } else if(typeof res_obj.globalParams.primarySupernode=="string" && res_obj.globalParams.primarySupernode !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { if (typeof res_obj.globalParams.receiverFloId !== 'string' || - res_obj.globalParams.receiverFloId !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { + + res_obj.globalParams.receiverFloId == localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { + // ** Changed it for "retrieve_shamirs_secret_btc_pvtkey" when backup su is requeter + //res_obj.globalParams.receiverFloId !== localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS) { processBackupUserOnMesssageRequest(response); return; } @@ -15943,7 +15938,8 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && - typeof res_obj.params[0].withdraw_id == "string") { + typeof res_obj.params[0].withdraw_id == "string" && + res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; @@ -15958,7 +15954,10 @@ retrieve_pvtkey_req_id]); res_obj.params[0].trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; RM_RPC.receive_rpc_response.call(this, JSON.stringify(res_obj)); - btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + + localbitcoinplusplus.actions.delay(300000).then(()=>{ + btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + }); } } break; @@ -16293,8 +16292,9 @@ .includes(res_obj.nodePubKey)) { let updateUserCryptoBalanceResponseObject = res_obj.params[0]; let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let updateUserCryptoBalanceResponseStringHash = Crypto.SHA256(updateUserCryptoBalanceResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseStringHash, updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, res_obj.nodePubKey ); @@ -17273,7 +17273,8 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && - typeof res_obj.params[0].withdraw_id == "string") { + typeof res_obj.params[0].withdraw_id == "string" && + res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; @@ -17288,7 +17289,10 @@ retrieve_pvtkey_req_id]); res_obj.params[0].trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; RM_RPC.backup_receive_rpc_response.call(this, JSON.stringify(res_obj)); - btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + + localbitcoinplusplus.actions.delay(300000).then(()=>{ + btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + }); } } break; @@ -17675,8 +17679,9 @@ .includes(res_obj.nodePubKey)) { let updateUserCryptoBalanceResponseObject = res_obj.params[0]; let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let updateUserCryptoBalanceResponseStringHash = Crypto.SHA256(updateUserCryptoBalanceResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseStringHash, updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, res_obj.nodePubKey ); @@ -18828,7 +18833,9 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && - typeof res_obj.params[0].withdraw_id == "string") { + typeof res_obj.params[0].withdraw_id == "string" && + res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { + let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; @@ -18843,7 +18850,10 @@ retrieve_pvtkey_req_id]); res_obj.params[0].trader_flo_address = localbitcoinplusplus.wallets.my_local_flo_address; RM_RPC.backup_receive_rpc_response.call(this, JSON.stringify(res_obj)); - btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + + localbitcoinplusplus.actions.delay(300000).then(()=>{ + btc_pvt_arr[retrieve_pvtkey_req_id] = []; // Unset the object + }); } } break; @@ -18854,7 +18864,6 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let updateUserCryptoBalanceResponseObject = res_obj.params[0]; - console.log(res_obj.params[0]); if(typeof res_obj.params[0].trader_flo_address !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) @@ -18869,8 +18878,9 @@ }; let updateUserCryptoBalanceResponseString = JSON.stringify( - updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); - let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseString, + updateUserCryptoBalanceResponseObject.updatedBTCBalanceObject); + let updateUserCryptoBalanceResponseStringHash = Crypto.SHA256(updateUserCryptoBalanceResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserCryptoBalanceResponseStringHash, updateUserCryptoBalanceResponseObject.updatedBTCBalanceObjectSign, res_obj.nodePubKey ); @@ -20165,6 +20175,20 @@ } } + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(idbData.myLocalFLOAddress)) { + + if (typeof localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == "string") { + idbData.lastConnectedTime = + new Date(); + idbData.lastConnectedSupernode = localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS; + updateinDB('localbitcoinUser', idbData); + } else { + mss = `WARNING: Failed to update current supernode connected status in localbitcoinUser.`; + showMessage(mss); + throw new Error(mss); + } + } + // Show balances displayBalances(idbData.myLocalFLOAddress); @@ -20889,6 +20913,16 @@ if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(evt.flo_public_key)) { + + // ReadyState was 3 when this node disconnected. Re-initiate the + // WS connection to be able to send/receive messages + if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object") { + const back_ws_url = localbitcoinplusplus.backupWS[getFLOId].ws_url; + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + } + msg = `INFO: Supernode ${getFLOId} joined.`; const switchMyWS = new backupSupernodesWebSocketObject(); @@ -20906,22 +20940,22 @@ showMessage(`INFO: Connected successfully to Supernode: ${evt.srcElement.url}`); console.log("CONNECTED"); - let my_local_data = await readDB('localbitcoinUser', '00-01'); - if (typeof my_local_data == "object" - && !localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(my_local_data.myLocalFLOAddress)) { - const conn_su_flo_id = await switchMyWS.getFloIdFromWSUrl(evt.srcElement.url); + // let my_local_data = await readDB('localbitcoinUser', '00-01'); + // if (typeof my_local_data == "object" + // && !localbitcoinplusplus.master_configurations.supernodesPubKeys + // .includes(my_local_data.myLocalFLOAddress)) { + // const conn_su_flo_id = await switchMyWS.getFloIdFromWSUrl(evt.srcElement.url); - if (typeof conn_su_flo_id == "string") { - my_local_data.lastConnectedTime = + new Date(); - my_local_data.lastConnectedSupernode = conn_su_flo_id; - updateinDB('localbitcoinUser', my_local_data); - } else { - mss = `WARNING: Failed to update current supernode connected status in localbitcoinUser.`; - showMessage(mss); - throw new Error(mss); - } - } + // if (typeof conn_su_flo_id == "string") { + // my_local_data.lastConnectedTime = + new Date(); + // //my_local_data.lastConnectedSupernode = conn_su_flo_id; + // updateinDB('localbitcoinUser', my_local_data); + // } else { + // mss = `WARNING: Failed to update current supernode connected status in localbitcoinUser.`; + // showMessage(mss); + // throw new Error(mss); + // } + // } }); From c2c95789f1459eb69ac72f92e6b8548d41cd361a Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 5 Jun 2019 14:54:51 +0530 Subject: [PATCH 35/95] fixed errors in backup syncing by primary supernode --- supernode/index.html | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 50c821b..e7a2d05 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12612,7 +12612,8 @@ const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "crypto_balances", "cash_balances", "userPublicData" ]; - localbitcoinplusplus.actions.get_sharable_db_data(tableArray).then( + + localbitcoinplusplus.actions.get_sharable_db_data(tableArray, primarySupernodeOfThisUser).then( function (su_db_data) { if (typeof su_db_data == "object") { su_db_data.trader_flo_address = params.trader_flo_address; @@ -12677,7 +12678,8 @@ .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) .then(server_sync_response=> - doSend(server_sync_response, params.requester_flo_id)); + doSend(server_sync_response)); + //doSend(server_sync_response, params.requester_flo_id)); } }); } @@ -15351,6 +15353,7 @@ } if (res_obj.method==="sync_backup_supernode_from_backup_supernode" || res_obj.method==="sync_primary_supernode_from_backup_supernode_response" + || res_obj.method==="sync_backup_supernode_from_backup_supernode_response" ) { onMessage(response); return; @@ -20159,14 +20162,18 @@ firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); } else { // it will ask backup from backup su next closest - for (let j = index-1; j >= index-localbitcoinplusplus.master_configurations.MaxBackups; j--) { - const nextBKSu = closestSuNodes[j].trader_flo_address; + for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let actual_num = j%index; + const nextBKSu = closestSuNodes[actual_num].trader_flo_address; if (nextBKSu !== idbData.myLocalFLOAddress - && closestSuNodes[index].is_live==true + && closestSuNodes[actual_num].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; + localbitcoinplusplus.actions .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[j].trader_flo_address); + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); } } } @@ -20916,7 +20923,8 @@ // ReadyState was 3 when this node disconnected. Re-initiate the // WS connection to be able to send/receive messages - if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object") { + if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object" + && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState !== 1) { const back_ws_url = localbitcoinplusplus.backupWS[getFLOId].ws_url; localbitcoinplusplus.backupWS[getFLOId] = null; localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); From d23b602db751406a0c4c0d53b1c71b598ef0028a Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 5 Jun 2019 16:37:05 +0530 Subject: [PATCH 36/95] fixed cancel trade button onclick error --- supernode/index.html | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index e7a2d05..4172eaa 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -20283,20 +20283,32 @@ const currency = myOrdersData.currency; const order_type = myOrdersData.order_type; const product = myOrdersData.product; - - //const status = status + const RM_TRADE = new localbitcoinplusplus.trade; + t += `
  • Trade Id: ${trade_id}
  • -
  • Type Of Order: ${order_type}
  • -
  • Product: ${product}
  • -
  • Price: ${price}
  • -
  • Currency: ${currency}
  • -
  • -

  • - `; +
  • Type Of Order: ${order_type}
  • +
  • Product: ${product}
  • +
  • Price: ${price}
  • +
  • Currency: ${currency}
  • +
  • +

  • + `; + }); t += ``; my_trades_div.innerHTML = t; + + var delclassname = document.getElementsByClassName("CANCEL_TRADE"); + + Array.from(delclassname).forEach(function(element) { + element.addEventListener('click', function() { + let cancel_td = this.id; + let trade_opts = cancel_td.split('-'); + RM_TRADE.cancelTrade(trade_opts[0], trade_opts[1], trade_opts[2]); + }); + }); }); } From 9c74aabb7a03d45f7f5d18267064d13203441e22 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 7 Jun 2019 17:13:15 +0530 Subject: [PATCH 37/95] added code for backup node giving dead supernode data to node not neigbours of dead supernode --- supernode/index.html | 47 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 4172eaa..5d99e1e 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15253,7 +15253,7 @@ setTimeout(function() { if ((typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY!=='string' || localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length<1) - ) { + ) { RM_WALLET.manually_assign_my_private_key(); loadExternalFiles(); dataBaseUIOperations(); @@ -15470,7 +15470,6 @@ if(websocket.readyState===1) { - // Meanwhile, request backup supernodes to sync data for down supernode in their resp. db. if (!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { @@ -15493,7 +15492,7 @@ }); } - return Promise.resolve(true) + return Promise.resolve(true); } else { let ms = `Error: Failed to connect to any supernode.`; showMessage(ms) @@ -20991,8 +20990,8 @@ const getSubjectSupernodeDetails = await readDBbyIndex('myClosestSupernodes', 'trader_flo_address', disconnectedWSServerFloId); if (typeof getSubjectSupernodeDetails=="object" && getSubjectSupernodeDetails[0].is_live!==true) { showMessage(`INFO: Connection to primary Supernode failed. Attempting to connect to secondary Supernode.`); - switchMyWS.switchToBackupWS(evt.srcElement.url); - } + switchMyWS.switchToBackupWS(evt.srcElement.url); + } }); }); @@ -21018,6 +21017,44 @@ switchMyWS.updateSupernodeAvailabilityStatus(`ws://${cs[0].ip}:${cs[0].port}`, false); }); + // Find out if you are the next eligible backup supernode, + // If true, send dead su's data to all your backup supernodes + // which are not fallen supernode's backup supernodes to sync + // data from you + const mcs = await readAllDB('myClosestSupernodes'); + const index = mcs.findIndex(f=>f.trader_flo_address==getFLOId); + tail = mcs.splice(0, index); + const newClosestSupernodeMasterList = mcs.concat(tail); + + for(i=0; i<=newClosestSupernodeMasterList.length; i++) { + if(newClosestSupernodeMasterList[i].is_live==true) break; + if(newClosestSupernodeMasterList[i].trader_flo_address== + localbitcoinplusplus.wallets.my_local_flo_address) { + + const nonBackUpSusForDeadSu = newClosestSupernodeMasterList + .filter(function(obj) { return mcs.indexOf(obj) == -1; }); + + console.log(nonBackUpSusForDeadSu); + + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + + localbitcoinplusplus.actions.get_sharable_db_data(tableArray, getFLOId) + .then(function (su_db_data) { + if (typeof su_db_data == "object") { + nonBackUpSusForDeadSu.map(nbs=>{ + su_db_data.trader_flo_address = nbs.trader_flo_address; + su_db_data.receiver_flo_address = nbs.trader_flo_address; + RM_RPC + .send_rpc + .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) + .then(server_sync_response=>doSend(server_sync_response, nbs.trader_flo_address)); + }); + } + }); + break; + } + } + msg = `INFO: Supernode ${getFLOId} left.`; } else { msg = `INFO: User node ${getFLOId} left.`; From 39b511f9f030424c4bff5a97eb228b69243ff64b Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 8 Jun 2019 19:08:09 +0530 Subject: [PATCH 38/95] fixed balance error in validateDepositedBTC --- supernode/index.html | 105 ++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 32 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 5d99e1e..02826a2 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10071,7 +10071,7 @@ RMAssets = `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + #!#validTradingAmount=10,50,100,#!#btcTradeMargin=5000 #!#MaxBackups=2 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, @@ -11369,7 +11369,8 @@ "SYNC_MY_LOCAL_DB_WITH_SUPERNODE_DB" && params.trader_flo_address.length > 0) { const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" + "crypto_balances", "cash_balances", "userPublicData", + "buyOrders", "sellOrders" ]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray).then( function (su_db_data) { @@ -11582,8 +11583,7 @@ params.id = helper_functions.unique_id(); params.status = 1; - params.btc_address = - generate_btc_keys_for_requester.address; + params.btc_address = generate_btc_keys_for_requester.address; params.bitcoinToBePaid = RM_TRADE.calculateCryptoEquivalentOfCash( params.depositing_amount, params.currency, @@ -11609,7 +11609,6 @@ .supernodesPubKeys .includes(su_data.myLocalFLOPublicKey) ) { - let receivedTradeInfoHash = Crypto.SHA256(JSON.stringify(receivedTradeInfo)); @@ -11621,17 +11620,13 @@ receivedTradeInfo["order_validator_public_key"] = su_data.myLocalFLOPublicKey; try { - const this_btc_pvt_key = - generate_btc_keys_for_requester.privateKeyWIF; - const this_btc_tx_key = - Crypto.util.randomBytes(64); - const - this_btc_pvt_key_shamirs_secret = + const this_btc_pvt_key = generate_btc_keys_for_requester.privateKeyWIF; + const this_btc_tx_key = Crypto.util.randomBytes(64); + const this_btc_pvt_key_shamirs_secret = RM_WALLET.createShamirsSecretShares(this_btc_pvt_key, 10, 5); - if (typeof this_btc_pvt_key_shamirs_secret == - "object" && - this_btc_pvt_key_shamirs_secret - .length > 0) { + if (typeof this_btc_pvt_key_shamirs_secret == "object" + && this_btc_pvt_key_shamirs_secret.length > 0) { + addDB("deposit", receivedTradeInfo); // Send the address to the requester @@ -12610,7 +12605,8 @@ "SYNC_MY_LOCAL_DB_WITH_SUPERNODE_DB" && params.trader_flo_address.length > 0) { const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" + "crypto_balances", "cash_balances", "userPublicData", + "buyOrders", "sellOrders" ]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray, primarySupernodeOfThisUser).then( @@ -12638,7 +12634,7 @@ "SYNC_PRIMARY_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > 0) { const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", - "system_btc_reserves_private_keys"]; + "system_btc_reserves_private_keys", "buyOrders", "sellOrders"]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray, params.trader_flo_address).then( function (su_db_data) { @@ -12664,7 +12660,8 @@ if (is_valid_request === true && params.job == "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > 0) { - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", + "buyOrders", "sellOrders"]; let rec_flo_id = (params.receiver_flo_address==params.trader_flo_address) ? "" : params.trader_flo_address; @@ -12985,12 +12982,7 @@ let chunk_ids = Crypto.util - .bytesToHex( - Crypto - .util - .randomBytes( - 64 - )); + .bytesToHex(Crypto.util.randomBytes(64)); let chunk_array = { "id": chunk_ids, @@ -14287,6 +14279,31 @@ !localbitcoinplusplus.master_configurations.tradableAsset2.includes(currency_code)) return false; let new_price = 1000000; + if (crypto_code=="BTC" && currency_code=="USD") { + new_price = 8000; + } + if (crypto_code=="BTC_TEST" && currency_code=="USD") { + new_price = 8000; + } + if (crypto_code=="BTC" && currency_code=="INR") { + new_price = 600000; + } + if (crypto_code=="BTC_TEST" && currency_code=="INR") { + new_price = 600000; + } + if (crypto_code=="FLO" && currency_code=="USD") { + new_price = 0.08; + } + if (crypto_code=="FLO_TEST" && currency_code=="USD") { + new_price = 0.08; + } + if (crypto_code=="FLO" && currency_code=="INR") { + new_price = 2.5; + } + if (crypto_code=="FLO_TEST" && currency_code=="INR") { + new_price = 2.5; + } + /************************** Fetch latest rates here ***************************/ @@ -14296,6 +14313,26 @@ // } else if(crypto_code=="FLO" || crypto_code=="FLO_TEST") { // new_price = (currency_code=="USD") ? 0.08 : 5.8; // } + + // fetch(`https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest`, { + // method: "POST", // *GET, POST, PUT, DELETE, etc. + // mode: "cors", // no-cors, cors, *same-origin + // cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached + // credentials: "same-origin", // include, *same-origin, omit + // headers: { + // "Content-Type": "application/json", + // 'X-CMC_PRO_API_KEY': 'fe231f8e-6d40-49c8-a22b-231123a7543a' + // }, + // redirect: "follow", // manual, *follow, error + // referrer: "no-referrer", // no-referrer, *client + // body: JSON.stringify({ + // 'start': '1', + // 'limit': '1', + // 'convert': 'USD,BTC' + // }), // body data type must match "Content-Type" header + // }) + // .then(response => response.json()); // parses response to JSON + Object.defineProperty(localbitcoinplusplus.trade, `current_${crypto_code}_price_in_${currency_code}`, { value: { @@ -16409,7 +16446,8 @@ // if (is_valid_request === true) { let data = res_obj.params[0]; const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" + "crypto_balances", "cash_balances", "userPublicData", + "buyOrders", "sellOrders" ]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray) .then(function (su_db_data) { @@ -17808,7 +17846,8 @@ // if (is_valid_request === true) { let data = res_obj.params[0]; const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" + "crypto_balances", "cash_balances", "userPublicData", + "buyOrders", "sellOrders" ]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray) .then(function (su_db_data) { @@ -18183,7 +18222,8 @@ const requester_supernode_flo_address = received_resp.trader_flo_address; const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", - "crypto_balances", "cash_balances", "userPublicData" + "crypto_balances", "cash_balances", "userPublicData", + "buyOrders", "sellOrders" ]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray).then( function (su_db_data) { @@ -20804,8 +20844,7 @@ /************************ Case of dispute *****************/ - if (0) { - //if (trader_deposits.bitcoinToBePaid - balance > localbitcoinplusplus.master_configurations.btcTradeMargin) { + if (trader_deposits.bitcoinToBePaid - balance > localbitcoinplusplus.master_configurations.btcTradeMargin) { console.log(trader_deposits.bitcoinToBePaid, balance, localbitcoinplusplus.master_configurations .btcTradeMargin); console.warn("User sent less cryptos"); @@ -20838,8 +20877,9 @@ crypto_currency: trader_deposits.product } _readDB('crypto_balances', trader_depositor_cash_id).then(function (res_btc_balances) { - if (typeof res_btc_balances == "object" && typeof res_btc_balances.result == - "object" && typeof res_btc_balances.crypto_balance == "number") { + if (typeof res_btc_balances == "object" + //&& typeof res_btc_balances.result == "object" + && typeof res_btc_balances.crypto_balance == "number") { updatedCryptobalances.crypto_balance = Number(parseFloat(res_btc_balances .crypto_balance + updatedCryptobalances.crypto_balance)); } @@ -21036,7 +21076,8 @@ console.log(nonBackUpSusForDeadSu); - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances"]; + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances" + , "crypto_balances", "buyOrders", "sellOrders"]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray, getFLOId) .then(function (su_db_data) { From 3ce1eb2a99b477391283d2b42eb1723624ca44cf Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 9 Jun 2019 19:03:08 +0530 Subject: [PATCH 39/95] fixed code to reconnect to new supernode when a eligible supernode comes back as primary or backup primary --- supernode/index.html | 157 ++++++++++++++++++++++++++++--------------- 1 file changed, 103 insertions(+), 54 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 02826a2..28a897a 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10071,7 +10071,7 @@ RMAssets = `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - #!#validTradingAmount=10,50,100,#!#btcTradeMargin=5000 + #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 #!#MaxBackups=2 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, @@ -16661,8 +16661,8 @@ .call(this, "reconnect_with_another_supernode", { "trader_flo_address": su_db_data.trader_flo_address, //"receiver_flo_address": "", // message for all - "ws_url": websocket.url, - "server_msg": `Your primary Supernode is live and synced. You can start using the system.`, + //"ws_url": websocket.url, + "server_msg": `Your primary/secondary Supernode is live and synced. You can start using the system.`, }).then(server_response=>doSend(server_response)); }); @@ -16743,19 +16743,36 @@ break; case "reconnect_with_another_supernode": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - let su_db_data = res_obj.params[0]; - const RM_RPC = new localbitcoinplusplus.rpc; - RM_RPC.filter_legit_requests(su_db_data.trader_flo_address, - async function (is_valid_request) { - if (is_valid_request!==true) return; + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey) + ) { + (async function() { + let su_db_data = res_obj.params[0]; + const MCS = await localbitcoinplusplus.kademlia.determineClosestSupernode(su_db_data.trader_flo_address, 10); + + // If user is already connected to primary return back + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == MCS[0].data.id) return; + + // If user is already connected to given Supernode return + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == su_db_data.trader_flo_address) return; + + const mcslist = MCS.map(m=>m.data.id); + + if(mcslist.indexOf(su_db_data.trader_flo_address) < mcslist.indexOf(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS)) { if (websocket.readyState === WebSocket.OPEN) { websocket.close(); - await startWebSocket(su_db_data.ws_url); - showMssage(`INFO: ${su_db_data.server_msg}`); + const newSu = await readDBbyIndex('myClosestSupernodes','trader_flo_address', su_db_data.trader_flo_address); + if (typeof newSu=="object" && typeof newSu[0].trader_flo_address=="string") { + await startWebSocket(`ws://${newSu[0].ip}:${newSu[0].port}`); + showMssage(`INFO: ${su_db_data.server_msg}`); + } else { + alert(`INFO: Please reload the page.`); + } } } - ); + + })(); } break; @@ -18158,6 +18175,40 @@ } break; + case "reconnect_with_another_supernode": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey) + ) { + (async function() { + let su_db_data = res_obj.params[0]; + const MCS = await localbitcoinplusplus.kademlia.determineClosestSupernode(su_db_data.trader_flo_address, 10); + + // If user is already connected to primary return back + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == MCS[0].data.id) return; + + // If user is already connected to given Supernode return + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == su_db_data.trader_flo_address) return; + + const mcslist = MCS.map(m=>m.data.id); + + if(mcslist.indexOf(su_db_data.trader_flo_address) < mcslist.indexOf(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS)) { + if (websocket.readyState === WebSocket.OPEN) { + websocket.close(); + const newSu = await readDBbyIndex('myClosestSupernodes','trader_flo_address', su_db_data.trader_flo_address); + if (typeof newSu=="object" && typeof newSu[0].trader_flo_address=="string") { + await startWebSocket(`ws://${newSu[0].ip}:${newSu[0].port}`); + showMssage(`INFO: ${su_db_data.server_msg}`); + } else { + alert(`INFO: Please reload the page.`); + } + } + } + + })(); + } + break; + default: break; } @@ -20175,50 +20226,48 @@ wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - if (typeof idbData.lastConnectedSupernode == "string" - && idbData.lastConnectedSupernode !== wsUri[0].trader_flo_address) { - showMessage(`INFO: We are fetching your latest data. This could take some time. Do not close the window until then.`); - - // Get data for deposits and withdraw starting from first (and currently alive) backup supernode - let closestSuNodes = await readAllDB('myClosestSupernodes'); - let firstAliveBackupFloIdForPrimarySupernode; - - for (let index = 1; index <= closestSuNodes.length-1; index++) { - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { - firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); - } - } - - // Update backup db as well for all supernodes you're serving as backup - for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { - let firstAliveBackupFloIdForBackupSupernode; - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - } else { - // it will ask backup from backup su next closest - for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { - let actual_num = j%index; - const nextBKSu = closestSuNodes[actual_num].trader_flo_address; - if (nextBKSu !== idbData.myLocalFLOAddress - && closestSuNodes[actual_num].is_live==true - && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; - - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - } - } - } - } + showMessage(`INFO: Syncing of latest data starting. This could take some time. Do not close the window until then.`); + + // Get data for deposits and withdraw starting from first (and currently alive) backup supernode + let closestSuNodes = await readAllDB('myClosestSupernodes'); + let firstAliveBackupFloIdForPrimarySupernode; + + for (let index = 1; index <= closestSuNodes.length-1; index++) { + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { + firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); + } } + + // Update backup db as well for all supernodes you're serving as backup + for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { + let firstAliveBackupFloIdForBackupSupernode; + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + } else { + // it will ask backup from backup su next closest + for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let actual_num = j%index; + const nextBKSu = closestSuNodes[actual_num].trader_flo_address; + if (nextBKSu !== idbData.myLocalFLOAddress + && closestSuNodes[actual_num].is_live==true + && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; + + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + } + } + } + } + } if (!localbitcoinplusplus.master_configurations.supernodesPubKeys From 4b601ceec68971f41d322d84cbbc83f714647c18 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 13 Jun 2019 12:53:13 +0530 Subject: [PATCH 40/95] fixed minor stuffs --- supernode/index.html | 57 ++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 28a897a..79371e2 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -16881,10 +16881,11 @@ && res_obj.method !== "send_back_shamirs_secret_btc_pvtkey" && res_obj.method !== "send_back_shamirs_secret_supernode_pvtkey" && res_obj.method !== "store_shamirs_secret_pvtkey_shares" + && res_obj.method !== "retrieve_shamirs_secret_supernode_pvtkey" ) { if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); @@ -18175,39 +18176,39 @@ } break; - case "reconnect_with_another_supernode": - if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" - && localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(res_obj.nodePubKey) - ) { - (async function() { - let su_db_data = res_obj.params[0]; - const MCS = await localbitcoinplusplus.kademlia.determineClosestSupernode(su_db_data.trader_flo_address, 10); - - // If user is already connected to primary return back - if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == MCS[0].data.id) return; + case "reconnect_with_another_supernode": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey) + ) { + (async function() { + let su_db_data = res_obj.params[0]; + const MCS = await localbitcoinplusplus.kademlia.determineClosestSupernode(su_db_data.trader_flo_address, 10); + + // If user is already connected to primary return back + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == MCS[0].data.id) return; - // If user is already connected to given Supernode return - if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == su_db_data.trader_flo_address) return; + // If user is already connected to given Supernode return + if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == su_db_data.trader_flo_address) return; - const mcslist = MCS.map(m=>m.data.id); + const mcslist = MCS.map(m=>m.data.id); - if(mcslist.indexOf(su_db_data.trader_flo_address) < mcslist.indexOf(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS)) { - if (websocket.readyState === WebSocket.OPEN) { - websocket.close(); - const newSu = await readDBbyIndex('myClosestSupernodes','trader_flo_address', su_db_data.trader_flo_address); - if (typeof newSu=="object" && typeof newSu[0].trader_flo_address=="string") { - await startWebSocket(`ws://${newSu[0].ip}:${newSu[0].port}`); - showMssage(`INFO: ${su_db_data.server_msg}`); - } else { - alert(`INFO: Please reload the page.`); - } + if(mcslist.indexOf(su_db_data.trader_flo_address) < mcslist.indexOf(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS)) { + if (websocket.readyState === WebSocket.OPEN) { + websocket.close(); + const newSu = await readDBbyIndex('myClosestSupernodes','trader_flo_address', su_db_data.trader_flo_address); + if (typeof newSu=="object" && typeof newSu[0].trader_flo_address=="string") { + await startWebSocket(`ws://${newSu[0].ip}:${newSu[0].port}`); + showMssage(`INFO: ${su_db_data.server_msg}`); + } else { + alert(`INFO: Please reload the page.`); } } + } - })(); - } - break; + })(); + } + break; default: break; From 43b04bbe1dba06c2f6293104d502cbd5744a4c49 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 14 Jun 2019 17:52:22 +0530 Subject: [PATCH 41/95] modified primary or backup syncing to be based on vector clock --- supernode/index.html | 190 ++++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 92 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 79371e2..f393053 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10071,7 +10071,7 @@ RMAssets = `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + #!#validTradingAmount=10,50,100,#!#btcTradeMargin=5000 #!#MaxBackups=2 #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, @@ -12336,75 +12336,32 @@ withdraw_res.currency, withdraw_res.change_adress, async function (res) { - console.log( - res - ); - if (typeof res == - "string" && - res.length > - 0) { + console.log(res); + if (typeof res == "string" + && res.length > 0) { try { - let - resp_obj = - JSON - .parse( - res - ); - let - resp_txid = - resp_obj - .txid - .result || - resp_obj - .txid; - let - msg = + let resp_obj = JSON.parse(res); + let resp_txid = resp_obj.txid.result || resp_obj.txid; + let msg = `Transaction Id for your withdrawn crypto asset: ${resp_txid}`; - readDB - ( - 'crypto_balances', - withdraw_res - .id - ) + readDB('crypto_balances', withdraw_res.id) .then( res_bal => { // btc_eq_receiving_amount // = // Number(parseFloat(EqCryptoWd).toFixed(8)); - res_bal - .crypto_balance -= - EqCryptoWd; - updateinDB - ( - 'crypto_balances', - res_bal, - withdraw_res - .id - ) - .then( - res_obj => { - const - res_obj_str = - JSON - .stringify( - res_obj - ); - const - res_obj_hash = - Crypto - .SHA256( - res_obj_str - ); - const - res_obj_sign = - RM_WALLET - .sign( - res_obj_hash, - localbitcoinplusplus - .wallets - .MY_SUPERNODE_PRIVATE_KEY - ); + res_bal.crypto_balance -= EqCryptoWd; + updateinDB('crypto_balances', res_bal, withdraw_res.id) + .then(res_obj => { + const res_obj_str = JSON.stringify(res_obj); + const res_obj_hash = Crypto.SHA256(res_obj_str); + const res_obj_sign = RM_WALLET .sign( + res_obj_hash, + localbitcoinplusplus + .wallets + .MY_SUPERNODE_PRIVATE_KEY + ); const updateUserCryptoBalanceObject = { @@ -14414,7 +14371,7 @@ trx.addoutput(change_adress, change_amount); } var sendFloData = - `localbitcoinpluslus tx: Send ${btc_eq_receiving_amount} satoshis to ${receiver_address}.`; //flochange adding place for flodata -- need a validation of 1024 chars + `localbitcoinpluslus tx: Send ${btc_eq_receiving_amount} ${crypto_type} to ${receiver_address}.`; //flochange adding place for flodata -- need a validation of 1024 chars if (crypto_type == "FLO" || crypto_type == "FLO_TEST") { trx.addflodata(sendFloData); // flochange .. create this function } @@ -14424,7 +14381,8 @@ let signedTxHash = trx.sign(utxo_addr_wif, 1); //SIGHASH_ALL DEFAULT 1 showMessage(`Signed Transaction Hash: ${signedTxHash}`); - + console.log(signedTxHash); + var http = new XMLHttpRequest(); var tx_send_url = `${blockchain_explorer}/api/tx/send`; var params = `{"rawtx":"${signedTxHash}"}`; @@ -15601,13 +15559,11 @@ try { var res_obj = JSON.parse(res); - if (typeof res_obj.method !== "string" - || typeof res_obj.globalParams !== "object" - || typeof res_obj.globalParams.receiverFloId !== "string" - || res_obj.globalParams.receiverFloId !== - localbitcoinplusplus.wallets.my_local_flo_address) { - console.warn(`WARNING: Incomplete onMessage request received.`); - //return; + if (typeof res_obj.globalParams !== "object" + || (typeof res_obj.globalParams.receiverFloId == "string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address)) { + return; } const isIncomingMessageValid = await validateIncomingMessage(res); @@ -16624,10 +16580,11 @@ if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - await updateinDB(tableStoreName, obj[prop], obj[ - prop].trader_flo_address).then(()=>{ - showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); - }); + //if(obj[prop].) + await updateinDB(tableStoreName, obj[prop], obj[prop].id, true) + .then(()=>{ + showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); + }); } } } else { @@ -16712,8 +16669,8 @@ for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] - .backup_updateinDB(tableStoreName, obj[prop], obj[prop] - .trader_flo_address).then(()=>{ + .backup_updateinDB(tableStoreName, obj[prop], obj[prop].id, true) + .then(()=>{ showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); }); } @@ -17223,6 +17180,8 @@ if(typeof res_obj.globalParams.primarySupernode !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) .then(my_closest_su_list=>{ + console.log(my_closest_su_list); + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; @@ -17732,7 +17691,7 @@ doSend(JSON.stringify(response_from_sever)); // send response to client break; - case "updateUserCryptoBalanceRequest": + case "updateUserCryptoBalanceRequest": if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { let updateUserCryptoBalanceResponseObject = res_obj.params[0]; @@ -19031,7 +18990,7 @@ if (!obj.hasOwnProperty(prop)) continue; await localbitcoinplusplus.newBackupDatabase.db[su_db_data.trader_flo_address] .backup_updateinDB(tableStoreName, obj[prop], obj[prop] - .trader_flo_address).then(()=>{ + .id, true).then(()=>{ showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); }); } @@ -19611,7 +19570,9 @@ } } - async function updateinDB(tablename, Obj, key) { + async function updateinDB(tablename, Obj, key, updateByVectorClock=false) { + // updateByVectorClock==true will not return Obj back. + // Return value will be undefined try { if(typeof Obj.vectorClock == "undefined") { Obj.vectorClock = 0; @@ -19623,9 +19584,32 @@ } var request = db.transaction([tablename], "readwrite") let store = request.objectStore(tablename) - await store.put(Obj); - await request.complete; - return Obj; + if (updateByVectorClock===true) { + if (typeof key=="undefined") { + key = Obj[store.keyPath]; + } + let objectStoreRequest = store.get(key); + objectStoreRequest.onsuccess = + function(event) { + var myRecord = objectStoreRequest.result; + if(typeof myRecord !=="object") { + console.error('WARNING: Failed to update '+tablename); + console.log(tablename); + return; + } + if (myRecord.vectorClock+1 < Obj.vectorClock) { + await store.put(Obj); + await request.complete; + resolve(Obj); + } + } + + } else { + await store.put(Obj); + await request.complete; + return Obj; + } + } catch (error) { return new Error(error); } @@ -19947,7 +19931,7 @@ } }, - async backup_updateinDB(tablename, Obj, key) { + async backup_updateinDB(tablename, Obj, key, updateByVectorClock=false) { try { if(typeof Obj.vectorClock == "undefined") { Obj.vectorClock = 0; @@ -19959,9 +19943,30 @@ } this.request = this.db.transaction([tablename], "readwrite") let store = this.request.objectStore(tablename) - await store.put(Obj); - await this.request.complete; - return Obj; + + if (updateByVectorClock===true) { + if (typeof key=="undefined") { + key = Obj[store.keyPath]; + } + let objectStoreRequest = store.get(key); + objectStoreRequest.onsuccess = + function(event) { + return new Promise(async (resolve, reject)=>{ + var myRecord = objectStoreRequest.result; + if (myRecord.vectorClock+1 < Obj.vectorClock) { + await store.put(Obj); + await this.request.complete; + resolve(Obj); + } + }) + } + + } else { + await store.put(Obj); + await this.request.complete; + return Obj; + } + } catch (error) { return new Error(error); } @@ -20940,14 +20945,15 @@ const RM_WALLET = new localbitcoinplusplus.wallets; const RM_RPC = new localbitcoinplusplus.rpc; - let updatedBTCBalanceObjectString = JSON.stringify( - updatedCryptobalances); - let updatedBTCBalanceObjectSign = RM_WALLET - .sign(updatedBTCBalanceObjectString, + const updatedBTCBalanceObjectString = JSON.stringify(updatedCryptobalances); + const updatedBTCBalanceObjectStringHash = Crypto.SHA256(updatedBTCBalanceObjectString); + + const updatedBTCBalanceObjectSign = RM_WALLET + .sign(updatedBTCBalanceObjectStringHash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY ); - let updateUserCryptoBalanceObject = { + const updateUserCryptoBalanceObject = { updatedBTCBalanceObject: updatedBTCBalanceObject, updatedBTCBalanceObjectSign: updatedBTCBalanceObjectSign, trader_flo_address: trader_deposits.trader_flo_address, From 738192720d3734529781e78350c26952eb14d808 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 16 Jun 2019 18:18:51 +0530 Subject: [PATCH 42/95] fixed seection of supernodes for getting backup for backup supernodes --- supernode/index.html | 107 ++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index f393053..800ad20 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11503,7 +11503,7 @@ params.trader_flo_address, params.product, params.currency); if (typeof trade_margin.remaining_crypto_credit == "number" && typeof trade_margin.remaining_fiat_credit == "number") { - let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash(params.buy_price); + let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash(params.buy_price, params.currency, params.product); if (trade_margin.remaining_crypto_credit > 0 && trade_margin.remaining_crypto_credit >= eqCrypto) { request.response = RM_TRADE.trade_sell.call( @@ -11939,7 +11939,7 @@ if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product)) { let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( - params.withdrawing_amount); + params.withdrawing_amount, params.currency, params.product); if (trade_margin.remaining_crypto_credit < 0 && trade_margin.remaining_crypto_credit < eqCrypto) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` @@ -11985,7 +11985,7 @@ eqBTC = Number(parseFloat(eqBTC).toFixed(8)); let withdrawer_new_btc_balance = withdrawer_btc_balance - eqBTC; - if (withdrawer_new_btc_balance > 0 && + if (withdrawer_new_btc_balance >= 0 && withdrawer_btc_balance > 0 && withdrawing_btc_amount_in_cash > 0 && eqBTC > 0 && eqBTC <= @@ -12780,7 +12780,7 @@ params.trader_flo_address, params.product, params.currency, primarySupernodeForThisUser); if (typeof trade_margin.remaining_crypto_credit == "number" && typeof trade_margin.remaining_fiat_credit == "number") { - let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash(params.buy_price); + let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash(params.buy_price, params.currency, params.product); if (trade_margin.remaining_crypto_credit > 0 && trade_margin.remaining_crypto_credit >= eqCrypto) { request.response = RM_TRADE.trade_sell.call( @@ -13229,7 +13229,7 @@ if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product)) { let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( - params.withdrawing_amount); + params.withdrawing_amount, params.currency, params.product); if (trade_margin.remaining_crypto_credit < 0 && trade_margin.remaining_crypto_credit < eqCrypto) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` @@ -13275,7 +13275,7 @@ eqBTC = Number(parseFloat(eqBTC).toFixed(8)); let withdrawer_new_btc_balance = withdrawer_btc_balance - eqBTC; - if (withdrawer_new_btc_balance > 0 && + if (withdrawer_new_btc_balance >= 0 && withdrawer_btc_balance > 0 && withdrawing_btc_amount_in_cash > 0 && eqBTC > 0 && eqBTC <= @@ -18151,14 +18151,14 @@ if (localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS == su_db_data.trader_flo_address) return; const mcslist = MCS.map(m=>m.data.id); - +95 if(mcslist.indexOf(su_db_data.trader_flo_address) < mcslist.indexOf(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS)) { if (websocket.readyState === WebSocket.OPEN) { websocket.close(); const newSu = await readDBbyIndex('myClosestSupernodes','trader_flo_address', su_db_data.trader_flo_address); if (typeof newSu=="object" && typeof newSu[0].trader_flo_address=="string") { await startWebSocket(`ws://${newSu[0].ip}:${newSu[0].port}`); - showMssage(`INFO: ${su_db_data.server_msg}`); + showMessage(`INFO: ${su_db_data.server_msg}`); } else { alert(`INFO: Please reload the page.`); } @@ -19590,17 +19590,18 @@ } let objectStoreRequest = store.get(key); objectStoreRequest.onsuccess = - function(event) { + async function(event) { var myRecord = objectStoreRequest.result; if(typeof myRecord !=="object") { - console.error('WARNING: Failed to update '+tablename); - console.log(tablename); - return; - } - if (myRecord.vectorClock+1 < Obj.vectorClock) { + Obj.vectorClock = 1; await store.put(Obj); await request.complete; - resolve(Obj); + return Obj; + } + else if (myRecord.vectorClock+1 < Obj.vectorClock) { + await store.put(Obj); + await request.complete; + return Obj; } } @@ -19941,6 +19942,7 @@ } else { Obj.vectorClock += 1; } + let that = this; this.request = this.db.transaction([tablename], "readwrite") let store = this.request.objectStore(tablename) @@ -19953,17 +19955,25 @@ function(event) { return new Promise(async (resolve, reject)=>{ var myRecord = objectStoreRequest.result; - if (myRecord.vectorClock+1 < Obj.vectorClock) { + var myRecord = objectStoreRequest.result; + if(typeof myRecord !=="object") { + Obj.vectorClock = 1; await store.put(Obj); - await this.request.complete; + await that.request.complete; + resolve(Obj); + return; + } + else if (myRecord.vectorClock+1 < Obj.vectorClock) { + await store.put(Obj); + await that.request.complete; resolve(Obj); } - }) + }); } } else { await store.put(Obj); - await this.request.complete; + await that.request.complete; return Obj; } @@ -20247,32 +20257,45 @@ } } - // Update backup db as well for all supernodes you're serving as backup - for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { - let firstAliveBackupFloIdForBackupSupernode; - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - } else { - // it will ask backup from backup su next closest - for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { - let actual_num = j%index; - const nextBKSu = closestSuNodes[actual_num].trader_flo_address; - if (nextBKSu !== idbData.myLocalFLOAddress - && closestSuNodes[actual_num].is_live==true - && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; + // Let current live status be recorded in DB + localbitcoinplusplus.actions.delay(5000).then(()=>{ + // Update backup db as well for all supernodes you're serving as backup + for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { + let firstAliveBackupFloIdForBackupSupernode; + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + + } else { + // it will ask backup from backup su next closest + for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let actual_num = j; + if(actual_num>=closestSuNodes.length-1) { + actual_num = j%index + } else { + actual_num = j+1; + } + const nextBKSu = closestSuNodes[actual_num].trader_flo_address; + if (nextBKSu !== idbData.myLocalFLOAddress + && closestSuNodes[actual_num].is_live==true + && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; + + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + + } } - } + } } - } + + }); + } From 2cf168039a2323682e911212f7944ce82edabde7 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 17 Jun 2019 17:43:03 +0530 Subject: [PATCH 43/95] added new field receiversList in global params --- supernode/index.html | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 800ad20..d484eb1 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11272,16 +11272,27 @@ request.globalParams.senderFloId = resObj.myLocalFLOAddress; if (typeof params[0].trader_flo_address !=="string") { + const n = localbitcoinplusplus.master_configurations.MaxBackups+1; const my_closest_su = await localbitcoinplusplus.kademlia - .determineClosestSupernode(resObj.myLocalFLOAddress); + .determineClosestSupernode(resObj.myLocalFLOAddress, n); + if (typeof my_closest_su=="object") { request.globalParams.primarySupernode = my_closest_su[0].data.id; + request.globalParams["receiversList"] = []; + for (let j = 0; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + request.globalParams.receiversList.push(my_closest_su[j].data.id); + } } } } if (typeof params[0].receiver_flo_address == "string") { request.globalParams.receiverFloId = params[0].receiver_flo_address; + if (typeof request.globalParams.receiversList == "object") { + if (!request.globalParams.receiversList.includes(params[0].receiver_flo_address)) { + request.globalParams.receiversList.push(params[0].receiver_flo_address); + } + } } return resolve(request.toString()); @@ -11581,6 +11592,8 @@ let generate_btc_keys_for_requester = RM_WALLET .generateFloKeys(null, params.product); + console.table(generate_btc_keys_for_requester); + params.id = helper_functions.unique_id(); params.status = 1; params.btc_address = generate_btc_keys_for_requester.address; @@ -12859,6 +12872,8 @@ let generate_btc_keys_for_requester = RM_WALLET .generateFloKeys(null, params.product); + console.table(generate_btc_keys_for_requester); + params.id = helper_functions.unique_id(); params.status = 1; params.btc_address = @@ -15560,11 +15575,10 @@ var res_obj = JSON.parse(res); if (typeof res_obj.globalParams !== "object" - || (typeof res_obj.globalParams.receiverFloId == "string" - && res_obj.globalParams.receiverFloId !== - localbitcoinplusplus.wallets.my_local_flo_address)) { - return; - } + || (typeof res_obj.globalParams.receiversList == "object" + && !request.globalParams.receiversList + .includes(localbitcoinplusplus.wallets.my_local_flo_address) + )) return; const isIncomingMessageValid = await validateIncomingMessage(res); console.log("isIncomingMessageValid: ", isIncomingMessageValid); @@ -16811,11 +16825,11 @@ try { var res_obj = JSON.parse(res); - // if (typeof res_obj.globalParams.receiverFloId=="string" - // && res_obj.globalParams.receiverFloId !== - // localbitcoinplusplus.wallets.my_local_flo_address) { - // return; - // } + if (typeof res_obj.globalParams !== "object" + || (typeof res_obj.globalParams.receiversList == "object" + && !request.globalParams.receiversList + .includes(localbitcoinplusplus.wallets.my_local_flo_address) + )) return; // Check if request is from primary user or backup user // If request is from backup user, divert the request to backup onmessage event From 0c7abd21bb91317116e220febe62cbb172e61b17 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 18 Jun 2019 16:04:15 +0530 Subject: [PATCH 44/95] changed getUserPublicKey function to readDB to get userPublicData in deposit_asset_request in backup_receive_rpc_response --- supernode/index.html | 676 ++++++++++++++++++++++--------------------- 1 file changed, 339 insertions(+), 337 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d484eb1..d9cef87 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10348,8 +10348,8 @@ } Promise.all(promises).then(cs=>{ - let isPreviousSupernodesLive = cs.map((su_status, index)=> - (typeof su_status[index] !== "object" || su_status[index].is_live == true ) + let isPreviousSupernodesLive = cs.map((su_status)=> + (typeof su_status[0] !== "object" || su_status[0].is_live == true ) ); if (!isPreviousSupernodesLive.includes(true)) { @@ -12833,7 +12833,7 @@ // already processed above break; case "deposit_asset_request": - RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { + RM_RPC.filter_legit_backup_requests(params.trader_flo_address, async function (is_valid_request) { if (is_valid_request !== true) return false; @@ -12853,355 +12853,357 @@ typeof params.trader_flo_address == "string" && params.trader_flo_address.length > 0 ) { - RM_WALLET.getUserPublicKey(params.trader_flo_address, - async function (requester_public_key) { - if (requester_public_key == undefined || - requester_public_key == null) { - err_msg = 'Failed to get public key of the user.'; + const requester_public_req = await backup_server_db_instance + .backup_readDB('userPublicData', params.trader_flo_address); + if (typeof requester_public_req!=="object") return; + const requester_public_key = requester_public_req.trader_flo_pubKey; + + if (typeof requester_public_key == "undefined" || + requester_public_key == null) { + err_msg = 'Failed to get public key of the user.'; + showMessage(err_msg); + throw new Error(err_msg); + } + params.depositor_public_key = requester_public_key; + + await RM_TRADE.resolve_current_crypto_price_in_fiat( + params.product, params.currency); + + if (localbitcoinplusplus.master_configurations.tradableAsset1 + .includes(params.product)) { + + let generate_btc_keys_for_requester = RM_WALLET + .generateFloKeys(null, params.product); + + console.table(generate_btc_keys_for_requester); + + params.id = helper_functions.unique_id(); + params.status = 1; + params.btc_address = + generate_btc_keys_for_requester.address; + + params.bitcoinToBePaid = RM_TRADE.calculateCryptoEquivalentOfCash( + params.depositing_amount, params.currency, + params.product); + + let receivedTradeInfo = { ...params }; + + if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == + "undefined") { + err_msg = 'Failed to determine Super node signing key.'; showMessage(err_msg); throw new Error(err_msg); } - params.depositor_public_key = requester_public_key; - await RM_TRADE.resolve_current_crypto_price_in_fiat( - params.product, params.currency); + readDB("localbitcoinUser", "00-01").then( + function (su_data) { + if (typeof su_data == "object" && + typeof su_data.myLocalFLOPublicKey == + "string" && + su_data.myLocalFLOPublicKey.length > + 0 && + localbitcoinplusplus.master_configurations + .supernodesPubKeys + .includes(su_data.myLocalFLOPublicKey) + ) { - if (localbitcoinplusplus.master_configurations.tradableAsset1 - .includes(params.product)) { + let receivedTradeInfoHash = + Crypto.SHA256(JSON.stringify(receivedTradeInfo)); - let generate_btc_keys_for_requester = RM_WALLET - .generateFloKeys(null, params.product); + receivedTradeInfo["depositDataHash"] = receivedTradeInfoHash; + receivedTradeInfo["order_validator_sign"] = + RM_WALLET.sign(receivedTradeInfoHash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + receivedTradeInfo["order_validator_public_key"] = su_data.myLocalFLOPublicKey; - console.table(generate_btc_keys_for_requester); + try { + const this_btc_pvt_key = + generate_btc_keys_for_requester.privateKeyWIF; + const this_btc_tx_key = + Crypto.util.randomBytes(64); + const + this_btc_pvt_key_shamirs_secret = + RM_WALLET.createShamirsSecretShares(this_btc_pvt_key, 10, 5); + if (typeof this_btc_pvt_key_shamirs_secret == + "object" && + this_btc_pvt_key_shamirs_secret + .length > 0) { + backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); - params.id = helper_functions.unique_id(); - params.status = 1; - params.btc_address = - generate_btc_keys_for_requester.address; - - params.bitcoinToBePaid = RM_TRADE.calculateCryptoEquivalentOfCash( - params.depositing_amount, params.currency, - params.product); - - let receivedTradeInfo = { ...params }; - - if (typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == - "undefined") { - err_msg = 'Failed to determine Super node signing key.'; - showMessage(err_msg); - throw new Error(err_msg); - } - - readDB("localbitcoinUser", "00-01").then( - function (su_data) { - if (typeof su_data == "object" && - typeof su_data.myLocalFLOPublicKey == - "string" && - su_data.myLocalFLOPublicKey.length > - 0 && - localbitcoinplusplus.master_configurations - .supernodesPubKeys - .includes(su_data.myLocalFLOPublicKey) - ) { - - let receivedTradeInfoHash = - Crypto.SHA256(JSON.stringify(receivedTradeInfo)); - - receivedTradeInfo["depositDataHash"] = receivedTradeInfoHash; - receivedTradeInfo["order_validator_sign"] = - RM_WALLET.sign(receivedTradeInfoHash, - localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY - ); - receivedTradeInfo["order_validator_public_key"] = su_data.myLocalFLOPublicKey; - - try { - const this_btc_pvt_key = - generate_btc_keys_for_requester.privateKeyWIF; - const this_btc_tx_key = - Crypto.util.randomBytes(64); - const - this_btc_pvt_key_shamirs_secret = - RM_WALLET.createShamirsSecretShares(this_btc_pvt_key, 10, 5); - if (typeof this_btc_pvt_key_shamirs_secret == - "object" && + // Send the address to the requester + let + deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, + data: receivedTradeInfo + }; + deposit_response_object.receiver_flo_address = params.trader_flo_address; + deposit_response_object.trader_flo_address = params.trader_flo_address; + + RM_RPC + .send_rpc + .call(this, + "deposit_asset_request_response", + deposit_response_object + ).then(deposit_request_response=> + doSend(deposit_request_response)); + + let + this_btc_pvt_key_shamirs_secret_array = this_btc_pvt_key_shamirs_secret - .length > 0) { - backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); + .map(chunks => { + let + chunk_ids = + Crypto.util + .bytesToHex(Crypto.util.randomBytes(64)); + let + chunk_array = { + "id": chunk_ids, + "privateKeyChunks": Crypto + .AES + .encrypt( + chunks, + this_btc_tx_key + ), + "trader_flo_address": params.trader_flo_address + }; + return chunk_array; + }); - // Send the address to the requester - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo - }; - deposit_response_object.receiver_flo_address = params.trader_flo_address; - deposit_response_object.trader_flo_address = params.trader_flo_address; - - RM_RPC - .send_rpc - .call(this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); - - let - this_btc_pvt_key_shamirs_secret_array = - this_btc_pvt_key_shamirs_secret - .map(chunks => { + // Send chunks of private keys to other supernodes + this_btc_pvt_key_shamirs_secret_array + .map(shares => { + RM_RPC + .send_rpc + .call( + this, + "store_shamirs_secret_pvtkey_shares", + shares + ).then(store_pvtkey_req=> + doSend(store_pvtkey_req)); + + }); + + if (typeof localbitcoinplusplus + .wallets.my_local_flo_address == + "string" && + typeof localbitcoinplusplus + .wallets.my_local_flo_public_key == + "string" && + typeof localbitcoinplusplus + .master_configurations + .supernodesPubKeys == + "object" && + localbitcoinplusplus + .master_configurations + .supernodesPubKeys.includes( + localbitcoinplusplus + .wallets.my_local_flo_public_key + )) { + try { + let + this_btc_pvt_key_shamirs_secret__id_array = + this_btc_pvt_key_shamirs_secret_array + .map(i => i.id); + let + btc_private_key_shamirs_id = + this_btc_pvt_key_shamirs_secret__id_array; + let + supernode_transaction_key = + this_btc_tx_key; + const + system_btc_reserves_private_keys_object = { + id: helper_functions + .unique_id(), + product: params + .product, + btc_address: params + .btc_address, + balance: null, + trader_flo_address: params + .trader_flo_address, + btc_private_key_shamirs_id: btc_private_key_shamirs_id, + supernode_transaction_key: supernode_transaction_key + } + backup_server_db_instance.backup_addDB( + "system_btc_reserves_private_keys", + system_btc_reserves_private_keys_object + ); + } catch (error) { + throw new Error( error); + } + } + return true; + } + } catch (error) { + throw new Error(error); + } + + // Send the address to the requester + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, + data: receivedTradeInfo, + receiver_flo_address: params.trader_flo_address, + trader_flo_address: params.trader_flo_address, + }; + + RM_RPC.send_rpc + .call(this, + "deposit_asset_request_response", + deposit_response_object + ).then(deposit_request_response=> + doSend(deposit_request_response)); + return true; + } + }); + + return false; + + } else if (!localbitcoinplusplus.master_configurations + .tradableAsset1.includes(params.product)) { + params.id = helper_functions.unique_id(); + params.status = 1; + // IMPORTANT - If deposit is a fiat make sure product and currency are both same + params.currency = params.product; + let receivedTradeInfo = { ...params }; + + backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( + function (su_data) { + if (typeof su_data == "object" && + typeof su_data.myLocalFLOPublicKey == + "string" && + su_data.myLocalFLOPublicKey.length > + 0 && + localbitcoinplusplus.master_configurations + .supernodesPubKeys + .includes(su_data.myLocalFLOPublicKey) + ) { + let receivedTradeInfoHash = + Crypto.SHA256(JSON.stringify( + receivedTradeInfo)); + + receivedTradeInfo[ + "depositDataHash"] = + receivedTradeInfoHash; + receivedTradeInfo[ + "order_validator_sign"] = + RM_WALLET.sign( + receivedTradeInfoHash, + localbitcoinplusplus.wallets + .MY_SUPERNODE_PRIVATE_KEY + ); + receivedTradeInfo[ + "order_validator_public_key" + ] = su_data.myLocalFLOPublicKey; + + // YOU NEED TO DETERMINE A BANK ACCOUNT HERE IF NO ONE IS WITHDRAWING + try { + backup_server_db_instance.backup_addDB("deposit", + receivedTradeInfo); + backup_server_db_instance.backup_readDBbyIndex( + "withdraw_cash", + "status", 1).then( + function ( + withdrawers_list + ) { + if (typeof withdrawers_list == + "object") { + if ( + withdrawers_list.length > 0) { + withdrawers_list.filter( + wd => wd.currency == + params.currency).map( + function (withdrawer) { + if ( + withdrawer.withdraw_amount == + params.depositing_amount && + withdrawer.currency == + params.currency + ) { + withdrawer.status = 2; // A depositor has been asked to deposit money + withdrawer.depositor_found_at = + new Date(); + withdrawer.depositor_flo_id = receivedTradeInfo.trader_flo_address; + backup_server_db_instance.backup_updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); + + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account + backup_server_db_instance.backup_updateinDB( + "deposit", + receivedTradeInfo, + receivedTradeInfo.trader_flo_address + ); + + let withdrawer_bank_account = withdrawer.receivinAddress; + + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Plese send the money to following bank address: "${withdrawer_bank_account}"`, + data: receivedTradeInfo, + withdrawer_data: withdrawer, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, + }; + + RM_RPC.send_rpc.call( + this, + "deposit_asset_request_response", + deposit_response_object + ).then(deposit_request_response=> + doSend(deposit_request_response)); + return true; + } else { + err_msg = "Deposit request failed: We could not find a withdrawer."; + showMessage(err_msg); + throw new Error(err_msg); + } + } + ); + } else { + //No one is withdrawing so provide your bank details let - chunk_ids = - Crypto.util - .bytesToHex(Crypto.util.randomBytes(64)); - let - chunk_array = { - "id": chunk_ids, - "privateKeyChunks": Crypto - .AES - .encrypt( - chunks, - this_btc_tx_key - ), - "trader_flo_address": params.trader_flo_address + deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Plese send the money to following bank address: "System determined bank".`, + data: receivedTradeInfo, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, }; - return chunk_array; - }); - // Send chunks of private keys to other supernodes - this_btc_pvt_key_shamirs_secret_array - .map(shares => { + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account + updateinDB + ( + "deposit", + receivedTradeInfo, + receivedTradeInfo + .trader_flo_address + ); + RM_RPC .send_rpc .call( this, - "store_shamirs_secret_pvtkey_shares", - shares - ).then(store_pvtkey_req=> - doSend(store_pvtkey_req)); - - }); - - if (typeof localbitcoinplusplus - .wallets.my_local_flo_address == - "string" && - typeof localbitcoinplusplus - .wallets.my_local_flo_public_key == - "string" && - typeof localbitcoinplusplus - .master_configurations - .supernodesPubKeys == - "object" && - localbitcoinplusplus - .master_configurations - .supernodesPubKeys.includes( - localbitcoinplusplus - .wallets.my_local_flo_public_key - )) { - try { - let - this_btc_pvt_key_shamirs_secret__id_array = - this_btc_pvt_key_shamirs_secret_array - .map(i => i.id); - let - btc_private_key_shamirs_id = - this_btc_pvt_key_shamirs_secret__id_array; - let - supernode_transaction_key = - this_btc_tx_key; - const - system_btc_reserves_private_keys_object = { - id: helper_functions - .unique_id(), - product: params - .product, - btc_address: params - .btc_address, - balance: null, - trader_flo_address: params - .trader_flo_address, - btc_private_key_shamirs_id: btc_private_key_shamirs_id, - supernode_transaction_key: supernode_transaction_key - } - backup_server_db_instance.backup_addDB( - "system_btc_reserves_private_keys", - system_btc_reserves_private_keys_object - ); - } catch (error) { - throw new Error( error); + "deposit_asset_request_response", + deposit_response_object + ).then(deposit_request_response=> + doSend(deposit_request_response)); + return true; } } - return true; - } - } catch (error) { - throw new Error(error); - } - - // Send the address to the requester - let deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo, - receiver_flo_address: params.trader_flo_address, - trader_flo_address: params.trader_flo_address, - }; - - RM_RPC.send_rpc - .call(this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); - return true; + }); + } catch (error) { + err_msg = "Deposit request failed: We could not find a withdrawer. Come again later."; + showMessage(err_msg); + throw new Error(err_msg); } - }); - return false; - - } else if (!localbitcoinplusplus.master_configurations - .tradableAsset1.includes(params.product)) { - params.id = helper_functions.unique_id(); - params.status = 1; - // IMPORTANT - If deposit is a fiat make sure product and currency are both same - params.currency = params.product; - let receivedTradeInfo = { ...params }; - - backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( - function (su_data) { - if (typeof su_data == "object" && - typeof su_data.myLocalFLOPublicKey == - "string" && - su_data.myLocalFLOPublicKey.length > - 0 && - localbitcoinplusplus.master_configurations - .supernodesPubKeys - .includes(su_data.myLocalFLOPublicKey) - ) { - let receivedTradeInfoHash = - Crypto.SHA256(JSON.stringify( - receivedTradeInfo)); - - receivedTradeInfo[ - "depositDataHash"] = - receivedTradeInfoHash; - receivedTradeInfo[ - "order_validator_sign"] = - RM_WALLET.sign( - receivedTradeInfoHash, - localbitcoinplusplus.wallets - .MY_SUPERNODE_PRIVATE_KEY - ); - receivedTradeInfo[ - "order_validator_public_key" - ] = su_data.myLocalFLOPublicKey; - - // YOU NEED TO DETERMINE A BANK ACCOUNT HERE IF NO ONE IS WITHDRAWING - try { - backup_server_db_instance.backup_addDB("deposit", - receivedTradeInfo); - backup_server_db_instance.backup_readDBbyIndex( - "withdraw_cash", - "status", 1).then( - function ( - withdrawers_list - ) { - if (typeof withdrawers_list == - "object") { - if ( - withdrawers_list.length > 0) { - withdrawers_list.filter( - wd => wd.currency == - params.currency).map( - function (withdrawer) { - if ( - withdrawer.withdraw_amount == - params.depositing_amount && - withdrawer.currency == - params.currency - ) { - withdrawer.status = 2; // A depositor has been asked to deposit money - withdrawer.depositor_found_at = + new Date(); - withdrawer.depositor_flo_id = receivedTradeInfo.trader_flo_address; - backup_server_db_instance.backup_updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); - - receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - backup_server_db_instance.backup_updateinDB( - "deposit", - receivedTradeInfo, - receivedTradeInfo.trader_flo_address - ); - - let withdrawer_bank_account = withdrawer.receivinAddress; - - let deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "${withdrawer_bank_account}"`, - data: receivedTradeInfo, - withdrawer_data: withdrawer, - receiver_flo_address: receivedTradeInfo.trader_flo_address, - trader_flo_address: receivedTradeInfo.trader_flo_address, - }; - - RM_RPC.send_rpc.call( - this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); - return true; - } else { - err_msg = "Deposit request failed: We could not find a withdrawer."; - showMessage(err_msg); - throw new Error(err_msg); - } - } - ); - } else { - //No one is withdrawing so provide your bank details - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "System determined bank".`, - data: receivedTradeInfo, - receiver_flo_address: receivedTradeInfo.trader_flo_address, - trader_flo_address: receivedTradeInfo.trader_flo_address, - }; - - receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - updateinDB - ( - "deposit", - receivedTradeInfo, - receivedTradeInfo - .trader_flo_address - ); - - RM_RPC - .send_rpc - .call( - this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); - return true; - } - } - }); - } catch (error) { - err_msg = "Deposit request failed: We could not find a withdrawer. Come again later."; - showMessage(err_msg); - throw new Error(err_msg); - } - - } - }); - } - }); + } + }); + } } else { err_msg = "deposit asset request error"; @@ -15576,7 +15578,7 @@ if (typeof res_obj.globalParams !== "object" || (typeof res_obj.globalParams.receiversList == "object" - && !request.globalParams.receiversList + && !res_obj.globalParams.receiversList .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; @@ -16634,7 +16636,8 @@ //"receiver_flo_address": "", // message for all //"ws_url": websocket.url, "server_msg": `Your primary/secondary Supernode is live and synced. You can start using the system.`, - }).then(server_response=>doSend(server_response)); + }) + //.then(server_response=>doSend(server_response)); }); } @@ -16827,7 +16830,7 @@ if (typeof res_obj.globalParams !== "object" || (typeof res_obj.globalParams.receiversList == "object" - && !request.globalParams.receiversList + && !res_obj.globalParams.receiversList .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; @@ -20256,7 +20259,7 @@ wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - + return; showMessage(`INFO: Syncing of latest data starting. This could take some time. Do not close the window until then.`); // Get data for deposits and withdraw starting from first (and currently alive) backup supernode @@ -20954,8 +20957,7 @@ if (typeof reserve_res == "object") { reserve_res.map(reserves => { reserves.balance = balance; - _updateinDB('system_btc_reserves_private_keys', reserves, - reserves.id); + _updateinDB('system_btc_reserves_private_keys', reserves, reserves.id); }); } }); From b6487f1aabab58a9e557e288642e9b735e7001b4 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 19 Jun 2019 17:22:45 +0530 Subject: [PATCH 45/95] fixed various issues in backup --- supernode/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d9cef87..0b78c01 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14577,7 +14577,7 @@ let buyerBTCResponseObject; let buyer_btc_id = `${buyPipeObj.trader_flo_address}_${buyPipeObj.product}`; - _readDB("crypto_balances", buyPipeObj.trader_flo_address).then( + _readDB("crypto_balances", buyer_btc_id).then( function (buyPipeBTCRes) { if (typeof buyPipeBTCRes == "object" && typeof buyPipeBTCRes .crypto_balance == "number") { @@ -14588,7 +14588,7 @@ } else { // The user bought BTC for first time buyerBTCResponseObject = { - id: `${buyPipeObj.trader_flo_address}_${buyPipeObj.product}`, + id: buyer_btc_id, trader_flo_address: buyPipeObj.trader_flo_address, crypto_balance: eqBTCBuyer, crypto_currency: buyPipeObj.product @@ -16865,7 +16865,7 @@ console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - if (ifAllPrevSuAreDead !== true) { + if (ifAllPrevSuAreDead !== true || res_obj.method=='sync_backup_supernode_from_backup_supernode_response') { console.log(res_obj); showMessage(`INFO: "checkIfAllPreviousSupernodesAreDeadForAUserNode" check failed.`); handle_backup_server_messages(response); From a02ea9f383f03e9ccea4656d0c26206fd2f3ebd6 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 21 Jun 2019 17:55:03 +0530 Subject: [PATCH 46/95] fixed deposit, btc reserves storing in backups --- supernode/index.html | 361 ++++++++++++++++++++++++++++++------------- 1 file changed, 257 insertions(+), 104 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 0b78c01..622c960 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12385,12 +12385,11 @@ } RM_RPC - .send_rpc( - "updateUserCryptoBalanceRequest", - updateUserCryptoBalanceObject - ).then(updateUserCryptoBalanceRequestObject=> - doSend(updateUserCryptoBalanceRequestObject)); - + .send_rpc( + "updateUserCryptoBalanceRequest", + updateUserCryptoBalanceObject + ).then(updateUserCryptoBalanceRequestObject=> + doSend(updateUserCryptoBalanceRequestObject)); } ) @@ -12631,7 +12630,7 @@ "SYNC_BACKUP_SUPERNODE_DB_WITH_BACKUP_SUPERNODE_DB" && params.trader_flo_address.length > 0) { const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", - "buyOrders", "sellOrders"]; + "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; let rec_flo_id = (params.receiver_flo_address==params.trader_flo_address) ? "" : params.trader_flo_address; @@ -13694,7 +13693,6 @@ updateUserCryptoBalanceObject ).then(updateUserCryptoBalanceRequestObject=> doSend(updateUserCryptoBalanceRequestObject)); - } ) @@ -14915,8 +14913,17 @@ //proceed only when the second promise is resolved return data; } catch (error) { - showMessage(`WARNING: Failed to get data from ${url}.`); - throw new Error(error); + var xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function() { + if (xhr.status === 200) { + callback(xhr.responseText); + } else { + showMessage(`WARNING: Failed to get data from ${url}.`); + throw new Error(`Request to ${url} failed: ${xhr.status}`); + } + }; + xhr.send(); } }, @@ -16321,7 +16328,33 @@ showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); } } - break; + break; + + case "updateUsertraderDepositsRequest": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + + let updateUserDepositsResponseObject = res_obj.params[0]; + let updateUserDepositsResponseString = JSON.stringify( + updateUserDepositsResponseObject.updatedTraderDepositObject); + let updateUserDepositsResponseStringHash = Crypto.SHA256(updateUserDepositsResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserDepositsResponseStringHash, + updateUserDepositsResponseObject.updatedDepositsObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + updateinDB("deposit", updateUserDepositsResponseObject.updatedTraderDepositObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserDepositsResponseObject.trader_flo_address) { + displayBalances(updateUserDepositsResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } + break; case "addNewKbucketNode": if (!localbitcoinplusplus.master_configurations.supernodesPubKeys @@ -16979,8 +17012,10 @@ if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { let su_db_data = res_obj.params[0]; - if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || - su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" + || su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address + || localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) ) return false; // Only the relevent user node should get response if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; @@ -17735,6 +17770,31 @@ break; + case "updateUsertraderDepositsRequest": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + let updateUserDepositsResponseObject = res_obj.params[0]; + let updateUserDepositsResponseString = JSON.stringify( + updateUserDepositsResponseObject.updatedTraderDepositObject); + let updateUserDepositsResponseStringHash = Crypto.SHA256(updateUserDepositsResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserDepositsResponseStringHash, + updateUserDepositsResponseObject.updatedDepositsObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + updateinDB("deposit", updateUserDepositsResponseObject.updatedTraderDepositObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserDepositsResponseObject.trader_flo_address) { + displayBalances(updateUserDepositsResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } + break; + case "addNewKbucketNode": if (!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; @@ -18272,23 +18332,15 @@ case "server_sync_response": if (typeof res_obj.params !== "object" - || typeof res_obj.params[0] !== "object") return; + || typeof res_obj.params[0] !== "object" + || localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; let su_backup_db_data = res_obj.params[0]; RM_RPC.filter_legit_backup_requests(su_backup_db_data.trader_flo_address, async function (is_valid_request) { if(!is_valid_request) return false; - let getPrimarySuObj = await localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.receiverFloId); - const primarySupernode = getPrimarySuObj[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernode]; - - 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); - }; - (async function () { for (let tableStoreName in su_backup_db_data) { // skip loop if the property is from prototype @@ -18302,17 +18354,17 @@ if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - await backup_server_db_instance.backup_updateinDB(tableStoreName, + await updateinDB(tableStoreName, obj[prop], obj[prop].trader_flo_address); } } } else { - let resdbdata = await backup_server_db_instance.backup_removeAllinDB(tableStoreName); + let resdbdata = await removeAllinDB(tableStoreName); if (resdbdata !== false) { if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - await backup_server_db_instance.backup_addDB(resdbdata, obj[prop]); + await addDB(resdbdata, obj[prop]); } } } @@ -18971,6 +19023,86 @@ break; + case "updateUsertraderDepositsRequest": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + let updateUserDepositsResponseObject = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + }); + + let updateUserDepositsResponseString = JSON.stringify( + updateUserDepositsResponseObject.updatedTraderDepositObject); + let updateUserDepositsResponseStringHash = Crypto.SHA256(updateUserDepositsResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserDepositsResponseStringHash, + updateUserDepositsResponseObject.updatedDepositsObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("deposits", + updateUserDepositsResponseObject.updatedTraderDepositObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserDepositsResponseObject.trader_flo_address) { + displayBalances(updateUserDepositsResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } + break; + + case "updateUserBTCReservesRequest": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + + let updateUserReservesResponseObject = res_obj.params[0]; + + if(typeof res_obj.params[0].trader_flo_address !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + 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); + }; + }); + + let updateUserReservesResponseString = JSON.stringify( + updateUserReservesResponseObject.updatedReservesObject); + let updateUserReservesResponseStringHash = Crypto.SHA256(updateUserReservesResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserReservesResponseStringHash, + updateUserReservesResponseObject.updatedBTCReservesObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("system_btc_reserves_private_keys", updateUserReservesResponseObject.updatedReservesObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserReservesResponseObject.trader_flo_address) { + displayBalances(updateUserReservesResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + } + break; + case "sync_backup_supernode_from_backup_supernode_response": let su_db_data = res_obj.params[0]; // if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || @@ -20256,66 +20388,8 @@ // Check last connected supernode, if not primary then // update the user data from other su first - wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); + //wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); - if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(idbData.myLocalFLOPublicKey)) { - return; - showMessage(`INFO: Syncing of latest data starting. This could take some time. Do not close the window until then.`); - - // Get data for deposits and withdraw starting from first (and currently alive) backup supernode - let closestSuNodes = await readAllDB('myClosestSupernodes'); - let firstAliveBackupFloIdForPrimarySupernode; - - for (let index = 1; index <= closestSuNodes.length-1; index++) { - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { - firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; - localbitcoinplusplus.actions - .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); - } - } - - // Let current live status be recorded in DB - localbitcoinplusplus.actions.delay(5000).then(()=>{ - // Update backup db as well for all supernodes you're serving as backup - for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { - let firstAliveBackupFloIdForBackupSupernode; - if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; - - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - - } else { - // it will ask backup from backup su next closest - for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { - let actual_num = j; - if(actual_num>=closestSuNodes.length-1) { - actual_num = j%index - } else { - actual_num = j+1; - } - const nextBKSu = closestSuNodes[actual_num].trader_flo_address; - if (nextBKSu !== idbData.myLocalFLOAddress - && closestSuNodes[actual_num].is_live==true - && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { - - firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; - - localbitcoinplusplus.actions - .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, - firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); - - } - } - } - } - - }); - - - } - if (!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(idbData.myLocalFLOAddress)) { @@ -21004,6 +21078,48 @@ updateUserCryptoBalanceObject) .then(updateUserCryptoBalanceRequestObject=> doSend(updateUserCryptoBalanceRequestObject)); + + const traderDepositsObjectString = JSON.stringify(trader_deposits); + const traderDepositsObjectStringHash = Crypto.SHA256(traderDepositsObjectString); + + const traderDepositsObjectSign = RM_WALLET + .sign(traderDepositsObjectStringHash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + + const updatedDepositObject = { + updatedTraderDepositObject: trader_deposits, + updatedDepositsObjectSign: traderDepositsObjectSign, + trader_flo_address: trader_deposits.trader_flo_address, + receiver_flo_address: trader_deposits.trader_flo_address + } + + RM_RPC + .send_rpc("updateUsertraderDepositsRequest", + updatedDepositObject) + .then(updateUsertraderDepositsRequestObject=> + doSend(updateUsertraderDepositsRequestObject)); + + const reservesObjectString = JSON.stringify(trader_deposits); + const reservesObjectStringHash = Crypto.SHA256(reservesObjectString); + + const reservesObjectSign = RM_WALLET + .sign(reservesObjectStringHash, + localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY + ); + + const updatedDepositObject = { + updatedReservesObject: trader_deposits, + updatedBTCReservesObjectSign: reservesObjectSign, + trader_flo_address: trader_deposits.trader_flo_address, + receiver_flo_address: trader_deposits.trader_flo_address + } + + RM_RPC + .send_rpc("updateUserBTCReservesRequest", + updatedDepositObject) + .then(reservesObject=> + doSend(reservesObject)); }); @@ -21060,6 +21176,7 @@ reactor.registerEvent('primarySupernodeUpdatingLatestDataForItsUserFromOtherSupernodes'); reactor.registerEvent('nodeIsAlive'); reactor.registerEvent('get_node_status_request'); + reactor.registerEvent('sync_primary_and_backup_db'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -21093,24 +21210,6 @@ switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); showMessage(`INFO: Connected successfully to Supernode: ${evt.srcElement.url}`); console.log("CONNECTED"); - - // let my_local_data = await readDB('localbitcoinUser', '00-01'); - // if (typeof my_local_data == "object" - // && !localbitcoinplusplus.master_configurations.supernodesPubKeys - // .includes(my_local_data.myLocalFLOAddress)) { - // const conn_su_flo_id = await switchMyWS.getFloIdFromWSUrl(evt.srcElement.url); - - // if (typeof conn_su_flo_id == "string") { - // my_local_data.lastConnectedTime = + new Date(); - // //my_local_data.lastConnectedSupernode = conn_su_flo_id; - // updateinDB('localbitcoinUser', my_local_data); - // } else { - // mss = `WARNING: Failed to update current supernode connected status in localbitcoinUser.`; - // showMessage(mss); - // throw new Error(mss); - // } - // } - }); reactor.addEventListener('primary_supernode_down', async function(evt) { @@ -21286,6 +21385,60 @@ }); }); + reactor.addEventlistener('sync_primary_and_backup_db', function() { + if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + + showMessage(`INFO: Syncing of latest data starting. This could take some time. Do not close the window until then.`); + + // Get data for deposits and withdraw starting from first (and currently alive) backup supernode + let closestSuNodes = await readAllDB('myClosestSupernodes'); + let firstAliveBackupFloIdForPrimarySupernode; + + for (let index = 1; index <= closestSuNodes.length-1; index++) { + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForPrimarySupernode !== "string") { + firstAliveBackupFloIdForPrimarySupernode = closestSuNodes[index].trader_flo_address; + localbitcoinplusplus.actions + .sync_primary_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, firstAliveBackupFloIdForPrimarySupernode); + } + } + + // Update backup db as well for all supernodes you're serving as backup + for (let index = closestSuNodes.length-1; index >= closestSuNodes.length-localbitcoinplusplus.master_configurations.MaxBackups; index--) { + let firstAliveBackupFloIdForBackupSupernode; + if (closestSuNodes[index].is_live==true && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[index].trader_flo_address; + + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + + } else { + // it will ask backup from backup su next closest + for (let j = index; j < index+localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let actual_num = j; + if(actual_num>=closestSuNodes.length-1) { + actual_num = j%index + } else { + actual_num = j+1; + } + const nextBKSu = closestSuNodes[actual_num].trader_flo_address; + if (nextBKSu !== localbitcoinplusplus.wallets.my_local_flo_address + && closestSuNodes[actual_num].is_live==true + && typeof firstAliveBackupFloIdForBackupSupernode !== "string") { + + firstAliveBackupFloIdForBackupSupernode = closestSuNodes[actual_num].trader_flo_address; + + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode(closestSuNodes[0].trader_flo_address, + firstAliveBackupFloIdForBackupSupernode, closestSuNodes[index].trader_flo_address); + + } + } + } + } + } + }) + From fff9b6dcbe8e77d4840f0e330d8b0d7237a7097d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 22 Jun 2019 18:15:16 +0530 Subject: [PATCH 47/95] added function to calculate hash of tables and db --- supernode/index.html | 77 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 622c960..97d1f68 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10229,6 +10229,61 @@ return arr; }, + getDBHash: async function(su="") { + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", + "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + + const dbDataOfSupernode = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, su); + if (typeof dbDataOfSupernode=="object" && Object.keys(dbDataOfSupernode).length>0) { + + myArray = {}; + Object.keys(dbDataOfSupernode) + .map(m=>myArray[m] = Crypto.SHA256(JSON.stringify(dbDataOfSupernode[m]))); + + const dbDataOfSupernodeStr = JSON.stringify(dbDataOfSupernode); + const dbDataOfSupernodeHash = Crypto.SHA256(dbDataOfSupernodeStr); + + let data_of = su.length>0 ? su:localbitcoinplusplus.wallets.my_local_flo_address; + + myArray["id"] = `SU_DB_${data_of}`; + myArray["DBHash"] = dbDataOfSupernodeHash; + myArray["trader_flo_address"] = localbitcoinplusplus.wallets.my_local_flo_address; + myArray["data_of"] = data_of; + myArray["timestamp"] = + new Date(); + + const RM_RPC = new localbitcoinplusplus.rpc; + + if (su=="") { + updateinDB('supernodesDbHash', myArray) + .then((resp)=>{ + RM_RPC + .send_rpc + .call(this, "hash_of_a_supernode_db_response", myArray) + .then(supernodesDbHash_response=> + doSend(supernodesDbHash_response) + ); + + showMessage(`INFO: "supernodesDbHash" table updated.`)}); + } else { + if (typeof localbitcoinplusplus.newBackupDatabase.db[su]!=="object") { + return false; + } + localbitcoinplusplus.newBackupDatabase.db[su] + .backup_updateinDB('supernodesDbHash', myArray) + .then(resp=>{ + RM_RPC + .send_rpc + .call(this, "hash_of_a_supernode_db_response", myArray) + .then(supernodesDbHash_response=> + doSend(supernodesDbHash_response)); + showMessage(`INFO: "supernodesDbHash" table updated.`) + }); + } + + } + return false; + }, + claim_deposit_withdraw: function (claim_id) { if (typeof claim_id == "string" && claim_id.length > 0) { try { @@ -19644,6 +19699,20 @@ unique: false }); } + if (!db.objectStoreNames.contains('supernodesDbHash')) { + var objectStore = db.createObjectStore("supernodesDbHash", { + keyPath: 'id' + }); + objectStore.createIndex('trader_flo_address', 'trader_flo_address', { + unique: false + }); + objectStore.createIndex('data_of', 'data_of', { + unique: true + }); + objectStore.createIndex('DBHash', 'DBHash', { + unique: true + }); + } } function readDB(tablename, id) { @@ -21108,7 +21177,7 @@ localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY ); - const updatedDepositObject = { + const updateUserBTCReservesRequestObject = { updatedReservesObject: trader_deposits, updatedBTCReservesObjectSign: reservesObjectSign, trader_flo_address: trader_deposits.trader_flo_address, @@ -21117,7 +21186,7 @@ RM_RPC .send_rpc("updateUserBTCReservesRequest", - updatedDepositObject) + updateUserBTCReservesRequestObject) .then(reservesObject=> doSend(reservesObject)); @@ -21385,7 +21454,7 @@ }); }); - reactor.addEventlistener('sync_primary_and_backup_db', function() { + reactor.addEventListener('sync_primary_and_backup_db', async function() { if (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { showMessage(`INFO: Syncing of latest data starting. This could take some time. Do not close the window until then.`); @@ -21437,7 +21506,7 @@ } } } - }) + }); From a7a7be27726e1d251c129b74f89b6192db05368b Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 23 Jun 2019 17:47:41 +0530 Subject: [PATCH 48/95] added getDBHash function in add, update and delete functions --- supernode/index.html | 481 +++++++++++++++++++++++++++++++++---------- 1 file changed, 367 insertions(+), 114 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 97d1f68..a14c3f3 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10229,11 +10229,17 @@ return arr; }, - getDBHash: async function(su="") { + getDBHash: async function(su=localbitcoinplusplus.wallets.my_local_flo_address) { const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; - const dbDataOfSupernode = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, su); + let get_su = await localbitcoinplusplus.kademlia.determineClosestSupernode(su); + + const supernode_flo_id = get_su[0].data.id; + + const subjectDB = (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) ? "":supernode_flo_id; + + const dbDataOfSupernode = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, subjectDB); if (typeof dbDataOfSupernode=="object" && Object.keys(dbDataOfSupernode).length>0) { myArray = {}; @@ -10243,12 +10249,10 @@ const dbDataOfSupernodeStr = JSON.stringify(dbDataOfSupernode); const dbDataOfSupernodeHash = Crypto.SHA256(dbDataOfSupernodeStr); - let data_of = su.length>0 ? su:localbitcoinplusplus.wallets.my_local_flo_address; - - myArray["id"] = `SU_DB_${data_of}`; + myArray["id"] = `SU_DB_${subjectDB}`; myArray["DBHash"] = dbDataOfSupernodeHash; myArray["trader_flo_address"] = localbitcoinplusplus.wallets.my_local_flo_address; - myArray["data_of"] = data_of; + myArray["data_of"] = subjectDB; myArray["timestamp"] = + new Date(); const RM_RPC = new localbitcoinplusplus.rpc; @@ -10366,7 +10370,16 @@ const promise2 = removeAllinDB('my_supernode_private_key_chunks'); - return Promise.all([promise1, promise2]).then(() => true).catch(e => false); + return Promise.all([promise1, promise2]) + .then(() => { + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + return true; + }) + .catch(e => false); }, // https://stackoverflow.com/a/39538518/5348972 @@ -10582,7 +10595,14 @@ }, updateClosestSupernodeSeeds: function(flo_addr) { return new Promise(async (resolve, reject) => { - await removeAllinDB('myClosestSupernodes'); + await removeAllinDB('myClosestSupernodes') + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); let nearestSupernodeAddresslist = await localbitcoinplusplus.kademlia.addClosestSupernodeInDB(flo_addr); nearestSupernodeAddresslist.map((nearestSupernodeAddress, index)=>{ updateinDB('myClosestSupernodes', { @@ -12511,6 +12531,11 @@ deposit_arr .trader_flo_address ); + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } } } ); @@ -13810,9 +13835,14 @@ backup_server_db_instance.backup_removeinDB ( "deposit", - deposit_arr - .trader_flo_address - ); + deposit_arr.trader_flo_address + ).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(deposit_arr.trader_flo_address); + } + }); } } ); @@ -14718,11 +14748,25 @@ _removeinDB( "buyOrders", buyPipeObj - .id); + .id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(buyPipeObj.trader_flo_address); + } + }); _removeinDB( "sellOrders", sellPipeObj - .id); + .id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(sellPipeObj.trader_flo_address); + } + }); } catch (error) { callback(false); showMessage(`WARNING: Failed to delete respective buy and sell orders in an operation.`); @@ -15800,6 +15844,11 @@ await addDB(resdbdata, obj[prop]); } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } } } @@ -15877,7 +15926,14 @@ .verify(cancel_request.trade_id, cancel_request.signed_trade_id, trader_data.trader_flo_pubKey)) { removeinDB(tradeDB, cancel_request.trade_id) - .then((id) => showMessage(`Trade Id ${id} deleted.`)); + .then((id) => { + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + showMessage(`Trade Id ${id} deleted.`); + }); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -15910,8 +15966,20 @@ trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { // Delete orders in clients DB try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); } catch (error) { callback(false); throw new Error(error); @@ -16106,9 +16174,21 @@ removeByIndex('deposit', 'trader_flo_address', depositor_cash_data.trader_flo_address - ); - removeinDB('withdraw_cash', - withdraw_data.id); + ).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); + removeinDB('withdraw_cash', withdraw_data.id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); let update_cash_balance_obj = { depositor_cash_data: depositor_cash_data, @@ -16232,8 +16312,20 @@ updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data - .trader_flo_address); - removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + .trader_flo_address).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); + removeinDB('withdraw_cash', withdraw_success_response.withdraw_id).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); return true; } return false; @@ -16576,6 +16668,11 @@ } } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); + } } } catch (error) { @@ -16702,6 +16799,11 @@ }); } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } } } @@ -16792,6 +16894,11 @@ showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); }); } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); + } } } } @@ -17101,6 +17208,11 @@ await addDB(resdbdata, obj[prop]); } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } } } @@ -17196,7 +17308,14 @@ .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.`)); + .then((id) => { + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(trader_data.trader_flo_address); + } + showMessage(`Trade Id ${id} deleted.`); + }); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -17231,8 +17350,22 @@ // Delete orders in clients DB try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); } catch (error) { callback(false); throw new Error(error); @@ -17504,9 +17637,21 @@ backup_server_db_instance.backup_removeByIndex('deposit', 'trader_flo_address', depositor_cash_data.trader_flo_address - ); - backup_server_db_instance.backup_removeinDB('withdraw_cash', - withdraw_data.id); + ).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(depositor_cash_data.trader_flo_address); + } + }); + backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_data.id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(withdraw_data.trader_flo_address); + } + }); let update_cash_balance_obj = { depositor_cash_data: depositor_cash_data, @@ -17638,8 +17783,21 @@ updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data - .trader_flo_address); - removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + .trader_flo_address).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); + removeinDB('withdraw_cash', withdraw_success_response.withdraw_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + }); return true; } return false; @@ -18024,6 +18182,11 @@ await BACKUP_DB.backup_addDB(resdbdata, obj[prop]); } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); + } } } @@ -18422,6 +18585,11 @@ await addDB(resdbdata, obj[prop]); } } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } } } @@ -18599,7 +18767,14 @@ .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.`)); + .then((id) => { + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(cancel_request.trader_flo_address); + } + showMessage(`Trade Id ${id} deleted.`); + }); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -18651,8 +18826,22 @@ // Delete orders in clients DB try { - backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); - backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); + backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(trade_balance_res.trade_infos.buyer_flo_id); + } + }); + backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(trade_balance_res.trade_infos.seller_flo_id); + } + }); } catch (error) { callback(false); throw new Error(error); @@ -18755,8 +18944,21 @@ 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); + .trader_flo_address).then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(withdraw_success_response.depositor_cash_data.trader_flo_address); + } + }); + backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_success_response.withdraw_id) + .then(()=>{ + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(withdraw_success_response.trader_flo_address); + } + }); return true; } return false; @@ -19094,27 +19296,27 @@ showMessage(backup_db_error_msg); throw new Error(backup_db_error_msg); }; - }); - let updateUserDepositsResponseString = JSON.stringify( - updateUserDepositsResponseObject.updatedTraderDepositObject); - let updateUserDepositsResponseStringHash = Crypto.SHA256(updateUserDepositsResponseString); - let isBalanceLegit = RM_WALLET.verify(updateUserDepositsResponseStringHash, - updateUserDepositsResponseObject.updatedDepositsObjectSign, - res_obj.nodePubKey - ); - if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("deposits", - updateUserDepositsResponseObject.updatedTraderDepositObject); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserDepositsResponseObject.trader_flo_address) { - displayBalances(updateUserDepositsResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); - } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); - } + let updateUserDepositsResponseString = JSON.stringify( + updateUserDepositsResponseObject.updatedTraderDepositObject); + let updateUserDepositsResponseStringHash = Crypto.SHA256(updateUserDepositsResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserDepositsResponseStringHash, + updateUserDepositsResponseObject.updatedDepositsObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("deposits", + updateUserDepositsResponseObject.updatedTraderDepositObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserDepositsResponseObject.trader_flo_address) { + displayBalances(updateUserDepositsResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } + }); } break; @@ -19123,38 +19325,38 @@ .includes(res_obj.nodePubKey)) { let updateUserReservesResponseObject = res_obj.params[0]; - + let backup_server_db_instance = ""; if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) .then(my_closest_su_list=>{ const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; 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); }; + + let updateUserReservesResponseString = JSON.stringify( + updateUserReservesResponseObject.updatedReservesObject); + let updateUserReservesResponseStringHash = Crypto.SHA256(updateUserReservesResponseString); + let isBalanceLegit = RM_WALLET.verify(updateUserReservesResponseStringHash, + updateUserReservesResponseObject.updatedBTCReservesObjectSign, + res_obj.nodePubKey + ); + if (isBalanceLegit) { + backup_server_db_instance.backup_updateinDB("system_btc_reserves_private_keys", updateUserReservesResponseObject.updatedReservesObject); + if (localbitcoinplusplus.wallets.my_local_flo_address == + updateUserReservesResponseObject.trader_flo_address) { + displayBalances(updateUserReservesResponseObject.trader_flo_address); + showMessage(`INFO: Your balance is updated.`); + } + return true; + } else { + showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); + } }); - - let updateUserReservesResponseString = JSON.stringify( - updateUserReservesResponseObject.updatedReservesObject); - let updateUserReservesResponseStringHash = Crypto.SHA256(updateUserReservesResponseString); - let isBalanceLegit = RM_WALLET.verify(updateUserReservesResponseStringHash, - updateUserReservesResponseObject.updatedBTCReservesObjectSign, - res_obj.nodePubKey - ); - if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("system_btc_reserves_private_keys", updateUserReservesResponseObject.updatedReservesObject); - if (localbitcoinplusplus.wallets.my_local_flo_address == - updateUserReservesResponseObject.trader_flo_address) { - displayBalances(updateUserReservesResponseObject.trader_flo_address); - showMessage(`INFO: Your balance is updated.`); - } - return true; - } else { - showMessage(`WARNING: Failed to update balance in your DB. Please refresh.`); - } } break; @@ -19211,6 +19413,11 @@ showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); }); } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); + } } } } @@ -19223,6 +19430,41 @@ } break; + case "hash_of_a_supernode_db_response": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const response_object = res_obj.params[0]; + if(typeof response_object.trader_flo_address !="string") return; + + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + if(typeof backup_server_db_instance !== "object" + || backup_server_db_instance==localbitcoinplusplus.wallets.my_local_flo_address) { + 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('supernodesDbHash', response_object.id) + .then(old_db_hash_obj=>{ + if(typeof old_db_hash_obj=="object") { + if((old_db_hash_obj.vectorClock>=response_object.vectorClock) + || (old_db_hash_obj.timestamp>=response_object.timestamp)) return; + } + backup_server_db_instance.backup_updateinDB('supernodesDbHash', response_object) + .then(()=>showMessage(`INFO: Datastore "supernodesDbHash" updated + with hash ${response_object.DBHash} on ${response_object.timestamp}.`)); + }); + + }); + + } + + break; + default: break; } @@ -19496,19 +19738,9 @@ temporary_ip: null } - const closestSupernodesTable = { - id: null, - ip: null, - is_live: null, - port: null, - timestamp: null, - trader_flo_address: null, - vectorClock: null - } - var db; const DBName = "localbitcoinDB"; - const request = window.indexedDB.open(DBName, 1); + const request = window.indexedDB.open(DBName, 2); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -19691,14 +19923,6 @@ unique: false }); } - if (!db.objectStoreNames.contains('closestSupernodesTable')) { - var objectStore = db.createObjectStore("closestSupernodesTable", { - keyPath: 'id' - }); - objectStore.createIndex('trader_flo_address', 'trader_flo_address', { - unique: false - }); - } if (!db.objectStoreNames.contains('supernodesDbHash')) { var objectStore = db.createObjectStore("supernodesDbHash", { keyPath: 'id' @@ -19782,6 +20006,11 @@ await store.add(dbObject); await request.complete; console.info("Data added in " + tablename); + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } return dbObject; } catch (error) { return new Error(error); @@ -19814,20 +20043,22 @@ Obj.vectorClock = 1; await store.put(Obj); await request.complete; - return Obj; - } - else if (myRecord.vectorClock+1 < Obj.vectorClock) { + } else if (myRecord.vectorClock+1 < Obj.vectorClock) { await store.put(Obj); await request.complete; - return Obj; } } } else { await store.put(Obj); await request.complete; - return Obj; } + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + localbitcoinplusplus.actions.getDBHash(); + } + return Obj; } catch (error) { return new Error(error); @@ -20144,6 +20375,13 @@ await store.add(dbObject); await this.request.complete; console.info("Data added in " + tablename); + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof dbObject.trader_flo_address=="string") { + localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); + } + } return dbObject; } catch (error) { return new Error(error); @@ -20178,20 +20416,35 @@ Obj.vectorClock = 1; await store.put(Obj); await that.request.complete; - resolve(Obj); - return; } else if (myRecord.vectorClock+1 < Obj.vectorClock) { await store.put(Obj); await that.request.complete; - resolve(Obj); } }); + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof dbObject.trader_flo_address=="string") { + localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); + } + } + resolve(Obj); + return; } } else { await store.put(Obj); await that.request.complete; + + // Update the DB Hash and inform rest + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof dbObject.trader_flo_address=="string") { + localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); + } + } + return Obj; } @@ -20231,21 +20484,21 @@ request.onerror = function (e) { reject(e); } - }) + }); }, async backup_removeAllinDB(tablename) { - try { - this.request = this.db.transaction([tablename], "readwrite") - var objectStore = this.request.objectStore(tablename); - var objectStoreRequest = await objectStore.clear(); - await this.request.complete; - console.info("All the data entry has been removed from your database " + tablename); - return tablename; - } catch (error) { - return new Error(error); - } + try { + this.request = this.db.transaction([tablename], "readwrite") + var objectStore = this.request.objectStore(tablename); + var objectStoreRequest = await objectStore.clear(); + await this.request.complete; + console.info("All the data entry has been removed from your database " + tablename); + return tablename; + } catch (error) { + return new Error(error); } + } } From daa22af04ae576d215cd23b6ed44896882c9adcf Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 24 Jun 2019 17:50:58 +0530 Subject: [PATCH 49/95] added code to validate db hash and send response for tables hash is latest --- supernode/index.html | 122 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 104 insertions(+), 18 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index a14c3f3..7346fc1 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10249,15 +10249,15 @@ const dbDataOfSupernodeStr = JSON.stringify(dbDataOfSupernode); const dbDataOfSupernodeHash = Crypto.SHA256(dbDataOfSupernodeStr); - myArray["id"] = `SU_DB_${subjectDB}`; + myArray["id"] = `SU_DB_${su}`; myArray["DBHash"] = dbDataOfSupernodeHash; myArray["trader_flo_address"] = localbitcoinplusplus.wallets.my_local_flo_address; - myArray["data_of"] = subjectDB; + myArray["data_of"] = su; myArray["timestamp"] = + new Date(); const RM_RPC = new localbitcoinplusplus.rpc; - if (su=="") { + if (su==localbitcoinplusplus.wallets.my_local_flo_address) { updateinDB('supernodesDbHash', myArray) .then((resp)=>{ RM_RPC @@ -10288,6 +10288,22 @@ return false; }, + check_if_you_have_latest_dbhash_of_a_db: function(su=localbitcoinplusplus.wallets.my_local_flo_address) { + if (su=localbitcoinplusplus.wallets.my_local_flo_address) { + readDB('supernodesDbHash', `SU_DB_${su}`) + .then(resp=>{ + if (typeof resp=="object") { + RM_RPC + .send_rpc + .call(this, "validate_latest_db_hash", resp) + .then(supernodesDbHash_response=> + console.log(supernodesDbHash_response)); + showMessage(`INFO: Request sent to check latest DB hash for ${su}.`); + } + }); + } + }, + claim_deposit_withdraw: function (claim_id) { if (typeof claim_id == "string" && claim_id.length > 0) { try { @@ -10503,7 +10519,7 @@ readDB('kBucketStore', kbuck.decodedId).then(kres=>{ if (typeof kres=="object") { kres.data = data; - kres.primary_supernode_flo_public_key = closestSupernodePubKey[0] + kres.primary_supernode_flo_public_key = closestSupernodePubKey[0]; } else { kbuckObj={ id: kbuck.decodedId, @@ -16638,9 +16654,6 @@ 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 @@ -18153,9 +18166,6 @@ 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 @@ -19465,6 +19475,62 @@ break; + case "validate_latest_db_hash": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const response_object = res_obj.params[0]; + if(typeof response_object.trader_flo_address !="string") return; + + localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + .then(my_closest_su_list=>{ + const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; + const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; + + if(typeof backup_server_db_instance !== "object" + || backup_server_db_instance==localbitcoinplusplus.wallets.my_local_flo_address) { + 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('supernodesDbHash', response_object.id) + .then(my_db_hash_obj=>{ + if(typeof my_db_hash_obj=="object") { + if((my_db_hash_obj.vectorClock>=response_object.vectorClock) + || (my_db_hash_obj.timestamp>=response_object.timestamp)) { + + let diffs = []; // compare two objects and get the tables with difference in hash + + for (key in my_db_hash_obj) { + if (my_db_hash_obj.hasOwnProperty(key)) { + if (response_object[key] && response_object[key] !== my_db_hash_obj[key] + && !['DBHash', 'data_of', 'id', 'timestamp', 'vectorClock'].includes(key)) { + diffs[key] = my_db_hash_obj[key]; + } + } + } + + localbitcoinplusplus.actions.get_sharable_db_data(diffs, primarySupernodeOfThisUser) + .then(function (su_db_data) { + if (typeof su_db_data == "object") { + su_db_data.trader_flo_address = primarySupernodeOfThisUser; + su_db_data.receiver_flo_address = res_obj.globalParams.senderFloId; + RM_RPC + .send_rpc + .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) + .then(server_sync_response=>doSend(server_sync_response)); + } + }); + + } + } + }); + + }); + + } + break; + default: break; } @@ -19740,7 +19806,7 @@ var db; const DBName = "localbitcoinDB"; - const request = window.indexedDB.open(DBName, 2); + const request = window.indexedDB.open(DBName, 1); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -20009,7 +20075,7 @@ // Update the DB Hash and inform rest if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); + //localbitcoinplusplus.actions.getDBHash(); } return dbObject; } catch (error) { @@ -20056,7 +20122,7 @@ // Update the DB Hash and inform rest if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); + //localbitcoinplusplus.actions.getDBHash(); } return Obj; @@ -20303,6 +20369,20 @@ unique: false }); } + if (!this.db.objectStoreNames.contains('supernodesDbHash')) { + var objectStore = this.db.createObjectStore("supernodesDbHash", { + keyPath: 'id' + }); + objectStore.createIndex('trader_flo_address', 'trader_flo_address', { + unique: false + }); + objectStore.createIndex('data_of', 'data_of', { + unique: true + }); + objectStore.createIndex('DBHash', 'DBHash', { + unique: true + }); + } }.bind(this) @@ -20379,7 +20459,7 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { if (typeof dbObject.trader_flo_address=="string") { - localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); + //localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); } } return dbObject; @@ -20441,7 +20521,7 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { if (typeof dbObject.trader_flo_address=="string") { - localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); + //localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); } } @@ -21574,8 +21654,8 @@ }); // Find out if you are the next eligible backup supernode, - // If true, send dead su's data to all your backup supernodes - // which are not fallen supernode's backup supernodes to sync + // If true, send dead supernode's data to all your backup supernodes + // which are not dead supernode's backup supernodes to sync // data from you const mcs = await readAllDB('myClosestSupernodes'); const index = mcs.findIndex(f=>f.trader_flo_address==getFLOId); @@ -21587,13 +21667,19 @@ if(newClosestSupernodeMasterList[i].trader_flo_address== localbitcoinplusplus.wallets.my_local_flo_address) { + // First check if you yourself have the right data to serve + // If not, either get the data or don't serve the users of + // that dead supernode. + + await localbitcoinplusplus.actions.getDBHash(getFLOId); + const nonBackUpSusForDeadSu = newClosestSupernodeMasterList .filter(function(obj) { return mcs.indexOf(obj) == -1; }); console.log(nonBackUpSusForDeadSu); const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances" - , "crypto_balances", "buyOrders", "sellOrders"]; + , "crypto_balances", "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; localbitcoinplusplus.actions.get_sharable_db_data(tableArray, getFLOId) .then(function (su_db_data) { From 15ecc3e52f8511409d1061dc9bdc665c9d17ed20 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 25 Jun 2019 17:17:07 +0530 Subject: [PATCH 50/95] added function to calculate latest vector clock and timestamp for tables in a db --- supernode/index.html | 469 ++++++++++++------------------------------- 1 file changed, 133 insertions(+), 336 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 7346fc1..b3e589e 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10229,23 +10229,70 @@ return arr; }, - getDBHash: async function(su=localbitcoinplusplus.wallets.my_local_flo_address) { - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", - "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + getHighestVectorClockInTablesOfaDB: function(dbDataOfSupernode=[]) { + return new Promise((resolve, reject)=>{ + let higestVCList = []; + Object.keys(dbDataOfSupernode).map((m,i)=>{ + if(typeof dbDataOfSupernode[m]=="object") { + arr = dbDataOfSupernode[m].map(d=>{ + if(typeof d !== 'undefined') { + return d.vectorClock; + } + }); + var max = Math.max.apply( null, arr ); + if(typeof max !=="number" || [-Infinity, NaN, false, null, undefined].includes(max)) max=0; + return higestVCList[`${m}_HVC`] = max; + } + }); + resolve(higestVCList); + }); + }, + getHighestTimestampInTablesOfaDB: function(dbDataOfSupernode=[]) { + return new Promise((resolve, reject)=>{ + let higestVCList = []; + Object.keys(dbDataOfSupernode).map((m,i)=>{ + if(typeof dbDataOfSupernode[m]=="object") { + arr = dbDataOfSupernode[m].map(d=>{ + if(typeof d !== 'undefined') { + return d.timestamp; + } + }); + var max = Math.max.apply( null, arr ); + if(typeof max !=="number" || [-Infinity, NaN, false, null, undefined].includes(max)) max=0; + return higestVCList[`${m}_HVC`] = max; + } + }); + resolve(higestVCList); + }); + }, + + getDBTablesLatestHashAndTimestamp: async function(su=localbitcoinplusplus.wallets.my_local_flo_address, actual_db_data=false, tableArray=false) { + let get_su = await localbitcoinplusplus.kademlia.determineClosestSupernode(su); const supernode_flo_id = get_su[0].data.id; const subjectDB = (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) ? "":supernode_flo_id; - const dbDataOfSupernode = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, subjectDB); + let dbDataOfSupernode; + + if (actual_db_data==false) { + if (typeof tableArray!=="object") { + tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", "crypto_balances", + "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + } + dbDataOfSupernode = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, subjectDB); + } + if (typeof dbDataOfSupernode=="object" && Object.keys(dbDataOfSupernode).length>0) { myArray = {}; Object.keys(dbDataOfSupernode) .map(m=>myArray[m] = Crypto.SHA256(JSON.stringify(dbDataOfSupernode[m]))); - + + const higestTimestampList = await localbitcoinplusplus.actions.getHighestTimestampInTablesOfaDB(dbDataOfSupernode); + const dbDataOfSupernodeStr = JSON.stringify(dbDataOfSupernode); const dbDataOfSupernodeHash = Crypto.SHA256(dbDataOfSupernodeStr); @@ -10253,37 +10300,18 @@ myArray["DBHash"] = dbDataOfSupernodeHash; myArray["trader_flo_address"] = localbitcoinplusplus.wallets.my_local_flo_address; myArray["data_of"] = su; - myArray["timestamp"] = + new Date(); + myArray["higestTimestampList"] = higestTimestampList; + + return myArray; - const RM_RPC = new localbitcoinplusplus.rpc; - - if (su==localbitcoinplusplus.wallets.my_local_flo_address) { - updateinDB('supernodesDbHash', myArray) - .then((resp)=>{ - RM_RPC - .send_rpc - .call(this, "hash_of_a_supernode_db_response", myArray) - .then(supernodesDbHash_response=> - doSend(supernodesDbHash_response) - ); - - showMessage(`INFO: "supernodesDbHash" table updated.`)}); - } else { - if (typeof localbitcoinplusplus.newBackupDatabase.db[su]!=="object") { - return false; - } - localbitcoinplusplus.newBackupDatabase.db[su] - .backup_updateinDB('supernodesDbHash', myArray) - .then(resp=>{ - RM_RPC - .send_rpc - .call(this, "hash_of_a_supernode_db_response", myArray) - .then(supernodesDbHash_response=> - doSend(supernodesDbHash_response)); - showMessage(`INFO: "supernodesDbHash" table updated.`) - }); - } + // const RM_RPC = new localbitcoinplusplus.rpc; + // RM_RPC + // .send_rpc + // .call(this, "do_you_have_latest_data_for_this_supernode", myArray) + // .then(supernodesDbHash_response=> + // doSend(supernodesDbHash_response)); + } return false; }, @@ -10386,16 +10414,7 @@ const promise2 = removeAllinDB('my_supernode_private_key_chunks'); - return Promise.all([promise1, promise2]) - .then(() => { - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - return true; - }) - .catch(e => false); + return Promise.all([promise1, promise2]).then(() => true).catch(e => false); }, // https://stackoverflow.com/a/39538518/5348972 @@ -10611,14 +10630,7 @@ }, updateClosestSupernodeSeeds: function(flo_addr) { return new Promise(async (resolve, reject) => { - await removeAllinDB('myClosestSupernodes') - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + await removeAllinDB('myClosestSupernodes'); let nearestSupernodeAddresslist = await localbitcoinplusplus.kademlia.addClosestSupernodeInDB(flo_addr); nearestSupernodeAddresslist.map((nearestSupernodeAddress, index)=>{ updateinDB('myClosestSupernodes', { @@ -12547,11 +12559,6 @@ deposit_arr .trader_flo_address ); - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } } } ); @@ -13852,13 +13859,7 @@ ( "deposit", deposit_arr.trader_flo_address - ).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(deposit_arr.trader_flo_address); - } - }); + ); } } ); @@ -14761,28 +14762,8 @@ .length > 0) { // Delete orders try { - _removeinDB( - "buyOrders", - buyPipeObj - .id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(buyPipeObj.trader_flo_address); - } - }); - _removeinDB( - "sellOrders", - sellPipeObj - .id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(sellPipeObj.trader_flo_address); - } - }); + _removeinDB("buyOrders", buyPipeObj.id); + _removeinDB("sellOrders", sellPipeObj.id); } catch (error) { callback(false); showMessage(`WARNING: Failed to delete respective buy and sell orders in an operation.`); @@ -15860,11 +15841,6 @@ await addDB(resdbdata, obj[prop]); } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } } } @@ -15942,14 +15918,7 @@ .verify(cancel_request.trade_id, cancel_request.signed_trade_id, trader_data.trader_flo_pubKey)) { removeinDB(tradeDB, cancel_request.trade_id) - .then((id) => { - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - showMessage(`Trade Id ${id} deleted.`); - }); + .then((id) => showMessage(`Trade Id ${id} deleted.`)); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -15982,20 +15951,8 @@ trade_balance_res.supernode_sign, trade_balance_res.supernodePubKey)) { // Delete orders in clients DB try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); } catch (error) { callback(false); throw new Error(error); @@ -16190,21 +16147,8 @@ removeByIndex('deposit', 'trader_flo_address', depositor_cash_data.trader_flo_address - ).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); - removeinDB('withdraw_cash', withdraw_data.id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + ); + removeinDB('withdraw_cash', withdraw_data.id); let update_cash_balance_obj = { depositor_cash_data: depositor_cash_data, @@ -16328,20 +16272,8 @@ updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data - .trader_flo_address).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); - removeinDB('withdraw_cash', withdraw_success_response.withdraw_id).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + .trader_flo_address); + removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); return true; } return false; @@ -16681,11 +16613,6 @@ } } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); - } } } catch (error) { @@ -16812,11 +16739,6 @@ }); } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } } } @@ -16907,11 +16829,6 @@ showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); }); } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); - } } } } @@ -17221,11 +17138,6 @@ await addDB(resdbdata, obj[prop]); } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } } } @@ -17321,14 +17233,7 @@ .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) => { - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(trader_data.trader_flo_address); - } - showMessage(`Trade Id ${id} deleted.`); - }); + .then((id) =>showMessage(`Trade Id ${id} deleted.`)); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -17363,22 +17268,8 @@ // Delete orders in clients DB try { - removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); - removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); } catch (error) { callback(false); throw new Error(error); @@ -17650,21 +17541,8 @@ backup_server_db_instance.backup_removeByIndex('deposit', 'trader_flo_address', depositor_cash_data.trader_flo_address - ).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(depositor_cash_data.trader_flo_address); - } - }); - backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_data.id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(withdraw_data.trader_flo_address); - } - }); + ); + backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_data.id); let update_cash_balance_obj = { depositor_cash_data: depositor_cash_data, @@ -17796,21 +17674,8 @@ updateinDB('cash_balances', withdraw_success_response.depositor_cash_data); updateinDB('cash_balances', withdraw_success_response.withdrawer_cash_data); removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data - .trader_flo_address).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); - removeinDB('withdraw_cash', withdraw_success_response.withdraw_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } - }); + .trader_flo_address); + removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); return true; } return false; @@ -18192,11 +18057,6 @@ await BACKUP_DB.backup_addDB(resdbdata, obj[prop]); } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); - } } } @@ -18595,11 +18455,6 @@ await addDB(resdbdata, obj[prop]); } } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(); - } } } @@ -18777,14 +18632,7 @@ .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) => { - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(cancel_request.trader_flo_address); - } - showMessage(`Trade Id ${id} deleted.`); - }); + .then((id) => showMessage(`Trade Id ${id} deleted.`)); } else { showMessage( `Failed to verify trade for trade id ${cancel_request.trade_id}` @@ -18836,22 +18684,8 @@ // Delete orders in clients DB try { - backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(trade_balance_res.trade_infos.buyer_flo_id); - } - }); - backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(trade_balance_res.trade_infos.seller_flo_id); - } - }); + backup_server_db_instance.backup_removeinDB("buyOrders", trade_balance_res.trade_infos.buy_order_id); + backup_server_db_instance.backup_removeinDB("sellOrders", trade_balance_res.trade_infos.sell_order_id); } catch (error) { callback(false); throw new Error(error); @@ -18954,21 +18788,8 @@ 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).then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(withdraw_success_response.depositor_cash_data.trader_flo_address); - } - }); - backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_success_response.withdraw_id) - .then(()=>{ - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(withdraw_success_response.trader_flo_address); - } - }); + .trader_flo_address); + backup_server_db_instance.backup_removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); return true; } return false; @@ -19423,11 +19244,6 @@ showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); }); } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - localbitcoinplusplus.actions.getDBHash(su_db_data.trader_flo_address); - } } } } @@ -19440,7 +19256,7 @@ } break; - case "hash_of_a_supernode_db_response": + case "do_you_have_latest_data_for_this_supernode": if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { const response_object = res_obj.params[0]; @@ -19458,16 +19274,18 @@ throw new Error(backup_db_error_msg); }; - backup_server_db_instance.backup_readDB('supernodesDbHash', response_object.id) - .then(old_db_hash_obj=>{ - if(typeof old_db_hash_obj=="object") { - if((old_db_hash_obj.vectorClock>=response_object.vectorClock) - || (old_db_hash_obj.timestamp>=response_object.timestamp)) return; - } - backup_server_db_instance.backup_updateinDB('supernodesDbHash', response_object) - .then(()=>showMessage(`INFO: Datastore "supernodesDbHash" updated - with hash ${response_object.DBHash} on ${response_object.timestamp}.`)); - }); + // backup_server_db_instance.backup_readDB('supernodesDbHash', response_object.id) + // .then(old_db_hash_obj=>{ + // if(typeof old_db_hash_obj=="object") { + // if((old_db_hash_obj.vectorClock>=response_object.vectorClock) + // || (old_db_hash_obj.timestamp>=response_object.timestamp)) return; + // } + // backup_server_db_instance.backup_updateinDB('supernodesDbHash', response_object) + // .then(()=>showMessage(`INFO: Datastore "supernodesDbHash" updated + // with hash ${response_object.DBHash} on ${response_object.timestamp}.`)); + // }); + + }); @@ -19503,7 +19321,8 @@ for (key in my_db_hash_obj) { if (my_db_hash_obj.hasOwnProperty(key)) { - if (response_object[key] && response_object[key] !== my_db_hash_obj[key] + if (response_object[key] + && response_object[key] !== my_db_hash_obj[key] && !['DBHash', 'data_of', 'id', 'timestamp', 'vectorClock'].includes(key)) { diffs[key] = my_db_hash_obj[key]; } @@ -20072,11 +19891,6 @@ await store.add(dbObject); await request.complete; console.info("Data added in " + tablename); - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - //localbitcoinplusplus.actions.getDBHash(); - } return dbObject; } catch (error) { return new Error(error); @@ -20119,11 +19933,6 @@ await store.put(Obj); await request.complete; } - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - //localbitcoinplusplus.actions.getDBHash(); - } return Obj; } catch (error) { @@ -20455,13 +20264,6 @@ await store.add(dbObject); await this.request.complete; console.info("Data added in " + tablename); - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof dbObject.trader_flo_address=="string") { - //localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); - } - } return dbObject; } catch (error) { return new Error(error); @@ -20502,13 +20304,6 @@ await that.request.complete; } }); - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof dbObject.trader_flo_address=="string") { - localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); - } - } resolve(Obj); return; } @@ -20516,15 +20311,6 @@ } else { await store.put(Obj); await that.request.complete; - - // Update the DB Hash and inform rest - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof dbObject.trader_flo_address=="string") { - //localbitcoinplusplus.actions.getDBHash(dbObject.trader_flo_address); - } - } - return Obj; } @@ -21654,14 +21440,12 @@ }); // Find out if you are the next eligible backup supernode, - // If true, send dead supernode's data to all your backup supernodes - // which are not dead supernode's backup supernodes to sync - // data from you + const mcs = await readAllDB('myClosestSupernodes'); const index = mcs.findIndex(f=>f.trader_flo_address==getFLOId); tail = mcs.splice(0, index); const newClosestSupernodeMasterList = mcs.concat(tail); - + for(i=0; i<=newClosestSupernodeMasterList.length; i++) { if(newClosestSupernodeMasterList[i].is_live==true) break; if(newClosestSupernodeMasterList[i].trader_flo_address== @@ -21671,29 +21455,42 @@ // If not, either get the data or don't serve the users of // that dead supernode. - await localbitcoinplusplus.actions.getDBHash(getFLOId); + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", + "crypto_balances", "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + + const su_db_data = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, getFLOId); + + const dbHashData = await localbitcoinplusplus.actions.getDBTablesLatestHashAndTimestamp(getFLOId, su_db_data); + + // Now you have db tables timestamp and tables hashes. Send it to other supernodes to check + // if you have the latest data. If you don't have the latest data, someone + // will send you the latest data which you can verify before updating. + + RM_RPC + .send_rpc + .call(this, "do_you_have_latest_data_for_this_supernode", dbHashData) + .then(server_sync_response=>doSend(server_sync_response)); + + // Send dead supernode's data to all your backup supernodes + // which are not dead supernode's backup supernodes to sync + // data from you const nonBackUpSusForDeadSu = newClosestSupernodeMasterList .filter(function(obj) { return mcs.indexOf(obj) == -1; }); console.log(nonBackUpSusForDeadSu); - - const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances" - , "crypto_balances", "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + + if (typeof su_db_data == "object") { + nonBackUpSusForDeadSu.map(nbs=>{ + su_db_data.trader_flo_address = nbs.trader_flo_address; + su_db_data.receiver_flo_address = nbs.trader_flo_address; - localbitcoinplusplus.actions.get_sharable_db_data(tableArray, getFLOId) - .then(function (su_db_data) { - if (typeof su_db_data == "object") { - nonBackUpSusForDeadSu.map(nbs=>{ - su_db_data.trader_flo_address = nbs.trader_flo_address; - su_db_data.receiver_flo_address = nbs.trader_flo_address; - RM_RPC - .send_rpc - .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) - .then(server_sync_response=>doSend(server_sync_response, nbs.trader_flo_address)); - }); - } - }); + RM_RPC + .send_rpc + .call(this, "sync_backup_supernode_from_backup_supernode_response", su_db_data) + .then(server_sync_response=>doSend(server_sync_response, nbs.trader_flo_address)); + }); + } break; } } From da9c50cbfc8d70a9155fc9219e45ac01ceca54df Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 26 Jun 2019 16:58:45 +0530 Subject: [PATCH 51/95] added code in do_you_have_latest_data_for_this_supernode section --- supernode/index.html | 86 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 68 insertions(+), 18 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index b3e589e..bc85fe0 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -9635,8 +9635,8 @@ btc_mainnet: "https://blockexplorer.com", btc_testnet: "https://testnet.blockexplorer.com", flo_mainnet: "http://flosight.duckdns.org", - //flo_testnet: "http://testnet-flosight.duckdns.org" - flo_testnet: "https://testnet.flocha.in" + flo_testnet: "http://testnet-flosight.duckdns.org" + //flo_testnet: "https://testnet.flocha.in" }, writable: false, configurable: false, @@ -10035,6 +10035,7 @@ localbitcoinplusplus.actions = { parse_flo_comments: function (callback) { + return callback('fofof'); if (this.floAddress == null) { return false; } @@ -10273,6 +10274,10 @@ const supernode_flo_id = get_su[0].data.id; + if (typeof supernode_flo_id !=="string") { + throw new Error(`WARNING: Failed to calculate supenode of this FLO Id: ${su}.`); + } + const subjectDB = (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) ? "":supernode_flo_id; let dbDataOfSupernode; @@ -10289,7 +10294,10 @@ myArray = {}; Object.keys(dbDataOfSupernode) - .map(m=>myArray[m] = Crypto.SHA256(JSON.stringify(dbDataOfSupernode[m]))); + .map(m=>{ + // SORT THE DATA HERE A/C TO TIMESTAMP AND THEN HASH + myArray[m] = Crypto.SHA256(JSON.stringify(dbDataOfSupernode[m])); + }); const higestTimestampList = await localbitcoinplusplus.actions.getHighestTimestampInTablesOfaDB(dbDataOfSupernode); @@ -10300,7 +10308,7 @@ myArray["DBHash"] = dbDataOfSupernodeHash; myArray["trader_flo_address"] = localbitcoinplusplus.wallets.my_local_flo_address; myArray["data_of"] = su; - myArray["higestTimestampList"] = higestTimestampList; + myArray["higestTimestampList"] = {...higestTimestampList}; return myArray; @@ -19263,7 +19271,7 @@ if(typeof response_object.trader_flo_address !="string") return; localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - .then(my_closest_su_list=>{ + .then(async my_closest_su_list=>{ const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; @@ -19274,18 +19282,56 @@ throw new Error(backup_db_error_msg); }; - // backup_server_db_instance.backup_readDB('supernodesDbHash', response_object.id) - // .then(old_db_hash_obj=>{ - // if(typeof old_db_hash_obj=="object") { - // if((old_db_hash_obj.vectorClock>=response_object.vectorClock) - // || (old_db_hash_obj.timestamp>=response_object.timestamp)) return; - // } - // backup_server_db_instance.backup_updateinDB('supernodesDbHash', response_object) - // .then(()=>showMessage(`INFO: Datastore "supernodesDbHash" updated - // with hash ${response_object.DBHash} on ${response_object.timestamp}.`)); - // }); + console.log(response_object); - + const tableArray = ["deposit", "withdraw_cash", "withdraw_btc", "cash_balances", + "crypto_balances", "buyOrders", "sellOrders", "system_btc_reserves_private_keys"]; + + const su_db_data_from_my_db = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, primarySupernodeOfThisUser); + + const dbHashData_from_my_db = await localbitcoinplusplus.actions.getDBTablesLatestHashAndTimestamp(primarySupernodeOfThisUser, su_db_data_from_my_db); + + // If you have same data as the sender has, you don't need to return any data to him + if (dbHashData_from_my_db.DBHash===response_object.DBHash) return; + if (dbHashData_from_my_db.id===response_object.id) return; + if (dbHashData_from_my_db.data_of===response_object.data_of) return; + if (dbHashData_from_my_db.trader_flo_address===response_object.trader_flo_address) return; + + let mismatched_fields = []; + + for (var q in dbHashData_from_my_db) { + if (dbHashData_from_my_db.hasOwnProperty(q) + || q=='higestTimestampList' + || q=='id' + || q=='data_of' + || q=='trader_flo_address') { + if (dbHashData_from_my_db[q]!==response_object[q]) { + mismatched_fields.push(q); + } + } + } + + console.log(mismatched_fields); + + let latest_data = {}; + + mismatched_fields.map(mf=>{ + backup_server_db_instance.backup_readAllDB(mf) + .then(res_data_obj=>{ + + let filtered_data = res_data_obj.filter(odho=>{ + if (typeof odho.vectorClock=="number" + && typeof response_object.higestTimestampList[`${mf}_HVC`] !=='undefined') { + return odho.vectorClock >= response_object.higestTimestampList[`${mf}_HVC`]; + } + }); + + latest_data[mf] = {...filtered_data}; + }); + }); + + // Send the data back to sender + console.log(latest_data); }); @@ -19636,6 +19682,7 @@ request.onsuccess = function (event) { db = request.result; + doShreeGanesh(); loadLocalDBData(); }; @@ -19867,9 +19914,13 @@ }); } - function readAllDB(tablename) { + function readAllDB(tablename, limit=0) { return new Promise((resolve, reject) => { let response = []; + // let keyRangeValue; + // if (limit>0) { + // keyRangeValue = IDBKeyRange.lowerBound(limit); + // } var objectStore = db.transaction(tablename).objectStore(tablename); objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; @@ -20387,7 +20438,6 @@ throw new Error(`Failed to fetch configurations: ${error}`); } } - doShreeGanesh(); From 2f9126942bf3c969d1002e1efd1c8159fecb52b9 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 9 Jul 2019 13:41:05 +0530 Subject: [PATCH 65/95] modified backup db remove functions to not delete data but keep just id, vector clock and timestamp --- supernode/index.html | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 85725e7..02779a3 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -20013,7 +20013,8 @@ }; request.onsuccess = function (event) { - if (request.result) { + if (request.result + && typeof request.result.is_deletable == "undefined") { resolve(request.result); } else { resolve(); @@ -20034,7 +20035,8 @@ objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; if (cursor) { - if (cursor.value[index] == indexValue) { + if (cursor.value[index] == indexValue + && typeof cursor.value.is_deletable == "undefined") { response.push(cursor.value); } cursor.continue(); @@ -20055,7 +20057,7 @@ var objectStore = db.transaction(tablename).objectStore(tablename); objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; - if (cursor) { + if (cursor && typeof cursor.value.is_deletable == "undefined") { response.push(cursor.value); cursor.continue(); } else { @@ -20369,7 +20371,8 @@ }; this.request.onsuccess = function (event) { - if (parent_request.result) { + if (parent_request.result + && typeof parent_request.result.is_deletable == "undefined") { resolve(parent_request.result); } else { resolve(); @@ -20390,7 +20393,8 @@ objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; if (cursor) { - if (cursor.value[index] == indexValue) { + if (cursor.value[index] == indexValue + && typeof cursor.value.is_deletable == "undefined") { response.push(cursor.value); } cursor.continue(); @@ -20407,7 +20411,7 @@ var objectStore = this.db.transaction(tablename).objectStore(tablename); objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; - if (cursor) { + if (cursor && typeof cursor.value.is_deletable == "undefined") { response.push(cursor.value); cursor.continue(); } else { From 17fbd1f80c8e924e8eb0c20740d2158ba4cea6a5 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 10 Jul 2019 11:51:23 +0530 Subject: [PATCH 66/95] fetching exchange rates from db than api calls --- supernode/index.html | 137 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 108 insertions(+), 29 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 02779a3..a91eb7d 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11387,6 +11387,10 @@ .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address); if (typeof my_closest_su=="object") { request.globalParams.primarySupernode = my_closest_su[0].data.id; + request.globalParams["receiversList"] = []; + for (let j = 0; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + request.globalParams.receiversList.push(my_closest_su[j].data.id); + } } } } else { @@ -14356,7 +14360,43 @@ }) }); }, - fiat_to_crypto_exchange_rate(crypto_code="", fiat="") { + // This function should be run periodically maybe through cron job + update_fiat_to_crypto_exchange_rate(crypto_code="", fiat="") { + this.fiat_to_crypto_exchange_rate_from_API(crypto_code, fiat) + .then(new_price=>{ + console.log(new_price); + if (typeof new_price=="number") { + + let rate_obj = { + id: `${crypto_code}_${fiat}`, + crypto_code: crypto_code, + currency_code: fiat, + rate: new_price, + timestamp: +new Date() + }; + const rate_obj_str = JSON.stringify(rate_obj); + const rate_obj_hash = Crypto.SHA256(rate_obj_str); + const RM_WALLET = new localbitcoinplusplus.wallets; + const rate_obj_sign = RM_WALLET.sign(rate_obj_hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); + rate_obj['supernode_pub_key'] = localbitcoinplusplus.wallets.my_local_flo_public_key; + rate_obj['sign'] = rate_obj_sign; + + updateinDB('crypto_fiat_rates', rate_obj) + .then(()=>{ + showMessage(`INFO: ${crypto_code}<=>${fiat} rate updated.`); + this.resolve_current_crypto_price_in_fiat(crypto_code, fiat); + }) + .catch(()=>console.error(`ERROR: Failed to update ${crypto_code}<=>${fiat} rate.`)); + + return true; + } else { + console.error(`ERROR: Failed to get valid response while fetching ${crypto_code}<=>${fiat} rate.`); + } + }).catch(e=>{ + console.error(e); + }); + }, + fiat_to_crypto_exchange_rate_from_API(crypto_code="", fiat="") { return new Promise((resolve, reject)=>{ if (crypto_code=="BTC") { @@ -14403,55 +14443,56 @@ } }); }, + fiat_to_crypto_exchange_rate(crypto_code="", fiat="") { + return new Promise((resolve, reject)=>{ + try { + let id = `${crypto_code}_${fiat}`; + readDB('crypto_fiat_rates', id) + .then(res=>{ + if (typeof res=="object") { + return resolve(res); + } + reject(false); + }); + } catch(e) { + reject(e); + } + }); + }, async set_current_crypto_price_in_fiat(crypto_code, currency_code) { if (!localbitcoinplusplus.master_configurations.tradableAsset1.includes(crypto_code) || !localbitcoinplusplus.master_configurations.tradableAsset2.includes(currency_code) || !localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return false; - let new_price = 0; + let rate_obj = null; if (crypto_code=="BTC" && currency_code=="USD") { - new_price = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); } if (crypto_code=="BTC_TEST" && currency_code=="USD") { - new_price = await this.fiat_to_crypto_exchange_rate("BTC", currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate("BTC", currency_code); } if (crypto_code=="BTC" && currency_code=="INR") { - new_price = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); } if (crypto_code=="BTC_TEST" && currency_code=="INR") { - new_price = await this.fiat_to_crypto_exchange_rate("BTC", currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate("BTC", currency_code); } if (crypto_code=="FLO" && currency_code=="USD") { - new_price = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); } if (crypto_code=="FLO_TEST" && currency_code=="USD") { - new_price = await this.fiat_to_crypto_exchange_rate("FLO", currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate("FLO", currency_code); } if (crypto_code=="FLO" && currency_code=="INR") { - new_price = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate(crypto_code, currency_code); } if (crypto_code=="FLO_TEST" && currency_code=="INR") { - new_price = await this.fiat_to_crypto_exchange_rate("FLO", currency_code); + rate_obj = await this.fiat_to_crypto_exchange_rate("FLO", currency_code); } - if(typeof new_price !== "number" || new_price<=0) throw new Error(`WARNING: Failed to get price.`); - - let rate_obj = { - id: `${crypto_code}_${currency_code}`, - crypto_code: crypto_code, - currency_code: currency_code, - rate: new_price, - timestamp: +new Date() - }; - const rate_obj_str = JSON.stringify(rate_obj); - const rate_obj_hash = Crypto.SHA256(rate_obj_str); - const RM_WALLET = new localbitcoinplusplus.wallets; - const rate_obj_sign = RM_WALLET.sign(rate_obj_hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); - rate_obj['supernode_pub_key'] = localbitcoinplusplus.wallets.my_local_flo_public_key; - rate_obj['sign'] = rate_obj_sign; - console.log(rate_obj); + if(rate_obj == null) throw new Error(`WARNING: Failed to get price.`); Object.defineProperty(localbitcoinplusplus.trade, `current_${crypto_code}_price_in_${currency_code}`, { @@ -15723,6 +15764,12 @@ function onOpen(evt) { reactor.dispatchEvent('new_supernode_connected', evt); + readDB('localbitcoinUser', '00-01').then(res=>{ + if (typeof res=="object" && res.myLocalFLOAddress=="string") { + localbitcoinplusplus.wallets.my_local_flo_address = res.myLocalFLOAddress; + localbitcoinplusplus.wallets.my_local_flo_public_key = res.myLocalFLOPublicKey; + } + }) readAllDB('myClosestSupernodes').then(sconn=>{ const switchMyWS = new backupSupernodesWebSocketObject(); sconn.map((m,i)=>{ @@ -19825,6 +19872,16 @@ temporary_ip: null } + const crypto_fiat_rates = { + id: null, + crypto_code: null, + currency_code: null, + rate: 0, + supernode_pub_key: null, + sign: null, + timestamp: +new Date() + } + var db; const DBName = "localbitcoinDB"; const request = window.indexedDB.open(DBName, 1); @@ -20000,6 +20057,17 @@ unique: false }); } + if (!db.objectStoreNames.contains('crypto_fiat_rates')) { + var objectStore = db.createObjectStore("crypto_fiat_rates", { + keyPath: 'id' + }); + objectStore.createIndex('currency_code', 'currency_code', { + unique: false + }); + objectStore.createIndex('crypto_code', 'crypto_code', { + unique: false + }); + } } function readDB(tablename, id) { @@ -20354,6 +20422,17 @@ unique: false }); } + if (!db.objectStoreNames.contains('crypto_fiat_rates')) { + var objectStore = db.createObjectStore("crypto_fiat_rates", { + keyPath: 'id' + }); + objectStore.createIndex('currency_code', 'currency_code', { + unique: false + }); + objectStore.createIndex('crypto_code', 'crypto_code', { + unique: false + }); + } }.bind(this) @@ -20758,7 +20837,6 @@ } }); - // Check last connected supernode, if not primary then // update the user data from other su first //wsUri = await localbitcoinplusplus.kademlia.getSupernodeSeed(idbData.myLocalFLOAddress); @@ -20803,8 +20881,9 @@ localbitcoinplusplus.master_configurations.tradableAsset1.forEach(function ( asset1) { localbitcoinplusplus.master_configurations.tradableAsset2.forEach( - function (asset2) { - RM_TRADE.resolve_current_crypto_price_in_fiat(asset1, asset2); + async function (asset2) { + await RM_TRADE.update_fiat_to_crypto_exchange_rate(asset1, asset2); + await RM_TRADE.resolve_current_crypto_price_in_fiat(asset1, asset2); }); }); } From 31b0f8547e3734b18e5ac3649a420127f393747d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 11 Jul 2019 19:53:05 +0530 Subject: [PATCH 67/95] modified db read functions to fetch both deletable/non-deletable data --- supernode/index.html | 197 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 160 insertions(+), 37 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index a91eb7d..152c2e9 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11382,35 +11382,34 @@ if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string") { request.globalParams.senderFloId = localbitcoinplusplus.wallets.my_local_flo_address; - if (typeof params[0].trader_flo_address !=="string") { + //if (typeof params[0].trader_flo_address !=="string") { const my_closest_su = await localbitcoinplusplus.kademlia - .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address); + .determineClosestSupernode('', '', supernodeKBucket, localbitcoinplusplus.wallets.my_local_flo_address); if (typeof my_closest_su=="object") { request.globalParams.primarySupernode = my_closest_su[0].data.id; request.globalParams["receiversList"] = []; - for (let j = 0; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { request.globalParams.receiversList.push(my_closest_su[j].data.id); } } - } + //} } else { const resObj = await readDB('localbitcoinUser', '00-01'); if(typeof resObj !== "object" || typeof resObj.myLocalFLOAddress !== "string") return; request.globalParams.senderFloId = resObj.myLocalFLOAddress; - if (typeof params[0].trader_flo_address !=="string") { - const n = localbitcoinplusplus.master_configurations.MaxBackups+1; + //if (typeof params[0].trader_flo_address !=="string") { const my_closest_su = await localbitcoinplusplus.kademlia - .determineClosestSupernode(resObj.myLocalFLOAddress, n); + .determineClosestSupernode('', '', supernodeKBucket, resObj.myLocalFLOAddress); if (typeof my_closest_su=="object") { request.globalParams.primarySupernode = my_closest_su[0].data.id; request.globalParams["receiversList"] = []; - for (let j = 0; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { request.globalParams.receiversList.push(my_closest_su[j].data.id); } } - } + //} } if (typeof params[0].receiver_flo_address == "string") { @@ -11866,7 +11865,10 @@ addDB( "system_btc_reserves_private_keys", system_btc_reserves_private_keys_object - ); + ).then(pk_res=>{ + // Send it to neighbor nodes to store as backup + reactor.dispatchEvent('store_backup_crypto_pk_object', pk_res); + }); } catch (error) { throw new Error( error); } @@ -13080,7 +13082,10 @@ backup_server_db_instance.backup_addDB( "system_btc_reserves_private_keys", system_btc_reserves_private_keys_object - ); + ).then(pk_res=>{ + // Send it to neighbor nodes to store as backup + reactor.dispatchEvent('store_backup_crypto_pk_object', pk_res); + }); } catch (error) { throw new Error( error); } @@ -14304,9 +14309,14 @@ let current_rate_obj = localbitcoinplusplus.trade[`current_${crypto_code}_price_in_${currency_code}`]; if (typeof current_rate_obj=="object" && localbitcoinplusplus.master_configurations.supernodesPubKeys.includes(current_rate_obj.supernode_pub_key)) { - + if (crypto_code=="BTC_TEST") { + crypto_code = "BTC" + } + if (crypto_code=="FLO_TEST") { + crypto_code = "FLO" + } let rate_obj = { - id: `${current_rate_obj.crypto_code}_${current_rate_obj.currency_code}`, + id: `${crypto_code}_${currency_code}`, crypto_code: crypto_code, currency_code: currency_code, rate: current_rate_obj.rate, @@ -15816,6 +15826,10 @@ .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; + if (typeof res_obj.globalParams.receiverFloId=="string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address) return; + const isIncomingMessageValid = await validateIncomingMessage(res); console.log("isIncomingMessageValid: ", isIncomingMessageValid); @@ -17088,6 +17102,10 @@ .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; + if (typeof res_obj.globalParams.receiverFloId=="string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address) return; + // Check if request is from primary user or backup user // If request is from backup user, divert the request to backup onmessage event let get_requester_supernode = ''; @@ -18520,6 +18538,10 @@ if (!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) return; + if (typeof res_obj.globalParams.receiverFloId=="string" + && res_obj.globalParams.receiverFloId !== + localbitcoinplusplus.wallets.my_local_flo_address) return; + if (typeof res_obj.method !== "undefined") { let response_from_sever; @@ -19607,6 +19629,36 @@ } break; + case "store_backup_system_btc_reserves_private_keys": + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey) + && res_obj.globalParams.receiverFloId==localbitcoinplusplus.wallets.my_local_flo_address + ) { + const resp_data = res_obj.params[0]; + let btc_pk_obj = localbitcoinplusplus.encrypt + .decryptMessage(resp_data.data.secret, resp_data.data.senderPublicKeyString); + + localbitcoinplusplus.kademlia.determineClosestSupernode(su).then(get_su=>{ + const supernode_flo_id = get_su[0].data.id; + if (typeof supernode_flo_id !=="string") throw new Error(`ERROR: Invalid FLO key.`); + if (typeof btc_pk_obj =="object"){ + + } + if (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) { + updateinDB("system_btc_reserves_private_keys", + btc_pk_obj, btc_pk_obj.id, false, false); + } else if(typeof localbitcoinplusplus.newBackupDatabase.db[supernode_flo_id]=="object") { + localbitcoinplusplus.newBackupDatabase + .db[supernode_flo_id].backup_updateinDB("system_btc_reserves_private_keys", + btc_pk_obj, btc_pk_obj.id, false, false); + } else { + throw new Error(`ERROR: Failed to store backup system_btc_reserves_private_keys id ${btc_pk_obj.id}`); + } + }); + } + break; + default: break; } @@ -20070,7 +20122,7 @@ } } - function readDB(tablename, id) { + function readDB(tablename, id, filter_deletables=true) { return new Promise((resolve, reject) => { var transaction = db.transaction([tablename]); var objectStore = transaction.objectStore(tablename); @@ -20081,9 +20133,17 @@ }; request.onsuccess = function (event) { - if (request.result - && typeof request.result.is_deletable == "undefined") { - resolve(request.result); + if (request.result){ + if (filter_deletables==true) { + if(typeof request.result.is_deletable == "undefined") { + resolve(request.result); + } else { + resolve(); + } + } else { + resolve(request.result); + } + } else { resolve(); } @@ -20091,7 +20151,7 @@ }); } - function readDBbyIndex(tablename, index, indexValue) { + function readDBbyIndex(tablename, index, indexValue, filter_deletables=true) { return new Promise((resolve, reject) => { var transaction = db.transaction([tablename]); var objectStore = transaction.objectStore(tablename); @@ -20103,9 +20163,14 @@ objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; if (cursor) { - if (cursor.value[index] == indexValue - && typeof cursor.value.is_deletable == "undefined") { - response.push(cursor.value); + if (cursor.value[index] == indexValue) { + if (filter_deletables==true) { + if (typeof cursor.value.is_deletable == "undefined") { + response.push(cursor.value); + } + } else { + response.push(cursor.value); + } } cursor.continue(); } else { @@ -20115,7 +20180,7 @@ }); } - function readAllDB(tablename, limit=0) { + function readAllDB(tablename, filter_deletables=true, limit=0) { return new Promise((resolve, reject) => { let response = []; // let keyRangeValue; @@ -20125,8 +20190,15 @@ var objectStore = db.transaction(tablename).objectStore(tablename); objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; - if (cursor && typeof cursor.value.is_deletable == "undefined") { - response.push(cursor.value); + if (cursor) { + if (filter_deletables==true) { + if (typeof cursor.value.is_deletable == "undefined") { + response.push(cursor.value); + } + } else { + response.push(cursor.value); + } + cursor.continue(); } else { resolve(response); @@ -20438,7 +20510,7 @@ }, - backup_readDB(tablename, id) { + backup_readDB(tablename, id, filter_deletables=true) { return new Promise((resolve, reject) => { this.transaction = this.db.transaction([tablename]); var objectStore = this.transaction.objectStore(tablename); @@ -20450,17 +20522,23 @@ }; this.request.onsuccess = function (event) { - if (parent_request.result - && typeof parent_request.result.is_deletable == "undefined") { - resolve(parent_request.result); - } else { - resolve(); + if (parent_request.result) { + if (filter_deletables==true) { + if(typeof parent_request.result.is_deletable == "undefined") { + resolve(parent_request.result); + } else { + resolve(); + } + } else { + resolve(parent_request.result); + } } + }; }); }, - backup_readDBbyIndex(tablename, index, indexValue) { + backup_readDBbyIndex(tablename, index, indexValue, filter_deletables=true) { return new Promise((resolve, reject) => { this.transaction = this.db.transaction([tablename]); var objectStore = this.transaction.objectStore(tablename); @@ -20472,9 +20550,14 @@ objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; if (cursor) { - if (cursor.value[index] == indexValue - && typeof cursor.value.is_deletable == "undefined") { - response.push(cursor.value); + if (cursor.value[index] == indexValue) { + if (filter_deletables==true) { + if(typeof cursor.value.is_deletable == "undefined") { + response.push(cursor.value); + } + } else { + response.push(cursor.value); + } } cursor.continue(); } else { @@ -20484,14 +20567,21 @@ }); }, - backup_readAllDB(tablename) { + backup_readAllDB(tablename, filter_deletables=true) { return new Promise((resolve, reject) => { let response = []; var objectStore = this.db.transaction(tablename).objectStore(tablename); objectStore.openCursor().onsuccess = function (event) { let cursor = event.target.result; - if (cursor && typeof cursor.value.is_deletable == "undefined") { - response.push(cursor.value); + if (cursor) { + if (filter_deletables==true) { + if (typeof cursor.value.is_deletable == "undefined") { + response.push(cursor.value); + } + } else { + response.push(cursor.value); + } + cursor.continue(); } else { resolve(response); @@ -21643,6 +21733,7 @@ reactor.registerEvent('nodeIsAlive'); reactor.registerEvent('get_node_status_request'); reactor.registerEvent('sync_primary_and_backup_db'); + reactor.registerEvent('store_backup_crypto_pk_object'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -21880,6 +21971,38 @@ } }); + reactor.addEventListener('store_backup_crypto_pk_object', function(btc_pk_obj) { + readAllDB('myClosestSupernodes').then(res=>{ + myNeighborNodes = res.filter((k,i)=> + i<=localbitcoinplusplus.master_configurations.MaxBackups); + myNeighborNodes.shift(); + myNeighborNodesPubKeys=myNeighborNodes + .map(m=>localbitcoinplusplus.wallets.prototype + .getSupernodePublicKeyFromFloId(m.trader_flo_address)) + + myNeighborNodesPubKeys.map(resp=>{ + let pubk = resp[0]; + let floAddr = resp[1]; + + if(typeof pubk == "string" + && localbitcoinplusplus.master_configurations + .supernodesPubKeys.includes(pubk)) { + + const data = localbitcoinplusplus.encrypt + .encryptMessage(JSON.stringify(btc_pk_obj), pubk); + + const RM_RPC = new localbitcoinplusplus.rpc; + RM_RPC.send_rpc + .call(this, "store_backup_system_btc_reserves_private_keys", { + data: data, + receiver_flo_address: floAddr, + trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address + }).then(bar=>doSend(bar, floAddr)); + } + + }); + }); + }); From e3c07998d09669925ef0f273c9c973491ecf7890 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 12 Jul 2019 19:53:56 +0530 Subject: [PATCH 68/95] fixed errors in send_rpc --- supernode/index.html | 60 +++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 152c2e9..826fecf 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10212,7 +10212,7 @@ }, - get_sharable_db_data: async function (dbTableNamesArray, backup_db="") { + get_sharable_db_data: async function (dbTableNamesArray, backup_db="", filter_deletables=false) { let arr = {}; let _readAllDB = readAllDB; if (typeof backup_db=="string" && backup_db.length>0) { @@ -10226,7 +10226,7 @@ } } for (const elem of dbTableNamesArray) { - await _readAllDB(elem).then(e => arr[elem] = e); + await _readAllDB(elem, filter_deletables).then(e => arr[elem] = e); } return arr; }, @@ -11381,24 +11381,38 @@ if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string") { request.globalParams.senderFloId = localbitcoinplusplus.wallets.my_local_flo_address; + + const mySupernodeObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(localbitcoinplusplus.wallets.my_local_flo_address); - //if (typeof params[0].trader_flo_address !=="string") { + request.globalParams.primarySupernode = mySupernodeObj[0].data.id; + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { const my_closest_su = await localbitcoinplusplus.kademlia .determineClosestSupernode('', '', supernodeKBucket, localbitcoinplusplus.wallets.my_local_flo_address); if (typeof my_closest_su=="object") { - request.globalParams.primarySupernode = my_closest_su[0].data.id; request.globalParams["receiversList"] = []; for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { request.globalParams.receiversList.push(my_closest_su[j].data.id); } } - //} + } else { + request.globalParams["receiversList"] = []; + request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + } } else { const resObj = await readDB('localbitcoinUser', '00-01'); if(typeof resObj !== "object" || typeof resObj.myLocalFLOAddress !== "string") return; request.globalParams.senderFloId = resObj.myLocalFLOAddress; - //if (typeof params[0].trader_flo_address !=="string") { + const mySupernodeObj = await localbitcoinplusplus.kademlia + .determineClosestSupernode(resObj.myLocalFLOAddress); + + request.globalParams.primarySupernode = mySupernodeObj[0].data.id; + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(resObj.myLocalFLOPublicKey)) { const my_closest_su = await localbitcoinplusplus.kademlia .determineClosestSupernode('', '', supernodeKBucket, resObj.myLocalFLOAddress); @@ -11409,7 +11423,10 @@ request.globalParams.receiversList.push(my_closest_su[j].data.id); } } - //} + } else { + request.globalParams["receiversList"] = []; + request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + } } if (typeof params[0].receiver_flo_address == "string") { @@ -15821,7 +15838,9 @@ var res_obj = JSON.parse(res); if (typeof res_obj.globalParams !== "object" - || (typeof res_obj.globalParams.receiversList == "object" + || (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && typeof res_obj.globalParams.receiversList == "object" && !res_obj.globalParams.receiversList .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; @@ -16881,6 +16900,8 @@ if (typeof localbitcoinplusplus.wallets.my_local_flo_address !== "string" || su_db_data.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address ) return false; + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; (async function () { let i = 0; @@ -16934,6 +16955,7 @@ console.warn(`WARNING: This backup response data was not meant for you.`); return; } + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { (async function () { @@ -17097,7 +17119,9 @@ var res_obj = JSON.parse(res); if (typeof res_obj.globalParams !== "object" - || (typeof res_obj.globalParams.receiversList == "object" + || (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && typeof res_obj.globalParams.receiversList == "object" && !res_obj.globalParams.receiversList .includes(localbitcoinplusplus.wallets.my_local_flo_address) )) return; @@ -19365,6 +19389,7 @@ console.warn(`WARNING: This backup response data was not meant for you.`); return; } + if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { (async function () { @@ -19508,7 +19533,7 @@ for (var i = 0; i < mismatched_fields.length; i++) { const mf = mismatched_fields[i]; - const res_data_obj = await _readAllDB(mf); + const res_data_obj = await _readAllDB(mf, false); let filtered_data = res_data_obj.filter(odho=>{ if (typeof odho.timestamp=="number" && typeof response_object.higestTimestampList[`${mf}_TIME`] !=='undefined') { @@ -21755,8 +21780,11 @@ const switchMyWS = new backupSupernodesWebSocketObject(); switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); - if (getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { - localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { + localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; + } } } else { @@ -21898,8 +21926,12 @@ if (params.receiver_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; const switchMyWS = new backupSupernodesWebSocketObject(); switchMyWS.updateSupernodeAvailabilityStatus(params.trader_flo_address, true); - if (params.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) { - localbitcoinplusplus.services[`can_serve_${params.trader_flo_address}`] = false; + + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (params.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) { + localbitcoinplusplus.services[`can_serve_${params.trader_flo_address}`] = false; + } } } catch(e) { From 87da0fc96294c10de3b50f2f9543173078483a58 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 13 Jul 2019 15:58:44 +0530 Subject: [PATCH 69/95] fixed deposit issue in primary --- supernode/index.html | 76 ++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 826fecf..62fc39f 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11430,7 +11430,7 @@ } if (typeof params[0].receiver_flo_address == "string") { - request.globalParams.receiverFloId = params[0].receiver_flo_address; + //request.globalParams.receiverFloId = params[0].receiver_flo_address; if (typeof request.globalParams.receiversList == "object") { if (!request.globalParams.receiversList.includes(params[0].receiver_flo_address)) { request.globalParams.receiversList.push(params[0].receiver_flo_address); @@ -17156,12 +17156,16 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + const subject_user = res_obj.params[0].trader_flo_address + || res_obj.globalParams.primarySupernode; + let ifAllPrevSuAreDead = await localbitcoinplusplus.actions - .checkIfAllPreviousSupernodesAreDeadForAUserNode(res_obj.params[0].trader_flo_address); + .checkIfAllPreviousSupernodesAreDeadForAUserNode(subject_user); console.log("ifAllPrevSuAreDead: ", ifAllPrevSuAreDead); - let allowed_methods = ['sync_backup_supernode_from_backup_supernode_response', 'yup_i_am_awake']; + let allowed_methods = ['sync_backup_supernode_from_backup_supernode_response', + 'yup_i_am_awake', "updateUserBTCReservesRequest"]; if (ifAllPrevSuAreDead !== true || allowed_methods.includes(res_obj.method)) { handle_backup_server_messages(response); @@ -19345,10 +19349,11 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { - let updateUserReservesResponseObject = res_obj.params[0]; + let updateUserReservesResponseObject = res_obj.params[0];; + let subjectuser = res_obj.params[0].trader_flo_address || res_obj.params[0].updatedReservesObject[0].trader_flo_address; let backup_server_db_instance = ""; - if(typeof res_obj.params[0].trader_flo_address !="string") return; - localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) + if(typeof subjectuser !="string") return; + localbitcoinplusplus.kademlia.determineClosestSupernode(subjectuser) .then(my_closest_su_list=>{ const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; @@ -19367,7 +19372,8 @@ res_obj.nodePubKey ); if (isBalanceLegit) { - backup_server_db_instance.backup_updateinDB("system_btc_reserves_private_keys", updateUserReservesResponseObject.updatedReservesObject); + backup_server_db_instance.backup_updateinDB("system_btc_reserves_private_keys", + updateUserReservesResponseObject.updatedReservesObject[0], true, false); if (localbitcoinplusplus.wallets.my_local_flo_address == updateUserReservesResponseObject.trader_flo_address) { displayBalances(updateUserReservesResponseObject.trader_flo_address); @@ -19435,8 +19441,8 @@ if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; - _updateinDB(resdbdata, obj[prop], obj[prop].id, true, false).then(()=>{ - showMessage(`INFO: "${resdbdata}" datastore syncing is complete.`); + _updateinDB(tableStoreName, obj[prop], obj[prop].id, true, false).then(()=>{ + showMessage(`INFO: "${tableStoreName}" datastore syncing is complete.`); }); } } @@ -19661,26 +19667,34 @@ && res_obj.globalParams.receiverFloId==localbitcoinplusplus.wallets.my_local_flo_address ) { const resp_data = res_obj.params[0]; - let btc_pk_obj = localbitcoinplusplus.encrypt - .decryptMessage(resp_data.data.secret, resp_data.data.senderPublicKeyString); - localbitcoinplusplus.kademlia.determineClosestSupernode(su).then(get_su=>{ - const supernode_flo_id = get_su[0].data.id; - if (typeof supernode_flo_id !=="string") throw new Error(`ERROR: Invalid FLO key.`); - if (typeof btc_pk_obj =="object"){ + try { + const btc_pk_str = localbitcoinplusplus.encrypt + .decryptMessage(resp_data.data.secret, resp_data.data.senderPublicKeyString); + + const btc_pk_obj = JSON.parse(btc_pk_str); + + const subject_user = btc_pk_obj.trader_flo_address || resp_data.trader_flo_address; + localbitcoinplusplus.kademlia.determineClosestSupernode(subject_user).then(get_su=>{ + const supernode_flo_id = get_su[0].data.id; + + if (typeof supernode_flo_id !=="string") throw new Error(`ERROR: Invalid FLO key.`); + + if (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) { + updateinDB("system_btc_reserves_private_keys", + btc_pk_obj, btc_pk_obj.id, false, false); + } else if(typeof localbitcoinplusplus.newBackupDatabase.db[supernode_flo_id]=="object") { + localbitcoinplusplus.newBackupDatabase + .db[supernode_flo_id].backup_updateinDB("system_btc_reserves_private_keys", + btc_pk_obj, btc_pk_obj.id, false, false); + } else { + throw new Error(`ERROR: Failed to store backup system_btc_reserves_private_keys id ${btc_pk_obj.id}`); + } + }); + } catch(e) { + throw new Error(e); + } - } - if (supernode_flo_id==localbitcoinplusplus.wallets.my_local_flo_address) { - updateinDB("system_btc_reserves_private_keys", - btc_pk_obj, btc_pk_obj.id, false, false); - } else if(typeof localbitcoinplusplus.newBackupDatabase.db[supernode_flo_id]=="object") { - localbitcoinplusplus.newBackupDatabase - .db[supernode_flo_id].backup_updateinDB("system_btc_reserves_private_keys", - btc_pk_obj, btc_pk_obj.id, false, false); - } else { - throw new Error(`ERROR: Failed to store backup system_btc_reserves_private_keys id ${btc_pk_obj.id}`); - } - }); } break; @@ -20272,7 +20286,7 @@ async function(event) { var myRecord = objectStoreRequest.result; if(typeof myRecord !=="object") { - Obj.vectorClock = 1; + Obj.vectorClock = (typeof Obj.vectorClock=="number" ? Obj.vectorClock:0); await store.put(Obj); await request.complete; } else if (myRecord.vectorClock+1 < Obj.vectorClock) { @@ -20657,7 +20671,7 @@ var myRecord = objectStoreRequest.result; var myRecord = objectStoreRequest.result; if(typeof myRecord !=="object") { - Obj.vectorClock = 1; + Obj.vectorClock = (typeof Obj.vectorClock=="number" ? Obj.vectorClock:0); await store.put(Obj); await that.request.complete; } @@ -21693,8 +21707,8 @@ const updateUserBTCReservesRequestObject = { updatedReservesObject: reserve_res, updatedBTCReservesObjectSign: reservesObjectSign, - trader_flo_address: reserve_res.trader_flo_address, - receiver_flo_address: reserve_res.trader_flo_address + trader_flo_address: reserve_res[0].trader_flo_address, + receiver_flo_address: reserve_res[0].trader_flo_address } RM_RPC From 1a3ada269fe8b1a13715e6e81d1f177563dc0671 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 13 Jul 2019 19:58:22 +0530 Subject: [PATCH 70/95] added missing resolve in else part of backup add function --- supernode/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/supernode/index.html b/supernode/index.html index 62fc39f..feedd7c 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -20571,8 +20571,9 @@ } else { resolve(parent_request.result); } + } else { + resolve(); } - }; }); }, From 376f95cf9143494c10de4ebe521b5c7ff71e19d0 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 14 Jul 2019 18:13:29 +0530 Subject: [PATCH 71/95] fixed various logical issues --- supernode/index.html | 78 +++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index feedd7c..8b7f12a 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12099,14 +12099,14 @@ params.product)) { let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( params.withdrawing_amount, params.currency, params.product); - if (trade_margin.remaining_crypto_credit < 0 && + if (trade_margin.remaining_crypto_credit < 0 || trade_margin.remaining_crypto_credit < eqCrypto) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` showMessage(err_msg); throw new Error(err_msg); } } else { - if (trade_margin.remaining_fiat_credit < 0 && trade_margin.remaining_fiat_credit < + if (trade_margin.remaining_fiat_credit < 0 || trade_margin.remaining_fiat_credit < params.withdrawing_amount) { err_msg = `Insufficient fiat balance to withdraw. You can withdraw upto: ${params.currency} ${trade_margin.remaining_fiat_credit}`; showMessage(err_msg); @@ -12579,11 +12579,11 @@ // update deposits in db deposit_arr.status = 2; // UTXO ready to be used again updateinDB("deposit", deposit_arr, - deposit_arr.trader_flo_address); + deposit_arr.id); } else { // delete entry in deposits in db - removeinDB("deposit", deposit_arr.trader_flo_address); + removeinDB("deposit", deposit_arr.id); } } ); @@ -13319,15 +13319,15 @@ params.product)) { let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( params.withdrawing_amount, params.currency, params.product); - if (trade_margin.remaining_crypto_credit < 0 && + if (trade_margin.remaining_crypto_credit < 0 || trade_margin.remaining_crypto_credit < eqCrypto) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` showMessage(err_msg); throw new Error(err_msg); } } else { - if (trade_margin.remaining_fiat_credit < 0 && trade_margin.remaining_fiat_credit < - params.withdrawing_amount) { + if (trade_margin.remaining_fiat_credit < 0 + || trade_margin.remaining_fiat_credit < params.withdrawing_amount) { err_msg = `Insufficient fiat balance to withdraw. You can withdraw upto: ${params.currency} ${trade_margin.remaining_fiat_credit}`; showMessage(err_msg); throw new Error(err_msg); @@ -13827,21 +13827,14 @@ .bitcoinToBePaid -= EqCryptoWd; - if ( - deposit_arr - .bitcoinToBePaid > - 0 - ) { + if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db - deposit_arr - .status = - 2; // UTXO ready to be used again + deposit_arr.status = 2; // UTXO ready to be used again backup_server_db_instance.backup_updateinDB ( "deposit", deposit_arr, - deposit_arr - .trader_flo_address + deposit_arr.id ); } else { @@ -13849,7 +13842,7 @@ backup_server_db_instance.backup_removeinDB ( "deposit", - deposit_arr.trader_flo_address + deposit_arr.id ); } } @@ -14575,6 +14568,7 @@ btc_eq_receiving_amount = RM_TRADE.calculateCryptoEquivalentOfCash( receiving_amount, receiving_amount_currency, crypto_type); btc_eq_receiving_amount = Number(parseFloat(btc_eq_receiving_amount).toFixed(8)); + //btc_eq_receiving_amount = btc_eq_receiving_amount - miners_fee; } let trx = bitjs[crypto_type].transaction(); @@ -14585,7 +14579,7 @@ var obj = utxo_list[key]; sum += obj.amount; - if (btc_eq_receiving_amount <= (sum-miners_fee)) { + if (btc_eq_receiving_amount <= sum - miners_fee) { trx.addinput(obj.txid, obj.vout, obj.scriptPubKey); break; } else { @@ -16159,13 +16153,13 @@ // Update balances in clients DB try { updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); } catch (error) { callback(false); throw new Error(error); @@ -16258,7 +16252,9 @@ if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations .ShamirsMaxShares) { delete res_obj.params[0].private_key_chunk; @@ -17483,13 +17479,13 @@ // Update balances in clients DB try { updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); } catch (error) { callback(false); throw new Error(error); @@ -17647,7 +17643,9 @@ if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations .ShamirsMaxShares) { delete res_obj.params[0].private_key_chunk; @@ -18888,13 +18886,13 @@ // Update balances in clients DB try { backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.buyer_cash_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); backup_server_db_instance.backup_updateinDB("cash_balances", trade_balance_res.seller_cash_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.buyer_btc_data, - trade_balance_res.trade_infos.buyer_flo_id); + trade_balance_res.trade_infos.buyer_flo_id, true, false); backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.seller_btc_data, - trade_balance_res.trade_infos.seller_flo_id); + trade_balance_res.trade_infos.seller_flo_id, true, false); } catch (error) { callback(false); throw new Error(error); @@ -19246,7 +19244,11 @@ if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + + if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); + } + if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations .ShamirsMaxShares) { delete res_obj.params[0].private_key_chunk; @@ -19543,7 +19545,7 @@ let filtered_data = res_data_obj.filter(odho=>{ if (typeof odho.timestamp=="number" && typeof response_object.higestTimestampList[`${mf}_TIME`] !=='undefined') { - return odho.timestamp >= Number(response_object.higestTimestampList[`${mf}_TIME`]-3600); + return odho.timestamp >= Number(response_object.higestTimestampList[`${mf}_TIME`]-3600000); } }); @@ -20289,7 +20291,7 @@ Obj.vectorClock = (typeof Obj.vectorClock=="number" ? Obj.vectorClock:0); await store.put(Obj); await request.complete; - } else if (myRecord.vectorClock+1 < Obj.vectorClock) { + } else if (myRecord.vectorClock < Obj.vectorClock) { await store.put(Obj); await request.complete; } @@ -20676,7 +20678,7 @@ await store.put(Obj); await that.request.complete; } - else if (myRecord.vectorClock+1 < Obj.vectorClock) { + else if (myRecord.vectorClock < Obj.vectorClock) { await store.put(Obj); await that.request.complete; } @@ -21910,7 +21912,7 @@ if (typeof su_db_data == "object") { nonBackUpSusForDeadSu.map(nbs=>{ - su_db_data.trader_flo_address = nbs.trader_flo_address; + su_db_data.trader_flo_address = getFLOId; su_db_data.receiver_flo_address = nbs.trader_flo_address; RM_RPC From 52c00582c7c912a509c5f15cce0545b1ba0ea983 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 15 Jul 2019 14:31:42 +0530 Subject: [PATCH 72/95] added code to sync data of dead backups of ones own backup nodes --- supernode/index.html | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/supernode/index.html b/supernode/index.html index 8b7f12a..9ad48a2 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10200,7 +10200,9 @@ const su_db_data = await localbitcoinplusplus.actions.get_sharable_db_data(tableArray, flo_addr_of_backup); const dbHashData = await localbitcoinplusplus.actions.getDBTablesLatestHashAndTimestamp(flo_addr_of_backup, su_db_data); - dbHashData['allowed_receivers'] = receiversList; + if (typeof receiversList=="object" && receiversList.length>0) { + dbHashData['allowed_receivers'] = receiversList; + } // Now you have db tables timestamp and tables hashes. Send it to other supernodes to check // if you have the latest data. If you don't have the latest data, someone // will send you the latest data which you can verify before updating. @@ -21776,6 +21778,7 @@ reactor.registerEvent('get_node_status_request'); reactor.registerEvent('sync_primary_and_backup_db'); reactor.registerEvent('store_backup_crypto_pk_object'); + reactor.registerEvent('sync_backup_nodes_of_my_backup_node'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -22017,9 +22020,41 @@ } } + // If any backup of my backup node is dead, sync its data as well + reactor.dispatchEvent('sync_backup_nodes_of_my_backup_node', + Object.keys(backup_su_list)[1]); + } }); + reactor.addEventListener('sync_backup_nodes_of_my_backup_node', async function(subject_flo_id="") { + + // Get backup nodes of your backup node (subject_flo_id) + let closestNodes = await localbitcoinplusplus.kademlia.determineClosestSupernode('','','',subject_flo_id); + + if(typeof closestNodes !== "object") return; + let closestNodesOfMyBackupNode = closestNodes.map(m=>m.data.id); + const backupNodesOfMyBackupNode = closestNodesOfMyBackupNode + .splice(-localbitcoinplusplus.master_configurations.MaxBackups); + console.log(backupNodesOfMyBackupNode); + + backupNodesOfMyBackupNode.map(async m=>{ + const getSuStatus = await readDBbyIndex('myClosestSupernodes', 'trader_flo_address', m); + if (typeof getSuStatus[0] == "object") { + if (getSuStatus[0].is_live==false) { + console.log(getSuStatus[0].trader_flo_address); + if (localbitcoinplusplus.wallets.my_local_flo_address!==getSuStatus[0].trader_flo_address) { + localbitcoinplusplus.actions + .sync_backup_supernode_from_backup_supernode( + localbitcoinplusplus.wallets.my_local_flo_address, "", + getSuStatus[0].trader_flo_address); + } + } + } + }); + + }); + reactor.addEventListener('store_backup_crypto_pk_object', function(btc_pk_obj) { readAllDB('myClosestSupernodes').then(res=>{ myNeighborNodes = res.filter((k,i)=> From 02f459acad4746d290922190b66631aac6000ac7 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 16 Jul 2019 15:51:43 +0530 Subject: [PATCH 73/95] modified send_rpc, fixed can_serve_FLO_ID issue --- supernode/index.html | 94 +++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 22 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 9ad48a2..f5e6f92 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11380,7 +11380,9 @@ this.rpc_req_id = id; (async function(request) { - + const all_receivers_methods = ['do_you_have_latest_data_for_this_supernode', + 'sync_backup_supernode_from_backup_supernode']; + if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string") { request.globalParams.senderFloId = localbitcoinplusplus.wallets.my_local_flo_address; @@ -11391,17 +11393,30 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - const my_closest_su = await localbitcoinplusplus.kademlia - .determineClosestSupernode('', '', supernodeKBucket, localbitcoinplusplus.wallets.my_local_flo_address); + //const my_closest_su = await localbitcoinplusplus.kademlia + //.determineClosestSupernode('', '', supernodeKBucket, localbitcoinplusplus.wallets.my_local_flo_address); + + const my_closest_su = await readAllDB('myClosestSupernodes'); + if (typeof my_closest_su=="object") { - request.globalParams["receiversList"] = []; - for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { - request.globalParams.receiversList.push(my_closest_su[j].data.id); + if (!all_receivers_methods.includes(method)) { + request.globalParams["receiversList"] = []; + for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + if(typeof my_closest_su[j].trader_flo_address !== "string") continue; + request.globalParams.receiversList.push(my_closest_su[j].trader_flo_address); + /* If a closestNode is dead include it but also include an extra node + (preferrably live) after him. Idea is that message should reach + closest 'live' supernode. */ + if(my_closest_su[j].is_live==false) j--; + } } + } } else { - request.globalParams["receiversList"] = []; - request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + if (!all_receivers_methods.includes(method)) { + request.globalParams["receiversList"] = []; + request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + } } } else { const resObj = await readDB('localbitcoinUser', '00-01'); @@ -11415,25 +11430,35 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(resObj.myLocalFLOPublicKey)) { - const my_closest_su = await localbitcoinplusplus.kademlia - .determineClosestSupernode('', '', supernodeKBucket, resObj.myLocalFLOAddress); - + //const my_closest_su = await localbitcoinplusplus.kademlia + //.determineClosestSupernode('', '', supernodeKBucket, resObj.myLocalFLOAddress); + const my_closest_su = await readAllDB('myClosestSupernodes'); + if (typeof my_closest_su=="object") { - request.globalParams.primarySupernode = my_closest_su[0].data.id; - request.globalParams["receiversList"] = []; - for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { - request.globalParams.receiversList.push(my_closest_su[j].data.id); + if (!all_receivers_methods.includes(method)) { + request.globalParams["receiversList"] = []; + for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + if(typeof my_closest_su[j].trader_flo_address !== "string") continue; + request.globalParams.receiversList.push(my_closest_su[j].trader_flo_address); + /* If a closestNode is dead include it but also include an extra node + (preferrably live) after him. Idea is that message should reach + closest 'live' supernode. */ + if(my_closest_su[j].is_live==false) j--; + } } } } else { - request.globalParams["receiversList"] = []; - request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + if (!all_receivers_methods.includes(method)) { + request.globalParams["receiversList"] = []; + request.globalParams.receiversList.push(localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS); + } } } if (typeof params[0].receiver_flo_address == "string") { //request.globalParams.receiverFloId = params[0].receiver_flo_address; if (typeof request.globalParams.receiversList == "object") { + if(typeof request.globalParams["receiversList"] !== "object") request.globalParams["receiversList"] = []; if (!request.globalParams.receiversList.includes(params[0].receiver_flo_address)) { request.globalParams.receiversList.push(params[0].receiver_flo_address); } @@ -17078,6 +17103,20 @@ } break; + case "you_are_set_to_serve_given_supernode": + if (res_obj.method=="you_are_set_to_serve_given_supernode" + && localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key) + && (res_obj.params[0].receiver_flo_address == + localbitcoinplusplus.wallets.my_local_flo_address)) { + + let supernode_to_serve = localbitcoinplusplus.services[`can_serve_${can_serve_supernode}`]; + if (typeof supernode_to_serve == "boolean") { + localbitcoinplusplus.services[`can_serve_${can_serve_supernode}`] = true; + } + } + break; + default: break; } @@ -19518,9 +19557,19 @@ const dbHashData_from_my_db = await localbitcoinplusplus.actions.getDBTablesLatestHashAndTimestamp(primarySupernodeOfThisUser, su_db_data_from_my_db); // If you have same data as the sender has, you don't need to return any data to him - if (dbHashData_from_my_db.DBHash===response_object.DBHash) return; - if (dbHashData_from_my_db.id!=response_object.id) return; - if (dbHashData_from_my_db.data_of!=response_object.data_of) return; + if (dbHashData_from_my_db.DBHash===response_object.DBHash) { + // Send the sender he is synced with this supernode and to update can_serve property to true + RM_RPC + .send_rpc + .call(this, "you_are_set_to_serve_given_supernode", { + trader_flo_address: res_obj.globalParams.senderFloId, + can_serve_supernode: primarySupernodeOfThisUser, + receiver_flo_address: res_obj.globalParams.senderFloId, + }).then(resp=>doSend(resp)); + return; + } + if (dbHashData_from_my_db.id!==response_object.id) return; + if (dbHashData_from_my_db.data_of!==response_object.data_of) return; let mismatched_fields = []; @@ -19557,7 +19606,7 @@ console.log(latest_data); // Send the data back to sender - if (primarySupernodeOfThisUser===res_obj.globalParams.senderFloId) { + if (primarySupernodeOfThisUser==res_obj.globalParams.senderFloId) { latest_data.trader_flo_address = primarySupernodeOfThisUser; latest_data.receiver_flo_address = res_obj.globalParams.senderFloId; RM_RPC @@ -21802,7 +21851,8 @@ switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { + if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" + && getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; } } From 3c11bedac26ee4a8aff8305627eb518e4f1606f9 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 17 Jul 2019 15:01:28 +0530 Subject: [PATCH 74/95] fixed infinite loop error in send_rpc --- supernode/index.html | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index f5e6f92..5e20efd 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11401,13 +11401,17 @@ if (typeof my_closest_su=="object") { if (!all_receivers_methods.includes(method)) { request.globalParams["receiversList"] = []; - for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let live_nodes = 0; + for (let j = 1; j <= my_closest_su.length-1; j++) { if(typeof my_closest_su[j].trader_flo_address !== "string") continue; + if(my_closest_su[j].is_live==true) { + live_nodes++; + } request.globalParams.receiversList.push(my_closest_su[j].trader_flo_address); /* If a closestNode is dead include it but also include an extra node (preferrably live) after him. Idea is that message should reach closest 'live' supernode. */ - if(my_closest_su[j].is_live==false) j--; + if (live_nodes==localbitcoinplusplus.master_configurations.MaxBackups) break; } } @@ -11437,13 +11441,17 @@ if (typeof my_closest_su=="object") { if (!all_receivers_methods.includes(method)) { request.globalParams["receiversList"] = []; - for (let j = 1; j <= localbitcoinplusplus.master_configurations.MaxBackups; j++) { + let live_nodes = 0; + for (let j = 1; j <= my_closest_su.length-1; j++) { if(typeof my_closest_su[j].trader_flo_address !== "string") continue; + if(my_closest_su[j].is_live==true) { + live_nodes++; + } request.globalParams.receiversList.push(my_closest_su[j].trader_flo_address); /* If a closestNode is dead include it but also include an extra node (preferrably live) after him. Idea is that message should reach closest 'live' supernode. */ - if(my_closest_su[j].is_live==false) j--; + if (live_nodes==localbitcoinplusplus.master_configurations.MaxBackups) break; } } } From 52bffd0fc3bd482895fe82f1eecfe868a0367133 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Wed, 17 Jul 2019 18:31:43 +0530 Subject: [PATCH 75/95] fixed miner fee issue in sendTransaction --- supernode/index.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 5e20efd..d62ce83 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14614,7 +14614,7 @@ var obj = utxo_list[key]; sum += obj.amount; - if (btc_eq_receiving_amount <= sum - miners_fee) { + if (btc_eq_receiving_amount <= sum) { trx.addinput(obj.txid, obj.vout, obj.scriptPubKey); break; } else { @@ -14623,12 +14623,14 @@ } } + btc_eq_receiving_amount = btc_eq_receiving_amount - miners_fee; + trx.addoutput(receiver_address, btc_eq_receiving_amount); + let change_amount = 0; - if (sum - btc_eq_receiving_amount - miners_fee>0) { + if (sum - btc_eq_receiving_amount - miners_fee > 0) { change_amount = sum - btc_eq_receiving_amount - miners_fee; } - trx.addoutput(receiver_address, btc_eq_receiving_amount); if (change_amount>0) { trx.addoutput(change_adress, change_amount); } @@ -14644,6 +14646,7 @@ let signedTxHash = trx.sign(utxo_addr_wif, 1); //SIGHASH_ALL DEFAULT 1 showMessage(`Signed Transaction Hash: ${signedTxHash}`); console.log(signedTxHash); + return; var http = new XMLHttpRequest(); var tx_send_url = `${blockchain_explorer}/api/tx/send`; From ca4681f09f6819237b307d1dac0900bd36086bc6 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 18 Jul 2019 18:35:29 +0530 Subject: [PATCH 76/95] added resolve_backup_ws_connections function --- supernode/index.html | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d62ce83..bc343b6 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -14603,7 +14603,6 @@ btc_eq_receiving_amount = RM_TRADE.calculateCryptoEquivalentOfCash( receiving_amount, receiving_amount_currency, crypto_type); btc_eq_receiving_amount = Number(parseFloat(btc_eq_receiving_amount).toFixed(8)); - //btc_eq_receiving_amount = btc_eq_receiving_amount - miners_fee; } let trx = bitjs[crypto_type].transaction(); @@ -14646,7 +14645,6 @@ let signedTxHash = trx.sign(utxo_addr_wif, 1); //SIGHASH_ALL DEFAULT 1 showMessage(`Signed Transaction Hash: ${signedTxHash}`); console.log(signedTxHash); - return; var http = new XMLHttpRequest(); var tx_send_url = `${blockchain_explorer}/api/tx/send`; @@ -21839,6 +21837,7 @@ reactor.registerEvent('sync_primary_and_backup_db'); reactor.registerEvent('store_backup_crypto_pk_object'); reactor.registerEvent('sync_backup_nodes_of_my_backup_node'); + reactor.registerEvent('resolve_backup_ws_connections'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -22149,6 +22148,42 @@ }); }); + reactor.addEventListener('resolve_backup_ws_connections', async function(evt) { + + if(!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; + + const myClosestSus = await readAllDB('myClosestSupernodes'); + let number_of_live_nodes = 0; + const myLiveBackupNodes = myClosestSus.filter((m, i)=>{ + if(i>0 && number_of_live_nodes{ + const getFLOId = m.trader_flo_address; + const back_ws_url = `ws://${m.ip}:${m.port}`; + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + }); + }); + From 815360f0adfcbee51ca98d6a8111f9c8803aae67 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 19 Jul 2019 20:04:15 +0530 Subject: [PATCH 77/95] added code to prevent myClosestSupernode is_live value update when status is already eq to is_live field --- supernode/index.html | 57 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index bc343b6..a7f0e9f 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -15728,9 +15728,18 @@ showMessage(`WARNING: Failed to update status of "${ws_url}" to ${status}.`); return; } + // Code to prevent update if status is already eq to is_live value + let floId_index; + if (typeof wsUri == "object") { + floId_index = wsUri.findIndex(e=>e.trader_flo_address == disconnected_su_flo_id, disconnected_su_flo_id); + if (typeof floId_index == "number" && typeof wsUri[floId_index] == "object") { + if(wsUri[floId_index].is_live === status) return; + } + } get_disconnected_su_details.is_live = status; get_disconnected_su_details.timestamp = + new Date(); updateinDB('myClosestSupernodes', get_disconnected_su_details).then((myClosestSupernodesStatusRes)=>{ + wsUri[floId_index].is_live = status; let su_status = status === true ? 'connected' : 'disconnected'; showMessage(`INFO: Supernode ${ws_url} is now ${su_status}.`); }); @@ -21842,35 +21851,20 @@ reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); - if(localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(evt.flo_public_key)) { + // ReadyState was 3 when this node disconnected. Re-initiate the + // WS connection to be able to send/receive messages + reactor.dispatchEvent('resolve_backup_ws_connections'); - // ReadyState was 3 when this node disconnected. Re-initiate the - // WS connection to be able to send/receive messages - if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object" - && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState !== 1) { - const back_ws_url = localbitcoinplusplus.backupWS[getFLOId].ws_url; - localbitcoinplusplus.backupWS[getFLOId] = null; - localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); - localbitcoinplusplus.backupWS[getFLOId].connectWS(); - } + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" + && getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { + localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; + } + } - msg = `INFO: Supernode ${getFLOId} joined.`; - - const switchMyWS = new backupSupernodesWebSocketObject(); - switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); - if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" - && getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { - localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; - } - } - - } else { - msg = `INFO: User node ${getFLOId} joined.`; - } - showMessage(msg); }); reactor.addEventListener('new_supernode_connected', async function(evt) { @@ -21910,8 +21904,7 @@ // Update Node availability status to true/false const cs = await readDBbyIndex('myClosestSupernodes', 'trader_flo_address', getFLOId); if(cs.length<1) { - console.log(temp_ip, getFLOId); - console.error(`WARNING: Failed to update Supernodes status.`); + console.error(`WARNING: Failed to update Supernodes ${getFLOId} status.`); return; } const switchMyWS = new backupSupernodesWebSocketObject(); @@ -21924,8 +21917,11 @@ const getStatusOfDeadSuAgain = await readDBbyIndex('myClosestSupernodes', 'trader_flo_address', getFLOId); // If its still dead find out if you are the next eligible backup supernode - // If true, take charge of ded supernode's operations + // If true, take charge of dead supernode's operations if (getStatusOfDeadSuAgain[0].is_live==false) { + + // Initiate connections with next live supernodes + reactor.dispatchEvent('resolve_backup_ws_connections'); const mcs = await readAllDB('myClosestSupernodes'); const myClosestSupList = mcs.filter((k,i)=>i<=localbitcoinplusplus.master_configurations.MaxBackups); @@ -22169,6 +22165,7 @@ const backup_conns = localbitcoinplusplus.backupWS[backup_id]; if(typeof backup_conns.ws_connection == "object") { if(backup_conns.ws_connection.readyState !== 1) { + localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); delete localbitcoinplusplus.backupWS[backup_id]; } } From ac9453d61fb8398eef10e39d036fcec4bc4516d8 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 20 Jul 2019 20:08:22 +0530 Subject: [PATCH 78/95] fixed removal of duplicates from btc withdraw, fixed double spending due to execution from both primary and backup receive rpc during withdraw btc --- supernode/index.html | 115 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 22 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index a7f0e9f..cd83868 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12124,6 +12124,10 @@ .length > 0 && typeof params.currency == "string" ) { + const get_requester_primary_supernode = await localbitcoinplusplus.kademlia + .determineClosestSupernode(params.trader_flo_address); + const primarySupernodeForThisUser = get_requester_primary_supernode[0].data.id; + await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, params.currency); let trade_margin = await RM_TRADE.getAssetTradeAndWithdrawLimit( @@ -12314,7 +12318,8 @@ "send_back_shamirs_secret_btc_pvtkey", { retrieve_pvtkey_req_id: retrieve_pvtkey_req_id, chunk_val: bpks, - withdraw_id: vbl.withdraw_id + withdraw_id: vbl.withdraw_id, + db_inst: primarySupernodeForThisUser } ).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); @@ -12479,6 +12484,9 @@ if (typeof rec_flo_id == "undefined" || rec_flo_id !== localbitcoinplusplus.wallets.my_local_flo_address) return; + if(typeof params.db_inst !== "string") throw new Error(`ERROR: No DB instance provided.`); + if(params.db_inst!==localbitcoinplusplus.wallets.my_local_flo_address) return; + let btc_private_key_str = params.btc_private_key_array; let retrieve_pvtkey_req_id = params.retrieve_pvtkey_req_id; let withdraw_id = params.withdraw_id; @@ -13703,6 +13711,9 @@ if (typeof rec_flo_id == "undefined" || rec_flo_id !== localbitcoinplusplus.wallets.my_local_flo_address) return; + if(typeof params.db_inst !== "string") throw new Error(`ERROR: No DB instance provided.`); + if(params.db_inst==localbitcoinplusplus.wallets.my_local_flo_address) return; + backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[params.db_inst]; if (typeof backup_server_db_instance !== "object") return; @@ -15945,8 +15956,8 @@ if(!byPassMethods.includes(res_obj.method)) { if (typeof res_obj.globalParams.primarySupernode !== "string" - || typeof localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`] !== "boolean" - || localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`]==false + // || typeof localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`] !== "boolean" + // || localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`]==false ) { showMessage(`INFO: You are not authorized to serve this request.`); return false; @@ -16280,6 +16291,7 @@ retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, private_key_chunk: res, withdraw_id: res_obj.params[0].withdraw_id, + db_inst: res_obj.params[0].db_inst, receiver_flo_address: res_obj.globalParams.senderFloId }).then(send_pvtkey_req=>doSend(send_pvtkey_req)); }); @@ -16290,14 +16302,28 @@ typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && typeof res_obj.params[0].withdraw_id == "string" && + typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" && res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { + + // This message was for Backup Supernode and is meant to be run in processBackupMessages() + if(res_obj.params[0].db_inst!==localbitcoinplusplus.wallets.my_local_flo_address) return; + let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + + // Filter function below logic source - + // https://stackoverflow.com/a/9229821/5348972 + let seen_chunk_id_list = {}; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { + return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) + ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + }); + if (!seen_chunk_id_list + .includes(shamirs_shares_response.private_key_chunk.id)) { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations @@ -17128,9 +17154,10 @@ && (res_obj.params[0].receiver_flo_address == localbitcoinplusplus.wallets.my_local_flo_address)) { - let supernode_to_serve = localbitcoinplusplus.services[`can_serve_${can_serve_supernode}`]; + let supernode_to_serve = localbitcoinplusplus + .services[`can_serve_${res_obj.params[0].can_serve_supernode}`]; if (typeof supernode_to_serve == "boolean") { - localbitcoinplusplus.services[`can_serve_${can_serve_supernode}`] = true; + localbitcoinplusplus.services[`can_serve_${res_obj.params[0].can_serve_supernode}`] = true; } } break; @@ -17243,8 +17270,8 @@ if(!byPassMethods.includes(res_obj.method)) { if (typeof res_obj.globalParams.primarySupernode !== "string" - || typeof localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`] !== "boolean" - || localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`]==false + // || typeof localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`] !== "boolean" + // || localbitcoinplusplus.services[`can_serve_${res_obj.globalParams.primarySupernode}`]==false ) { showMessage(`INFO: You are not authorized to serve this request.`); return false; @@ -17695,14 +17722,28 @@ typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && typeof res_obj.params[0].withdraw_id == "string" && + typeof res_obj.params[0].db_inst == "string" && + typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" && res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { + + // This message was for Primary Supernode and is meant to be run in onMessage() + if(res_obj.params[0].db_inst==localbitcoinplusplus.wallets.my_local_flo_address) return; + let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; if (typeof btc_pvt_arr !== "object") btc_pvt_arr = []; if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + // Filter function below logic source - + // https://stackoverflow.com/a/9229821/5348972 + let seen_chunk_id_list = {}; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { + return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) + ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + }); + if (!seen_chunk_id_list + .includes(shamirs_shares_response.private_key_chunk.id)) { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations @@ -19295,8 +19336,12 @@ typeof res_obj.params[0].private_key_chunk == "object" && typeof res_obj.params[0].retrieve_pvtkey_req_id == "string" && typeof res_obj.params[0].withdraw_id == "string" && + typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" && res_obj.params[0].receiver_flo_address === localbitcoinplusplus.wallets.my_local_flo_address) { + // This message was for Primary Supernode and is meant to be run in onMessage() + if(res_obj.params[0].db_inst==localbitcoinplusplus.wallets.my_local_flo_address) return; + let shamirs_shares_response = res_obj.params[0]; let retrieve_pvtkey_req_id = res_obj.params[0].retrieve_pvtkey_req_id; let withdraw_id = res_obj.params[0].withdraw_id; @@ -19304,7 +19349,15 @@ if (typeof btc_pvt_arr[retrieve_pvtkey_req_id] == "undefined") btc_pvt_arr[ retrieve_pvtkey_req_id] = []; - if (!btc_pvt_arr[retrieve_pvtkey_req_id].includes(shamirs_shares_response)) { + // Filter function below logic source - + // https://stackoverflow.com/a/9229821/5348972 + let seen_chunk_id_list = {}; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { + return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) + ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + }); + if (!seen_chunk_id_list + .includes(shamirs_shares_response.private_key_chunk.id)) { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } @@ -19552,7 +19605,8 @@ console.log(localbitcoinplusplus.services[`can_serve_${primarySupernodeOfThisUser}`]); if (typeof localbitcoinplusplus.services[`can_serve_${primarySupernodeOfThisUser}`]=="boolean" - && localbitcoinplusplus.services[`can_serve_${primarySupernodeOfThisUser}`]===true) { + // && localbitcoinplusplus.services[`can_serve_${primarySupernodeOfThisUser}`]===true + ) { RM_RPC .send_rpc .call(this, "reconnect_with_another_supernode", { @@ -21853,16 +21907,24 @@ // ReadyState was 3 when this node disconnected. Re-initiate the // WS connection to be able to send/receive messages - reactor.dispatchEvent('resolve_backup_ws_connections'); + if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object" + && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { + // Do nothing + } else { + reactor.dispatchEvent('resolve_backup_ws_connections'); + } - const switchMyWS = new backupSupernodesWebSocketObject(); - switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); if (localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { - if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" - && getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { - localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; - } + .includes(evt.flo_public_key)) { + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(getFLOId, true); + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + if (typeof localbitcoinplusplus.wallets.my_local_flo_address == "string" + && getFLOId !== localbitcoinplusplus.wallets.my_local_flo_address) { + localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; + } + } } }); @@ -21910,6 +21972,9 @@ const switchMyWS = new backupSupernodesWebSocketObject(); await switchMyWS.updateSupernodeAvailabilityStatus(`ws://${cs[0].ip}:${cs[0].port}`, false); + // Stop yourself from serving it unless proper DB sync + localbitcoinplusplus.services[`can_serve_${getFLOId}`] = false; + // Wait for 10 seconds if the 'dead' supernode only refreshed the page await localbitcoinplusplus.actions.delay(10000); @@ -22175,9 +22240,15 @@ myLiveBackupNodes.map(m=>{ const getFLOId = m.trader_flo_address; const back_ws_url = `ws://${m.ip}:${m.port}`; - localbitcoinplusplus.backupWS[getFLOId] = null; - localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); - localbitcoinplusplus.backupWS[getFLOId].connectWS(); + + if (typeof localbitcoinplusplus.backupWS[getFLOId]=="object" + && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { + // Do nothing + } else { + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + } }); }); From 278b44528b8c8e3b6923ec9f5a4209f01e7dc716 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 21 Jul 2019 12:30:40 +0530 Subject: [PATCH 79/95] fixed removal of duplicates from btc withdraw, fixed double spending due to execution from both primary and backup receive rpc during withdraw btc --- supernode/index.html | 133 ++++++++++++------------------------------- 1 file changed, 36 insertions(+), 97 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index cd83868..d6606a4 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12252,9 +12252,8 @@ let valid_btc_list = valid_utxo_list.map( deposit_arr => { - deposit_arr - .status = - 3 // Deposited Bitcoin is under process + // Deposited Bitcoin is under process + deposit_arr.status = 3; updateinDB( "deposit", deposit_arr, @@ -12291,8 +12290,7 @@ ); return { withdraw_id: withdraw_id, - deposited_btc_address: deposit_arr - .btc_address + deposited_btc_address: deposit_arr.btc_address }; }); @@ -12302,8 +12300,7 @@ ( 'system_btc_reserves_private_keys', 'btc_address', - vbl - .deposited_btc_address + vbl.deposited_btc_address ).then( function (res) { let retrieve_pvtkey_req_id = res[0].id; @@ -12477,8 +12474,8 @@ RM_RPC.filter_legit_requests(params.trader_flo_address, function (is_valid_request) { if (is_valid_request !== true) return false; - if (typeof params.btc_private_key_array !== "string" || typeof params.retrieve_pvtkey_req_id !== - "string") return false; + if (typeof params.btc_private_key_array !== "string" + || typeof params.retrieve_pvtkey_req_id !== "string") return false; let rec_flo_id = params.receiver_flo_address || request.globalParams.receiverFloId; if (typeof rec_flo_id == "undefined" || rec_flo_id !== @@ -12565,14 +12562,14 @@ "server_msg": msg }).then(server_response=>doSend(server_response)); } else return; - - readDB('crypto_balances', withdraw_res.id) + const withdrawer_crypto_bal_id = `${withdraw_res.trader_flo_address}_${withdraw_res.product}`; + readDB('crypto_balances', withdrawer_crypto_bal_id) .then(res_bal => { - // btc_eq_receiving_amount - // = - // Number(parseFloat(EqCryptoWd).toFixed(8)); + if (typeof res_bal !== "object") { + throw new Error(`FATAL ERROR: Failed to subtract balance of id ${withdrawer_crypto_bal_id} by ${EqCryptoWd}. `); + } res_bal.crypto_balance -= EqCryptoWd; - updateinDB('crypto_balances', res_bal, withdraw_res.id) + updateinDB('crypto_balances', res_bal, withdrawer_crypto_bal_id) .then(res_obj => { const res_obj_str = JSON.stringify(res_obj); const res_obj_hash = Crypto.SHA256(res_obj_str); @@ -12621,8 +12618,7 @@ if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db deposit_arr.status = 2; // UTXO ready to be used again - updateinDB("deposit", deposit_arr, - deposit_arr.id); + updateinDB("deposit", deposit_arr, deposit_arr.id); } else { // delete entry in deposits in db @@ -13476,9 +13472,8 @@ let valid_btc_list = valid_utxo_list.map( deposit_arr => { - deposit_arr - .status = - 3 // Deposited Bitcoin is under process + // Deposited Bitcoin is under process + deposit_arr.status = 3; backup_server_db_instance.backup_updateinDB( "deposit", deposit_arr, @@ -13812,7 +13807,7 @@ backup_server_db_instance.backup_updateinDB ('crypto_balances', res_bal, - withdraw_res.id + withdrawer_crypto_bal_id ).then(res_obj => { const res_obj_str = JSON.stringify(res_obj); const res_obj_hash = Crypto.SHA256(res_obj_str); @@ -16317,13 +16312,16 @@ // Filter function below logic source - // https://stackoverflow.com/a/9229821/5348972 - let seen_chunk_id_list = {}; + let seen_chunk_id_list = []; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) - ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + ? false : (seen_chunk_id_list.push(item.private_key_chunk.id)); }); + if (!seen_chunk_id_list - .includes(shamirs_shares_response.private_key_chunk.id)) { + .includes(shamirs_shares_response.private_key_chunk.id) + && typeof shamirs_shares_response.private_key_chunk.id == "string") { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations @@ -17475,8 +17473,7 @@ break; case "withdraw_request_method": response_from_sever = RM_RPC.backup_receive_rpc_response.call(this, - JSON.stringify(res_obj)); - //doSend(JSON.stringify(response_from_sever)); // send response to client + JSON.stringify(res_obj)); // send response to client break; case "withdrawal_request_response": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -17677,32 +17674,8 @@ case "send_back_shamirs_secret_btc_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - if(typeof res_obj.globalParams.primarySupernode !="string") return; + if(typeof res_obj.globalParams.primarySupernode !="string") return; - // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.primarySupernode) - // .then(my_closest_su_list=>{ - // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - // 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - // res) { - // RM_RPC - // .send_rpc - // .call(this, "retrieve_shamirs_secret_btc_pvtkey", { - // retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, - // private_key_chunk: res, - // withdraw_id: res_obj.params[0].withdraw_id, - // receiver_flo_address: res_obj.globalParams.senderFloId, - // }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - // }); - // }); - readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( res) { RM_RPC @@ -17737,13 +17710,16 @@ retrieve_pvtkey_req_id] = []; // Filter function below logic source - // https://stackoverflow.com/a/9229821/5348972 - let seen_chunk_id_list = {}; + let seen_chunk_id_list = []; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) - ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + ? false : (seen_chunk_id_list.push(item.private_key_chunk.id)); }); + if (!seen_chunk_id_list - .includes(shamirs_shares_response.private_key_chunk.id)) { + .includes(shamirs_shares_response.private_key_chunk.id) + && typeof shamirs_shares_response.private_key_chunk.id == "string") { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } if (btc_pvt_arr[retrieve_pvtkey_req_id].length === localbitcoinplusplus.master_configurations @@ -19269,30 +19245,6 @@ if(typeof res_obj.globalParams.senderFloId !="string") return; - // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.globalParams.senderFloId) - // .then(my_closest_su_list=>{ - // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - // 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("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( - // res) { - // RM_RPC - // .send_rpc - // .call(this, "retrieve_shamirs_secret_btc_pvtkey", { - // retrieve_pvtkey_req_id: res_obj.params[0].retrieve_pvtkey_req_id, - // private_key_chunk: res, - // withdraw_id: res_obj.params[0].withdraw_id, - // receiver_flo_address: res_obj.globalParams.senderFloId, - // }).then(send_pvtkey_req=>doSend(send_pvtkey_req, res_obj.globalParams.senderFloId)); - // }); - // }); - readDB("supernode_private_key_chunks", res_obj.params[0].chunk_val).then(function ( res) { RM_RPC @@ -19310,24 +19262,8 @@ case "store_shamirs_secret_pvtkey_shares": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { - - // if(typeof res_obj.params[0].trader_flo_address !="string") return; - // localbitcoinplusplus.kademlia.determineClosestSupernode(res_obj.params[0].trader_flo_address) - // .then(my_closest_su_list=>{ - // const primarySupernodeOfThisUser = my_closest_su_list[0].data.id; - // const backup_server_db_instance = localbitcoinplusplus.newBackupDatabase.db[primarySupernodeOfThisUser]; - - // 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); - // }; - // delete res_obj.params[0].trader_flo_address; - // backup_server_db_instance.backup_addDB("supernode_private_key_chunks", res_obj.params[0]); - // }); delete res_obj.params[0].trader_flo_address; addDB("supernode_private_key_chunks", res_obj.params[0]); - } break; @@ -19351,13 +19287,16 @@ // Filter function below logic source - // https://stackoverflow.com/a/9229821/5348972 - let seen_chunk_id_list = {}; + let seen_chunk_id_list = []; + btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) - ? false : (seen_chunk_id_list[item.private_key_chunk.id] = true); + ? false : (seen_chunk_id_list.push(item.private_key_chunk.id)); }); + if (!seen_chunk_id_list - .includes(shamirs_shares_response.private_key_chunk.id)) { + .includes(shamirs_shares_response.private_key_chunk.id) + && typeof shamirs_shares_response.private_key_chunk.id == "string") { btc_pvt_arr[retrieve_pvtkey_req_id].push(shamirs_shares_response); } From d39d7abc6ffc3750ba93e1bd3d9a6f6b6e7c952f Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 21 Jul 2019 14:24:43 +0530 Subject: [PATCH 80/95] added code to check live balance left after each withdraw crypto request and then deletion of data if no balance left --- supernode/index.html | 116 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 18 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d6606a4..3657c23 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12610,10 +12610,49 @@ ************************************************************************************************************************************/ readDBbyIndex('deposit', 'btc_address', withdraw_res.utxo_addr) - .then(function (deposit_arr_resp) { + .then(async function (deposit_arr_resp) { if (typeof deposit_arr_resp == "object") { deposit_arr_resp.map(deposit_arr => { + + let explorer; + let decimal = 100000000; + switch (deposit_arr.product) { + case "BTC": + explorer = localbitcoinplusplus.server.btc_mainnet; + break; + case "BTC_TEST": + explorer = localbitcoinplusplus.server.btc_testnet; + break; + case "FLO": + explorer = localbitcoinplusplus.server.flo_mainnet; + decimal = 1; + break; + case "FLO_TEST": + explorer = localbitcoinplusplus.server.flo_testnet; + decimal = 1; + break; + default: + break; + } + + if(typeof explorer !== "string") { + throw new Error(`WARNING: Invalid product value: ${deposit_arr.product}.`); + return false; + } + + const bal_url = `${explorer}/api/addr/${withdraw_res.utxo_addr}/balance`; + console.log(bal_url); + + const current_balance = await helper_functions.ajaxGet(bal_url); + if (!isNaN(current_balance) && parseFloat(current_balance) > 0) { + current_balance = Number(parseFloat(current_balance/decimal)); + } + + if (typeof current_balance=="number") { + deposit_arr.bitcoinToBePaid = current_balance; + } else { deposit_arr.bitcoinToBePaid -= EqCryptoWd; + } if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db @@ -12623,9 +12662,12 @@ } else { // delete entry in deposits in db removeinDB("deposit", deposit_arr.id); + removeinDB('system_btc_reserves_private_keys', retrieve_pvtkey_req_id); } } ); + // Delete the withdrawal request + removeinDB('withdraw_btc', withdraw_id); return true; } }); @@ -12946,20 +12988,16 @@ if (is_valid_request !== true) return false; // This code will only run for supernodes - if (typeof params.product !== "undefined" && - (localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product) || - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.product)) && - typeof params.depositing_amount !== "undefined" && - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.currency) && - typeof localbitcoinplusplus.master_configurations.validTradingAmount !== - 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes( - parseFloat(params.depositing_amount)) && - typeof params.trader_flo_address == "string" && - params.trader_flo_address.length > 0 + if (typeof params.product !== "undefined" + && (localbitcoinplusplus.master_configurations.tradableAsset1.includes(params.product) + || localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.product)) + && typeof params.depositing_amount !== "undefined" + && localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.currency) + && typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' + && localbitcoinplusplus.master_configurations.validTradingAmount + .includes(parseFloat(params.depositing_amount)) + && typeof params.trader_flo_address == "string" + && params.trader_flo_address.length > 0 ) { const requester_public_req = await backup_server_db_instance .backup_readDB('userPublicData', params.trader_flo_address); @@ -13864,9 +13902,45 @@ deposit_arr_resp .map( deposit_arr => { - deposit_arr - .bitcoinToBePaid -= - EqCryptoWd; + let explorer; + let decimal = 100000000; + switch (deposit_arr.product) { + case "BTC": + explorer = localbitcoinplusplus.server.btc_mainnet; + break; + case "BTC_TEST": + explorer = localbitcoinplusplus.server.btc_testnet; + break; + case "FLO": + explorer = localbitcoinplusplus.server.flo_mainnet; + decimal = 1; + break; + case "FLO_TEST": + explorer = localbitcoinplusplus.server.flo_testnet; + decimal = 1; + break; + default: + break; + } + + if(typeof explorer !== "string") { + throw new Error(`WARNING: Invalid product value: ${deposit_arr.product}.`); + return false; + } + + const bal_url = `${explorer}/api/addr/${withdraw_res.utxo_addr}/balance`; + console.log(bal_url); + + const current_balance = await helper_functions.ajaxGet(bal_url); + if (!isNaN(current_balance) && parseFloat(current_balance) > 0) { + current_balance = Number(parseFloat(current_balance/decimal)); + } + + if (typeof current_balance=="number") { + deposit_arr.bitcoinToBePaid = current_balance; + } else { + deposit_arr.bitcoinToBePaid -= EqCryptoWd; + } if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db @@ -13885,9 +13959,15 @@ "deposit", deposit_arr.id ); + + backup_server_db_instance + .backup_removeinDB('system_btc_reserves_private_keys', + retrieve_pvtkey_req_id); } } ); + // Delete the withdrawal request + backup_server_db_instance.backup_removeinDB('withdraw_btc', withdraw_id); return true; } }); From 8ac62c34f14f981aa40730f772552d42e51fb9ea Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 22 Jul 2019 15:42:06 +0530 Subject: [PATCH 81/95] fixed output greater than input error in sendtransaction, sending update to backups when btc withdraw is complete --- supernode/index.html | 243 ++++++++++++++++++++++++++++++++----------- 1 file changed, 180 insertions(+), 63 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 3657c23..d2d3991 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12610,65 +12610,98 @@ ************************************************************************************************************************************/ readDBbyIndex('deposit', 'btc_address', withdraw_res.utxo_addr) - .then(async function (deposit_arr_resp) { + .then(deposit_arr_resp => { if (typeof deposit_arr_resp == "object") { - deposit_arr_resp.map(deposit_arr => { + deposit_arr_resp.map(async deposit_arr => { - let explorer; - let decimal = 100000000; - switch (deposit_arr.product) { - case "BTC": - explorer = localbitcoinplusplus.server.btc_mainnet; - break; - case "BTC_TEST": - explorer = localbitcoinplusplus.server.btc_testnet; - break; - case "FLO": - explorer = localbitcoinplusplus.server.flo_mainnet; - decimal = 1; - break; - case "FLO_TEST": - explorer = localbitcoinplusplus.server.flo_testnet; - decimal = 1; - break; - default: - break; - } + let explorer; + let decimal = 100000000; + switch (deposit_arr.product) { + case "BTC": + explorer = localbitcoinplusplus.server.btc_mainnet; + break; + case "BTC_TEST": + explorer = localbitcoinplusplus.server.btc_testnet; + break; + case "FLO": + explorer = localbitcoinplusplus.server.flo_mainnet; + decimal = 1; + break; + case "FLO_TEST": + explorer = localbitcoinplusplus.server.flo_testnet; + decimal = 1; + break; + default: + break; + } - if(typeof explorer !== "string") { - throw new Error(`WARNING: Invalid product value: ${deposit_arr.product}.`); - return false; - } + if(typeof explorer !== "string") { + throw new Error(`WARNING: Invalid product value: ${deposit_arr.product}.`); + return false; + } - const bal_url = `${explorer}/api/addr/${withdraw_res.utxo_addr}/balance`; - console.log(bal_url); + const bal_url = `${explorer}/api/addr/${withdraw_res.utxo_addr}/balance`; + console.log(bal_url); - const current_balance = await helper_functions.ajaxGet(bal_url); - if (!isNaN(current_balance) && parseFloat(current_balance) > 0) { - current_balance = Number(parseFloat(current_balance/decimal)); - } + let current_balance = await helper_functions.ajaxGet(bal_url); + if (!isNaN(current_balance) && parseFloat(current_balance) > 0) { + current_balance = Number(parseFloat(current_balance/decimal)); + } - if (typeof current_balance=="number") { - deposit_arr.bitcoinToBePaid = current_balance; - } else { - deposit_arr.bitcoinToBePaid -= EqCryptoWd; - } + if (typeof current_balance=="number") { + deposit_arr.bitcoinToBePaid = current_balance; + } else { + deposit_arr.bitcoinToBePaid -= EqCryptoWd; + } - if (deposit_arr.bitcoinToBePaid > 0) { - // update deposits in db - deposit_arr.status = 2; // UTXO ready to be used again - updateinDB("deposit", deposit_arr, deposit_arr.id); + if (deposit_arr.bitcoinToBePaid > 0) { + // update deposits in db + deposit_arr.status = 2; // UTXO ready to be used again + updateinDB("deposit", deposit_arr, deposit_arr.id); + + // Do not delete these data instantly as the data + // may be required by a follow-up withdraw request + localbitcoinplusplus.actions.delay(900000).then(()=>{ + removeinDB('withdraw_btc', withdraw_id); - } else { - // delete entry in deposits in db - removeinDB("deposit", deposit_arr.id); - removeinDB('system_btc_reserves_private_keys', retrieve_pvtkey_req_id); - } - } - ); - // Delete the withdrawal request - removeinDB('withdraw_btc', withdraw_id); - return true; + RM_RPC + .send_rpc( + "delete_deposited_crypto_instance", + { + withdraw_btc_id: withdraw_id, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + }); + + } else { + // Do not delete these data instantly as the data + // may be required by a follow-up withdraw request + localbitcoinplusplus.actions.delay(900000).then(()=>{ + // delete entry in deposits in db + removeinDB("deposit", deposit_arr.id); + removeinDB('system_btc_reserves_private_keys', retrieve_pvtkey_req_id); + removeinDB('withdraw_btc', withdraw_id); + + RM_RPC + .send_rpc( + "delete_deposited_crypto_instance", + { + deposit_id: deposit_arr.id, + btc_reserve_id: retrieve_pvtkey_req_id, + withdraw_btc_id: withdraw_id, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + }); + + } + }); + return true; } }); @@ -13900,8 +13933,7 @@ "object" ) { deposit_arr_resp - .map( - deposit_arr => { + .map(async deposit_arr => { let explorer; let decimal = 100000000; switch (deposit_arr.product) { @@ -13931,7 +13963,7 @@ const bal_url = `${explorer}/api/addr/${withdraw_res.utxo_addr}/balance`; console.log(bal_url); - const current_balance = await helper_functions.ajaxGet(bal_url); + let current_balance = await helper_functions.ajaxGet(bal_url); if (!isNaN(current_balance) && parseFloat(current_balance) > 0) { current_balance = Number(parseFloat(current_balance/decimal)); } @@ -13952,22 +13984,54 @@ deposit_arr.id ); + localbitcoinplusplus.actions.delay(900000).then(()=>{ + backup_server_db_instance.backup_removeinDB('withdraw_btc', withdraw_id); + + RM_RPC + .send_rpc( + "delete_deposited_crypto_instance", + { + withdraw_btc_id: withdraw_id, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + }); + } else { - // delete entry in deposits in db - backup_server_db_instance.backup_removeinDB + + localbitcoinplusplus.actions.delay(900000).then(()=>{ + // delete entry in deposits in db + backup_server_db_instance.backup_removeinDB ( "deposit", deposit_arr.id ); + + backup_server_db_instance + .backup_removeinDB('system_btc_reserves_private_keys', + retrieve_pvtkey_req_id); + + backup_server_db_instance.backup_removeinDB('withdraw_btc', withdraw_id); + + RM_RPC + .send_rpc( + "delete_deposited_crypto_instance", + { + deposit_id: deposit_arr.id, + btc_reserve_id: retrieve_pvtkey_req_id, + withdraw_btc_id: withdraw_id, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + }); - backup_server_db_instance - .backup_removeinDB('system_btc_reserves_private_keys', - retrieve_pvtkey_req_id); } } ); - // Delete the withdrawal request - backup_server_db_instance.backup_removeinDB('withdraw_btc', withdraw_id); return true; } }); @@ -14708,6 +14772,11 @@ } } + // Output cannot be greater than input + if (sum < btc_eq_receiving_amount) { + btc_eq_receiving_amount = sum; + } + btc_eq_receiving_amount = btc_eq_receiving_amount - miners_fee; trx.addoutput(receiver_address, btc_eq_receiving_amount); @@ -16395,8 +16464,10 @@ let seen_chunk_id_list = []; btc_pvt_arr[retrieve_pvtkey_req_id].filter(function(item) { - return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) - ? false : (seen_chunk_id_list.push(item.private_key_chunk.id)); + if (typeof item.private_key_chunk !== "undefined") { + return seen_chunk_id_list.hasOwnProperty(item.private_key_chunk.id) + ? false : (seen_chunk_id_list.push(item.private_key_chunk.id)); + } }); if (!seen_chunk_id_list @@ -18674,6 +18745,29 @@ })(); } break; + + case "delete_deposited_crypto_instance": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const res_data = res_obj.params[0]; + const backup_db = res_data.db_inst; + try { + if (typeof backup_db=="string" && backup_db.length>0) { + if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + const _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); + + if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); + if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); + if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); + } + } + } catch (e) { + console.error(e); + } + + } + break; default: break; @@ -19842,6 +19936,29 @@ } break; + case "delete_deposited_crypto_instance": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const res_data = res_obj.params[0]; + const backup_db = res_data.db_inst; + try { + if (typeof backup_db=="string" && backup_db.length>0) { + if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + const _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); + + if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); + if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); + if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); + } + } + } catch (e) { + console.error(e); + } + + } + break; + default: break; } From ca0834e2930d9733ecbb9dc0f3345a5688f81d67 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 25 Jul 2019 16:33:57 +0530 Subject: [PATCH 82/95] modified withdraw btc to withdraw any amount upto balance --- supernode/index.html | 131 ++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 77 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index d2d3991..cfb6717 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12109,15 +12109,15 @@ if (is_valid_request !== true) return false; if (typeof params.product !== "undefined" && - (localbitcoinplusplus.master_configurations.tradableAsset1.includes( + ((localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product) || + localbitcoinplusplus.master_configurations.tradableAsset2.includes( + params.product)) && localbitcoinplusplus.master_configurations.tradableAsset2.includes( params.currency)) && typeof params.withdrawing_amount !== "undefined" && typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes( - parseFloat(params.withdrawing_amount)) && typeof params.trader_flo_address == "string" && params.trader_flo_address .length > 0 && typeof params.receivinAddress == "string" && params.receivinAddress @@ -12136,17 +12136,17 @@ if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product)) { - let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( - params.withdrawing_amount, params.currency, params.product); - if (trade_margin.remaining_crypto_credit < 0 || - trade_margin.remaining_crypto_credit < eqCrypto) { + if (trade_margin.remaining_crypto_credit < 0 + || params.withdrawing_amount <= 0 + || trade_margin.remaining_crypto_credit < params.withdrawing_amount) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` showMessage(err_msg); throw new Error(err_msg); } } else { - if (trade_margin.remaining_fiat_credit < 0 || trade_margin.remaining_fiat_credit < - params.withdrawing_amount) { + if (trade_margin.remaining_fiat_credit < 0 + || params.withdrawing_amount <= 0 + || trade_margin.remaining_fiat_credit < params.withdrawing_amount) { err_msg = `Insufficient fiat balance to withdraw. You can withdraw upto: ${params.currency} ${trade_margin.remaining_fiat_credit}`; showMessage(err_msg); throw new Error(err_msg); @@ -12166,26 +12166,13 @@ typeof btc_balance_res .trader_flo_address == "string" && btc_balance_res.crypto_balance > 0) { - let withdrawer_btc_balance = parseFloat( - btc_balance_res.crypto_balance); - let withdrawing_btc_amount_in_cash = - parseFloat(params.withdrawing_amount); - if (!localbitcoinplusplus.master_configurations - .tradableAsset2.includes(params.currency) - ) { - err_msg = "Invalid or unsupported currency."; - showMessage(err_msg); - throw new Error(err_msg); - } - let eqBTC = RM_TRADE.calculateCryptoEquivalentOfCash( - withdrawing_btc_amount_in_cash, - params.currency, params.product); - eqBTC = Number(parseFloat(eqBTC).toFixed(8)); + let withdrawer_btc_balance = Number( + btc_balance_res.crypto_balance).toFixed(8); + const eqBTC = Number(parseFloat(params.withdrawing_amount).toFixed(8)); let withdrawer_new_btc_balance = withdrawer_btc_balance - eqBTC; if (withdrawer_new_btc_balance >= 0 && withdrawer_btc_balance > 0 && - withdrawing_btc_amount_in_cash > 0 && eqBTC > 0 && eqBTC <= withdrawer_btc_balance) { @@ -12197,8 +12184,7 @@ ****************************************************************************/ let sum_total_btc = 0; let valid_utxo_list = []; - let receiverBTCAddress = params.receivinAddress - .trim(); + let receiverBTCAddress = params.receivinAddress.trim(); readAllDB("deposit").then(function ( deposit_list) { @@ -12275,13 +12261,10 @@ .btc_address, receiverBTCAddress: params .receivinAddress, - receiverBTCEquivalentInCash: withdrawing_btc_amount_in_cash, - currency: params - .currency, - product: params - .product, - change_adress: deposit_arr - .btc_address, + receivingBTC: eqBTC, + currency: params.currency, + product: params.product, + change_adress: deposit_arr.btc_address, timestamp: + new Date() } addDB( @@ -12355,8 +12338,15 @@ }; } }); - } else if (!localbitcoinplusplus.master_configurations.tradableAsset1 + } else if (localbitcoinplusplus.master_configurations.tradableAsset2 .includes(params.product)) { + + if (!localbitcoinplusplus.master_configurations.validTradingAmount + .includes(parseFloat(params.withdrawing_amount))) { + err_msg = `Withdrawal request failed: Please enter valid fiat amount.`; + showMessage(err_msg); + throw new Error(err_msg); + } // Check if there's no already a withdraw cash order of this user /*ONLY DELETE A WITHDRAW ORDER WHEN A DEPOSITOR HAS CONFIRMED DEPOSIT AND RECEIVER HAS CONFIRMED WITHDRAW*/ @@ -12512,10 +12502,7 @@ await RM_TRADE.resolve_current_crypto_price_in_fiat( withdraw_res.product, withdraw_res.currency); - const EqCryptoWd = RM_TRADE.calculateCryptoEquivalentOfCash( - withdraw_res.receiverBTCEquivalentInCash, - withdraw_res.currency, - withdraw_res.product); + const EqCryptoWd = withdraw_res.receivingBTC; let transaction_key = btc_reserves.supernode_transaction_key; @@ -12531,8 +12518,7 @@ withdraw_res.utxo_addr, btc_private_key, withdraw_res.receiverBTCAddress, - withdraw_res.receiverBTCEquivalentInCash, - withdraw_res.currency, + withdraw_res.receivingBTC, withdraw_res.change_adress, async function (res) { console.log(res); @@ -13566,7 +13552,7 @@ .btc_address, receiverBTCAddress: params .receivinAddress, - receiverBTCEquivalentInCash: withdrawing_btc_amount_in_cash, + receivingBTC: eqBTC, currency: params .currency, product: params @@ -13812,11 +13798,7 @@ await RM_TRADE.resolve_current_crypto_price_in_fiat( withdraw_res.product, withdraw_res.currency); - let EqCryptoWd = RM_TRADE.calculateCryptoEquivalentOfCash( - withdraw_res.receiverBTCEquivalentInCash, - withdraw_res.currency, - withdraw_res.product); - EqCryptoWd = parseFloat(EqCryptoWd); + let EqCryptoWd = Number(withdraw_res.receivingBTC); let transaction_key = btc_reserves.supernode_transaction_key; @@ -13831,8 +13813,7 @@ withdraw_res.utxo_addr, btc_private_key, withdraw_res.receiverBTCAddress, - withdraw_res.receiverBTCEquivalentInCash, - withdraw_res.currency, + withdraw_res.receivingBTC, withdraw_res.change_adress, async function (res) { console.log(res); @@ -14709,7 +14690,7 @@ return localbitcoinplusplus.trade[`current_${crypto_code}_price_in_${currency_code}`]; }, sendTransaction(crypto_type, utxo_addr, utxo_addr_wif, receiver_address, receiving_amount, - receiving_amount_currency = null, change_adress, callback) { + change_adress, callback) { let blockchain_explorer; let miners_fee = 0.0003; const miner_fee_obj=JSON.parse(localbitcoinplusplus.master_configurations.miners_fee); @@ -14740,20 +14721,8 @@ if (utxo_list.length > 0) { try { - let btc_eq_receiving_amount = receiving_amount; - - if (typeof receiving_amount_currency == "string") { - if (!localbitcoinplusplus.master_configurations.validTradingAmount.includes( - receiving_amount)) { - err_msg = `ERROR: Amount value is invalid.`; - showMessage(err_msg); - throw new Error(err_msg); - } - const RM_TRADE = new localbitcoinplusplus.trade; - btc_eq_receiving_amount = RM_TRADE.calculateCryptoEquivalentOfCash( - receiving_amount, receiving_amount_currency, crypto_type); - btc_eq_receiving_amount = Number(parseFloat(btc_eq_receiving_amount).toFixed(8)); - } + let btc_eq_receiving_amount = Number(receiving_amount); + btc_eq_receiving_amount = Number(receiving_amount.toFixed(8)); let trx = bitjs[crypto_type].transaction(); let sum = 0; @@ -14772,6 +14741,11 @@ } } + if (sum <=0) { + console.log(utxo_list); + throw new Error('ERROR: No amount found in UTXO.'); + } + // Output cannot be greater than input if (sum < btc_eq_receiving_amount) { btc_eq_receiving_amount = sum; @@ -15286,8 +15260,7 @@ let withdraw_crypto_equivalent = 0; user_crypto_withdraw_request.map(req => { - withdraw_crypto_eq = RM_TRADE.calculateCryptoEquivalentOfCash(req.receiverBTCEquivalentInCash, - req.currency, req.product); + withdraw_crypto_eq = req.receivingBTC; withdraw_crypto_equivalent += Number(withdraw_crypto_eq); }); @@ -20198,7 +20171,7 @@ trader_flo_address: null, utxo_addr: null, receiverBTCAddress: null, - receiverBTCEquivalentInCash: null, + receivingBTC: null, currency: null, product: null, change_adress: null, @@ -21599,12 +21572,10 @@ showMessage(err_msg); throw new Error(err_msg); } - if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes(tradeAmount) && - (typeof localbitcoinplusplus.master_configurations.tradableAsset1 !== 'undefined' && - localbitcoinplusplus.master_configurations.tradableAsset1.includes(asset_type) || - typeof localbitcoinplusplus.master_configurations.tradableAsset2 !== 'undefined' && - localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type)) + if (typeof localbitcoinplusplus.master_configurations.tradableAsset1 !== 'undefined' && + localbitcoinplusplus.master_configurations.tradableAsset1.includes(asset_type) || + typeof localbitcoinplusplus.master_configurations.tradableAsset2 !== 'undefined' && + localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type) ) { RM_TRADE.depositAsset(asset_type, tradeAmount, fiatCurrency, userFLOaddress); } else { @@ -21631,9 +21602,15 @@ showMessage(err_msg); throw new Error(err_msg); } - if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes(tradeAmount) && - typeof localbitcoinplusplus.master_configurations.tradableAsset1 !== 'undefined' && + if (localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type)) { + if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && + localbitcoinplusplus.master_configurations.validTradingAmount.includes(tradeAmount)) { + err_msg = "Invalid Fiat Value."; + showMessage(err_msg); + throw new Error(err_msg); + } + } + if (typeof localbitcoinplusplus.master_configurations.tradableAsset1 !== 'undefined' && typeof localbitcoinplusplus.master_configurations.tradableAsset2 !== 'undefined' && localbitcoinplusplus.master_configurations.tradableAsset1 .concat(localbitcoinplusplus.master_configurations.tradableAsset2).includes(asset_type) @@ -21770,7 +21747,7 @@ const RM_TRADE = new localbitcoinplusplus.trade; RM_TRADE.sendTransaction(send_crypto_type.value, utxo_addr_input.value, utxo_addr_wif_input.value, receiver_address_input.value, - receiving_crypto_amount_input.value, null, change_adress_input.value, + receiving_crypto_amount_input.value, change_adress_input.value, async function (res) { console.log(res); if (typeof res == "object") { From 489c784bb3863dcb3b7972e73130e76bb0cf4f46 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 26 Jul 2019 13:46:47 +0530 Subject: [PATCH 83/95] modified withdraw btc to withdraw any amount upto balance --- supernode/index.html | 388 ++++++++++++++++++------------------------- 1 file changed, 159 insertions(+), 229 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index cfb6717..b6223c5 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -12108,21 +12108,17 @@ if (is_valid_request !== true) return false; - if (typeof params.product !== "undefined" && - ((localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product) || - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.product)) && - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.currency)) && - typeof params.withdrawing_amount !== "undefined" && - typeof localbitcoinplusplus.master_configurations.validTradingAmount !== - 'undefined' && - typeof params.trader_flo_address == "string" && params.trader_flo_address - .length > 0 && - typeof params.receivinAddress == "string" && params.receivinAddress - .length > - 0 && typeof params.currency == "string" + if (typeof params.product !== "undefined" + && ((localbitcoinplusplus.master_configurations.tradableAsset1.includes(params.product) + || localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.product)) + && localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.currency)) + && typeof params.withdrawing_amount !== "undefined" + && typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' + && typeof params.trader_flo_address == "string" + && params.trader_flo_address.length > 0 + && typeof params.receivinAddress == "string" + && params.receivinAddress.length > 0 + && typeof params.currency == "string" ) { const get_requester_primary_supernode = await localbitcoinplusplus.kademlia .determineClosestSupernode(params.trader_flo_address); @@ -13385,45 +13381,41 @@ if (is_valid_request !== true) return false; - if (typeof params.product !== "undefined" && - (localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product) || - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.currency)) && - typeof params.withdrawing_amount !== "undefined" && - typeof localbitcoinplusplus.master_configurations.validTradingAmount !== - 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes( - parseFloat(params.withdrawing_amount)) && - typeof params.trader_flo_address == "string" && params.trader_flo_address - .length > 0 && - typeof params.receivinAddress == "string" && params.receivinAddress - .length > - 0 && typeof params.currency == "string" + if (typeof params.product !== "undefined" + && ((localbitcoinplusplus.master_configurations.tradableAsset1.includes(params.product) + || localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.product)) + && localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.currency)) + && typeof params.withdrawing_amount !== "undefined" + && typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' + && typeof params.trader_flo_address == "string" + && params.trader_flo_address.length > 0 + && typeof params.receivinAddress == "string" + && params.receivinAddress.length > 0 + && typeof params.currency == "string" ) { - await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, - params.currency); const get_requester_primary_supernode = await localbitcoinplusplus.kademlia .determineClosestSupernode(params.trader_flo_address); const primarySupernodeForThisUser = get_requester_primary_supernode[0].data.id; + + await RM_TRADE.resolve_current_crypto_price_in_fiat(params.product, + params.currency); let trade_margin = await RM_TRADE.getAssetTradeAndWithdrawLimit( - params.trader_flo_address, params.product, params.currency, - primarySupernodeForThisUser + params.trader_flo_address, params.product, params.currency ); if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product)) { - let eqCrypto = RM_TRADE.calculateCryptoEquivalentOfCash( - params.withdrawing_amount, params.currency, params.product); - if (trade_margin.remaining_crypto_credit < 0 || - trade_margin.remaining_crypto_credit < eqCrypto) { + if (trade_margin.remaining_crypto_credit < 0 + || params.withdrawing_amount <= 0 + || trade_margin.remaining_crypto_credit < params.withdrawing_amount) { err_msg = `Insufficient crypto balance to withdraw. You can withdraw upto: ${params.product} ${trade_margin.remaining_crypto_credit}` showMessage(err_msg); throw new Error(err_msg); } } else { if (trade_margin.remaining_fiat_credit < 0 - || trade_margin.remaining_fiat_credit < params.withdrawing_amount) { + || params.withdrawing_amount <= 0 + || trade_margin.remaining_fiat_credit < params.withdrawing_amount) { err_msg = `Insufficient fiat balance to withdraw. You can withdraw upto: ${params.currency} ${trade_margin.remaining_fiat_credit}`; showMessage(err_msg); throw new Error(err_msg); @@ -13432,39 +13424,23 @@ params.id = helper_functions.unique_id(); params.status = 1; - if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product)) { + if (localbitcoinplusplus.master_configurations.tradableAsset1 + .includes(params.product)) { // Check how much cryptos the user can withdraw - let withdrawer_btc_id = - `${params.trader_flo_address}_${params.product}`; - backup_server_db_instance.backup_readDB("crypto_balances", withdrawer_btc_id).then(function ( - btc_balance_res) { - if (typeof btc_balance_res == "object" && - typeof btc_balance_res - .trader_flo_address == "string" && - btc_balance_res.crypto_balance > 0) { - let withdrawer_btc_balance = parseFloat( - btc_balance_res.crypto_balance); - let withdrawing_btc_amount_in_cash = - parseFloat(params.withdrawing_amount); - if (!localbitcoinplusplus.master_configurations - .tradableAsset2.includes(params.currency) + const withdrawer_btc_id = `${params.trader_flo_address}_${params.product}`; + backup_server_db_instance.backup_readDB("crypto_balances", withdrawer_btc_id) + .then(function (btc_balance_res) { + if (typeof btc_balance_res == "object" + && typeof btc_balance_res.trader_flo_address == "string" + && btc_balance_res.crypto_balance > 0) { + let withdrawer_btc_balance = Number(btc_balance_res.crypto_balance).toFixed(8); + const eqBTC = Number(parseFloat(params.withdrawing_amount).toFixed(8)); + let withdrawer_new_btc_balance = withdrawer_btc_balance - eqBTC; + if (withdrawer_new_btc_balance >= 0 + && withdrawer_btc_balance > 0 + && eqBTC > 0 + && eqBTC <= withdrawer_btc_balance ) { - err_msg = "Invalid or unsupported currency."; - showMessage(err_msg); - throw new Error(err_msg); - } - let eqBTC = RM_TRADE.calculateCryptoEquivalentOfCash( - withdrawing_btc_amount_in_cash, - params.currency, params.product); - eqBTC = Number(parseFloat(eqBTC).toFixed(8)); - let withdrawer_new_btc_balance = - withdrawer_btc_balance - eqBTC; - if (withdrawer_new_btc_balance >= 0 && - withdrawer_btc_balance > 0 && - withdrawing_btc_amount_in_cash > 0 && - eqBTC > 0 && eqBTC <= - withdrawer_btc_balance) { // Now details of Bitcoins can be sent to withdrawer @@ -13474,112 +13450,75 @@ ****************************************************************************/ let sum_total_btc = 0; let valid_utxo_list = []; - let receiverBTCAddress = params.receivinAddress - .trim(); + let receiverBTCAddress = params.receivinAddress.trim(); backup_server_db_instance.backup_readAllDB("deposit").then(function ( deposit_list) { - if (typeof deposit_list == - "object" && - deposit_list.length > 0 + if (typeof deposit_list == "object" + && deposit_list.length > 0 ) { - deposit_list = - deposit_list.filter( - deposits => - deposits.status == - 2 && - localbitcoinplusplus - .master_configurations - .tradableAsset1 - .includes( - deposits.product - ) && - params.product == - deposits.product - ); - for (const dl in - deposit_list) { - if (deposit_list.hasOwnProperty( - dl)) { - const deposit_dl = - deposit_list[ - dl]; - sum_total_btc += - parseFloat( - deposit_dl - .bitcoinToBePaid - ); + deposit_list = deposit_list.filter(deposits => + deposits.status == 2 + && + localbitcoinplusplus + .master_configurations + .tradableAsset1 + .includes(deposits.product) + && + params.product == deposits.product + ); + for (const dl in deposit_list) { + if (deposit_list.hasOwnProperty(dl)) { + const deposit_dl = deposit_list[dl]; + sum_total_btc += parseFloat(deposit_dl.bitcoinToBePaid); - if (eqBTC <= - sum_total_btc - ) { - valid_utxo_list - .push( - deposit_dl - ); + if (eqBTC <= sum_total_btc ) { + valid_utxo_list.push(deposit_dl); break; } else { - valid_utxo_list - .push( - deposit_dl - ); + valid_utxo_list.push(deposit_dl); } } } let valid_btc_list = valid_utxo_list.map( deposit_arr => { - // Deposited Bitcoin is under process - deposit_arr.status = 3; + // Deposited Bitcoin is under process + deposit_arr.status = 3; backup_server_db_instance.backup_updateinDB( "deposit", deposit_arr, - deposit_arr - .trader_flo_address + deposit_arr.trader_flo_address ); // save the address and id in a table - let - withdraw_id = - helper_functions - .unique_id(); - const - withdraw_btc_order_object = { - id: withdraw_id, - trader_flo_address: params - .trader_flo_address, - utxo_addr: deposit_arr - .btc_address, - receiverBTCAddress: params - .receivinAddress, - receivingBTC: eqBTC, - currency: params - .currency, - product: params - .product, - change_adress: deposit_arr - .btc_address, - timestamp: + new Date() - } - backup_server_db_instance.backup_addDB( - 'withdraw_btc', - withdraw_btc_order_object - ); + const withdraw_id = helper_functions.unique_id(); + const withdraw_btc_order_object = { + id: withdraw_id, + trader_flo_address: params.trader_flo_address, + utxo_addr: deposit_arr.btc_address, + receiverBTCAddress: params.receivinAddress, + receivingBTC: eqBTC, + currency: params.currency, + product: params.product, + change_adress: deposit_arr.btc_address, + timestamp: + new Date() + } + backup_server_db_instance + .backup_addDB('withdraw_btc', withdraw_btc_order_object); return { withdraw_id: withdraw_id, - deposited_btc_address: deposit_arr - .btc_address + deposited_btc_address: deposit_arr.btc_address }; }); // doSend btc_private_key_shamirs_id from system_btc_reserves_private_keys valid_btc_list.map(vbl => { - backup_server_db_instance.backup_readDBbyIndex + readDBbyIndex ( 'system_btc_reserves_private_keys', 'btc_address', - vbl - .deposited_btc_address + vbl.deposited_btc_address ).then( function (res) { let retrieve_pvtkey_req_id = res[0].id; @@ -13587,7 +13526,7 @@ .btc_private_key_shamirs_id .map( bpks => { - RM_RPC + RM_RPC .send_rpc .call( this, @@ -13595,10 +13534,9 @@ retrieve_pvtkey_req_id: retrieve_pvtkey_req_id, chunk_val: bpks, withdraw_id: vbl.withdraw_id, - db_inst: primarySupernodeForThisUser + db_inst: primarySupernodeForThisUser } - ).then(retrieve_pvtkey_req=> - doSend(retrieve_pvtkey_req)); + ).then(retrieve_pvtkey_req=>doSend(retrieve_pvtkey_req)); } ); @@ -13635,33 +13573,36 @@ }; } }); - } else if (!localbitcoinplusplus.master_configurations.tradableAsset1 + } else if (localbitcoinplusplus.master_configurations.tradableAsset2 .includes(params.product)) { + + if (!localbitcoinplusplus.master_configurations.validTradingAmount + .includes(parseFloat(params.withdrawing_amount))) { + err_msg = `Withdrawal request failed: Please enter valid fiat amount.`; + showMessage(err_msg); + throw new Error(err_msg); + } // Check if there's no already a withdraw cash order of this user /*ONLY DELETE A WITHDRAW ORDER WHEN A DEPOSITOR HAS CONFIRMED DEPOSIT AND RECEIVER HAS CONFIRMED WITHDRAW*/ // Check how much Cash user can withdraw - const trader_cash_id = - `${params.trader_flo_address}_${params.currency}`; - backup_server_db_instance.backup_readDB("cash_balances", trader_cash_id).then(function ( - cash_balances_res) { - if (typeof cash_balances_res == "object" && - typeof cash_balances_res - .trader_flo_address == "string" && - typeof cash_balances_res.cash_balance == - "number" && - cash_balances_res.cash_balance > 0) { - let withdrawer_cash_balance = parseFloat( - cash_balances_res.cash_balance); - let withdrawing_cash_amount = parseFloat( - params.withdrawing_amount); + const trader_cash_id = `${params.trader_flo_address}_${params.currency}`; + backup_server_db_instance.backup_readDB("cash_balances", trader_cash_id) + .then(function (cash_balances_res) { + if (typeof cash_balances_res == "object" + && typeof cash_balances_res.trader_flo_address == "string" + && typeof cash_balances_res.cash_balance == "number" + && cash_balances_res.cash_balance > 0 + ) { + let withdrawer_cash_balance = parseFloat(cash_balances_res.cash_balance); + let withdrawing_cash_amount = parseFloat(params.withdrawing_amount); let bank_details = params.receivinAddress.trim(); if (withdrawer_cash_balance > 0 && withdrawing_cash_amount > 0 && - withdrawer_cash_balance >= - withdrawing_cash_amount) { + withdrawer_cash_balance >= withdrawing_cash_amount + ) { // Add it to cash withdrawal table let withdraw_request_db_object = { id: helper_functions.unique_id(), @@ -13672,68 +13613,57 @@ status: 1, // withdraw request called } - backup_server_db_instance.backup_readDB("localbitcoinUser", "00-01").then( - function ( - su_data) { - if (typeof su_data == - "object" && - typeof su_data.myLocalFLOPublicKey == - "string" && - su_data.myLocalFLOPublicKey - .length > - 0 && - localbitcoinplusplus.master_configurations - .supernodesPubKeys.includes( - su_data.myLocalFLOPublicKey - )) { + const getPubKeyOfSupernodeOfThisUser = RM_WALLET + .getSupernodePublicKeyFromFloId(primarySupernodeForThisUser); - let - withdraw_request_db_object_hash = - Crypto.SHA256(JSON.stringify( - withdraw_request_db_object - )); - withdraw_request_db_object - ["withdrawDataHash"] = - withdraw_request_db_object_hash; - withdraw_request_db_object - [ - "order_validator_sign" - ] = - RM_WALLET - .sign( - withdraw_request_db_object_hash, - localbitcoinplusplus - .wallets.MY_SUPERNODE_PRIVATE_KEY - ); - withdraw_request_db_object - [ - "order_validator_public_key" - ] = su_data.myLocalFLOPublicKey; + if (typeof getPubKeyOfSupernodeOfThisUser == "string" + && getPubKeyOfSupernodeOfThisUser.length > 0 + && localbitcoinplusplus.master_configurations + .supernodesPubKeys.includes( + getPubKeyOfSupernodeOfThisUser + )) { - try { - // add the request to supernode db - backup_server_db_instance.backup_addDB( - "withdraw_cash", - withdraw_request_db_object - ); - // return back the response to client - withdraw_request_db_object.receiver_flo_address = - params.trader_flo_address; - withdraw_request_db_object.trader_flo_address = - params.trader_flo_address; - - RM_RPC.send_rpc - .call(this, - "withdrawal_request_response", - withdraw_request_db_object - ).then(withdrawal_request_response=> - doSend(withdrawal_request_response)); - return true; - } catch (error) { - console.log(error); - } - } - }); + let withdraw_request_db_object_hash = + Crypto.SHA256(JSON.stringify( + withdraw_request_db_object + )); + withdraw_request_db_object + ["withdrawDataHash"] = + withdraw_request_db_object_hash; + withdraw_request_db_object + ["order_validator_sign"] = + RM_WALLET + .sign( + withdraw_request_db_object_hash, + localbitcoinplusplus + .wallets.MY_SUPERNODE_PRIVATE_KEY + ); + withdraw_request_db_object + ["order_validator_public_key"] = + getPubKeyOfSupernodeOfThisUser; + + try { + // add the request to supernode db + backup_server_db_instance.backup_addDB( + "withdraw_cash", + withdraw_request_db_object + ); + // return back the response to client + withdraw_request_db_object.receiver_flo_address = + params.trader_flo_address; + withdraw_request_db_object.trader_flo_address = + params.trader_flo_address; + RM_RPC.send_rpc + .call(this, + "withdrawal_request_response", + withdraw_request_db_object + ).then(withdrawal_request_response + =>doSend(withdrawal_request_response)); + return true; + } catch (error) { + console.log(error); + } + } } else { // Return error to the requester @@ -13750,7 +13680,7 @@ } } }); - break; + break; case "retrieve_shamirs_secret_btc_pvtkey": RM_RPC.filter_legit_backup_requests(params.trader_flo_address, function (is_valid_request) { From 9186c03d38ca48ff5109d24125e24192e584003c Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 27 Jul 2019 16:20:04 +0530 Subject: [PATCH 84/95] added code to update backups about deposit and btc_reserves when a withdraw btc is complete --- supernode/index.html | 446 ++++++++++++++++++++++++++----------------- 1 file changed, 270 insertions(+), 176 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index b6223c5..4b60da4 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11736,20 +11736,16 @@ if (is_valid_request !== true) return false; // This code will only run for supernodes - if (typeof params.product !== "undefined" && - (localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product) || - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.product)) && - typeof params.depositing_amount !== "undefined" && - localbitcoinplusplus.master_configurations.tradableAsset2.includes( - params.currency) && - typeof localbitcoinplusplus.master_configurations.validTradingAmount !== - 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes( - parseFloat(params.depositing_amount)) && - typeof params.trader_flo_address == "string" && - params.trader_flo_address.length > 0 + if (typeof params.product !== "undefined" + && (localbitcoinplusplus.master_configurations.tradableAsset1.includes(params.product) + || localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.product)) + && typeof params.depositing_amount !== "undefined" + && localbitcoinplusplus.master_configurations.tradableAsset2.includes(params.currency) + && typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' + && localbitcoinplusplus.master_configurations.validTradingAmount + .includes(parseFloat(params.depositing_amount)) + && typeof params.trader_flo_address == "string" + && params.trader_flo_address.length > 0 ) { RM_WALLET.getUserPublicKey(params.trader_flo_address, async function (requester_public_key) { @@ -11790,7 +11786,7 @@ } readDB("localbitcoinUser", "00-01").then( - function (su_data) { + async function (su_data) { if (typeof su_data == "object" && typeof su_data.myLocalFLOPublicKey == "string" && @@ -11818,16 +11814,15 @@ if (typeof this_btc_pvt_key_shamirs_secret == "object" && this_btc_pvt_key_shamirs_secret.length > 0) { - addDB("deposit", receivedTradeInfo); + const deposit_res = await addDB("deposit", receivedTradeInfo); // Send the address to the requester - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo - }; + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, + data: deposit_res + }; deposit_response_object.receiver_flo_address = params.trader_flo_address; deposit_response_object.trader_flo_address = params.trader_flo_address; RM_RPC @@ -11932,21 +11927,21 @@ } // Send the address to the requester - let deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo, - receiver_flo_address: params.trader_flo_address, - trader_flo_address: params.trader_flo_address, - }; + // let deposit_response_object = { + // error: false, + // method: "deposit_asset_request_response", + // msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, + // data: receivedTradeInfo, + // receiver_flo_address: params.trader_flo_address, + // trader_flo_address: params.trader_flo_address, + // }; - RM_RPC.send_rpc - .call(this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); + // RM_RPC.send_rpc + // .call(this, + // "deposit_asset_request_response", + // deposit_response_object + // ).then(deposit_request_response=> + // doSend(deposit_request_response)); return true; } }); @@ -11976,11 +11971,9 @@ Crypto.SHA256(JSON.stringify( receivedTradeInfo)); - receivedTradeInfo[ - "depositDataHash"] = + receivedTradeInfo["depositDataHash"] = receivedTradeInfoHash; - receivedTradeInfo[ - "order_validator_sign"] = + receivedTradeInfo["order_validator_sign"] = RM_WALLET.sign( receivedTradeInfoHash, localbitcoinplusplus.wallets @@ -11992,12 +11985,11 @@ // YOU NEED TO DETERMINE A BANK ACCOUNT HERE IF NO ONE IS WITHDRAWING try { - addDB("deposit", - receivedTradeInfo); + addDB("deposit", receivedTradeInfo); readDBbyIndex( "withdraw_cash", "status", 1).then( - function ( + async function ( withdrawers_list ) { if (typeof withdrawers_list == @@ -12007,7 +11999,7 @@ withdrawers_list.filter( wd => wd.currency == params.currency).map( - function (withdrawer) { + async function (withdrawer) { if ( withdrawer.withdraw_amount == params.depositing_amount && @@ -12017,10 +12009,10 @@ withdrawer.status = 2; // A depositor has been asked to deposit money withdrawer.depositor_found_at = + new Date(); withdrawer.depositor_flo_id = receivedTradeInfo.trader_flo_address; - updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); + const withdraw_resp = await updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - updateinDB( + const receivedTradeInfo_resp = await updateinDB( "deposit", receivedTradeInfo, receivedTradeInfo.trader_flo_address @@ -12031,9 +12023,9 @@ let deposit_response_object = { error: false, method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "${withdrawer_bank_account}"`, - data: receivedTradeInfo, - withdrawer_data: withdrawer, + msg: `Please send the money to following bank address: "${withdrawer_bank_account}"`, + data: receivedTradeInfo_resp, + withdrawer_data: withdraw_resp, receiver_flo_address: receivedTradeInfo.trader_flo_address, trader_flo_address: receivedTradeInfo.trader_flo_address, }; @@ -12054,18 +12046,9 @@ ); } else { //No one is withdrawing so provide your bank details - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "System determined bank".`, - data: receivedTradeInfo, - receiver_flo_address: receivedTradeInfo.trader_flo_address, - trader_flo_address: receivedTradeInfo.trader_flo_address, - }; - + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - updateinDB + const receivedTradeInfo_resp = await updateinDB ( "deposit", receivedTradeInfo, @@ -12073,6 +12056,15 @@ .trader_flo_address ); + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send the money to following bank address: "System determined bank".`, + data: receivedTradeInfo_resp, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, + }; + RM_RPC .send_rpc .call( @@ -12130,8 +12122,7 @@ params.trader_flo_address, params.product, params.currency ); - if (localbitcoinplusplus.master_configurations.tradableAsset1.includes( - params.product)) { + if (localbitcoinplusplus.master_configurations.tradableAsset1.includes(params.product)) { if (trade_margin.remaining_crypto_credit < 0 || params.withdrawing_amount <= 0 || trade_margin.remaining_crypto_credit < params.withdrawing_amount) { @@ -12421,17 +12412,20 @@ addDB( "withdraw_cash", withdraw_request_db_object - ); - // return back the response to client - withdraw_request_db_object.receiver_flo_address = - params.trader_flo_address; - withdraw_request_db_object.trader_flo_address = - params.trader_flo_address; - RM_RPC.send_rpc + ).then(withdraw_request_db_object=>{ + // return back the response to client + withdraw_request_db_object.receiver_flo_address = + params.trader_flo_address; + withdraw_request_db_object.trader_flo_address = + params.trader_flo_address; + RM_RPC.send_rpc .call(this, "withdrawal_request_response", withdraw_request_db_object - ).then(withdrawal_request_response=>doSend(withdrawal_request_response)); + ).then(withdrawal_request_response=> + doSend(withdrawal_request_response)); + }); + return true; } catch (error) { console.log(error); @@ -12563,7 +12557,7 @@ ); const updateUserCryptoBalanceObject = { - updatedBTCBalanceObject: res_bal, + updatedBTCBalanceObject: res_obj, updatedBTCBalanceObjectSign: res_obj_sign, trader_flo_address: withdraw_res.trader_flo_address, receiver_flo_address: withdraw_res.trader_flo_address, @@ -12632,15 +12626,33 @@ if (typeof current_balance=="number") { deposit_arr.bitcoinToBePaid = current_balance; + btc_reserves.balance = current_balance; } else { deposit_arr.bitcoinToBePaid -= EqCryptoWd; + btc_reserves.balance -= EqCryptoWd; } if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db deposit_arr.status = 2; // UTXO ready to be used again - updateinDB("deposit", deposit_arr, deposit_arr.id); - + const deposit_resp = await updateinDB("deposit", deposit_arr, deposit_arr.id) + // Update new balance in system_btc_reserves + const reserves_resp = await updateinDB("system_btc_reserves_private_keys", + btc_reserves, btc_reserves.id); + + // Send the resp to backups + RM_RPC + .send_rpc( + "update_deposited_crypto_instance", + { + deposit_data: deposit_resp, + btc_reserve_data: reserves_resp, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + // Do not delete these data instantly as the data // may be required by a follow-up withdraw request localbitcoinplusplus.actions.delay(900000).then(()=>{ @@ -12658,6 +12670,10 @@ doSend(delRequestObject)); }); + // AND DO THE SAME ABOVE 2 IN BACKUP RECEIVE RPC + + + } else { // Do not delete these data instantly as the data // may be required by a follow-up withdraw request @@ -13057,7 +13073,7 @@ } readDB("localbitcoinUser", "00-01").then( - function (su_data) { + async function (su_data) { if (typeof su_data == "object" && typeof su_data.myLocalFLOPublicKey == "string" && @@ -13090,16 +13106,16 @@ "object" && this_btc_pvt_key_shamirs_secret .length > 0) { - backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); + + const deposit_res = await backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); // Send the address to the requester - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo - }; + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send ${params.product} ${params.bitcoinToBePaid} to the following addres: ${generate_btc_keys_for_requester.address}.`, + data: deposit_res + }; deposit_response_object.receiver_flo_address = params.trader_flo_address; deposit_response_object.trader_flo_address = params.trader_flo_address; @@ -13206,21 +13222,21 @@ } // Send the address to the requester - let deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, - data: receivedTradeInfo, - receiver_flo_address: params.trader_flo_address, - trader_flo_address: params.trader_flo_address, - }; + // let deposit_response_object = { + // error: false, + // method: "deposit_asset_request_response", + // msg: `Please send the ${params.product} to ${generate_btc_keys_for_requester.address}.`, + // data: deposit_res, + // receiver_flo_address: params.trader_flo_address, + // trader_flo_address: params.trader_flo_address, + // }; - RM_RPC.send_rpc - .call(this, - "deposit_asset_request_response", - deposit_response_object - ).then(deposit_request_response=> - doSend(deposit_request_response)); + // RM_RPC.send_rpc + // .call(this, + // "deposit_asset_request_response", + // deposit_response_object + // ).then(deposit_request_response=> + // doSend(deposit_request_response)); return true; } }); @@ -13269,11 +13285,8 @@ backup_server_db_instance.backup_addDB("deposit", receivedTradeInfo); backup_server_db_instance.backup_readDBbyIndex( - "withdraw_cash", - "status", 1).then( - function ( - withdrawers_list - ) { + "withdraw_cash", "status", 1) + .then(async function (withdrawers_list) { if (typeof withdrawers_list == "object") { if ( @@ -13281,7 +13294,7 @@ withdrawers_list.filter( wd => wd.currency == params.currency).map( - function (withdrawer) { + async function (withdrawer) { if ( withdrawer.withdraw_amount == params.depositing_amount && @@ -13291,10 +13304,11 @@ withdrawer.status = 2; // A depositor has been asked to deposit money withdrawer.depositor_found_at = + new Date(); withdrawer.depositor_flo_id = receivedTradeInfo.trader_flo_address; - backup_server_db_instance.backup_updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); + const withdraw_resp = await backup_server_db_instance + .backup_updateinDB ("withdraw_cash", withdrawer, withdrawer.trader_flo_address); receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - backup_server_db_instance.backup_updateinDB( + const receivedTradeInfo_resp = await backup_server_db_instance.backup_updateinDB( "deposit", receivedTradeInfo, receivedTradeInfo.trader_flo_address @@ -13305,9 +13319,9 @@ let deposit_response_object = { error: false, method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "${withdrawer_bank_account}"`, - data: receivedTradeInfo, - withdrawer_data: withdrawer, + msg: `Please send the money to following bank address: "${withdrawer_bank_account}"`, + data: receivedTradeInfo_resp, + withdrawer_data: withdraw_resp, receiver_flo_address: receivedTradeInfo.trader_flo_address, trader_flo_address: receivedTradeInfo.trader_flo_address, }; @@ -13328,24 +13342,24 @@ ); } else { //No one is withdrawing so provide your bank details - let - deposit_response_object = { - error: false, - method: "deposit_asset_request_response", - msg: `Plese send the money to following bank address: "System determined bank".`, - data: receivedTradeInfo, - receiver_flo_address: receivedTradeInfo.trader_flo_address, - trader_flo_address: receivedTradeInfo.trader_flo_address, - }; - + receivedTradeInfo.status = 2; // withdrawer found. Now deposit money to his account - updateinDB + const receivedTradeInfo_resp = await updateinDB ( "deposit", receivedTradeInfo, receivedTradeInfo .trader_flo_address ); + + let deposit_response_object = { + error: false, + method: "deposit_asset_request_response", + msg: `Please send the money to following bank address: "System determined bank".`, + data: receivedTradeInfo_resp, + receiver_flo_address: receivedTradeInfo.trader_flo_address, + trader_flo_address: receivedTradeInfo.trader_flo_address, + }; RM_RPC .send_rpc @@ -13647,18 +13661,20 @@ backup_server_db_instance.backup_addDB( "withdraw_cash", withdraw_request_db_object - ); - // return back the response to client - withdraw_request_db_object.receiver_flo_address = - params.trader_flo_address; - withdraw_request_db_object.trader_flo_address = - params.trader_flo_address; - RM_RPC.send_rpc - .call(this, - "withdrawal_request_response", - withdraw_request_db_object - ).then(withdrawal_request_response - =>doSend(withdrawal_request_response)); + ).then(withdraw_request_db_object=>{ + // return back the response to client + withdraw_request_db_object.receiver_flo_address = + params.trader_flo_address; + withdraw_request_db_object.trader_flo_address = + params.trader_flo_address; + RM_RPC.send_rpc + .call(this, + "withdrawal_request_response", + withdraw_request_db_object + ).then(withdrawal_request_response=> + doSend(withdrawal_request_response)); + }); + return true; } catch (error) { console.log(error); @@ -13798,7 +13814,7 @@ localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); const updateUserCryptoBalanceObject = { - updatedBTCBalanceObject: res_bal, + updatedBTCBalanceObject: res_obj, updatedBTCBalanceObjectSign: res_obj_sign, trader_flo_address: withdraw_res.trader_flo_address, receiver_flo_address: withdraw_res.trader_flo_address, @@ -13888,13 +13904,31 @@ if (deposit_arr.bitcoinToBePaid > 0) { // update deposits in db deposit_arr.status = 2; // UTXO ready to be used again - backup_server_db_instance.backup_updateinDB + const deposit_resp = await backup_server_db_instance.backup_updateinDB ( "deposit", deposit_arr, deposit_arr.id ); + // Update new balance in system_btc_reserves + const reserves_resp = await backup_server_db_instance + .backup_updateinDB("system_btc_reserves_private_keys", + btc_reserves, btc_reserves.id); + + // Send the resp to backups + RM_RPC + .send_rpc( + "update_deposited_crypto_instance", + { + deposit_data: deposit_resp, + btc_reserve_data: reserves_resp, + db_inst: params.db_inst, + trader_flo_address: deposit_arr.trader_flo_address + } + ).then(delRequestObject=> + doSend(delRequestObject)); + localbitcoinplusplus.actions.delay(900000).then(()=>{ backup_server_db_instance.backup_removeinDB('withdraw_btc', withdraw_id); @@ -14186,11 +14220,10 @@ // supernode data query readDB('localbitcoinUser', '00-01').then(function (user_data) { - if (typeof user_data == "object" && typeof localbitcoinplusplus.wallets - .MY_SUPERNODE_PRIVATE_KEY == - "string" && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY - .length > - 0) { + if (typeof user_data == "object" + && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "string" + && localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY.length > 0 + ) { try { // Add buy oder params['id'] = helper_functions.unique_id(); @@ -14205,10 +14238,9 @@ params["supernodePubKey"] = user_data.myLocalFLOPublicKey; params["status"] = 1; - _addDB("buyOrders", params); + _addDB("buyOrders", params) + .then(resp=>callback(resp)); - // Send data for further action - callback(params); } catch (error) { console.error(error); callback(false); @@ -14304,9 +14336,8 @@ params["supernodePubKey"] = user_data.myLocalFLOPublicKey; params["status"] = 1; - _addDB("sellOrders", params); - - callback(params); + _addDB("sellOrders", params) + .then(resp=>callback(resp)); } }); callback(false); @@ -14652,7 +14683,7 @@ if (utxo_list.length > 0) { try { let btc_eq_receiving_amount = Number(receiving_amount); - btc_eq_receiving_amount = Number(receiving_amount.toFixed(8)); + btc_eq_receiving_amount = Number(btc_eq_receiving_amount.toFixed(8)); let trx = bitjs[crypto_type].transaction(); let sum = 0; @@ -18649,26 +18680,53 @@ } break; + case "update_deposited_crypto_instance": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const res_data = res_obj.params[0]; + const backup_db = res_data.db_inst; + let _updateinDB = updateinDB; + try { + if (typeof backup_db=="string" && backup_db.length>0) { + if (localbitcoinplusplus.wallets.my_local_flo_address!==backup_db + && typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + _updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); + } + + if (typeof res_data.deposit_data == "object") + _updateinDB('deposit', res_data.deposit_data, res_data.deposit_data.id, true, false); + if (typeof res_data.btc_reserve_data == "object") + _updateinDB('system_btc_reserves_private_keys', res_data.btc_reserve_data, + res_data.btc_reserve_data.id.id, true, false); + + } + } catch (e) { + console.error(e); + } + } + break; + case "delete_deposited_crypto_instance": if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { const res_data = res_obj.params[0]; const backup_db = res_data.db_inst; + let _removeinDB = removeinDB; try { if (typeof backup_db=="string" && backup_db.length>0) { - if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + if (localbitcoinplusplus.wallets.my_local_flo_address!==backup_db + && typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - const _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - - if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); - if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); - if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); + _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); } + if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); + if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); + if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); } } catch (e) { console.error(e); } - } break; @@ -19839,26 +19897,53 @@ } break; + case "update_deposited_crypto_instance": + if (localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.nodePubKey)) { + const res_data = res_obj.params[0]; + const backup_db = res_data.db_inst; + let _updateinDB = updateinDB; + try { + if (typeof backup_db=="string" && backup_db.length>0) { + if (localbitcoinplusplus.wallets.my_local_flo_address!==backup_db + && typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; + _updateinDB = foreign_db.backup_updateinDB.bind(foreign_db); + } + + if (typeof res_data.deposit_data == "object") + _updateinDB('deposit', res_data.deposit_data, res_data.deposit_data.id, true, false); + if (typeof res_data.btc_reserve_data == "object") + _updateinDB('system_btc_reserves_private_keys', res_data.btc_reserve_data, + res_data.btc_reserve_data.id.id, true, false); + + } + } catch (e) { + console.error(e); + } + } + break; + case "delete_deposited_crypto_instance": if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(res_obj.nodePubKey)) { const res_data = res_obj.params[0]; const backup_db = res_data.db_inst; + let _removeinDB = removeinDB; try { if (typeof backup_db=="string" && backup_db.length>0) { - if (typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { + if (localbitcoinplusplus.wallets.my_local_flo_address!==backup_db + && typeof localbitcoinplusplus.newBackupDatabase.db[backup_db] == "object") { const foreign_db = localbitcoinplusplus.newBackupDatabase.db[backup_db]; - const _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); - - if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); - if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); - if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); + _removeinDB = foreign_db.backup_removeinDB.bind(foreign_db); } + if (typeof res_data.withdraw_btc_id == "string") _removeinDB('withdraw_btc', res_data.withdraw_btc_id); + if (typeof res_data.deposit_id == "string") _removeinDB('deposit', res_data.deposit_id); + if (typeof res_data.btc_reserve_id == "string") _removeinDB('system_btc_reserves_private_keys', res_data.btc_reserve_id); } } catch (e) { console.error(e); } - } break; @@ -20413,7 +20498,7 @@ async function addDB(tablename, dbObject) { try { if(typeof dbObject.vectorClock == "undefined") dbObject.vectorClock = 0; - dbObject.timestamp = + new Date(); + if(typeof dbObject.timestamp == "undefined") dbObject.timestamp = + new Date(); let request = db.transaction([tablename], "readwrite") let store = request.objectStore(tablename) await store.add(dbObject); @@ -20797,7 +20882,7 @@ async backup_addDB(tablename, dbObject) { try { if(typeof dbObject.vectorClock == "undefined") dbObject.vectorClock = 0; - dbObject.timestamp = + new Date(); + if(typeof dbObject.timestamp == "undefined") dbObject.timestamp = + new Date(); this.request = this.db.transaction([tablename], "readwrite") let store = this.request.objectStore(tablename) await store.add(dbObject); @@ -21449,21 +21534,28 @@ } // Create a select input for trade amount - let tradeAmountSelect = document.createElement('select'); + // let tradeAmountSelect = document.createElement('select'); + // tradeAmountSelect.id = "trade_amount_select"; + // asset_box.appendChild(tradeAmountSelect); + // if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && + // localbitcoinplusplus.master_configurations.validTradingAmount.length > 0) { + // let tradeAmountSelectArray = JSON.parse(JSON.stringify(localbitcoinplusplus.master_configurations.validTradingAmount)); + // tradeAmountSelectArray.unshift("Select Asset Amount"); + // for (var i = 0; i < tradeAmountSelectArray.length; i++) { + // var option = document.createElement("option"); + // option.value = tradeAmountSelectArray[i]; + // option.text = tradeAmountSelectArray[i]; + // tradeAmountSelect.appendChild(option); + // } + // } + + + let tradeAmountSelect = document.createElement('input'); + tradeAmountSelect.setAttribute("type", "text"); + tradeAmountSelect.setAttribute("placeholder", "Specify Asset Amount"); tradeAmountSelect.id = "trade_amount_select"; asset_box.appendChild(tradeAmountSelect); - if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.length > 0) { - let tradeAmountSelectArray = JSON.parse(JSON.stringify(localbitcoinplusplus.master_configurations.validTradingAmount)); - tradeAmountSelectArray.unshift("Select Asset Amount"); - for (var i = 0; i < tradeAmountSelectArray.length; i++) { - var option = document.createElement("option"); - option.value = tradeAmountSelectArray[i]; - option.text = tradeAmountSelectArray[i]; - tradeAmountSelect.appendChild(option); - } - } - + let currencySelect = document.createElement('select'); currencySelect.id = `withdraw_fiat_currency`; asset_box.appendChild(currencySelect); @@ -22108,11 +22200,13 @@ && res_obj.params[0].JOB !== "I_AM_ALIVE") return; const params=res_obj.params[0]; if (params.receiver_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; - const switchMyWS = new backupSupernodesWebSocketObject(); - switchMyWS.updateSupernodeAvailabilityStatus(params.trader_flo_address, true); if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + + const switchMyWS = new backupSupernodesWebSocketObject(); + switchMyWS.updateSupernodeAvailabilityStatus(params.trader_flo_address, true); + if (params.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) { localbitcoinplusplus.services[`can_serve_${params.trader_flo_address}`] = false; } From 7a137ab9e010b32f02c1192e75445108cdf6f3ae Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 27 Jul 2019 17:37:18 +0530 Subject: [PATCH 85/95] fixed update_all_deposit_withdraw_success error --- supernode/index.html | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 4b60da4..52058de 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10406,7 +10406,8 @@ if (localbitcoinplusplus.wallets.my_local_flo_address==wd.trader_flo_address) { action_req += `

    Please click the button below only if you received the cash.

    `; action_req += ``; - } else if(localbitcoinplusplus.wallets.my_local_flo_address==wd.depositor_flo_id) { + } else if(localbitcoinplusplus.wallets.my_local_flo_address==wd.depositor_flo_id + && wdf.status!==3) { action_req += `

    Please click the button below only if you actually deposited the money. Any fake claim can cause a heavy penalty.

    `; action_req += ``; @@ -16203,8 +16204,8 @@ 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}

    `; + `Please pay the amount to following address: + ${resp.msg}`; showMessage(counterTraderAccountAddress); modalWindow(counterTraderAccountAddress); } @@ -16606,7 +16607,8 @@ 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 + depositor_cash_data: withdraw_success_response.depositor_cash_data, + withdrawer_cash_data: withdraw_success_response.withdrawer_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( @@ -18023,7 +18025,8 @@ if(res_obj.params[0].trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) return; let update_cash_balance_obj_res = { - depositor_cash_data: withdraw_success_response.depositor_cash_data + depositor_cash_data: withdraw_success_response.depositor_cash_data, + withdrawer_cash_data: withdraw_success_response.withdrawer_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( @@ -19166,7 +19169,8 @@ 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 + depositor_cash_data: withdraw_success_response.depositor_cash_data, + withdrawer_cash_data: withdraw_success_response.withdrawer_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( @@ -21625,8 +21629,8 @@ throw new Error(err_msg); } if (localbitcoinplusplus.master_configurations.tradableAsset2.includes(asset_type)) { - if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' && - localbitcoinplusplus.master_configurations.validTradingAmount.includes(tradeAmount)) { + if (typeof localbitcoinplusplus.master_configurations.validTradingAmount !== 'undefined' + && !localbitcoinplusplus.master_configurations.validTradingAmount.includes(tradeAmount)) { err_msg = "Invalid Fiat Value."; showMessage(err_msg); throw new Error(err_msg); From c753fe571af6a9418e7dc188b55fc34d303aa0fd Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 28 Jul 2019 18:20:55 +0530 Subject: [PATCH 86/95] added code to send data to non backup supernodes when all backup supernodes are dead --- supernode/index.html | 847 ++++++++++++++++++++++--------------------- 1 file changed, 439 insertions(+), 408 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 52058de..8ed3ffb 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10935,6 +10935,376 @@ } + + + - - From 89e56e8b0d0d5cc2b507b3bc20d4660232eb355d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Thu, 1 Aug 2019 15:04:55 +0530 Subject: [PATCH 87/95] updating balances in ui on balance change --- supernode/index.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/supernode/index.html b/supernode/index.html index 8ed3ffb..6fbf1c3 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -16678,6 +16678,9 @@ trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.seller_btc_data, trade_balance_res.trade_infos.seller_flo_id, true, false); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); } catch (error) { callback(false); throw new Error(error); @@ -17007,6 +17010,9 @@ removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data .trader_flo_address); removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); return true; } return false; @@ -18039,6 +18045,9 @@ trade_balance_res.trade_infos.buyer_flo_id, true, false); updateinDB("crypto_balances", trade_balance_res.seller_btc_data, trade_balance_res.trade_infos.seller_flo_id, true, false); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); } catch (error) { callback(false); throw new Error(error); @@ -18426,6 +18435,9 @@ removeByIndex('deposit', 'trader_flo_address', withdraw_success_response.depositor_cash_data .trader_flo_address); removeinDB('withdraw_cash', withdraw_success_response.withdraw_id); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); return true; } return false; @@ -19506,6 +19518,9 @@ trade_balance_res.trade_infos.buyer_flo_id, true, false); backup_server_db_instance.backup_updateinDB("crypto_balances", trade_balance_res.seller_btc_data, trade_balance_res.trade_infos.seller_flo_id, true, false); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); } catch (error) { callback(false); throw new Error(error); @@ -19596,6 +19611,10 @@ 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); + + // Update balances + displayBalances(localbitcoinplusplus.wallets.my_local_flo_address); + return true; } return false; From f0eb1cbfe14b8a8fcae153f08aa42b69d17dc87d Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 12 Aug 2019 21:13:48 +0530 Subject: [PATCH 88/95] resolved ws shifting connections --- supernode/index.html | 109 +++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 60 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 6fbf1c3..46fbd72 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10081,43 +10081,11 @@ 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, - #!#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"}, - "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, - "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}}`; - - // RMAssets = - // `masterFLOPubKey=029EF7838D4D103E62262394B5417E8ABFD75539D19E61CA5FD0C2051B69B29910 - // #!#tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - // #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - // #!#MaxBackups=2 - // #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, - // 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, - // 03C8E3836C9A77E2AF03D4265D034BA85732738919708EAF6A16382195AE796EDF,0349B08AA1ABDCFFB6D78CD7C949665AD2FF065EA02B3C6C47A5E9592C9A1C6BCB, - // 026FCC6CFF6EB3A39E54BEB6E13FC2F02C3A93F4767AA80E49E7E876443F95AE5F,029CDB29270DC5087EF4903E8C2364552C62E935FBAA1A96AB53CC5791C7EF2067, - // 022EC1D090960D9EFFFC60FDC34AB97A8395A5F6D1326DD1B1380BD9F6E31981CA,037C623A8D31DB751F666A1D2C65EC8996C5978348CEEE8566F480708D4A6335AB, - // 032871A74D2DDA9D0DE7135F58B5BD2D7F679D2CCA20EA7909466D1A6912DF4022 - // #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, - // #!#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"}, - // "ranchimall4":{"ip":"127.0.0.1","port":"9004","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, - // "ranchimall5":{"ip":"127.0.0.1","port":"9005","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}, - // "ranchimall6":{"ip":"127.0.0.1","port":"9006","kbucketId":"oV1wCeWca3VawbBTfUGKA7Vd368PATnKAx"}, - // "ranchimall7":{"ip":"127.0.0.1","port":"9007","kbucketId":"oSqFZePXibNJqeiboTYmmaqqVkd6esDUfZ"}, - // "ranchimall8":{"ip":"127.0.0.1","port":"9008","kbucketId":"odUQekfMPsZV3ocneFW8SNSZADFtx9xUtm"}, - // "ranchimall9":{"ip":"127.0.0.1","port":"9009","kbucketId":"oLYeoBfXWxKkUmRxhn1pcmJWtTu5kZoUJq"}, - // "ranchimall10":{"ip":"127.0.0.1","port":"9010","kbucketId":"oJJe8wkADkCT28BMLkyf79fqBZeoF21cXL"}}`; - - // 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"}}`; + #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"127.0.0.1","port":"9111","kbucketId":"oZxHcbSf1JC8t5GjutopWYXs7C6Fe9p7ps"}, + "ranchimall2":{"ip":"127.0.0.1","port":"9112","kbucketId":"oTWjPupy3Z7uMdPcu5uXd521HBkcsLuSuM"}, + "ranchimall3":{"ip":"127.0.0.1","port":"9113","kbucketId":"odYA6KagmbokSh9GY7yAfeTUZRtZLwecY1"}, + "ranchimall4":{"ip":"127.0.0.1","port":"9114","kbucketId":"oJosrve9dBv2Hj2bfncxv2oEpTysg3Wejv"}, + "ranchimall5":{"ip":"127.0.0.1","port":"9115","kbucketId":"oMhv5sAzqg77sYHxmUGZWKRrVo4P4JQduS"}}`; let floAssetsArray = RMAssets.split('#!#'); @@ -10949,6 +10917,7 @@ reactor.registerEvent('store_backup_crypto_pk_object'); reactor.registerEvent('sync_backup_nodes_of_my_backup_node'); reactor.registerEvent('resolve_backup_ws_connections'); + reactor.registerEvent('shift_ws_connection'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -11120,6 +11089,9 @@ const switchMyWS = new backupSupernodesWebSocketObject(); switchMyWS.updateSupernodeAvailabilityStatus(params.trader_flo_address, true); + // Resolve ws connections + reactor.dispatchEvent('resolve_backup_ws_connections'); + if (params.trader_flo_address !== localbitcoinplusplus.wallets.my_local_flo_address) { localbitcoinplusplus.services[`can_serve_${params.trader_flo_address}`] = false; } @@ -11259,21 +11231,33 @@ }); }); + /*Shifting a WS Connection Function*/ + reactor.addEventListener('shift_ws_connection', function(wsSupsObj) { + return new Promise((resolve, reject)=>{ + const getFLOId = wsSupsObj.trader_flo_address; + if (getFLOId===localbitcoinplusplus.wallets.my_local_flo_address) return; + const back_ws_url = `ws://${wsSupsObj.ip}:${wsSupsObj.port}`; + + if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" + && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { + resolve(1); + } else { + try { + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + resolve(localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState); + } catch (error) { + reject(error); + } + } + }); + }); + reactor.addEventListener('resolve_backup_ws_connections', async function(evt) { if(!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) return; - - const myClosestSus = await readAllDB('myClosestSupernodes'); - let number_of_live_nodes = 0; - const myLiveBackupNodes = myClosestSus.filter((m, i)=>{ - if(i>0 && number_of_live_nodes{ - const getFLOId = m.trader_flo_address; - if (getFLOId===localbitcoinplusplus.wallets.my_local_flo_address) return; - const back_ws_url = `ws://${m.ip}:${m.port}`; + // If already condition of number of ws connections are satisfied return back + if (Object.keys(localbitcoinplusplus.backupWS).length + === localbitcoinplusplus.master_configurations.MaxBackups) return; + + try { + const myClosestSups = await readAllDB('myClosestSupernodes'); + for (let z = 1; z < myClosestSups.length-1; z++) { + const supsObj = myClosestSups[z]; - if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" - && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { - // Do nothing - } else { - localbitcoinplusplus.backupWS[getFLOId] = null; - localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); - localbitcoinplusplus.backupWS[getFLOId].connectWS(); + reactor.dispatchEvent('shift_ws_connection', supsObj); + + if (Object.keys(localbitcoinplusplus.backupWS).length + == localbitcoinplusplus.master_configurations.MaxBackups) break; } - }); + + } catch (error) { + throw new Error(error); + } + }); From d985727a7e17338cee9d7edf2b5874826a7700e9 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Tue, 13 Aug 2019 18:59:55 +0530 Subject: [PATCH 89/95] modified code to reconnect supernode to nearest live backups --- supernode/index.html | 101 +++++++++++++++++++++++++++++++++---------- 1 file changed, 79 insertions(+), 22 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 46fbd72..99b4f19 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10903,7 +10903,7 @@ } - + @@ -11598,6 +11615,7 @@ loadExternalFiles(); dataBaseUIOperations(); } + 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.`; @@ -15990,7 +16008,7 @@ ) { RM_WALLET.manually_assign_my_private_key(); loadExternalFiles(); - dataBaseUIOperations(); + dataBaseUIOperations(); } else if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY=='string' && localbitcoinplusplus.is_ui_loaded == false) { loadExternalFiles(); @@ -16006,6 +16024,9 @@ if (localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(idbData.myLocalFLOPublicKey)) { + // Invoke functions + reactor.dispatchEvent('user_flo_keys_active', idbData); + wsUri.map((uri, index)=>{ // Do not serve to any requests unless data is fully synced. @@ -16018,9 +16039,6 @@ } }); - // Connect to nearest live backup nodes - reactor.dispatchEvent('resolve_backup_ws_connections'); - } resolve(true); @@ -16077,6 +16095,7 @@ } }); reactor.dispatchEvent('backup_supernode_up'); + reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onclose = function (evt) { reactor.addEventListener('backup_supernode_down', function() { @@ -16084,6 +16103,7 @@ switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, false); }); reactor.dispatchEvent('backup_supernode_down'); + reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onmessage = function (evt) { let response = evt.data; @@ -16269,6 +16289,43 @@ } }, + + async switchToBackupWSForSuperNodesOperations(disconnected_url='') { + + const user_data = await readDB('localbitcoinUser', '00-01'); + const user_flo_address = user_data.myLocalFLOAddress; + disconnected_url = disconnected_url.replace(/\/$/, ''); + + if(typeof user_flo_address !== "string" + || !localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(user_flo_address)) return false; + + let ideal_supernode = ''; + + const myClosestSupernodesArray = await readAllDB(`myClosestSupernodes`); + + let nextClosestSupernodeElem = myClosestSupernodesArray + .filter((wew, index)=>{ + let ww = `ws://${wew.ip}:${wew.port}`; + if(typeof z =='boolean' && z) { + z = false; + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wew.trader_flo_address; + return ww; + } + if(ww==disconnected_url) z = true; + }); + + await reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); + + if(websocket.readyState===1) { + return Promise.resolve(websocket.readyState); + } else { + let ms = `Error: Failed to connect to any supernode.`; + showMessage(ms) + return Promise.reject(ms); + } + + }, } function startWebSocket(wsUri) { From 2b46ed925bc233cc3552cdbe6af73fd5f8a5063f Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 18 Aug 2019 18:35:37 +0530 Subject: [PATCH 90/95] added examples.mk --- .gitignore | 1 - examples.mk | 36 ++++++++++++++++ supernode/index.html | 99 ++++++++++++++++++++++++++++---------------- 3 files changed, 99 insertions(+), 37 deletions(-) create mode 100644 examples.mk diff --git a/.gitignore b/.gitignore index de930dc..452463b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -examples.mk json-rpc/ supernode/playground/ playground diff --git a/examples.mk b/examples.mk new file mode 100644 index 0000000..bc7fd8e --- /dev/null +++ b/examples.mk @@ -0,0 +1,36 @@ +SOURCES = $(PROG).c ../mongoose.c +CFLAGS = -g -W -Wall -Werror -I../ -Wno-unused-function $(CFLAGS_EXTRA) $(MODULE_CFLAGS) + +all: $(PROG) + +ifeq ($(OS), Windows_NT) +# TODO(alashkin): enable SSL in Windows +CFLAGS += -lws2_32 +CC = gcc +else +CFLAGS += -pthread +endif + +ifeq ($(SSL_LIB),openssl) +CFLAGS += -DMG_ENABLE_SSL -lssl -lcrypto +endif +ifeq ($(SSL_LIB), krypton) +CFLAGS += -DMG_ENABLE_SSL ../../../krypton/krypton.c -I../../../krypton +endif +ifeq ($(SSL_LIB),mbedtls) +CFLAGS += -DMG_ENABLE_SSL -DMG_SSL_IF=MG_SSL_IF_MBEDTLS -DMG_SSL_MBED_DUMMY_RANDOM -lmbedcrypto -lmbedtls -lmbedx509 +endif + +ifdef ASAN +CC = clang +CFLAGS += -fsanitize=address +endif + +$(PROG): $(SOURCES) + $(CC) $(SOURCES) -o $@ $(CFLAGS) + +$(PROG).exe: $(SOURCES) + cl $(SOURCES) /I../.. /MD /Fe$@ + +clean: + rm -rf *.gc* *.dSYM *.exe *.obj *.o a.out $(PROG) diff --git a/supernode/index.html b/supernode/index.html index 99b4f19..aa8c563 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11235,26 +11235,27 @@ /*Shifting a WS Connection Function*/ reactor.addEventListener('shift_ws_connection', function(wsSupsObj) { - return new Promise((resolve, reject)=>{ - const getFLOId = wsSupsObj.trader_flo_address; - if (getFLOId===localbitcoinplusplus.wallets.my_local_flo_address) return; - const back_ws_url = `ws://${wsSupsObj.ip}:${wsSupsObj.port}`; + const getFLOId = wsSupsObj.trader_flo_address; + if (getFLOId===localbitcoinplusplus.wallets.my_local_flo_address) return; + const back_ws_url = `ws://${wsSupsObj.ip}:${wsSupsObj.port}`; - if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" - && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { - resolve(1); - } else { - try { - localbitcoinplusplus.backupWS[getFLOId] = null; - localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); - localbitcoinplusplus.backupWS[getFLOId].connectWS(); - resolve(localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState); - } catch (error) { - console.error(error); - switchToBackupWSForSuperNodesOperations(back_ws_url); - } - } - }); + if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" + && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { + // This will check if more ws conns are required or not + reactor.dispatchEvent('resolve_backup_ws_connections'); + } else { + try { + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + /* Now in connectWS if connection fails call switchToBackupWSForSuperNodesOperations() in onClose() + for next su node, if its success check for max baxkup connection conditon, if required + execute 'resolve_backup_ws_connections' in onOpen() or exit */ + } catch (error) { + console.error(error); + switchToBackupWSForSuperNodesOperations(back_ws_url); + } + } }); reactor.addEventListener('resolve_backup_ws_connections', async function(evt) { @@ -11268,15 +11269,41 @@ reactor.dispatchEvent('clean_dead_ws_conections'); try { + // Get list of neighbour supernodes const myClosestSups = await readAllDB('myClosestSupernodes'); + + // Get list of backup ws connection current status + const currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) + .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState===1); - for (let z = 1; z < myClosestSups.length-1; z++) { + for (let z = 1; z <= myClosestSups.length-1; z++) { + const supsObj = myClosestSups[z]; + + // ws conn already present + if (supsObj.trader_flo_address===currenctBackupWsList[z]) continue; + + if (currenctBackupWsList.length + == localbitcoinplusplus.master_configurations.MaxBackups) { + + + // Perhaps its better that a connection is switched off only + // when backup sync has been done successfully. + + + // Stop any further (and far) ws backup conns + // for (let y = z; y <= myClosestSups.length-1; y++) { + // const extra_conns_flo_id = myClosestSups[y]; + // const backup_conns = localbitcoinplusplus.backupWS[extra_conns_flo_id]; + // if(typeof backup_conns.ws_connection == "object") { + // localbitcoinplusplus.backupWS[extra_conns_flo_id].ws_connection.close(); + // //delete localbitcoinplusplus.backupWS[backup_id]; + // } + // } + break; + } reactor.dispatchEvent('shift_ws_connection', supsObj); - - if (Object.keys(localbitcoinplusplus.backupWS).length - == localbitcoinplusplus.master_configurations.MaxBackups) break; } } catch (error) { @@ -11291,9 +11318,9 @@ if (localbitcoinplusplus.backupWS.hasOwnProperty(backup_id)) { const backup_conns = localbitcoinplusplus.backupWS[backup_id]; if(typeof backup_conns.ws_connection == "object") { - if(backup_conns.ws_connection.readyState !== 1) { + if(backup_conns.ws_connection.readyState > 1) { localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); - delete localbitcoinplusplus.backupWS[backup_id]; + //delete localbitcoinplusplus.backupWS[backup_id]; } } } @@ -16081,6 +16108,12 @@ db_inst: localbitcoinplusplus.wallets.my_local_flo_address }).then(req=>doSend(req)); } + + // Check if the supernode is backup ws connections satisfy max baxkup master + // config condition. If false, request ws connection to next backup supernode. + // Simply execute 'resolve_backup_ws_connections' event. + reactor.dispatchEvent('resolve_backup_ws_connections'); + } else { if (typeof conn_su_flo_id == "string") { my_local_data.lastConnectedTime = + new Date(); @@ -16098,12 +16131,14 @@ reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onclose = function (evt) { - reactor.addEventListener('backup_supernode_down', function() { + reactor.addEventListener('backup_supernode_down', async function() { showMessage(`Disconnected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, false); + // Invoke next backup server to connect + await switchToBackupWSForSuperNodesOperations(evt.srcElement.url); + reactor.dispatchEvent('clean_dead_ws_conections'); }); reactor.dispatchEvent('backup_supernode_down'); - reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onmessage = function (evt) { let response = evt.data; @@ -16315,16 +16350,8 @@ if(ww==disconnected_url) z = true; }); - await reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); + reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); - if(websocket.readyState===1) { - return Promise.resolve(websocket.readyState); - } else { - let ms = `Error: Failed to connect to any supernode.`; - showMessage(ms) - return Promise.reject(ms); - } - }, } From b36e5f980bc079c32d3b9870cdd27c552393d191 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Fri, 23 Aug 2019 14:15:35 +0530 Subject: [PATCH 91/95] improved backup ws connection functionality --- supernode/index.html | 207 +++++++++++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 77 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index aa8c563..026be69 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10918,9 +10918,38 @@ reactor.registerEvent('sync_backup_nodes_of_my_backup_node'); reactor.registerEvent('resolve_backup_ws_connections'); reactor.registerEvent('shift_ws_connection'); + reactor.registerEvent('switchToBackupWSForSuperNodesOperations'); reactor.registerEvent('user_flo_keys_active'); reactor.registerEvent('clean_dead_ws_conections'); + reactor.addEventListener('switchToBackupWSForSuperNodesOperations', async function(disconnected_url='') { + const user_data = await readDB('localbitcoinUser', '00-01'); + const user_flo_pubKey = user_data.myLocalFLOPublicKey; + disconnected_url = disconnected_url.replace(/\/$/, ''); + + if(typeof user_flo_pubKey !== "string" + || !localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(user_flo_pubKey)) return false; + + let ideal_supernode = ''; + + const myClosestSupernodesArray = await readAllDB(`myClosestSupernodes`); + + let nextClosestSupernodeElem = myClosestSupernodesArray + .filter((wew, index)=>{ + let ww = `ws://${wew.ip}:${wew.port}`; + if(typeof z =='boolean' && z) { + z = false; + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wew.trader_flo_address; + return ww; + } + if(ww==disconnected_url) z = true; + }); + + reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); + + }); + reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -11239,21 +11268,30 @@ if (getFLOId===localbitcoinplusplus.wallets.my_local_flo_address) return; const back_ws_url = `ws://${wsSupsObj.ip}:${wsSupsObj.port}`; + let currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) + .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); + + if (currenctBackupWsList.length + === localbitcoinplusplus.master_configurations.MaxBackups) return; + if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { - // This will check if more ws conns are required or not - reactor.dispatchEvent('resolve_backup_ws_connections'); + // Connect to next backup + reactor.dispatchEvent('switchToBackupWSForSuperNodesOperations', back_ws_url); } else { try { - localbitcoinplusplus.backupWS[getFLOId] = null; - localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); - localbitcoinplusplus.backupWS[getFLOId].connectWS(); - /* Now in connectWS if connection fails call switchToBackupWSForSuperNodesOperations() in onClose() - for next su node, if its success check for max baxkup connection conditon, if required - execute 'resolve_backup_ws_connections' in onOpen() or exit */ + if (typeof localbitcoinplusplus.backupWS[getFLOId]!=="object" + || localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState>2) { + localbitcoinplusplus.backupWS[getFLOId] = null; + localbitcoinplusplus.backupWS[getFLOId] = new backupSupernodesWebSocketObject(back_ws_url); + localbitcoinplusplus.backupWS[getFLOId].connectWS(); + /* Now in connectWS if connection fails call switchToBackupWSForSuperNodesOperations() in onClose() + for next su node, if its success check for max baxkup connection conditon, if required + execute 'resolve_backup_ws_connections' in onOpen() or exit */ + } } catch (error) { console.error(error); - switchToBackupWSForSuperNodesOperations(back_ws_url); + reactor.dispatchEvent('switchToBackupWSForSuperNodesOperations', back_ws_url); } } }); @@ -11266,44 +11304,34 @@ if(!localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(usrPubKey)) return; - reactor.dispatchEvent('clean_dead_ws_conections'); - try { // Get list of neighbour supernodes const myClosestSups = await readAllDB('myClosestSupernodes'); // Get list of backup ws connection current status - const currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) - .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState===1); + let currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) + .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); for (let z = 1; z <= myClosestSups.length-1; z++) { const supsObj = myClosestSups[z]; + + // Get latest ws connection status (again) + currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) + .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); // ws conn already present if (supsObj.trader_flo_address===currenctBackupWsList[z]) continue; if (currenctBackupWsList.length - == localbitcoinplusplus.master_configurations.MaxBackups) { - - - // Perhaps its better that a connection is switched off only - // when backup sync has been done successfully. - - - // Stop any further (and far) ws backup conns - // for (let y = z; y <= myClosestSups.length-1; y++) { - // const extra_conns_flo_id = myClosestSups[y]; - // const backup_conns = localbitcoinplusplus.backupWS[extra_conns_flo_id]; - // if(typeof backup_conns.ws_connection == "object") { - // localbitcoinplusplus.backupWS[extra_conns_flo_id].ws_connection.close(); - // //delete localbitcoinplusplus.backupWS[backup_id]; - // } - // } - break; - } - + === localbitcoinplusplus.master_configurations.MaxBackups) break; + + /* Break the loop as soon as this line runs + as any further ws conn releated event will be + taken care in shift_ws_connection event itself. */ reactor.dispatchEvent('shift_ws_connection', supsObj); + break; + } } catch (error) { @@ -11314,17 +11342,53 @@ /* Remove WS connections which are not active currently */ reactor.addEventListener('clean_dead_ws_conections', function() { - for (const backup_id in localbitcoinplusplus.backupWS) { - if (localbitcoinplusplus.backupWS.hasOwnProperty(backup_id)) { - const backup_conns = localbitcoinplusplus.backupWS[backup_id]; - if(typeof backup_conns.ws_connection == "object") { - if(backup_conns.ws_connection.readyState > 1) { - localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); - //delete localbitcoinplusplus.backupWS[backup_id]; - } + // for (const backup_id in localbitcoinplusplus.backupWS) { + // if (localbitcoinplusplus.backupWS.hasOwnProperty(backup_id)) { + // const backup_conns = localbitcoinplusplus.backupWS[backup_id]; + // if(typeof backup_conns.ws_connection == "object") { + // let max_conns = 0; + // if(backup_conns.ws_connection.readyState < 2) { + // max_conns++; + // if(max_conns<=localbitcoinplusplus.master_configurations.MaxBackups) continue; + // localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); + // delete localbitcoinplusplus.backupWS[backup_id]; + // } else { + // localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); + // delete localbitcoinplusplus.backupWS[backup_id]; + // } + // } + // } + // } + + // remove above lines with these + readAllDB(`myClosestSupernodes`).then(sups=>{ + sups + .filter(f=>{ + const supWSConn = localbitcoinplusplus.backupWS[f.trader_flo_address]; + if(typeof supWSConn=="object" && supWSConn.ws_connection.readyState<2) { + return f; + } + }) + .map(backup_id=>{ + if (localbitcoinplusplus.backupWS.hasOwnProperty(backup_id)) { + const backup_conns = localbitcoinplusplus.backupWS[backup_id]; + if(typeof backup_conns.ws_connection == "object") { + let max_conns = 0; + if(backup_conns.ws_connection.readyState < 2) { + max_conns++; + if(max_conns>localbitcoinplusplus.master_configurations.MaxBackups) { + localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); + delete localbitcoinplusplus.backupWS[backup_id]; + } + } else { + localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); + delete localbitcoinplusplus.backupWS[backup_id]; + } + } } - } - } + }); + }); + }); /*This function denotes that a user is probably live and is using the system*/ @@ -15966,6 +16030,9 @@ if(localbitcoinplusplus.master_configurations.supernodesPubKeys .includes(idbData.myLocalFLOPublicKey)) { + // Invoke functions + reactor.dispatchEvent('user_flo_keys_active', idbData); + wsUri.map((uri, index)=>{ // Do not serve to any requests unless data is fully synced. @@ -16066,6 +16133,9 @@ } }); + // Connect to nearest live backup nodes + reactor.dispatchEvent('resolve_backup_ws_connections'); + } resolve(true); @@ -16079,11 +16149,14 @@ this.ws_connection = null; } backupSupernodesWebSocketObject.prototype = { - + connectWS() { + this.ws_connection = new WebSocket(this.ws_url); const switchMyWS = new backupSupernodesWebSocketObject(); this.ws_connection.onopen = function (evt) { + console.info('lalalala '+evt.srcElement.url); + reactor.addEventListener('backup_supernode_up', async function() { showMessage(`Connected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); @@ -16106,13 +16179,20 @@ trader_flo_address: localbitcoinplusplus.wallets.my_local_flo_address, receiver_flo_address: conn_su_flo_id, db_inst: localbitcoinplusplus.wallets.my_local_flo_address - }).then(req=>doSend(req)); + }) + //.then(req=>doSend(req)); } - // Check if the supernode is backup ws connections satisfy max baxkup master + // Check if the number of backup ws connections satisfy max baxkup master // config condition. If false, request ws connection to next backup supernode. - // Simply execute 'resolve_backup_ws_connections' event. - reactor.dispatchEvent('resolve_backup_ws_connections'); + const currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) + .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); + + if (currenctBackupWsList.length + < localbitcoinplusplus.master_configurations.MaxBackups) { + // Request next backup to connect + reactor.dispatchEvent('switchToBackupWSForSuperNodesOperations', evt.srcElement.url); + } } else { if (typeof conn_su_flo_id == "string") { @@ -16128,15 +16208,15 @@ } }); reactor.dispatchEvent('backup_supernode_up'); - reactor.dispatchEvent('clean_dead_ws_conections'); + //reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onclose = function (evt) { reactor.addEventListener('backup_supernode_down', async function() { showMessage(`Disconnected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, false); // Invoke next backup server to connect - await switchToBackupWSForSuperNodesOperations(evt.srcElement.url); - reactor.dispatchEvent('clean_dead_ws_conections'); + await reactor.dispatchEvent('switchToBackupWSForSuperNodesOperations', evt.srcElement.url); + //reactor.dispatchEvent('clean_dead_ws_conections'); }); reactor.dispatchEvent('backup_supernode_down'); }.bind(this); @@ -16325,34 +16405,7 @@ }, - async switchToBackupWSForSuperNodesOperations(disconnected_url='') { - const user_data = await readDB('localbitcoinUser', '00-01'); - const user_flo_address = user_data.myLocalFLOAddress; - disconnected_url = disconnected_url.replace(/\/$/, ''); - - if(typeof user_flo_address !== "string" - || !localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(user_flo_address)) return false; - - let ideal_supernode = ''; - - const myClosestSupernodesArray = await readAllDB(`myClosestSupernodes`); - - let nextClosestSupernodeElem = myClosestSupernodesArray - .filter((wew, index)=>{ - let ww = `ws://${wew.ip}:${wew.port}`; - if(typeof z =='boolean' && z) { - z = false; - localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wew.trader_flo_address; - return ww; - } - if(ww==disconnected_url) z = true; - }); - - reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); - - }, } function startWebSocket(wsUri) { From 1679a8104f6ffd54251722afde8039aaae267ab3 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 24 Aug 2019 16:42:43 +0530 Subject: [PATCH 92/95] fixed more bugs in backup ws and fixed readyState unchanged on onclose event error --- supernode/index.html | 114 ++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 50 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 026be69..bb7991d 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10703,7 +10703,7 @@ }) }, - addClosestSupernodeInDB: function(flo_addr, KB=KBucket) { + addClosestSupernodeInDB: function(flo_addr, KB=supernodeKBucket) { return new Promise(async (resolve, reject)=>{ const supernodeSeeds = localbitcoinplusplus.master_configurations.supernodeSeeds; if (typeof supernodeSeeds !== "object") reject("Failed to get supernode seeds."); @@ -10921,35 +10921,7 @@ reactor.registerEvent('switchToBackupWSForSuperNodesOperations'); reactor.registerEvent('user_flo_keys_active'); reactor.registerEvent('clean_dead_ws_conections'); - - reactor.addEventListener('switchToBackupWSForSuperNodesOperations', async function(disconnected_url='') { - const user_data = await readDB('localbitcoinUser', '00-01'); - const user_flo_pubKey = user_data.myLocalFLOPublicKey; - disconnected_url = disconnected_url.replace(/\/$/, ''); - if(typeof user_flo_pubKey !== "string" - || !localbitcoinplusplus.master_configurations.supernodesPubKeys - .includes(user_flo_pubKey)) return false; - - let ideal_supernode = ''; - - const myClosestSupernodesArray = await readAllDB(`myClosestSupernodes`); - - let nextClosestSupernodeElem = myClosestSupernodesArray - .filter((wew, index)=>{ - let ww = `ws://${wew.ip}:${wew.port}`; - if(typeof z =='boolean' && z) { - z = false; - localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wew.trader_flo_address; - return ww; - } - if(ww==disconnected_url) z = true; - }); - - reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); - - }); - reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -11033,6 +11005,11 @@ // If true, take charge of dead supernode's operations if (getStatusOfDeadSuAgain[0].is_live==false) { + // Kill the connection manually to ensure connection is really closed. + if (localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { + localbitcoinplusplus.backupWS[getFLOId].ws_connection.close(); + } + // Initiate connections with next live supernodes reactor.dispatchEvent('resolve_backup_ws_connections'); @@ -11271,9 +11248,6 @@ let currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); - if (currenctBackupWsList.length - === localbitcoinplusplus.master_configurations.MaxBackups) return; - if (typeof localbitcoinplusplus.backupWS[getFLOId]==="object" && localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { // Connect to next backup @@ -11296,6 +11270,7 @@ } }); + /*Get the most eligible non-connected backup within max backup condition*/ reactor.addEventListener('resolve_backup_ws_connections', async function(evt) { const usrDbObj = await readDB('localbitcoinUser', '00-01'); @@ -11307,31 +11282,40 @@ try { // Get list of neighbour supernodes const myClosestSups = await readAllDB('myClosestSupernodes'); - + const myClosestSupsFloList = myClosestSups.map(m=>m.trader_flo_address); // Get list of backup ws connection current status let currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); - for (let z = 1; z <= myClosestSups.length-1; z++) { + for (let z = 0; z <= myClosestSups.length-1; z++) { const supsObj = myClosestSups[z]; + // Do not send your own object data + if(supsObj.trader_flo_address===localbitcoinplusplus.wallets.my_local_flo_address + || z===0) continue; + // Get latest ws connection status (again) currenctBackupWsList = Object.keys(localbitcoinplusplus.backupWS) .filter(m=>localbitcoinplusplus.backupWS[m].ws_connection.readyState<2); - // ws conn already present - if (supsObj.trader_flo_address===currenctBackupWsList[z]) continue; - - if (currenctBackupWsList.length - === localbitcoinplusplus.master_configurations.MaxBackups) break; + if (currenctBackupWsList.length) { + // ws conn already present + if (supsObj.trader_flo_address===currenctBackupWsList[z-1]) continue; + + if (myClosestSupsFloList.indexOf(supsObj.trader_flo_address) + <= myClosestSupsFloList.indexOf(currenctBackupWsList[z-1])) { + /* Break the loop as soon as this line runs + as any further ws conn releated event will be + taken care in shift_ws_connection event itself. */ + reactor.dispatchEvent('shift_ws_connection', supsObj); + break; + } + } else { + reactor.dispatchEvent('shift_ws_connection', supsObj); + break; + } - /* Break the loop as soon as this line runs - as any further ws conn releated event will be - taken care in shift_ws_connection event itself. */ - reactor.dispatchEvent('shift_ws_connection', supsObj); - break; - } } catch (error) { @@ -11340,6 +11324,40 @@ }); + /*To connect to next backup of given url*/ + reactor.addEventListener('switchToBackupWSForSuperNodesOperations', async function(disconnected_url='') { + const user_data = await readDB('localbitcoinUser', '00-01'); + const user_flo_pubKey = user_data.myLocalFLOPublicKey; + disconnected_url = disconnected_url.replace(/\/$/, ''); + + if(typeof user_flo_pubKey !== "string" + || !localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(user_flo_pubKey)) return false; + + let ideal_supernode = ''; + + const myClosestSupernodesArray = await readAllDB(`myClosestSupernodes`); + + let nextClosestSupernodeElem = myClosestSupernodesArray + .filter((wew, index)=>{ + let ww = `ws://${wew.ip}:${wew.port}`; + if(ww==disconnected_url) z = true; + if(typeof z =='boolean' && z) { + z = false; + localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = wew.trader_flo_address; + return ww; + } + }); + + if (typeof nextClosestSupernodeElem=="object") { + reactor.dispatchEvent('shift_ws_connection', nextClosestSupernodeElem[0]); + } else { + console.log(nextClosestSupernodeElem); + throw new Error(`ERROR: Failed to shift a ws connection.`); + } + + }); + /* Remove WS connections which are not active currently */ reactor.addEventListener('clean_dead_ws_conections', function() { // for (const backup_id in localbitcoinplusplus.backupWS) { @@ -16155,8 +16173,6 @@ this.ws_connection = new WebSocket(this.ws_url); const switchMyWS = new backupSupernodesWebSocketObject(); this.ws_connection.onopen = function (evt) { - console.info('lalalala '+evt.srcElement.url); - reactor.addEventListener('backup_supernode_up', async function() { showMessage(`Connected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, true); @@ -16208,15 +16224,13 @@ } }); reactor.dispatchEvent('backup_supernode_up'); - //reactor.dispatchEvent('clean_dead_ws_conections'); }.bind(this); this.ws_connection.onclose = function (evt) { reactor.addEventListener('backup_supernode_down', async function() { showMessage(`Disconnected to backup Supernode sever: ${evt.srcElement.url}.`); switchMyWS.updateSupernodeAvailabilityStatus(evt.srcElement.url, false); - // Invoke next backup server to connect + // Request next backup server to connect await reactor.dispatchEvent('switchToBackupWSForSuperNodesOperations', evt.srcElement.url); - //reactor.dispatchEvent('clean_dead_ws_conections'); }); reactor.dispatchEvent('backup_supernode_down'); }.bind(this); From bb7779c159e42f13c39511d33416a347192ce92b Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sat, 24 Aug 2019 16:45:21 +0530 Subject: [PATCH 93/95] fixed more bugs in backup ws and fixed readyState unchanged on onclose event error --- supernode/index.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/supernode/index.html b/supernode/index.html index bb7991d..467df06 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11006,6 +11006,10 @@ if (getStatusOfDeadSuAgain[0].is_live==false) { // Kill the connection manually to ensure connection is really closed. + /* Source of inspiration:- + https://github.com/dart-lang/sdk/issues/25536 + https://bugs.chromium.org/p/chromium/issues/detail?id=76358 + */ if (localbitcoinplusplus.backupWS[getFLOId].ws_connection.readyState==1) { localbitcoinplusplus.backupWS[getFLOId].ws_connection.close(); } From 9edaad678f682220c6d8d71f580f1ab474675e76 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Sun, 25 Aug 2019 13:21:55 +0530 Subject: [PATCH 94/95] fixed more bugs in backup ws and fixed readyState unchanged on onclose event error --- supernode/index.html | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 467df06..85683dd 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -11307,13 +11307,26 @@ // ws conn already present if (supsObj.trader_flo_address===currenctBackupWsList[z-1]) continue; - if (myClosestSupsFloList.indexOf(supsObj.trader_flo_address) - <= myClosestSupsFloList.indexOf(currenctBackupWsList[z-1])) { + // Get the highest index of connected supernodes + const highestIndexOfConnectedSupernode = Object.keys(localbitcoinplusplus.backupWS) + .reduce((acc, val) => + (acc === undefined || myClosestSupsFloList.indexOf(val) > myClosestSupsFloList.indexOf(acc)) + ? myClosestSupsFloList.indexOf(val) : myClosestSupsFloList.indexOf(acc)); + + if (myClosestSupsFloList.indexOf(supsObj.trader_flo_address) < highestIndexOfConnectedSupernode) { /* Break the loop as soon as this line runs as any further ws conn releated event will be taken care in shift_ws_connection event itself. */ reactor.dispatchEvent('shift_ws_connection', supsObj); break; + } else { + if (currenctBackupWsList.length + < localbitcoinplusplus.master_configurations.MaxBackups) { + + reactor.dispatchEvent('shift_ws_connection', supsObj); + break; + } + break; } } else { reactor.dispatchEvent('shift_ws_connection', supsObj); From eec8e42314bcebdb9905336d10489974c4990731 Mon Sep 17 00:00:00 2001 From: Abhishek Sinha Date: Mon, 26 Aug 2019 11:34:14 +0530 Subject: [PATCH 95/95] invoked remove_extra_backup_connection function --- supernode/index.html | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/supernode/index.html b/supernode/index.html index 85683dd..5ef635e 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -10920,7 +10920,7 @@ reactor.registerEvent('shift_ws_connection'); reactor.registerEvent('switchToBackupWSForSuperNodesOperations'); reactor.registerEvent('user_flo_keys_active'); - reactor.registerEvent('clean_dead_ws_conections'); + reactor.registerEvent('remove_extra_backup_connections'); reactor.addEventListener('fireNodeWelcomeBackEvent', function(evt) { let getFLOId = bitjs.FLO_TEST.pubkey2address(evt.flo_public_key); @@ -11376,29 +11376,11 @@ }); /* Remove WS connections which are not active currently */ - reactor.addEventListener('clean_dead_ws_conections', function() { - // for (const backup_id in localbitcoinplusplus.backupWS) { - // if (localbitcoinplusplus.backupWS.hasOwnProperty(backup_id)) { - // const backup_conns = localbitcoinplusplus.backupWS[backup_id]; - // if(typeof backup_conns.ws_connection == "object") { - // let max_conns = 0; - // if(backup_conns.ws_connection.readyState < 2) { - // max_conns++; - // if(max_conns<=localbitcoinplusplus.master_configurations.MaxBackups) continue; - // localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); - // delete localbitcoinplusplus.backupWS[backup_id]; - // } else { - // localbitcoinplusplus.backupWS[backup_id].ws_connection.close(); - // delete localbitcoinplusplus.backupWS[backup_id]; - // } - // } - // } - // } + reactor.addEventListener('remove_extra_backup_connections', function() { // remove above lines with these readAllDB(`myClosestSupernodes`).then(sups=>{ - sups - .filter(f=>{ + sups.filter(f=>{ const supWSConn = localbitcoinplusplus.backupWS[f.trader_flo_address]; if(typeof supWSConn=="object" && supWSConn.ws_connection.readyState<2) { return f; @@ -17688,6 +17670,8 @@ i++; if (i==Object.keys(su_db_data).length-2) { localbitcoinplusplus.services[`can_serve_${su_db_data[`trader_flo_address`]}`] = true; + // Close unnecessary connections now + reactor.dispatchEvent('remove_extra_backup_connections'); } // skip loop if the property is from prototype if (tableStoreName == 'trader_flo_address' @@ -20197,6 +20181,8 @@ i++; if (i==Object.keys(su_db_data).length-2) { localbitcoinplusplus.services[`can_serve_${su_db_data.trader_flo_address}`] = true; + // Close unnecessary connections now + reactor.dispatchEvent('remove_extra_backup_connections'); } // skip loop if the property is from prototype if (tableStoreName == 'trader_flo_address' @@ -21860,7 +21846,8 @@ reactor.dispatchEvent('sync_primary_and_backup_db'); showMessage(`INFO: You need to update serve to true to start serving as Primary Supernode.`); } else { - localbitcoinplusplus.services[`can_serve_${localbitcoinplusplus.wallets.my_local_flo_address}`] = true; + localbitcoinplusplus.services[`can_serve_${localbitcoinplusplus.wallets.my_local_flo_address}`] = true; + reactor.dispatchEvent('remove_extra_backup_connections'); } }