diff --git a/supernode/cash_payments_handler.html b/supernode/cash_payments_handler.html index dbb0521..5de0170 100644 --- a/supernode/cash_payments_handler.html +++ b/supernode/cash_payments_handler.html @@ -11278,6 +11278,59 @@ }; + + + @@ -14244,6 +14705,16 @@ dataBaseUIOperations(); } + // Private key is built. Now execute private key dependent functions + const RM_WALLET = new localbitcoinplusplus.wallets; + const pubkey = RM_WALLET + .generateFloKeys(localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY) + .pubKeyHex + if(localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(pubkey)) { + reactor.dispatchEvent("user_flo_keys_active", pubkey); + } + 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.`; @@ -14278,6 +14749,15 @@ enumerable: false } ); + + // Private key is built. Now execute private key dependent functions + const pubkey = RM_WALLET + .generateFloKeys(localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY) + .pubKeyHex + if(localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(pubkey)) { + reactor.dispatchEvent("user_flo_keys_active", pubkey); + } }, rebuild_private_key: function( private_key_shamirs_shares, @@ -15291,41 +15771,27 @@ params.currency ); + params.id = helper_functions.unique_id(); + params.status = 1; + if ( localbitcoinplusplus.master_configurations.tradableAsset1.includes( params.product ) ) { + const eqBTC = Number(parseFloat(params.withdrawing_amount).toFixed(8)); + if ( trade_margin.remaining_crypto_credit < 0 || - params.withdrawing_amount <= 0 || + eqBTC <= 0 || trade_margin.remaining_crypto_credit < - params.withdrawing_amount + eqBTC ) { 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 || - 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); - } - } - 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}`; readDB("crypto_balances", withdrawer_btc_id).then( @@ -15339,9 +15805,7 @@ 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 ( @@ -15500,9 +15964,19 @@ showMessage(err_msg); throw new Error(err_msg); } + 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); + } // 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*/ + /* 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}`; @@ -20032,8 +20506,6 @@ 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. @@ -20051,7 +20523,7 @@ }); // Connect to nearest live backup nodes - reactor.dispatchEvent("resolve_backup_ws_connections"); + //reactor.dispatchEvent("resolve_backup_ws_connections"); } localbitcoinplusplus.MY_SUPERNODE_FLO_ADDRESS = @@ -20083,12 +20555,15 @@ idbData.myLocalFLOAddress ); + const getClosestSuList = await readAllDB("myClosestSupernodes"); + + reactor.dispatchEvent("createClosestSupernodesObject", getClosestSuList); + if ( localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( idbData.myLocalFLOPublicKey ) ) { - const getClosestSuList = await readAllDB("myClosestSupernodes"); if ( wsUri[0].trader_flo_address !== idbData.myLocalFLOAddress || getClosestSuList.length < @@ -20097,6 +20572,10 @@ showMessage( `INFO: Invalid connection. Refreshing the closest supernode list in DB.` ); + + // Possible entry of new Supernode. Export data of users + //localbitcoinplusplus.actions.exportUserDataFromOneSupernodeToAnother(idbData.myLocalFLOAddress); + wsUri = await localbitcoinplusplus.kademlia.updateClosestSupernodeSeeds( idbData.myLocalFLOAddress ); @@ -20151,8 +20630,6 @@ 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. @@ -20168,7 +20645,7 @@ }); // Connect to nearest live backup nodes - reactor.dispatchEvent("resolve_backup_ws_connections"); + //reactor.dispatchEvent("resolve_backup_ws_connections"); } resolve(true); @@ -20186,90 +20663,21 @@ connectWS() { this.ws_connection = new WebSocket(this.ws_url); const switchMyWS = new backupSupernodesWebSocketObject(); - this.ws_connection.onopen = function(evt) { - 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") { - const conn_su_flo_id = await switchMyWS.getFloIdFromWSUrl( - evt.srcElement.url - ); - - if ( - localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( - my_local_data.myLocalFLOPublicKey - ) - ) { - // If conn_su_flo_id is not an immediate backup then give your data to it to sync - const myClosestSus = await readAllDB("myClosestSupernodes"); - const myClosestSusList = myClosestSus.map( - m => m.trader_flo_address - ); - if ( - myClosestSusList.indexOf(conn_su_flo_id) > - localbitcoinplusplus.master_configurations.MaxBackups - ) { - // Ask conn_su_flo_id to ask you your DB data - const RM_RPC = new localbitcoinplusplus.rpc(); - RM_RPC.send_rpc.call(this, "request_me_db_data", { - 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)); - } - - // Check if the number of backup ws connections satisfy max baxkup master - // config condition. If false, request ws connection to next backup supernode. - 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") { - 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"); + this.ws_connection.onopen = async function(evt) { + await reactor.dispatchEvent("backup_supernode_up", evt.srcElement.url); + await reactor.dispatchEvent("remove_extra_backup_connections"); }.bind(this); this.ws_connection.onclose = function(evt) { reactor.dispatchEvent("backup_supernode_down", evt); }.bind(this); this.ws_connection.onmessage = function(evt) { let response = evt.data; + console.log(`backup message: ${response}`); let isItANodeLeavingMessage = response.search(`\\-- left`); if (isItANodeLeavingMessage >= 0) { - reactor.dispatchEvent("fireNodeGoodByeEvent", response); + //localbitcoinplusplus.actions.informAllANodeLeft(response); + return; } let isRequestToLinkIp = response.search("linkMyLocalIPToMyFloId"); @@ -20380,8 +20788,7 @@ "trader_flo_address", disconnected_su_flo_id ); - const get_disconnected_su_details = - get_disconnected_su_details_list[0]; + const get_disconnected_su_details = get_disconnected_su_details_list[0]; if (typeof get_disconnected_su_details !== "object") { showMessage( `WARNING: Failed to update status of "${ws_url}" to ${status}.` @@ -20389,28 +20796,17 @@ 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; - } + if (typeof localbitcoinplusplus.myClosestSupernodes[disconnected_su_flo_id] == "object") { + if (localbitcoinplusplus.myClosestSupernodes[disconnected_su_flo_id].is_live === status) return; } + localbitcoinplusplus.myClosestSupernodes[disconnected_su_flo_id].is_live = status; 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}.`); - } - ); + const myClosestSupernodesStatusRes = await updateinDB("myClosestSupernodes", get_disconnected_su_details); + if(status!==myClosestSupernodesStatusRes.is_live) throw new Error(`ERROR: Failed to update the status of Supernode to ${status}.`); + localbitcoinplusplus.myClosestSupernodes[disconnected_su_flo_id].is_live = myClosestSupernodesStatusRes.is_live; + let su_status = (myClosestSupernodesStatusRes.is_live === true) ? "connected" : "disconnected"; + showMessage(`INFO: Supernode ${ws_url} is now ${su_status}.`); }, async switchToBackupWS(disconnected_url = "") { @@ -20455,6 +20851,12 @@ } ); + if(nextClosestSupernodeElem.length<1) { + let ms = `Error: Failed to connect to any supernode.`; + showMessage(ms); + return Promise.reject(ms); + } + ideal_supernode = `ws://${nextClosestSupernodeElem[0].ip}:${nextClosestSupernodeElem[0].port}`; await startWebSocket(ideal_supernode); @@ -20517,7 +20919,8 @@ }); } - function onOpen(evt) { + async function onOpen(evt) { + await reactor.dispatchEvent("createClosestSupernodesObject"); reactor.dispatchEvent("new_supernode_connected", evt); readDB("localbitcoinUser", "00-01").then(res => { if (typeof res == "object" && res.myLocalFLOAddress == "string") { @@ -20540,6 +20943,13 @@ } function onClose(evt) { + // Also close the backup ws conns + if(localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(localbitcoinplusplus.wallets.my_local_flo_public_key)) { + for(conn in localbitcoinplusplus.backupWS) { + localbitcoinplusplus.backupWS[conn].ws_connection.close(); + } + } reactor.dispatchEvent("primary_supernode_down", evt); } @@ -20550,8 +20960,8 @@ // and fire respective events let isItANodeLeavingMessage = response.search(`\\-- left`); if (isItANodeLeavingMessage >= 0) { - reactor.dispatchEvent("fireNodeGoodByeEvent", response); - return; + //localbitcoinplusplus.actions.informAllANodeLeft(response); + return; } const isMsgFromCashier = response.search("__FOR__CASHIER__"); @@ -20579,6 +20989,100 @@ try { var res_obj = JSON.parse(res); + const RM_WALLET = new localbitcoinplusplus.wallets(); + const RM_TRADE = new localbitcoinplusplus.trade(); + const RM_RPC = new localbitcoinplusplus.rpc(); + + if(res_obj.protocol === "__ALL_SUPERNODES_MSG__") { + if (!localbitcoinplusplus.master_configurations.supernodesPubKeys + .includes(res_obj.su_pubKey)) return; + + // Break any possiblity of a loop + if(typeof res_obj.initialSender==="string" + && res_obj.initialSender=== + localbitcoinplusplus.wallets.my_local_flo_address) return; + + const msg_obj = {}; + msg_obj.protocol = res_obj.protocol; + msg_obj.event = res_obj.event; + msg_obj.data = {subject_flo_id: res_obj.data.subject_flo_id}; + msg_obj.hash = Crypto.SHA256(msg_obj); + let isValidMsg = RM_WALLET.verify( + msg_obj.hash, + res_obj.sign, + res_obj.su_pubKey + ); + + if(isValidMsg!==true) return; + + switch (res_obj.event) { + case "supernode_went_down": + // This should be run by only 1 Supernode who is the reciever + if(localbitcoinplusplus.wallets.my_local_flo_address + !== res_obj.receiverFloAddress) return; + reactor.dispatchEvent('fireNodeGoodByeEvent', res_obj.data.subject_flo_id); + + // SYNC DATA OF ALL SUPERNODES IN MIDDLE OF SENDER AND RECEIVER + // Get the Supernodes in between sender and receiver of this message + const all_supernodes = Object.keys(localbitcoinplusplus.myClosestSupernodes); + const tableArray = [ + "deposit", + "cash_deposits", + "withdraw_cash", + "withdraw_btc", + "cash_balances", + "crypto_balances", + "buyOrders", + "sellOrders", + "system_btc_reserves_private_keys" + ]; + /* Sync/Forward data of all Supernodes between res_obj.initialSender (i.e + node which informed you about a another node's death) + and you. + */ + for (let q = all_supernodes.length-1; q>=0; q--) { + const su_obj = localbitcoinplusplus.myClosestSupernodes[all_supernodes[q]]; + if(su_obj.trader_flo_address===res_obj.initialSender) break; + if(su_obj.trader_flo_address===localbitcoinplusplus.wallets.my_local_flo_address) + continue; + + // Send data to next Supernode + localbitcoinplusplus.actions.get_sharable_db_data( + tableArray, + su_obj.trader_flo_address + ).then(su_db_data=>{ + RM_RPC.send_rpc + .call( + this, + "sync_backup_supernode_from_backup_supernode_response", + su_db_data + ) + .then(server_sync_response => + doSend(server_sync_response, su_obj.trader_flo_address) + ); + }); + + // Sync data from other Supernodes as well + // localbitcoinplusplus.actions.sync_backup_supernode_from_backup_supernode( + // localbitcoinplusplus.wallets.my_local_flo_address, + // "", + // su_obj.trader_flo_address + // ); + } + break; + + case "supernode_came_back": + if(localbitcoinplusplus.wallets.my_local_flo_address + !== res_obj.receiverFloAddress) return; + reactor.dispatchEvent('resolve_backup_ws_connections'); + break; + + default: + break; + } + return; + } + if ( typeof res_obj.globalParams !== "object" || (localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( @@ -20698,10 +21202,6 @@ 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 ( @@ -20865,6 +21365,7 @@ // skip loop if the property is from prototype if ( tableStoreName == "trader_flo_address" || + tableStoreName == "receiver_flo_address" || !su_db_data.hasOwnProperty(tableStoreName) ) continue; @@ -21756,6 +22257,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }) @@ -21788,6 +22290,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }).then(ipRes => { @@ -22046,17 +22549,23 @@ if (obj.length > 0) { for (var prop in obj) { if (!obj.hasOwnProperty(prop)) continue; + + if(typeof obj[prop].is_deletable==="boolean" + && obj[prop].is_deletable===true) { + removeinDB(tableStoreName, obj[prop].id); + continue; + } + await updateinDB( tableStoreName, obj[prop], obj[prop].id, true, false - ).then(() => { - showMessage( - `INFO: "${tableStoreName}" datastore syncing is complete.` - ); - }); + ); + showMessage( + `INFO: "${tableStoreName}" datastore syncing is complete.` + ); } } @@ -22374,6 +22883,28 @@ } break; + case "request_me_db_data": + if ( + localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + res_obj.nodePubKey + ) + ) { + const resp = res_obj.params[0]; + + if ( + localbitcoinplusplus.wallets.my_local_flo_address !== + resp.receiver_flo_address + ) + return; + + localbitcoinplusplus.actions.sync_backup_supernode_from_backup_supernode( + localbitcoinplusplus.wallets.my_local_flo_address, + resp.trader_flo_address, + resp.db_inst + ); + } + break; + default: break; } @@ -22392,7 +22923,8 @@ let isItANodeLeavingMessage = response.search(`\\-- left`); if (isItANodeLeavingMessage >= 0) { - reactor.dispatchEvent("fireNodeGoodByeEvent", response); + //localbitcoinplusplus.actions.informAllANodeLeft(response); + return; } var res_pos = response.indexOf("{"); @@ -22731,6 +23263,7 @@ // skip loop if the property is from prototype if ( tableStoreName == "trader_flo_address" || + tableStoreName == "receiver_flo_address" || !su_db_data.hasOwnProperty(tableStoreName) ) continue; @@ -23806,6 +24339,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }) @@ -23838,6 +24372,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }).then(ipRes => { @@ -24264,7 +24799,7 @@ if ( typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && - localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( + !localbitcoinplusplus.master_configurations.supernodesPubKeys.includes( localbitcoinplusplus.wallets.my_local_flo_public_key ) ) { @@ -24459,7 +24994,8 @@ let isItANodeLeavingMessage = response.search(`\\-- left`); if (isItANodeLeavingMessage >= 0) { - reactor.dispatchEvent("fireNodeGoodByeEvent", response); + //localbitcoinplusplus.actions.informAllANodeLeft(response); + return; } var res_pos = response.indexOf("{"); @@ -24589,6 +25125,7 @@ // skip loop if the property is from prototype if ( tableStoreName == "trader_flo_address" || + tableStoreName == "receiver_flo_address" || !su_backup_db_data.hasOwnProperty(tableStoreName) ) continue; @@ -25260,6 +25797,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }) @@ -25291,6 +25829,7 @@ ) return; updateinDB("ipTable", { + id: helper_functions.unique_id(), flo_public_key: req_params.requesters_pub_key, temporary_ip: incoming_msg_local_ip }).then(ipRes => { @@ -25993,32 +26532,41 @@ console.log(mismatched_fields); let latest_data = {}; + let old_data = {}; for (var i = 0; i < mismatched_fields.length; i++) { const mf = mismatched_fields[i]; + latest_data[mf] = []; + old_data[mf] = []; const res_data_obj = await _readAllDB(mf, false); - let filtered_data = res_data_obj.filter(odho => { + if(res_data_obj.length===0) { + old_data[mf].push(res_data_obj); + continue; + } + for (let j = 0; j < res_data_obj.length; j++) { + const odho = res_data_obj[j]; if ( typeof odho.timestamp == "number" && - typeof response_object.higestTimestampList[ - `${mf}_TIME` - ] !== "undefined" + typeof response_object + .higestTimestampList[`${mf}_TIME`] !== "undefined" ) { - return ( - odho.timestamp >= - Number( - response_object.higestTimestampList[ - `${mf}_TIME` - ] - 3600000 - ) - ); - } - }); - - latest_data[mf] = filtered_data; + if(odho.timestamp >= + Number( + response_object.higestTimestampList[ + `${mf}_TIME` + ] - 3600000 + )) { + latest_data[mf].push(odho); + } else { + if(typeof odho.is_deletable ==="boolean") continue; + old_data[mf].push(odho); + } + } + } } console.log(latest_data); + console.log(old_data); // Send the data back to sender if ( @@ -26051,6 +26599,15 @@ doSend(server_sync_response) ); } + + let old_data_with_values = Object.values(old_data).filter(f=>f.length>0); + if(Object.values(old_data_with_values).length) { + localbitcoinplusplus.actions.sync_backup_supernode_from_backup_supernode( + localbitcoinplusplus.wallets.my_local_flo_address, + res_obj.globalParams.senderFloId, + primarySupernodeOfThisUser + ); + } }); } @@ -26603,14 +27160,18 @@ const request_array = [ "send_back_shamirs_secret_supernode_pvtkey", "retrieve_shamirs_secret_supernode_pvtkey", - "store_shamirs_secret_pvtkey_shares" + "store_shamirs_secret_pvtkey_shares", + "request_me_db_data" ]; let finalMessage = message; const msgObj = JSON.parse(message); - if (!request_array.includes(msgObj.method)) { + if (!request_array.includes(msgObj.method) || ( + typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY === + "string" + )) { const RM_WALLET = new localbitcoinplusplus.wallets(); message = JSON.stringify(msgObj); @@ -26633,6 +27194,11 @@ localbitcoinplusplus.wallets.my_local_flo_public_key; finalMessage = JSON.stringify(msgObj); + } else { + msgObj.nodePubKey = + localbitcoinplusplus.wallets.my_local_flo_public_key; + + finalMessage = JSON.stringify(msgObj); } // The message is for a specific supernode only @@ -26683,7 +27249,7 @@ } } - console.log("SENT: " + finalMessage); + console.trace("SENT: " + finalMessage); } function validateIncomingMessage(message) { @@ -26697,7 +27263,8 @@ const request_array = [ "send_back_shamirs_secret_supernode_pvtkey", "retrieve_shamirs_secret_supernode_pvtkey", - "store_shamirs_secret_pvtkey_shares" + "store_shamirs_secret_pvtkey_shares", + "request_me_db_data" ]; try { @@ -26891,7 +27458,7 @@ 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 @@ -27074,7 +27641,10 @@ } if (!db.objectStoreNames.contains("ipTable")) { var objectStore = db.createObjectStore("ipTable", { - keyPath: "flo_public_key" + keyPath: "id" + }); + objectStore.createIndex("flo_public_key", "flo_public_key", { + unique: false }); objectStore.createIndex("temporary_ip", "temporary_ip", { unique: false @@ -27161,7 +27731,42 @@ }); } - function readDBbyIndex( + // function readDBbyIndex( + // tablename, + // index, + // indexValue, + // filter_deletables = true + // ) { + // return new Promise((resolve, reject) => { + // var transaction = db.transaction([tablename]); + // var objectStore = transaction.objectStore(tablename); + // let response = []; + // var myIndex = objectStore.index(index); + // myIndex.openCursor().onerror = function(event) { + // console.error("Error fetching data"); + // reject(event); + // }; + // myIndex.openCursor().onsuccess = function(event) { + // let cursor = event.target.result; + // if (cursor) { + // 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 { + // resolve(response); + // } + // }; + // }); + // } + + function readDBbyIndex( tablename, index, indexValue, @@ -27171,12 +27776,11 @@ var transaction = db.transaction([tablename]); var objectStore = transaction.objectStore(tablename); let response = []; - var myIndex = objectStore.index(index); - myIndex.openCursor().onerror = function(event) { + objectStore.openCursor().onerror = function(event) { console.error("Error fetching data"); reject(event); }; - myIndex.openCursor().onsuccess = function(event) { + objectStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (cursor) { if (cursor.value[index] == indexValue) { @@ -27272,6 +27876,8 @@ // leave the vector clock field unchanged } else { Obj.vectorClock += 1; + // If vectorClock is increased, also update timestamp + Obj.timestamp = +new Date(); } if (typeof Obj.timestamp !== "number") { Obj.timestamp = +new Date(); @@ -27622,10 +28228,23 @@ var objectStore = this.db.createObjectStore("kBucketStore", { keyPath: "id" }); + objectStore.createIndex( + "primary_supernode_flo_public_key", + "primary_supernode_flo_public_key", + { + unique: false + } + ); } if (!this.db.objectStoreNames.contains("ipTable")) { var objectStore = this.db.createObjectStore("ipTable", { - keyPath: "flo_public_key" + keyPath: "id" + }); + objectStore.createIndex("flo_public_key", "flo_public_key", { + unique: false + }); + objectStore.createIndex("temporary_ip", "temporary_ip", { + unique: false }); } if (!this.db.objectStoreNames.contains("myClosestSupernodes")) { @@ -27647,7 +28266,7 @@ }); } if (!this.db.objectStoreNames.contains("crypto_fiat_rates")) { - var objectStore = db.createObjectStore("crypto_fiat_rates", { + var objectStore = this.db.createObjectStore("crypto_fiat_rates", { keyPath: "id" }); objectStore.createIndex("currency_code", "currency_code", { @@ -27747,6 +28366,41 @@ }); }, + // 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); + // let response = []; + // var myIndex = objectStore.index(index); + // myIndex.openCursor().onerror = function(event) { + // console.error("Error fetching data"); + // reject(event); + // }; + // myIndex.openCursor().onsuccess = function(event) { + // let cursor = event.target.result; + // if (cursor) { + // 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 { + // resolve(response); + // } + // }; + // }); + // }, + backup_readDBbyIndex( tablename, index, @@ -27757,12 +28411,11 @@ this.transaction = this.db.transaction([tablename]); var objectStore = this.transaction.objectStore(tablename); let response = []; - var myIndex = objectStore.index(index); - myIndex.openCursor().onerror = function(event) { + objectStore.openCursor().onerror = function(event) { console.error("Error fetching data"); reject(event); }; - myIndex.openCursor().onsuccess = function(event) { + objectStore.openCursor().onsuccess = function(event) { let cursor = event.target.result; if (cursor) { if (cursor.value[index] == indexValue) { @@ -27828,6 +28481,7 @@ }; this.request.onerror = function (event) { + console.trace(event); reject(event); } } catch (error) { @@ -27852,6 +28506,8 @@ // leave the vector clock field unchanged } else { Obj.vectorClock += 1; + // If vectorClock is increased, also update timestamp + Obj.timestamp = +new Date(); } if (typeof Obj.timestamp !== "number") { Obj.timestamp = +new Date(); @@ -28725,6 +29381,7 @@ }); withdrawAssetButton.addEventListener("click", function(params) { + let asset_type = assetTypeInput.value; let receivinAddress = prompt( `Please enter your ${asset_type} receiving address.` ); @@ -28734,7 +29391,6 @@ throw new Error(err_msg); } - let asset_type = assetTypeInput.value; let tradeAmount = parseFloat(tradeAmountSelect.value); let fiatCurrency = currencySelect.value;