Move transaction process to coupling.js
This commit is contained in:
parent
1b6488bdd1
commit
946087481a
123
src/coupling.js
Normal file
123
src/coupling.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const group = require("./group");
|
||||||
|
const price = require("./price");
|
||||||
|
|
||||||
|
var DB; //container for database
|
||||||
|
|
||||||
|
function initiate() {
|
||||||
|
price.getRates().then(cur_rate => {
|
||||||
|
group.getBestPairs(cur_rate)
|
||||||
|
.then(bestPairQueue => processCoupling(bestPairQueue))
|
||||||
|
.catch(error => console.error("initiateCoupling", error))
|
||||||
|
}).catch(error => console.error(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function processCoupling(bestPairQueue) {
|
||||||
|
bestPairQueue.get().then(pair_result => {
|
||||||
|
let buyer_best = pair_result.buyOrder,
|
||||||
|
seller_best = pair_result.sellOrder;
|
||||||
|
console.debug("Sell:", seller_best);
|
||||||
|
console.debug("Buy:", buyer_best);
|
||||||
|
spendFLO(buyer_best, seller_best, pair_result.null_base).then(spend_result => {
|
||||||
|
let tx_quantity = spend_result.quantity,
|
||||||
|
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
|
||||||
|
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
|
||||||
|
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.cur_rate, tx_quantity);
|
||||||
|
//process txn query in SQL
|
||||||
|
DB.transaction(txQueries).then(_ => {
|
||||||
|
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
|
||||||
|
console.log(`Transaction was successful! BuyOrder:${buyer_best.id}| SellOrder:${seller_best.id}`);
|
||||||
|
price.updateLastTime();
|
||||||
|
//Since a tx was successful, match again
|
||||||
|
processCoupling(bestPairQueue);
|
||||||
|
}).catch(error => console.error(error));
|
||||||
|
}).catch(error => console.error(error));
|
||||||
|
}).catch(error => {
|
||||||
|
let noBuy, noSell;
|
||||||
|
if (error.buy === undefined)
|
||||||
|
noBuy = false;
|
||||||
|
else if (error.buy !== false) {
|
||||||
|
console.error(error.buy);
|
||||||
|
noBuy = null;
|
||||||
|
} else {
|
||||||
|
console.log("No valid buyOrders.");
|
||||||
|
noBuy = true;
|
||||||
|
}
|
||||||
|
if (error.sell === undefined)
|
||||||
|
noSell = false;
|
||||||
|
else if (error.sell !== false) {
|
||||||
|
console.error(error.sell);
|
||||||
|
noSell = null;
|
||||||
|
} else {
|
||||||
|
console.log("No valid sellOrders.");
|
||||||
|
noSell = true;
|
||||||
|
}
|
||||||
|
price.noOrder(noBuy, noSell);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function spendFLO(buyOrder, sellOrder, null_base) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY base", [sellOrder.floID]).then(result => {
|
||||||
|
let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
|
||||||
|
txQueries = [],
|
||||||
|
flag_baseNull = false;
|
||||||
|
for (let i = 0; i < result.length && rem > 0; i++)
|
||||||
|
if (result[i].base || null_base) {
|
||||||
|
if (rem < result[i].quantity) {
|
||||||
|
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, result[i].id]]);
|
||||||
|
rem = 0;
|
||||||
|
} else {
|
||||||
|
txQueries.push(["DELETE FROM Vault WHERE id=?", [result[i].id]]);
|
||||||
|
rem -= result[i].quantity;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
flag_baseNull = true;
|
||||||
|
resolve({
|
||||||
|
quantity: Math.min(buyOrder.quantity, sellOrder.quantity) - rem,
|
||||||
|
txQueries,
|
||||||
|
incomplete: rem > 0,
|
||||||
|
flag_baseNull
|
||||||
|
});
|
||||||
|
}).catch(error => reject(error));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function processOrders(seller_best, buyer_best, txQueries, quantity, clear_sell) {
|
||||||
|
if (quantity > buyer_best.quantity || quantity > seller_best.quantity)
|
||||||
|
throw Error("Tx quantity cannot be more than order quantity");
|
||||||
|
//Process Buy Order
|
||||||
|
if (quantity == buyer_best.quantity)
|
||||||
|
txQueries.push(["DELETE FROM BuyOrder WHERE id=?", [buyer_best.id]]);
|
||||||
|
else
|
||||||
|
txQueries.push(["UPDATE BuyOrder SET quantity=quantity-? WHERE id=?", [quantity, buyer_best.id]]);
|
||||||
|
//Process Sell Order
|
||||||
|
if (quantity == seller_best.quantity || clear_sell)
|
||||||
|
txQueries.push(["DELETE FROM SellOrder WHERE id=?", [seller_best.id]]);
|
||||||
|
else
|
||||||
|
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBalance(seller_best, buyer_best, txQueries, cur_price, quantity) {
|
||||||
|
//Update rupee balance for seller and buyer
|
||||||
|
let totalAmount = cur_price * quantity;
|
||||||
|
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance+? WHERE floID=?", [totalAmount, seller_best.floID]]);
|
||||||
|
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance-? WHERE floID=?", [totalAmount, buyer_best.floID]]);
|
||||||
|
//Add coins to Buyer
|
||||||
|
txQueries.push(["INSERT INTO Vault(floID, base, quantity) VALUES (?, ?, ?)", [buyer_best.floID, cur_price, quantity]])
|
||||||
|
//Record transaction
|
||||||
|
txQueries.push(["INSERT INTO Transactions (seller, buyer, quantity, unitValue) VALUES (?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, quantity, cur_price]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initiate,
|
||||||
|
group,
|
||||||
|
price,
|
||||||
|
set DB(db) {
|
||||||
|
DB = db;
|
||||||
|
group.DB = db;
|
||||||
|
price.DB = db;
|
||||||
|
}
|
||||||
|
}
|
||||||
122
src/market.js
122
src/market.js
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const group = require("./group");
|
const coupling = require('./coupling');
|
||||||
const price = require("./price");
|
|
||||||
const MINIMUM_BUY_REQUIREMENT = 0.1;
|
const MINIMUM_BUY_REQUIREMENT = 0.1;
|
||||||
|
|
||||||
var DB; //container for database
|
var DB; //container for database
|
||||||
@ -56,7 +55,7 @@ const tokenAPI = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function returnRates() {
|
function returnRates() {
|
||||||
return price.currentRate;
|
return coupling.price.currentRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSellOrder(floID, quantity, min_price) {
|
function addSellOrder(floID, quantity, min_price) {
|
||||||
@ -152,112 +151,6 @@ function cancelOrder(type, id, floID) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initiateCoupling() {
|
|
||||||
price.getRates().then(cur_rate => {
|
|
||||||
group.getBestPairs(cur_rate)
|
|
||||||
.then(bestPairQueue => processCoupling(bestPairQueue))
|
|
||||||
.catch(error => console.error("initiateCoupling", error))
|
|
||||||
}).catch(error => console.error(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
function processCoupling(bestPairQueue) {
|
|
||||||
bestPairQueue.get().then(pair_result => {
|
|
||||||
let buyer_best = pair_result.buyOrder,
|
|
||||||
seller_best = pair_result.sellOrder;
|
|
||||||
console.debug("Sell:", seller_best);
|
|
||||||
console.debug("Buy:", buyer_best);
|
|
||||||
spendFLO(buyer_best, seller_best, pair_result.null_base).then(spend_result => {
|
|
||||||
let tx_quantity = spend_result.quantity,
|
|
||||||
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
|
|
||||||
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
|
|
||||||
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.cur_rate, tx_quantity);
|
|
||||||
//process txn query in SQL
|
|
||||||
DB.transaction(txQueries).then(_ => {
|
|
||||||
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
|
|
||||||
console.log(`Transaction was successful! BuyOrder:${buyer_best.id}| SellOrder:${seller_best.id}`);
|
|
||||||
price.updateLastTime();
|
|
||||||
//Since a tx was successful, match again
|
|
||||||
processCoupling(bestPairQueue);
|
|
||||||
}).catch(error => console.error(error));
|
|
||||||
}).catch(error => console.error(error));
|
|
||||||
}).catch(error => {
|
|
||||||
let noBuy, noSell;
|
|
||||||
if (error.buy === undefined)
|
|
||||||
noBuy = false;
|
|
||||||
else if (error.buy !== false) {
|
|
||||||
console.error(error.buy);
|
|
||||||
noBuy = null;
|
|
||||||
} else {
|
|
||||||
console.log("No valid buyOrders.");
|
|
||||||
noBuy = true;
|
|
||||||
}
|
|
||||||
if (error.sell === undefined)
|
|
||||||
noSell = false;
|
|
||||||
else if (error.sell !== false) {
|
|
||||||
console.error(error.sell);
|
|
||||||
noSell = null;
|
|
||||||
} else {
|
|
||||||
console.log("No valid sellOrders.");
|
|
||||||
noSell = true;
|
|
||||||
}
|
|
||||||
price.noOrder(noBuy, noSell);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function spendFLO(buyOrder, sellOrder, null_base) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY base", [sellOrder.floID]).then(result => {
|
|
||||||
let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
|
|
||||||
txQueries = [],
|
|
||||||
flag_baseNull = false;
|
|
||||||
for (let i = 0; i < result.length && rem > 0; i++)
|
|
||||||
if (result[i].base || null_base) {
|
|
||||||
if (rem < result[i].quantity) {
|
|
||||||
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, result[i].id]]);
|
|
||||||
rem = 0;
|
|
||||||
} else {
|
|
||||||
txQueries.push(["DELETE FROM Vault WHERE id=?", [result[i].id]]);
|
|
||||||
rem -= result[i].quantity;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
flag_baseNull = true;
|
|
||||||
resolve({
|
|
||||||
quantity: Math.min(buyOrder.quantity, sellOrder.quantity) - rem,
|
|
||||||
txQueries,
|
|
||||||
incomplete: rem > 0,
|
|
||||||
flag_baseNull
|
|
||||||
});
|
|
||||||
}).catch(error => reject(error));
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function processOrders(seller_best, buyer_best, txQueries, quantity, clear_sell) {
|
|
||||||
if (quantity > buyer_best.quantity || quantity > seller_best.quantity)
|
|
||||||
throw Error("Tx quantity cannot be more than order quantity");
|
|
||||||
//Process Buy Order
|
|
||||||
if (quantity == buyer_best.quantity)
|
|
||||||
txQueries.push(["DELETE FROM BuyOrder WHERE id=?", [buyer_best.id]]);
|
|
||||||
else
|
|
||||||
txQueries.push(["UPDATE BuyOrder SET quantity=quantity-? WHERE id=?", [quantity, buyer_best.id]]);
|
|
||||||
//Process Sell Order
|
|
||||||
if (quantity == seller_best.quantity || clear_sell)
|
|
||||||
txQueries.push(["DELETE FROM SellOrder WHERE id=?", [seller_best.id]]);
|
|
||||||
else
|
|
||||||
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateBalance(seller_best, buyer_best, txQueries, cur_price, quantity) {
|
|
||||||
//Update rupee balance for seller and buyer
|
|
||||||
let totalAmount = cur_price * quantity;
|
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance+? WHERE floID=?", [totalAmount, seller_best.floID]]);
|
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance-? WHERE floID=?", [totalAmount, buyer_best.floID]]);
|
|
||||||
//Add coins to Buyer
|
|
||||||
txQueries.push(["INSERT INTO Vault(floID, base, quantity) VALUES (?, ?, ?)", [buyer_best.floID, cur_price, quantity]])
|
|
||||||
//Record transaction
|
|
||||||
txQueries.push(["INSERT INTO Transactions (seller, buyer, quantity, unitValue) VALUES (?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, quantity, cur_price]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAccountDetails(floID) {
|
function getAccountDetails(floID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let select = [];
|
let select = [];
|
||||||
@ -598,11 +491,11 @@ function confirmWithdrawalRupee() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function periodicProcess() {
|
function periodicProcess() {
|
||||||
transactionReCheck();
|
blockchainReCheck();
|
||||||
initiateCoupling();
|
coupling.initiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
function transactionReCheck() {
|
function blockchainReCheck() {
|
||||||
confirmDepositFLO();
|
confirmDepositFLO();
|
||||||
confirmDepositRupee();
|
confirmDepositRupee();
|
||||||
retryWithdrawalFLO();
|
retryWithdrawalFLO();
|
||||||
@ -622,10 +515,9 @@ module.exports = {
|
|||||||
depositRupee,
|
depositRupee,
|
||||||
withdrawRupee,
|
withdrawRupee,
|
||||||
periodicProcess,
|
periodicProcess,
|
||||||
group,
|
group: coupling.group,
|
||||||
set DB(db) {
|
set DB(db) {
|
||||||
DB = db;
|
DB = db;
|
||||||
group.DB = db;
|
coupling.DB = db;
|
||||||
price.DB = db;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -68,7 +68,7 @@ function SignUp(req, res) {
|
|||||||
return res.status(INVALID.e_code).send(req_str.message);
|
return res.status(INVALID.e_code).send(req_str.message);
|
||||||
let txQueries = [];
|
let txQueries = [];
|
||||||
txQueries.push(["INSERT INTO Users(floID, pubKey) VALUES (?, ?)", [data.floID, data.pubKey]]);
|
txQueries.push(["INSERT INTO Users(floID, pubKey) VALUES (?, ?)", [data.floID, data.pubKey]]);
|
||||||
txQueries.push(["INSERT INTO Cash (floID) Values (?)", data.floID]);
|
txQueries.push(["INSERT INTO Cash (floID) Values (?)", [data.floID]]);
|
||||||
DB.transaction(txQueries).then(_ => {
|
DB.transaction(txQueries).then(_ => {
|
||||||
storeRequest(data.floID, req_str, data.sign);
|
storeRequest(data.floID, req_str, data.sign);
|
||||||
res.send("Account Created");
|
res.send("Account Created");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user