diff options
| author | Adam Soltys <[email protected]> | 2020-06-08 13:04:02 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2020-06-08 13:04:02 -0700 |
| commit | 7a3a07bc711ea57fd8a84e809e7ecd0d6e64b5c2 (patch) | |
| tree | b31a06affa4b932990744997c271f6d65502d60c /routes | |
| parent | 298672d3f50938ba06a16f8e04d607b7033703b8 (diff) | |
| download | coinos-server-7a3a07bc711ea57fd8a84e809e7ecd0d6e64b5c2.tar.gz coinos-server-7a3a07bc711ea57fd8a84e809e7ecd0d6e64b5c2.zip | |
reduce network traffic
Diffstat (limited to 'routes')
| -rw-r--r-- | routes/assets.js | 24 | ||||
| -rw-r--r-- | routes/bitcoin/receive.js | 59 | ||||
| -rw-r--r-- | routes/bitcoin/send.js | 6 | ||||
| -rw-r--r-- | routes/lightning/receive.js | 10 | ||||
| -rw-r--r-- | routes/lightning/send.js | 14 | ||||
| -rw-r--r-- | routes/liquid/receive.js | 90 | ||||
| -rw-r--r-- | routes/liquid/send.js | 4 | ||||
| -rw-r--r-- | routes/payments.js | 35 | ||||
| -rw-r--r-- | routes/send.js | 6 | ||||
| -rw-r--r-- | routes/users.js | 39 |
10 files changed, 161 insertions, 126 deletions
diff --git a/routes/assets.js b/routes/assets.js index 9c60500c..25ed8ea6 100644 --- a/routes/assets.js +++ b/routes/assets.js @@ -56,15 +56,15 @@ app.post("/assets", auth, async (req, res) => { params.token_amount = token_amount; params.token_address = token_address; params.token_amount = parseInt(params.token_amount); - } + } let ria; try { ria = await lq.rawIssueAsset(funded.hex, [params]); - } catch(e) { + } catch (e) { l.info(asset_amount, token_amount, params); throw new Error(e.message); - } + } const { asset, hex, token } = ria[0]; const brt = await lq.blindRawTransaction(hex, true, [], false); @@ -79,10 +79,16 @@ app.post("/assets", auth, async (req, res) => { user_id, asset: config.liquid.btcasset }, + include: { + model: db.User, + as: "user" + }, lock: transaction.LOCK.UPDATE, transaction }); + let { user } = account; + if (Math.round(funded.fee * SATS) > account.balance) { l.error( "amount exceeds balance", @@ -95,6 +101,7 @@ app.post("/assets", auth, async (req, res) => { account.balance -= Math.round(funded.fee * SATS); await account.save({ transaction }); + emit(user.username, "account", account); account = await db.Account.create( { @@ -109,6 +116,8 @@ app.post("/assets", auth, async (req, res) => { { transaction } ); + emit(user.username, "account", account); + const asset_payment = await db.Payment.create( { account_id: account.id, @@ -122,12 +131,13 @@ app.post("/assets", auth, async (req, res) => { }, { transaction } ); + emit(user.username, "payment", asset_payment); issuances[txid] = { user_id, asset, asset_amount, - asset_payment_id: asset_payment.id, + asset_payment_id: asset_payment.id }; if (token_amount) { @@ -143,6 +153,7 @@ app.post("/assets", auth, async (req, res) => { }, { transaction } ); + emit(user.username, "account", account); const token_payment = await db.Payment.create( { @@ -157,15 +168,12 @@ app.post("/assets", auth, async (req, res) => { }, { transaction } ); + emit(user.username, "payment", token_payment); issuances[txid].token = token; issuances[txid].token_amount = token_amount; issuances[txid].token_payment_id = token_payment.id; } - - - let user = await getUserById(user_id, transaction); - emit(user.username, "user", user); }); res.send(issuances[txid]); diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js index 77aabd68..6928dd5c 100644 --- a/routes/bitcoin/receive.js +++ b/routes/bitcoin/receive.js @@ -25,7 +25,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { if (payments.includes(hash)) return; Promise.all( - tx.outs.map(async (o) => { + tx.outs.map(async o => { const { value } = o; let address; @@ -40,29 +40,29 @@ zmqRawTx.on("message", async (topic, message, sequence) => { let user = await db.User.findOne({ where: { - username: addresses[address], - }, + username: addresses[address] + } }); const invoice = await db.Invoice.findOne({ where: { user_id: user.id, - network: "BTC", + network: "BTC" }, - order: [["id", "DESC"]], + order: [["id", "DESC"]] }); const currency = invoice ? invoice.currency : user.currency; const rate = invoice ? invoice.rate : app.get("rates")[user.currency]; - const tip = invoice ? invoice.tip : null; + const tip = invoice ? invoice.tip : 0; let confirmed = false; const account = await db.Account.findOne({ where: { user_id: user.id, - asset: config.liquid.btcasset, - }, + asset: config.liquid.btcasset + } }); account.pending += value; @@ -99,14 +99,13 @@ zmqRawTx.on("message", async (topic, message, sequence) => { tip, confirmed, address, - network: "BTC", + network: "BTC" }); payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); - user = await getUser(user.username); + emit(user.username, "account", account); emit(user.username, "payment", payment); - emit(user.username, "user", user); l.info("bitcoin detected", user.username, o.value); } }) @@ -117,32 +116,38 @@ let queue = {}; zmqRawBlock.on("message", async (topic, message, sequence) => { const payments = await db.Payment.findAll({ - where: { confirmed: false }, + where: { confirmed: false } }); - const hashes = payments.map((p) => p.hash); - let block = bitcoin.Block.fromHex(message.toString("hex")); - block.transactions.map((tx) => { + block.transactions.map(tx => { let hash = reverse(tx.getHash()).toString("hex"); - if (hashes.includes(hash)) queue[hash] = 1; + if (payments.find(p => p.hash === hash)) queue[hash] = 1; }); }); setInterval(async () => { try { - let arr = Object.keys(queue); + const arr = Object.keys(queue); for (let i = 0; i < arr.length; i++) { - let hash = arr[i]; + const hash = arr[i]; - let p = await db.Payment.findOne({ + const p = await db.Payment.findOne({ where: { hash, confirmed: 0, received: 1 }, - include: { - model: db.Account, - as: "account", - }, + include: [ + { + model: db.Account, + as: "account" + }, + { + model: db.User, + as: "user" + } + ] }); + const { user } = p; + if (p) { p.confirmed = 1; p.account.balance += p.amount + p.tip; @@ -151,14 +156,14 @@ setInterval(async () => { await p.account.save(); await p.save(); - let user = await getUserById(p.user_id); - emit(user.username, "user", user); + emit(user.username, "account", p.account); emit(user.username, "payment", p); l.info("bitcoin confirmed", user.username, p.amount, p.tip); - delete queue[hash]; } else { - l.warn("Couldn't find payment", hash); + l.warn("couldn't find payment", hash); } + + delete queue[hash]; } } catch (e) { l.error("problem processing queued bitcoin transaction", e.message); diff --git a/routes/bitcoin/send.js b/routes/bitcoin/send.js index b47af00e..5dafba35 100644 --- a/routes/bitcoin/send.js +++ b/routes/bitcoin/send.js @@ -80,12 +80,12 @@ module.exports = async (req, res) => { let payment = await db.Payment.create(params); - user = await getUser(user.username); - emit(user.username, "user", user); - payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); + + emit(user.username, "payment", payment); res.send(payment); + l.info("sent bitcoin", user.username, total); } catch (e) { l.error("error sending bitcoin", e.message); diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js index 0e8d7e22..6a9c95c8 100644 --- a/routes/lightning/receive.js +++ b/routes/lightning/receive.js @@ -21,10 +21,16 @@ const handlePayment = async msg => { user_id, asset: config.liquid.btcasset }, + include: { + model: db.User, + as: 'user', + }, lock: transaction.LOCK.UPDATE, transaction }); + const { user } = account; + let preimage = msg.r_preimage.toString("hex"); let payment = await db.Payment.create({ @@ -50,12 +56,10 @@ const handlePayment = async msg => { await payment.save({ transaction }); payments.push(msg.payment_request); - let user = await getUserById(user_id, transaction); - payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); emit(user.username, "payment", payment); - emit(user.username, "user", user); + emit(user.username, "account", payment.account); l.info( "lightning payment received", diff --git a/routes/lightning/send.js b/routes/lightning/send.js index e3b5c75a..9c4f2259 100644 --- a/routes/lightning/send.js +++ b/routes/lightning/send.js @@ -50,8 +50,9 @@ module.exports = async (req, res) => { max_parts: 10 }); + if (m.payment_error) throw new Error(m.payment_error); + ({ - payment_error: error, payment_route: { total_fees: fee, total_amt: total }, payment_preimage: preimage } = m); @@ -73,11 +74,6 @@ module.exports = async (req, res) => { l.info("lnb sent back", amount); } - if (error) { - l.error("error sending lightning", error); - return res.status(500).send(error); - } - if (seen.includes(preimage)) { l.warn("duplicate payment detected", preimage); throw new Error("Duplicate payment detected"); @@ -108,12 +104,12 @@ module.exports = async (req, res) => { payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); + emit(user.username, "account", payment.account); + emit(user.username, "payment", payment); + seen.push(preimage); l.info("sent lightning", user.username, total); - user = await getUser(user.username, transaction); - emit(user.username, "user", user); - seen.push(hash); res.send(payment); }); diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js index 47058c4d..b3f82a2d 100644 --- a/routes/liquid/receive.js +++ b/routes/liquid/receive.js @@ -28,11 +28,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { const address = o.scriptPubKey.addresses[0]; if (Object.keys(addresses).includes(address)) { - let user = await db.User.findOne({ - where: { - username: addresses[address] - } - }); + let user = await getUser(addresses[address]); let confirmed = 0; @@ -69,7 +65,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { if (existing) { ({ ticker, precision, name } = existing); - } + } } params = { ...params, ...{ ticker, precision, name } }; @@ -103,7 +99,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { const currency = invoice ? invoice.currency : user.currency; const rate = invoice ? invoice.rate : app.get("rates")[user.currency]; - const tip = invoice ? invoice.tip : null; + const tip = invoice ? invoice.tip : 0; let payment = await db.Payment.create({ account_id: account.id, @@ -123,9 +119,7 @@ zmqRawTx.on("message", async (topic, message, sequence) => { payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); - user = await getUser(user.username); emit(user.username, "payment", payment); - emit(user.username, "user", user); l.info("liquid detected", user.username, asset, value); } }) @@ -139,8 +133,6 @@ zmqRawBlock.on("message", async (topic, message, sequence) => { where: { confirmed: 0 } }); - const hashes = payments.map(p => p.hash); - const block = elements.Block.fromHex(message.toString("hex"), true); const hash = await lq.getBlockHash(block.height); const json = await lq.getBlock(hash, 2); @@ -157,6 +149,9 @@ zmqRawBlock.on("message", async (topic, message, sequence) => { token_amount, token_payment_id } = issuances[tx.txid]; + + const user = await getUserById(user_id); + let account = await db.Account.findOne({ where: { user_id, asset }, lock: transaction.LOCK.UPDATE, @@ -168,12 +163,18 @@ zmqRawBlock.on("message", async (topic, message, sequence) => { let payment = await db.Payment.findOne({ where: { id: asset_payment_id }, + include: { + model: db.Account, + as: "account" + }, lock: transaction.LOCK.UPDATE, transaction }); payment.confirmed = true; await payment.save({ transaction }); + emit(user.username, "account", account); + emit(user.username, "payment", payment); if (token) { account = await db.Account.findOne({ @@ -187,53 +188,68 @@ zmqRawBlock.on("message", async (topic, message, sequence) => { payment = await db.Payment.findOne({ where: { id: token_payment_id }, + include: { + model: db.Account, + as: "account" + }, lock: transaction.LOCK.UPDATE, transaction }); payment.confirmed = true; await payment.save({ transaction }); - } - const user = await getUserById(user_id, transaction); - emit(user.username, "user", user); + emit(user.username, "account", account); + emit(user.username, "payment", payment); + } }); - } else if (hashes.includes(tx.txid)) queue[tx.txid] = 1; + } else if (payments.find(p => p.hash === tx.txid)) queue[tx.txid] = 1; }); }); setInterval(async () => { try { - let arr = Object.keys(queue); + const arr = Object.keys(queue); for (let i = 0; i < arr.length; i++) { - let hash = arr[i]; + const hash = arr[i]; - let p = await db.Payment.findOne({ + const p = await db.Payment.findOne({ where: { hash, confirmed: 0, received: 1 }, - include: { - model: db.Account, - as: "account" - } + include: [ + { + model: db.Account, + as: "account" + }, + { + model: db.User, + as: "user" + } + ] }); - p.confirmed = 1; - p.account.balance += p.amount + p.tip; - p.account.pending -= Math.min(p.account.pending, p.amount + p.tip); + const { user } = p; + + if (p) { + p.confirmed = 1; + p.account.balance += p.amount + p.tip; + p.account.pending -= Math.min(p.account.pending, p.amount + p.tip); - await p.account.save(); - await p.save(); + await p.account.save(); + await p.save(); - let user = await getUserById(p.user_id); - emit(user.username, "user", user); - emit(user.username, "payment", p); - l.info( - "liquid confirmed", - user.username, - p.account.asset, - p.amount, - p.tip - ); + emit(user.username, "account", p.account); + emit(user.username, "payment", p); + l.info( + "liquid confirmed", + user.username, + p.account.asset, + p.amount, + p.tip + ); + } else { + l.warn("couldn't find payment", hash); + } delete queue[hash]; } diff --git a/routes/liquid/send.js b/routes/liquid/send.js index e4344238..321adba2 100644 --- a/routes/liquid/send.js +++ b/routes/liquid/send.js @@ -115,8 +115,8 @@ module.exports = async (req, res) => { } } - user = await getUser(user.username, transaction); - emit(user.username, "user", user); + emit(user.username, "account", main.account); + emit(user.username, "payment", main); res.send(main); }); } catch (e) { diff --git a/routes/payments.js b/routes/payments.js index db40c73e..8f731f78 100644 --- a/routes/payments.js +++ b/routes/payments.js @@ -15,18 +15,20 @@ const { join } = require("path"); if (u.liquid) addresses[u.liquid] = u.username; }); - payments = (await db.Payment.findAll({ - attributes: ["hash"] - })).map(p => p.hash); + payments = ( + await db.Payment.findAll({ + attributes: ["hash"] + }) + ).map(p => p.hash); app.post("/send", auth, require("./send")); if (config.lna) { if (config.lna.clightning) { - const lnapath = join(require('os').homedir(), '.lightningreg/regtest') - const lnbpath = join(require('os').homedir(), '.lightningregb/regtest') - lna = require('clightning-client')(lnapath); - lnb = require('clightning-client')(lnbpath); + const lnapath = join(require("os").homedir(), ".lightningreg/regtest"); + const lnbpath = join(require("os").homedir(), ".lightningregb/regtest"); + lna = require("clightning-client")(lnapath); + lnb = require("clightning-client")(lnbpath); } else { lna = lnd(config.lna); lnb = lnd(config.lnb); @@ -56,20 +58,17 @@ const { join } = require("path"); } app.get("/payments", auth, async (req, res) => { - const payments = await db.Payment.findAll({ - where: { - user_id: req.user.id, - [Op.or]: { - received: true, - amount: { - [Op.lt]: 0, - }, - }, + let payments = await req.user.getPayments({ + where: { + account_id: req.user.account_id }, - order: [["id", "DESC"]] + order: [["id", "DESC"]], + include: { + model: db.Account, + as: "account" + } }); - emit(req.user.username, "payments", payments); res.send(payments); }); })(); diff --git a/routes/send.js b/routes/send.js index 7091c4bc..837a9e45 100644 --- a/routes/send.js +++ b/routes/send.js @@ -47,7 +47,7 @@ module.exports = async (req, res) => { l.info("sent internal", user.username, -payment.amount); - user = await getUser(user.username, transaction); + emit(user.username, "payment", payment); emit(user.username, "user", user); res.send(payment); @@ -117,11 +117,9 @@ module.exports = async (req, res) => { { transaction } ); - user = await getUser(user.username, transaction); - emit(user.username, "user", user); - payment = payment.get({ plain: true }); payment.account = account.get({ plain: true }); + emit(user.username, "account", account); emit(user.username, "payment", payment); l.info("received internal", user.username, payment.amount); diff --git a/routes/users.js b/routes/users.js index 6fdd1423..76a8bc8d 100644 --- a/routes/users.js +++ b/routes/users.js @@ -72,7 +72,7 @@ app.get("/challenge", async (req, res) => { app.post("/register", async (req, res) => { let err = m => res.status(500).send(m); let { user } = req.body; - + if (!user.username) return err("Username required"); let exists = await db.User.count({ where: { username: user.username } }); @@ -104,7 +104,7 @@ app.post("/register", async (req, res) => { if (!challenge[ip] || user.response !== challenge[ip]) { l.info("failed challenge", ip, user.response, challenge[ip]); return res.status(500).send("Failed challenge"); - } + } delete challenge[ip]; @@ -153,9 +153,7 @@ app.post("/register", async (req, res) => { user.account_id = account.id; await user.save(); - user = await getUser(user.username); res.send(pick(user, ...whitelist)); - emit(user.username, "user", user); l.info("new user", user.username, ip); }); @@ -163,7 +161,6 @@ app.post("/disable2fa", auth, twofa, async (req, res) => { let { user } = req; user.twofa = false; await user.save(); - user = await getUser(user.username); emit(user.username, "user", user); emit(user.username, "otpsecret", user.otpsecret); l.info("disabled 2fa", user.username); @@ -183,7 +180,6 @@ app.post("/2fa", auth, async (req, res) => { if (isValid) { user.twofa = true; user.save(); - user = await getUser(user.username); emit(user.username, "user", req.user); } else { return res.status(500).send("Invalid token"); @@ -243,7 +239,6 @@ app.post("/user", auth, async (req, res) => { } await user.save(); - user = await getUser(user.username); emit(user.username, "user", user); res.send({ user, token }); } catch (e) { @@ -253,7 +248,11 @@ app.post("/user", auth, async (req, res) => { app.post("/login", async (req, res) => { let twofa = req.body.token; - l.info("login attempt", req.body.username, req.headers["x-forwarded-for"] || req.connection.remoteAddress); + l.info( + "login attempt", + req.body.username, + req.headers["x-forwarded-for"] || req.connection.remoteAddress + ); try { let user = await getUser(req.body.username); @@ -266,7 +265,7 @@ app.post("/login", async (req, res) => { l.warn( "invalid username or password attempt", req.body.username, - req.body.password, + req.body.password ); return res.status(401).end(); } @@ -303,7 +302,6 @@ app.post("/address", auth, async (req, res) => { user.address = await bc.getNewAddress("", req.body.type || "bech32"); await user.save(); addresses[user.address] = user.username; - user = await getUser(user.username); emit(user.username, "user", user); res.send(user.address); }); @@ -323,9 +321,8 @@ app.post("/account", auth, async (req, res) => { await account.save(); - user = await getUser(user.username); - emit(user.username, "user", user); - res.send(account); + emit(user.username, "account", account); + res.end(); } catch (e) { l.error(e.message); return res.status(500).send("There was a problem updating the account"); @@ -343,10 +340,22 @@ app.post("/shiftAccount", auth, async (req, res) => { user.account_id = account.id; await user.save(); + let payments = await user.getPayments({ + where: { + account_id: user.account_id + }, + order: [["id", "DESC"]], + limit: 12, + include: { + model: db.Account, + as: "account" + } + }); + user.payments = payments; + user.account = account; - user = await getUser(user.username); emit(user.username, "user", user); - res.send(account); + res.end(); } catch (e) { l.error(e.message); return res.status(500).send("There was a problem switching accounts"); |
