diff --git a/args/schema.sql b/args/schema.sql index ed2a387..e8a087e 100644 --- a/args/schema.sql +++ b/args/schema.sql @@ -76,7 +76,7 @@ CREATE TABLE RequestLog( id INT NOT NULL AUTO_INCREMENT, floID CHAR(34) NOT NULL, request TEXT NOT NULL, - sign TEXT NOT NULL, + sign VARCHAR(160) NOT NULL, proxy BOOLEAN NOT NULL, request_time DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(id), diff --git a/docs/scripts/exchangeAPI.js b/docs/scripts/exchangeAPI.js index 6eb08c1..c4905e2 100644 --- a/docs/scripts/exchangeAPI.js +++ b/docs/scripts/exchangeAPI.js @@ -350,7 +350,7 @@ function cancelOrder(type, id, floID, proxySecret) { //receiver should be object eg {floID1: amount1, floID2: amount2 ...} function transferToken(receiver, token, floID, proxySecret) { return new Promise((resolve, reject) => { - if (typeof receiver !== Object || receiver === null) + if (typeof receiver !== 'object' || receiver === null) return reject("Invalid receiver: parameter is not an object"); let invalidIDs = [], invalidAmt = []; diff --git a/src/backup/head.js b/src/backup/head.js index 07c53a6..e6ada2d 100644 --- a/src/backup/head.js +++ b/src/backup/head.js @@ -107,13 +107,13 @@ collectShares.retrive = function(floID, sinkID, share) { return console.error("Something is wrong! Slaves are sending different sinkID"); if (share.startsWith(SINK_KEY_INDICATOR)) { let sinkKey = share.substring(SINK_KEY_INDICATOR.length); - //console.debug("Received sinkKey:", sinkID, sinkKey); + console.debug("Received sink:", sinkID); self.verify(sinkKey); } else self.shares[floID] = share.split("|"); try { let sinkKey = floCrypto.retrieveShamirSecret([].concat(...Object.values(self.shares))); - //console.debug("Retrived sinkKey:", sinkID, sinkKey); + console.debug("Retrived sink:", sinkID); self.verify(sinkKey); } catch { //Unable to retrive sink private key. Waiting for more shares! Do nothing for now @@ -212,7 +212,7 @@ function informLiveNodes(init) { console.warn("sinkID and sinkKey in DB are not pair!"); storeSink(global.sinkID, global.sinkPrivKey); } - //console.debug("Loaded sinkKey:", global.sinkID, global.sinkPrivKey) + console.debug("Loaded sink:", global.sinkID); sendSharesToNodes(global.sinkID, generateShares(global.sinkPrivKey)) } else { //Share is present in DB, try to collect remaining shares and retrive sinkKey @@ -227,7 +227,7 @@ function informLiveNodes(init) { console.log("Starting the exchange..."); collectShares.active = false; let newSink = floCrypto.generateNewID(); - console.debug("Generated sinkKey:", newSink.floID, newSink.privKey); + console.debug("Generated sink:", newSink.floID, newSink.privKey); storeSink(newSink.floID, newSink.privKey); sendSharesToNodes(newSink.floID, generateShares(newSink.privKey)); } diff --git a/src/market.js b/src/market.js index 3dde029..883ae85 100644 --- a/src/market.js +++ b/src/market.js @@ -8,6 +8,8 @@ const { TRANSFER_HASH_PREFIX } = require('./_constants')["market"]; +const MINI_PERIOD_INTERVAL = require('./_constants')['app']['PERIOD_INTERVAL'] / 10; + var DB, assetList; //container for database and allowed assets function login(floID, proxyKey) { @@ -195,30 +197,32 @@ function getAccountDetails(floID) { } function getTransactionDetails(txid) { - let tableName, type; - if (txid.startsWith(TRANSFER_HASH_PREFIX)) { - tableName = 'TransferTransactions'; - type = 'transfer'; - } else if (txid.startsWith(TRADE_HASH_PREFIX)) { - tableName = 'TradeTransactions'; - type = 'trade'; - } else - return reject(INVALID("Invalid TransactionID")); - DB.query(`SELECT * FROM ${tableName} WHERE txid=?`, [txid]).then(result => { - if (result.length) { - let details = result[0]; - details.type = type; - if (tableName === 'TransferTransactions') //As json object is stored for receiver in transfer (to support one-to-many) - details.receiver = JSON.parse(details.receiver); - resolve(details); + return new Promise((resolve, reject) => { + let tableName, type; + if (txid.startsWith(TRANSFER_HASH_PREFIX)) { + tableName = 'TransferTransactions'; + type = 'transfer'; + } else if (txid.startsWith(TRADE_HASH_PREFIX)) { + tableName = 'TradeTransactions'; + type = 'trade'; } else - reject(INVALID("Transaction not found")); - }).catch(error => reject(error)) + return reject(INVALID("Invalid TransactionID")); + DB.query(`SELECT * FROM ${tableName} WHERE txid=?`, [txid]).then(result => { + if (result.length) { + let details = result[0]; + details.type = type; + if (tableName === 'TransferTransactions') //As json object is stored for receiver in transfer (to support one-to-many) + details.receiver = JSON.parse(details.receiver); + resolve(details); + } else + reject(INVALID("Transaction not found")); + }).catch(error => reject(error)) + }) } function transferToken(sender, receivers, token) { return new Promise((resolve, reject) => { - if (floCrypto.validateAddr(sender)) + if (!floCrypto.validateAddr(sender)) reject(INVALID(`Invalid sender (${sender})`)); else if (token !== floGlobals.currency && !assetList.includes(token)) reject(INVALID(`Invalid token (${token})`)); @@ -232,14 +236,14 @@ function transferToken(sender, receivers, token) { totalAmount += receivers[floID]; if (invalidIDs.length) reject(INVALID(`Invalid receiver (${invalidIDs})`)); - else getAssetBalance.check(senderID, token, totalAmount).then(_ => { + else getAssetBalance.check(sender, token, totalAmount).then(_ => { consumeAsset(sender, token, totalAmount).then(txQueries => { if (token === floGlobals.currency) for (let floID in receivers) txQueries.push(["INSERT INTO Cash (floID, balance) VALUE (?, ?) ON DUPLICATE KEY UPDATE balance=balance+?", [floID, receivers[floID], receivers[floID]]]); else for (let floID in receivers) - txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [floID, receivers[floID]]]); + txQueries.push(["INSERT INTO Vault(floID, quantity, asset) VALUES (?, ?, ?)", [floID, receivers[floID], token]]); let time = Date.now(); let hash = TRANSFER_HASH_PREFIX + Crypto.SHA256(JSON.stringify({ sender: sender, @@ -249,8 +253,8 @@ function transferToken(sender, receivers, token) { tx_time: time, })); txQueries.push([ - "INSERT INTO TransferTransactions (sender, receiver, token, totalAmount, tx_time, txid)", - [sender, JSON.stringify(receiver), token, totalAmount, global.convertDateToString(time), hash] + "INSERT INTO TransferTransactions (sender, receiver, token, totalAmount, tx_time, txid) VALUE (?, ?, ?, ?, ?, ?)", + [sender, JSON.stringify(receivers), token, totalAmount, global.convertDateToString(time), hash] ]); DB.transaction(txQueries) .then(result => resolve(hash)) @@ -286,7 +290,7 @@ function confirmDepositFLO() { results.forEach(req => { confirmDepositFLO.checkTx(req.floID, req.txid).then(amount => { let txQueries = []; - txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [req.floID, amount]]); + txQueries.push(["INSERT INTO Vault(floID, quantity, asset) VALUES (?, ?, ?)", [req.floID, amount, "FLO"]]); txQueries.push(["UPDATE InputFLO SET status=?, amount=? WHERE id=?", ["SUCCESS", amount, req.id]]); DB.transaction(txQueries) .then(result => console.debug("FLO deposited:", req.floID, amount)) @@ -303,7 +307,9 @@ function confirmDepositFLO() { confirmDepositFLO.checkTx = function(sender, txid) { return new Promise((resolve, reject) => { - let receiver = global.myFloID; //receiver should be market's floID (ie, adminID) + let receiver = global.sinkID; //receiver should be market's floID (ie, sinkID) + if (!receiver) + return reject([false, 'sinkID not loaded']); floBlockchainAPI.getTx(txid).then(tx => { let vin_sender = tx.vin.filter(v => v.addr === sender) if (!vin_sender.length) @@ -436,6 +442,8 @@ function confirmDepositToken() { confirmDepositToken.checkTx = function(sender, txid) { return new Promise((resolve, reject) => { let receiver = global.sinkID; //receiver should be market's floID (ie, sinkID) + if (!receiver) + return reject([false, 'sinkID not loaded']); tokenAPI.getTx(txid).then(tx => { if (tx.parsedFloData.type !== "transfer") return reject([true, "Transaction type not 'transfer'"]); @@ -525,6 +533,13 @@ function periodicProcess() { } function blockchainReCheck() { + if (blockchainReCheck.timeout) { + clearTimeout(blockchainReCheck.timeout); + blockchainReCheck.timeout = null; + } + if (!global.sinkID) + return blockchainReCheck.timeout = setTimeout(blockchainReCheck, MINI_PERIOD_INTERVAL); + confirmDepositFLO(); confirmDepositToken(); retryWithdrawalFLO(); @@ -532,6 +547,7 @@ function blockchainReCheck() { confirmWithdrawalFLO(); confirmWithdrawalToken(); } +blockchainReCheck.timeout = null; module.exports = { login, diff --git a/src/request.js b/src/request.js index c2cd73c..78a0901 100644 --- a/src/request.js +++ b/src/request.js @@ -58,7 +58,7 @@ validateRequest.getSignKey = (floID, pubKey) => new Promise((resolve, reject) => DB.query("SELECT session_time, proxyKey FROM UserSession WHERE floID=?", [floID]).then(result => { if (result.length < 1) reject(INVALID("Session not active")); - else if (proxy && result[0].session_time + MAX_SESSION_TIMEOUT < Date.now()) + else if (result[0].session_time + MAX_SESSION_TIMEOUT < Date.now()) reject(INVALID("Session Expired! Re-login required")); else resolve(result[0].proxyKey); @@ -87,7 +87,7 @@ function logRequest(floID, req_str, sign, proxy = false) { function processRequest(res, rText, validateObj, sign, floID, pubKey, marketFn) { validateRequest(validateObj, sign, floID, pubKey).then(req_str => { marketFn().then(result => { - logRequest(data.floID, req_str, data.sign, !data.pubKey); + logRequest(floID, req_str, sign, !pubKey); res.send(result); }).catch(error => { if (error instanceof INVALID)