diff --git a/.gitignore b/.gitignore index 1a39658..de930dc 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,13 @@ examples.mk json-rpc/ supernode/playground/ playground -supernode/index1.html +supernode/test/in +supernode/test/in/index1.html +supernode/test/in/index2.html +supernode/test/in/index3.html +supernode/test/in/index4.html supernode/flosend.html -supernode/index1 (copy).html \ No newline at end of file +supernode/index1 (copy).html +supernode/websocket_chat +.vscode/ +supernode/test/ diff --git a/supernode/index.html b/supernode/index.html index 83ab162..a0b53c0 100644 --- a/supernode/index.html +++ b/supernode/index.html @@ -530,11 +530,11 @@ @@ -10069,12 +10069,21 @@ // btcTradeMargin is tolerable difference between Crypto trader should deposit and cryptos he actually deposited RMAssets = `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, - #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 - #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 - #!#supernodesPubKeys=03692E641440795B6279F548C7156775EB624CC8A27FDA94C5E3B8945EC94DE1F1,02F22822D5E887ABBDA3D5E3A51574C547FEAAC00BF01185AA56858D4C9B00334F, + #!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + #!#supernodesPubKeys=0315C3A20FE7096CC2E0F81A80D5F1A687B8F9EFA65242A0B0881E1BA3EE7D7D53, + 03F7493F11B8E44B9798CD434D20FBE7FA34B9779D144984889D11A17C56A18742,039B4AA00DBFC0A6631DE6DA83526611A0E6B857D3579DF840BBDEAE8B6898E3B6, #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, - #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oURVEZQ6sPT8mwDVTGiBVPqJYqjctXYfF3"}, - "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oapBngvTbcNCSfQfzJ9RS1QYfb4ppSQ9KQ"}}`; + #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"127.0.0.1","port":"9001","kbucketId":"oZxHcbSf1JC8t5GjutopWYXs7C6Fe9p7ps"}, + "ranchimall2":{"ip":"127.0.0.1","port":"9002","kbucketId":"oTWjPupy3Z7uMdPcu5uXd521HBkcsLuSuM"}, + "ranchimall3":{"ip":"127.0.0.1","port":"9003","kbucketId":"odYA6KagmbokSh9GY7yAfeTUZRtZLwecY1"}}`; + // RMAssets = + // `tradableAsset1=BTC,FLO,BTC_TEST,FLO_TEST#!#tradableAsset2=INR,USD,BTC,FLO,BTC_TEST,FLO_TEST, + // #!#supernodes=127.0.0.1,212.88.88.2#!#MASTER_NODE=023B9F60692A17FAC805D012C5C8ADA3DD19A980A3C5F0D8A5B3500CC54D6E8B75 + // #!#MASTER_RECEIVING_ADDRESS=oVRq2nka1GtALQT8pbuLHAGjqAQ7PAo6uy#!#validTradingAmount=10000,50000,100000,#!#btcTradeMargin=5000 + // #!#supernodesPubKeys=03692E641440795B6279F548C7156775EB624CC8A27FDA94C5E3B8945EC94DE1F1,02F22822D5E887ABBDA3D5E3A51574C547FEAAC00BF01185AA56858D4C9B00334F, + // #!#externalFiles={"d3js":"58f54395efa8346e8e94d12609770f66b916897e7f4e05f6c98780cffa5c70a3"}, + // #!#ShamirsMaxShares=8#!#supernodeSeeds={"ranchimall1":{"ip":"ranchimall1.duckdns.org","port":"9002","kbucketId":"oURVEZQ6sPT8mwDVTGiBVPqJYqjctXYfF3"}, + // "ranchimall2":{"ip":"ranchimall1.duckdns.org","port":"9003","kbucketId":"oapBngvTbcNCSfQfzJ9RS1QYfb4ppSQ9KQ"}}`; let floAssetsArray = RMAssets.split('#!#'); @@ -10086,7 +10095,7 @@ let k = assets_string.split('='); if (k[1].indexOf(',') > 0) { k[1] = k[1].split(',') - .map(val => !isNaN(val) ? parseFloat(val) : val) + .map(val => !isNaN(val) ? parseFloat(val) : val.trim()) .filter(v => ![null, "", undefined, NaN].includes(v)); } else if (!isNaN(k[1])) { k[1] = parseFloat(k[1]); @@ -10196,7 +10205,7 @@ t += ``; }); - t += ` `; + t += ``; modalWindow(t); } @@ -10847,14 +10856,39 @@ } return false; }, + manually_assign_my_private_key: function() { + readDB('localbitcoinUser', '00-01').then(usr=>{ + if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) { + const RM_WALLET = new localbitcoinplusplus.wallets; + const pk_manual = prompt("Please enter your private key: "); + let gen_new_keys = RM_WALLET.generateFloKeys(pk_manual); + if (gen_new_keys.address==usr.myLocalFLOAddress) { + //localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY = gen_new_keys.privateKeyWIF; + Object.defineProperty(localbitcoinplusplus.wallets, 'MY_SUPERNODE_PRIVATE_KEY', { + value: gen_new_keys.privateKeyWIF, + writable: false, + configurable: false, + enumerable: false + }); + return true; + } else { + let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; + showMessage(mes); + throw new Error(mes); + } + } + }).catch(e=>{ + let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; + showMessage(mes); + throw new Error(mes); + }); + }, rebuild_my_private_key: function (transactionKey) { const RM_WALLET = new localbitcoinplusplus.wallets; let my_pvt_key = RM_WALLET.rebuild_private_key(MY_PRIVATE_KEY_SHAMIRS_SHARES, transactionKey); - if (typeof my_pvt_key == "undefined") { - showMessage(`WARNING: Failed to create your private keys.`); - throw new Error(`Failed to create your private keys.`); - } + if (typeof my_pvt_key == "undefined") return this.manually_assign_my_private_key(); + Object.defineProperty(localbitcoinplusplus.wallets, 'MY_SUPERNODE_PRIVATE_KEY', { value: my_pvt_key, writable: false, @@ -13445,7 +13479,7 @@ localbitcoinplusplusObj.myLocalFLOAddress = newKeys.address; localbitcoinplusplusObj.myLocalFLOPublicKey = newKeys.pubKeyHex; - // launch KBucekts + // launch KBuckets launchKBuckects = await localbitcoinplusplus.kademlia.launchKBucket(newKeys.address); if (!launchKBuckects) { @@ -13709,7 +13743,7 @@ writeToScreen("DISCONNECTED"); } - function onMessage(evt) { + async function onMessage(evt) { var response = evt.data; var res_pos = response.indexOf('{'); if (res_pos >= 0) { @@ -13717,7 +13751,12 @@ try { var res_obj = JSON.parse(res); - if (typeof res_obj.method !== undefined) { + const isIncomingMessageValid = await validateIncomingMessage(res); + console.log("isIncomingMessageValid: ", isIncomingMessageValid); + + if (!isIncomingMessageValid) return; + + if (typeof res_obj.method !== "undefined") { let response_from_sever; const RM_WALLET = new localbitcoinplusplus.wallets; @@ -13995,24 +14034,37 @@ }); doSend(send_pvtkey_req); return; + } else { + let send_pvtkey_req = RM_RPC + .send_rpc + .call(this, "retrieve_shamirs_secret_supernode_pvtkey", ""); + doSend(send_pvtkey_req); + return; } }); } break; case "retrieve_shamirs_secret_supernode_pvtkey": + if(typeof retrieve_pvtkey_counter=="undefined") retrieve_pvtkey_counter = 0; if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object" && typeof res_obj.params[0].private_key_chunk == "object" && typeof localbitcoinplusplus.wallets.supernode_transaction_key == "object") { + let share = res_obj.params[0].private_key_chunk.privateKeyChunks; if (typeof share !== "undefined" && !MY_PRIVATE_KEY_SHAMIRS_SHARES.includes(share)) { MY_PRIVATE_KEY_SHAMIRS_SHARES.push(share); } if (MY_PRIVATE_KEY_SHAMIRS_SHARES.length == 5) { RM_WALLET.rebuild_my_private_key(localbitcoinplusplus.wallets.supernode_transaction_key); - return; + } + } else { + if (retrieve_pvtkey_counter>5 && typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY == "undefined") { + RM_WALLET.manually_assign_my_private_key(); + return; } } + retrieve_pvtkey_counter++; break; case "send_back_shamirs_secret_btc_pvtkey": if (typeof res_obj.params == "object" && typeof res_obj.params[0] == "object") { @@ -14529,6 +14581,10 @@ ); break; + case "backup_server_sync_response": + console.log(res_obj); + break; + default: break; } @@ -14546,10 +14602,128 @@ } function doSend(message) { - writeToScreen("SENT: " + message); - websocket.send(message); + + const request_array = [ + 'update_external_file_request', + 'send_back_shamirs_secret_supernode_pvtkey', + 'addNewKbucketNode', + 'sync_with_supernode', + 'add_user_public_data' + ]; + + let finalMessage = message; + + const msgObj = JSON.parse(message); + + if (!request_array.includes(msgObj.method)) { + const RM_WALLET = new localbitcoinplusplus.wallets; + + if (typeof message !== "string") { + message = JSON.stringify(message); + } + const message256hash = Crypto.SHA256(message); + + if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") + throw new Error(`Private key could not be found.`); + + const nodeSignedMessage = RM_WALLET.sign(message256hash, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); + + msgObj.nodeMessage256hash = message256hash; + msgObj.nodeSignedMessage = nodeSignedMessage; + msgObj.nodePubKey = localbitcoinplusplus.wallets.my_local_flo_public_key; + + finalMessage = JSON.stringify(msgObj); + } + + writeToScreen("SENT: " + finalMessage); + websocket.send(finalMessage); } + function validateIncomingMessage(message) { + return new Promise((resolve, reject)=>{ + if(message.length <1) { + showMessage(`WARNING: The incoming websocket message on was empty.`); + reject(false)}; + const request_array = [ + 'update_external_file_request', + 'send_back_shamirs_secret_supernode_pvtkey', + 'addNewKbucketNode', + 'sync_with_supernode', + 'add_user_public_data' + ]; + + try { + const msgObj = JSON.parse(message); + + if (request_array.includes(msgObj.method)) resolve(true); + + const getFloId = bitjs.FLO_TEST.pubkey2address(msgObj.nodePubKey); + + // Check if the public key belongs to real sender + if (getFloId !== msgObj.globalParams.senderFloId) { + showMessage(`Sender FLO address did not match signer FLO address.`); + reject(false) + } + const initialMsgObj = { + jsonrpc:msgObj.jsonrpc, + id:msgObj.id, + method:msgObj.method, + params:msgObj.params, + globalParams:msgObj.globalParams, + } + + const initialMsgObjStr = JSON.stringify(initialMsgObj); + console.log(initialMsgObjStr); + + const initialMsgObjStrHash = Crypto.SHA256(initialMsgObjStr); + console.log(initialMsgObjStrHash); + + const RM_WALLET = new localbitcoinplusplus.wallets; + if (RM_WALLET.verify(initialMsgObjStrHash, msgObj.nodeSignedMessage, msgObj.nodePubKey)) { + resolve(true); + } else { + showMessage(`WARNING: Incoming Websocket message verification failed.`) + reject(false); + } + + } catch (error) { + reject(error); + } + }) + } + + // function doSendToBackupServers(message) { + // try { + // const supernodesFloAddrList = localbitcoinplusplus.master_configurations.supernodesPubKeys + // .map(fid=>bitjs.FLO_TEST.pubkey2address(fid)); + + // const messageObject = JSON.parse(message) + + // if(!supernodesFloAddrList.includes(messageObject.globalParams.senderFloId)) return; + + // if(typeof localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY !== "string") + // throw new Error(`Private key could not be found.`); + + // const RM_WALLET = localbitcoinplusplus.wallets; + + // const supernodeSignedMessage = RM_WALLET.sign(message, localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY); + + // messageObject.supernodeSignedMessage = supernodeSignedMessage; + // messageObject.supernodePubKey = localbitcoinplusplus.wallets.my_local_flo_public_key; + // messageObject.messageForOnlySupernodes = true; + // messageObject.method = `backup_${messageObject.method}`; + + // const messageString = JSON.stringify(messageObject); + + // supernodesFloAddrList.map(flo_id=>localbitcoinplusplus.encrypt + // .messageBroadcasting(messageString, flo_id, messageObject.method)); + + // } catch (error) { + // console.error(error); + // } + + // } + function writeToScreen(message) { // var pre = document.createElement("p"); // pre.style.wordWrap = "break-word"; @@ -14683,7 +14857,7 @@ var db; const DBName = "localbitcoinDB"; - var request = window.indexedDB.open(DBName, 1); + const request = window.indexedDB.open(DBName, 1); request.onerror = function (event) { //https://stackoverflow.com/questions/13972385/invalidstateerror-while-opening-indexeddb-in-firefox @@ -15413,26 +15587,8 @@ txKey[0][0]; resolve(true); } else { - readDB('localbitcoinUser', '00-01').then(usr=>{ - if (typeof usr=="object" && usr.myLocalFLOAddress.length>0) { - const RM_WALLET = new localbitcoinplusplus.wallets; - const pk_manual = prompt("Please enter your private key: "); - let gen_new_keys = RM_WALLET.generateFloKeys(pk_manual); - if (gen_new_keys.address==usr.myLocalFLOAddress) { - localbitcoinplusplus.wallets.MY_SUPERNODE_PRIVATE_KEY = gen_new_keys.privateKeyWIF; - resolve(true); - } else { - let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; - showMessage(mes); - reject(mes); - } - } - }).catch(e=>{ - let mes = `WARNING: Failed to build your private key. You can reset keys and generate new keys from keys section below.`; - showMessage(mes); - reject(mes); - }); - + const RM_WALLET = new localbitcoinplusplus.wallets; + RM_WALLET.manually_assign_my_private_key(); } }) } diff --git a/supernode/websocket_chat b/supernode/websocket_chat index c882df3..a51368c 100755 Binary files a/supernode/websocket_chat and b/supernode/websocket_chat differ diff --git a/supernode/websocket_chat.c b/supernode/websocket_chat.c index d0c42b8..084e547 100644 --- a/supernode/websocket_chat.c +++ b/supernode/websocket_chat.c @@ -6,7 +6,7 @@ #include "mongoose.h" static sig_atomic_t s_signal_received = 0; -static const char *s_http_port = "9000"; +static const char *s_http_port = "9001"; static struct mg_serve_http_opts s_http_server_opts; static void signal_handler(int sig_num) {