Multi-asset: coupling process

This commit is contained in:
sairajzero 2022-02-04 02:28:02 +05:30
parent dbad25044a
commit 92caef2c37
4 changed files with 89 additions and 66 deletions

View File

@ -47,6 +47,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
CREATE TABLE SellOrder ( CREATE TABLE SellOrder (
id INT NOT NULL AUTO_INCREMENT, id INT NOT NULL AUTO_INCREMENT,
floID CHAR(34) NOT NULL, floID CHAR(34) NOT NULL,
asset VARCHAR(64) NOT NULL,
quantity FLOAT NOT NULL, quantity FLOAT NOT NULL,
minPrice DECIMAL(10, 2), minPrice DECIMAL(10, 2),
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP, time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
@ -57,6 +58,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
CREATE TABLE BuyOrder ( CREATE TABLE BuyOrder (
id INT NOT NULL AUTO_INCREMENT, id INT NOT NULL AUTO_INCREMENT,
floID CHAR(34) NOT NULL, floID CHAR(34) NOT NULL,
asset VARCHAR(64) NOT NULL,
quantity FLOAT NOT NULL, quantity FLOAT NOT NULL,
maxPrice DECIMAL(10, 2) NOT NULL, maxPrice DECIMAL(10, 2) NOT NULL,
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP, time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
@ -67,6 +69,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
CREATE TABLE Transactions ( CREATE TABLE Transactions (
seller CHAR(34) NOT NULL, seller CHAR(34) NOT NULL,
buyer CHAR(34) NOT NULL, buyer CHAR(34) NOT NULL,
asset VARCHAR(64) NOT NULL,
quantity FLOAT NOT NULL, quantity FLOAT NOT NULL,
unitValue DECIMAL(10, 2) NOT NULL, unitValue DECIMAL(10, 2) NOT NULL,
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP, tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,

View File

@ -3,11 +3,16 @@
const group = require("./group"); const group = require("./group");
const price = require("./price"); const price = require("./price");
var DB; //container for database var DB, assetList; //container for database and assetList
function initiate() { function initiate() {
price.getRates().then(cur_rate => { for (let asset in assetList)
group.getBestPairs(cur_rate) startCouplingForAsset(asset);
}
function startCouplingForAsset(asset) {
price.getRates(asset).then(cur_rate => {
group.getBestPairs(asset, cur_rate)
.then(bestPairQueue => processCoupling(bestPairQueue)) .then(bestPairQueue => processCoupling(bestPairQueue))
.catch(error => console.error("initiateCoupling", error)) .catch(error => console.error("initiateCoupling", error))
}).catch(error => console.error(error)); }).catch(error => console.error(error));
@ -19,14 +24,14 @@ function processCoupling(bestPairQueue) {
seller_best = pair_result.sellOrder; seller_best = pair_result.sellOrder;
console.debug("Sell:", seller_best); console.debug("Sell:", seller_best);
console.debug("Buy:", buyer_best); console.debug("Buy:", buyer_best);
spendFLO(buyer_best, seller_best, pair_result.null_base).then(spend_result => { spendAsset(bestPairQueue.asset, buyer_best, seller_best, pair_result.null_base).then(spend_result => {
let tx_quantity = spend_result.quantity, let tx_quantity = spend_result.quantity,
txQueries = spend_result.txQueries, txQueries = spend_result.txQueries,
clear_sell = spend_result.incomplete && !spend_result.flag_baseNull; //clear_sell can be true only if an order is placed without enough FLO clear_sell = spend_result.incomplete && !spend_result.flag_baseNull; //clear_sell can be true only if an order is placed without enough ASSET
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell); processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.cur_rate, tx_quantity); updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity);
//begin audit //begin audit
beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.cur_rate, tx_quantity).then(audit => { beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity).then(audit => {
//process txn query in SQL //process txn query in SQL
DB.transaction(txQueries).then(_ => { DB.transaction(txQueries).then(_ => {
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull); bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
@ -58,13 +63,13 @@ function processCoupling(bestPairQueue) {
console.log("No valid sellOrders."); console.log("No valid sellOrders.");
noSell = true; noSell = true;
} }
price.noOrder(noBuy, noSell); price.noOrder(bestPairQueue.asset, noBuy, noSell);
}); });
} }
function spendFLO(buyOrder, sellOrder, null_base) { function spendAsset(asset, buyOrder, sellOrder, null_base) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY base", [sellOrder.floID]).then(result => { DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? AND asset=? ORDER BY base", [sellOrder.floID, asset]).then(result => {
let rem = Math.min(buyOrder.quantity, sellOrder.quantity), let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
txQueries = [], txQueries = [],
flag_baseNull = false; flag_baseNull = false;
@ -104,49 +109,50 @@ function processOrders(seller_best, buyer_best, txQueries, quantity, clear_sell)
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]); txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
} }
function updateBalance(seller_best, buyer_best, txQueries, cur_price, quantity) { function updateBalance(seller_best, buyer_best, txQueries, asset, cur_price, quantity) {
//Update rupee balance for seller and buyer //Update cash balance for seller and buyer
let totalAmount = cur_price * quantity; let totalAmount = cur_price * quantity;
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance+? WHERE floID=?", [totalAmount, seller_best.floID]]); txQueries.push(["UPDATE Cash SET balance=balance+? WHERE floID=?", [totalAmount, seller_best.floID]]);
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance-? WHERE floID=?", [totalAmount, buyer_best.floID]]); txQueries.push(["UPDATE Cash SET balance=balance-? WHERE floID=?", [totalAmount, buyer_best.floID]]);
//Add coins to Buyer //Add coins to Buyer
txQueries.push(["INSERT INTO Vault(floID, base, quantity) VALUES (?, ?, ?)", [buyer_best.floID, cur_price, quantity]]) txQueries.push(["INSERT INTO Vault(floID, asset, base, quantity) VALUES (?, ?, ?, ?)", [buyer_best.floID, asset, cur_price, quantity]])
//Record transaction //Record transaction
txQueries.push(["INSERT INTO Transactions (seller, buyer, quantity, unitValue) VALUES (?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, quantity, cur_price]]); txQueries.push(["INSERT INTO Transactions (seller, buyer, asset, quantity, unitValue) VALUES (?, ?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, asset, quantity, cur_price]]);
} }
function beginAudit(sellerID, buyerID, unit_price, quantity) { function beginAudit(sellerID, buyerID, asset, unit_price, quantity) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
auditBalance(sellerID, buyerID).then(old_bal => resolve({ auditBalance(sellerID, buyerID, asset).then(old_bal => resolve({
end: () => endAudit(sellerID, buyerID, old_bal, unit_price, quantity) end: () => endAudit(sellerID, buyerID, asset, old_bal, unit_price, quantity)
})).catch(error => reject(error)) })).catch(error => reject(error))
}) })
} }
function endAudit(sellerID, buyerID, old_bal, unit_price, quantity) { function endAudit(sellerID, buyerID, asset, old_bal, unit_price, quantity) {
auditBalance(sellerID, buyerID).then(new_bal => { auditBalance(sellerID, buyerID, asset).then(new_bal => {
DB.query("INSERT INTO auditTransaction (sellerID, buyerID, quantity, unit_price, total_cost, " + DB.query("INSERT INTO auditTransaction (asset, quantity, unit_price, total_cost," +
" Rupee_seller_old, Rupee_seller_new, Rupee_buyer_old, Rupee_buyer_new," + " sellerID, seller_old_cash, seller_old_asset, seller_new_cash, seller_new_asset," +
" FLO_seller_old, FLO_seller_new, FLO_buyer_old, FLO_buyer_new) " + " buyerID, buyer_old_cash, buyer_old_asset, buyer_new_cash, buyer_new_asset)" +
" Value (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [sellerID, buyerID, quantity, unit_price, quantity * unit_price, " Value (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [
old_bal[sellerID].Rupee, new_bal[sellerID].Rupee, old_bal[buyerID].Rupee, new_bal[buyerID].Rupee, asset, quantity, unit_price, quantity * unit_price,
old_bal[sellerID].FLO, new_bal[sellerID].FLO, old_bal[buyerID].FLO, new_bal[buyerID].FLO, sellerID, old_bal[sellerID].cash, old_bal[sellerID].asset, new_bal[sellerID].cash, new_bal[sellerID].asset,
buyerID, old_bal[buyerID].cash, old_bal[buyerID].asset, new_bal[buyerID].cash, new_bal[buyerID].asset,
]).then(_ => null).catch(error => console.error(error)) ]).then(_ => null).catch(error => console.error(error))
}).catch(error => console.error(error)); }).catch(error => console.error(error));
} }
function auditBalance(sellerID, buyerID) { function auditBalance(sellerID, buyerID, asset) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let balance = { let balance = {
[sellerID]: {}, [sellerID]: {},
[buyerID]: {} [buyerID]: {}
}; };
DB.query("SELECT floID, rupeeBalance FROM Cash WHERE floID IN (?, ?)", [sellerID, buyerID]).then(result => { DB.query("SELECT floID, balance FROM Cash WHERE floID IN (?, ?)", [sellerID, buyerID]).then(result => {
for (let i in result) for (let i in result)
balance[result[i].floID].Rupee = result[i].rupeeBalance; balance[result[i].floID].cash = result[i].balance;
DB.query("SELECT floID, SUM(quantity) as floBal FROM Vault WHERE floID IN (?, ?) GROUP BY floID", [sellerID, buyerID]).then(result => { DB.query("SELECT floID, SUM(quantity) as asset_balance FROM Vault WHERE asset=? AND floID IN (?, ?) GROUP BY floID", [asset, sellerID, buyerID]).then(result => {
for (let i in result) for (let i in result)
balance[result[i].floID].FLO = result[i].floBal; balance[result[i].floID].asset = result[i].asset_balance;
resolve(balance); resolve(balance);
}).catch(error => reject(error)) }).catch(error => reject(error))
}).catch(error => reject(error)) }).catch(error => reject(error))
@ -155,11 +161,17 @@ function auditBalance(sellerID, buyerID) {
module.exports = { module.exports = {
initiate, initiate,
group, group: {
addTag: group.addTag,
removeTag: group.removeTag
},
price, price,
set DB(db) { set DB(db) {
DB = db; DB = db;
group.DB = db; group.DB = db;
price.DB = db; price.DB = db;
},
set assetList(list) {
assetList = list;
} }
} }

View File

@ -25,22 +25,25 @@ function removeTag(floID, tag) {
}) })
} }
function getBestPairs(currentRate) { function getBestPairs(asset, cur_rate) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT tag, sellPriority, buyPriority FROM TagList").then(result => { DB.query("SELECT tag, sellPriority, buyPriority FROM TagList").then(result => {
//Sorted in Ascending (ie, stack; pop for highest) //Sorted in Ascending (ie, stack; pop for highest)
let tags_buy = result.sort((a, b) => a.buyPriority > b.buyPriority ? 1 : -1).map(r => r.tag); let tags_buy = result.sort((a, b) => a.buyPriority > b.buyPriority ? 1 : -1).map(r => r.tag);
let tags_sell = result.sort((a, b) => a.sellPriority > b.sellPriority ? 1 : -1).map(r => r.tag); let tags_sell = result.sort((a, b) => a.sellPriority > b.sellPriority ? 1 : -1).map(r => r.tag);
resolve(new bestPair(currentRate, tags_buy, tags_sell)); resolve(new bestPair(asset, cur_rate, tags_buy, tags_sell));
}).catch(error => reject(error)) }).catch(error => reject(error))
}) })
} }
const bestPair = function(cur_rate, tags_buy, tags_sell) { const bestPair = function(asset, cur_rate, tags_buy, tags_sell) {
const currentRate = cur_rate;
Object.defineProperty(this, 'asset', {
get: () => asset
});
Object.defineProperty(this, 'cur_rate', { Object.defineProperty(this, 'cur_rate', {
get: () => currentRate get: () => cur_rate,
}); });
this.get = () => new Promise((resolve, reject) => { this.get = () => new Promise((resolve, reject) => {
@ -89,7 +92,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
const getSellOrder = () => new Promise((resolve, reject) => { const getSellOrder = () => new Promise((resolve, reject) => {
let cache = getSellOrder.cache; let cache = getSellOrder.cache;
if (cache.cur_order) { //If cache already has a pending order if (cache.cur_order) { //If cache already has a pending order
verifySellOrder(cache.cur_order, currentRate, cache.mode_null).then(result => { verifySellOrder(cache.cur_order, asset, cur_rate, cache.mode_null).then(result => {
cache.cur_order = result; cache.cur_order = result;
resolve(result); resolve(result);
}).catch(error => { }).catch(error => {
@ -102,7 +105,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
.catch(error => reject(error)) .catch(error => reject(error))
}) })
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority } else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
getTopValidSellOrder(cache.orders, currentRate, cache.mode_null).then(result => { getTopValidSellOrder(cache.orders, asset, cur_rate, cache.mode_null).then(result => {
cache.cur_order = result; cache.cur_order = result;
resolve(result); resolve(result);
}).catch(error => { }).catch(error => {
@ -116,14 +119,14 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
}) })
} else if (cache.tags.length) { //If cache has remaining tags } else if (cache.tags.length) { //If cache has remaining tags
cache.cur_tag = cache.tags.pop(); cache.cur_tag = cache.tags.pop();
getSellOrdersInTag(cache.cur_tag, currentRate).then(orders => { getSellOrdersInTag(cache.cur_tag, asset, cur_rate).then(orders => {
cache.orders = orders; cache.orders = orders;
getSellOrder() getSellOrder()
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error)) .catch(error => reject(error))
}).catch(error => reject(error)); }).catch(error => reject(error));
} else if (!cache.end) { //Un-tagged floID's orders (do only once) } else if (!cache.end) { //Un-tagged floID's orders (do only once)
getUntaggedSellOrders(currentRate).then(orders => { getUntaggedSellOrders(asset, cur_rate).then(orders => {
cache.orders = orders; cache.orders = orders;
cache.cur_tag = null; cache.cur_tag = null;
cache.end = true; cache.end = true;
@ -150,7 +153,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
const getBuyOrder = () => new Promise((resolve, reject) => { const getBuyOrder = () => new Promise((resolve, reject) => {
let cache = getBuyOrder.cache; let cache = getBuyOrder.cache;
if (cache.cur_order) { //If cache already has a pending order if (cache.cur_order) { //If cache already has a pending order
verifyBuyOrder(cache.cur_order, currentRate).then(result => { verifyBuyOrder(cache.cur_order, cur_rate).then(result => {
cache.cur_order = result; cache.cur_order = result;
resolve(result); resolve(result);
}).catch(error => { }).catch(error => {
@ -163,7 +166,7 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
.catch(error => reject(error)) .catch(error => reject(error))
}) })
} else if (cache.orders && cache.orders.length) { //If cache already has orders in priority } else if (cache.orders && cache.orders.length) { //If cache already has orders in priority
getTopValidBuyOrder(cache.orders, currentRate).then(result => { getTopValidBuyOrder(cache.orders, cur_rate).then(result => {
cache.cur_order = result; cache.cur_order = result;
resolve(result); resolve(result);
}).catch(error => { }).catch(error => {
@ -177,14 +180,14 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
}) })
} else if (cache.tags.length) { //If cache has remaining tags } else if (cache.tags.length) { //If cache has remaining tags
cache.cur_tag = cache.tags.pop(); cache.cur_tag = cache.tags.pop();
getBuyOrdersInTag(cache.cur_tag, currentRate).then(orders => { getBuyOrdersInTag(cache.cur_tag, asset, cur_rate).then(orders => {
cache.orders = orders; cache.orders = orders;
getBuyOrder() getBuyOrder()
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error)) .catch(error => reject(error))
}).catch(error => reject(error)); }).catch(error => reject(error));
} else if (!cache.end) { //Un-tagged floID's orders (do only once) } else if (!cache.end) { //Un-tagged floID's orders (do only once)
getUntaggedBuyOrders(currentRate).then(orders => { getUntaggedBuyOrders(asset, cur_rate).then(orders => {
cache.orders = orders; cache.orders = orders;
cache.cur_tag = null; cache.cur_tag = null;
cache.end = true; cache.end = true;
@ -200,31 +203,34 @@ const bestPair = function(cur_rate, tags_buy, tags_sell) {
}; };
} }
function getUntaggedSellOrders(cur_price) { function getUntaggedSellOrders(asset, cur_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" + DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
" LEFT JOIN Tags ON Tags.floID = SellOrder.floID" + " LEFT JOIN Tags ON Tags.floID = SellOrder.floID" +
" WHERE Tags.floID IS NULL AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed DESC", [cur_price]) " WHERE Tags.floID IS NULL AND SellOrder.asset = ? AND SellOrder.minPrice <=?" +
" ORDER BY SellOrder.time_placed DESC", [asset, cur_price])
.then(orders => resolve(orders)) .then(orders => resolve(orders))
.catch(error => reject(error)) .catch(error => reject(error))
}) })
} }
function getUntaggedBuyOrders(cur_price) { function getUntaggedBuyOrders(asset, cur_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" + DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
" LEFT JOIN Tags ON Tags.floID = BuyOrder.floID" + " LEFT JOIN Tags ON Tags.floID = BuyOrder.floID" +
" WHERE Tags.floID IS NULL AND BuyOrder.maxPrice >=? ORDER BY BuyOrder.time_placed DESC", [cur_price]) " WHERE Tags.floID IS NULL AND BuyOrder.asset = ? AND BuyOrder.maxPrice >=? " +
" ORDER BY BuyOrder.time_placed DESC", [asset, cur_price])
.then(orders => resolve(orders)) .then(orders => resolve(orders))
.catch(error => reject(error)) .catch(error => reject(error))
}) })
} }
function getSellOrdersInTag(tag, cur_price) { function getSellOrdersInTag(tag, asset, cur_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" + DB.query("SELECT SellOrder.id, SellOrder.floID, SellOrder.quantity FROM SellOrder" +
" INNER JOIN Tags ON Tags.floID = SellOrder.floID" + " INNER JOIN Tags ON Tags.floID = SellOrder.floID" +
" WHERE Tags.tag = ? AND SellOrder.minPrice <=? ORDER BY SellOrder.time_placed DESC", [tag, cur_price]).then(orders => { " WHERE Tags.tag = ? AND SellOrder.asset = ? AND SellOrder.minPrice <=?" +
" ORDER BY SellOrder.time_placed DESC", [tag, asset, cur_price]).then(orders => {
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required. if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
resolve(orders); resolve(orders);
else else
@ -238,11 +244,12 @@ function getSellOrdersInTag(tag, cur_price) {
}); });
} }
function getBuyOrdersInTag(tag, cur_price) { function getBuyOrdersInTag(tag, asset, cur_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" + DB.query("SELECT BuyOrder.id, BuyOrder.floID, BuyOrder.quantity FROM BuyOrder" +
" INNER JOIN Tags ON Tags.floID = BuyOrder.floID" + " INNER JOIN Tags ON Tags.floID = BuyOrder.floID" +
" WHERE Tags.tag = ? AND BuyOrder.maxPrice >=? ORDER BY BuyOrder.time_placed DESC", [tag, cur_price]).then(orders => { " WHERE Tags.tag = ? AND BuyOrder.asset = ? AND BuyOrder.maxPrice >=?" +
" ORDER BY BuyOrder.time_placed DESC", [tag, asset, cur_price]).then(orders => {
if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required. if (orders.length <= 1) // No (or) Only-one order, hence priority sort not required.
resolve(orders); resolve(orders);
else else
@ -287,26 +294,26 @@ function fetch_api(api, id) {
}) })
} }
function getTopValidSellOrder(orders, cur_price, mode_null) { function getTopValidSellOrder(orders, asset, cur_price, mode_null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!orders.length) if (!orders.length)
return reject(false) return reject(false)
verifySellOrder(orders.pop(), cur_price, mode_null) //pop: as the orders are sorted in ascending (highest point should be checked 1st) verifySellOrder(orders.pop(), asset, cur_price, mode_null) //pop: as the orders are sorted in ascending (highest point should be checked 1st)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => { .catch(error => {
if (error !== false) if (error !== false)
return reject(error); return reject(error);
getTopValidSellOrder(orders, cur_price, mode_null) getTopValidSellOrder(orders, asset, cur_price, mode_null)
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error)); .catch(error => reject(error));
}); });
}); });
} }
function verifySellOrder(sellOrder, cur_price, mode_null) { function verifySellOrder(sellOrder, asset, cur_price, mode_null) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!mode_null) if (!mode_null)
DB.query("SELECT quantity, base FROM Vault WHERE floID=? AND base IS NOT NULL ORDER BY base", [sellOrder.floID]).then(result => { DB.query("SELECT quantity, base FROM Vault WHERE floID=? AND asset=? AND base IS NOT NULL ORDER BY base", [sellOrder.floID, asset]).then(result => {
let rem = sellOrder.quantity, let rem = sellOrder.quantity,
sell_base = 0, sell_base = 0,
base_quantity = 0; base_quantity = 0;
@ -329,7 +336,7 @@ function verifySellOrder(sellOrder, cur_price, mode_null) {
resolve(sellOrder); resolve(sellOrder);
}).catch(error => reject(error)); }).catch(error => reject(error));
else if (mode_null) else if (mode_null)
DB.query("SELECT SUM(quantity) as total FROM Vault WHERE floID=?", [sellOrder.floID]).then(result => { DB.query("SELECT SUM(quantity) as total FROM Vault WHERE floID=? AND asset=?", [sellOrder.floID, asset]).then(result => {
if (result.total < sellOrder.quantity) if (result.total < sellOrder.quantity)
console.warn(`Sell Order ${sellOrder.id} was made without enough FLO. This should not happen`); console.warn(`Sell Order ${sellOrder.id} was made without enough FLO. This should not happen`);
if (result.total > 0) if (result.total > 0)
@ -358,10 +365,10 @@ function getTopValidBuyOrder(orders, cur_price) {
function verifyBuyOrder(buyOrder, cur_price) { function verifyBuyOrder(buyOrder, cur_price) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
DB.query("SELECT rupeeBalance AS bal FROM Cash WHERE floID=?", [buyOrder.floID]).then(result => { DB.query("SELECT balance AS bal FROM Cash WHERE floID=?", [buyOrder.floID]).then(result => {
if (result[0].bal < cur_price * buyOrder.quantity) { if (result[0].bal < cur_price * buyOrder.quantity) {
//This should not happen unless a buy order is placed when user doesnt have enough rupee balance //This should not happen unless a buy order is placed when user doesnt have enough cash balance
console.warn(`Buy order ${buyOrder.id} is active, but rupee# is insufficient`); console.warn(`Buy order ${buyOrder.id} is active, but Cash is insufficient`);
reject(false); reject(false);
} else } else
resolve(buyOrder); resolve(buyOrder);

View File

@ -67,7 +67,7 @@ function addSellOrder(floID, asset, quantity, min_price) {
return reject(INVALID(`Invalid asset (${asset})`)); return reject(INVALID(`Invalid asset (${asset})`));
getAssetBalance.check(floID, asset, quantity).then(_ => { getAssetBalance.check(floID, asset, quantity).then(_ => {
checkSellRequirement(floID).then(_ => { checkSellRequirement(floID).then(_ => {
DB.query("INSERT INTO SellOrder(floID, quantity, minPrice) VALUES (?, ?, ?)", [floID, quantity, min_price]) DB.query("INSERT INTO SellOrder(floID, asset, quantity, minPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, min_price])
.then(result => resolve("Added SellOrder to DB")) .then(result => resolve("Added SellOrder to DB"))
.catch(error => reject(error)); .catch(error => reject(error));
}).catch(error => reject(error)) }).catch(error => reject(error))
@ -100,7 +100,7 @@ function addBuyOrder(floID, asset, quantity, max_price) {
else if (!allowedAssets.includes(asset)) else if (!allowedAssets.includes(asset))
return reject(INVALID(`Invalid asset (${asset})`)); return reject(INVALID(`Invalid asset (${asset})`));
getAssetBalance.check(floID, asset, quantity).then(_ => { getAssetBalance.check(floID, asset, quantity).then(_ => {
DB.query("INSERT INTO BuyOrder(floID, quantity, maxPrice) VALUES (?, ?, ?)", [floID, quantity, max_price]) DB.query("INSERT INTO BuyOrder(floID, asset, quantity, maxPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, max_price])
.then(result => resolve("Added BuyOrder to DB")) .then(result => resolve("Added BuyOrder to DB"))
.catch(error => reject(error)); .catch(error => reject(error));
}).catch(error => reject(error)); }).catch(error => reject(error));
@ -462,6 +462,7 @@ module.exports = {
coupling.DB = db; coupling.DB = db;
}, },
set allowedAssets(assets) { set allowedAssets(assets) {
allowedAssets = assets; allowedAssets = Object.keys(assets);
coupling.assetList = assets;
} }
}; };