From a3ae613d7e2cde43096dcd80f8a1e04a7fb2512f Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 14 Oct 2019 23:41:20 -0700 Subject: use database transaction when updating balance on block receipt --- bitcoinPayments.js | 44 +++++++++++++++++++++++++++++--------------- sendCoins.js | 13 ++++++------- stripe.js | 3 ++- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/bitcoinPayments.js b/bitcoinPayments.js index 479298b8..b3d54a21 100644 --- a/bitcoinPayments.js +++ b/bitcoinPayments.js @@ -103,26 +103,40 @@ module.exports = (app, bc, db, addresses, payments, emit) => { let block = bitcoin.Block.fromHex(message); l("block", block.getHash().toString("hex")); - const processPayment = async p => { - if ((await bc.getRawTransaction(p.hash, true)).confirmations > 0) { - let user = await db.User.findByPk(p.user_id); - l(user.pending); - p.confirmed = true; - user.balance += p.amount; - user.pending -= p.amount; - await user.save(); - await p.save(); + const processPayment = async (payment, transaction) => { + if ( + (await bc.getRawTransaction(payment.hash, true)).confirmations > 0 + ) { + let user = await db.User.findByPk(payment.user_id, { transaction }); + payment.confirmed = true; + user.balance += payment.amount; + user.pending -= payment.amount; + await user.save({ transaction }); + await payment.save({ transaction }); emit(user.username, "user", user); emit(user.username, "block", message); } }; - await db.Payment.findAll({ - where: { confirmed: false } - }).reduce(async (prev, payment) => { - const result = await prev; - return [...result, await processPayment(payment)]; - }, Promise.resolve([])); + const transaction = await db.transaction(); + try { + const payments = await db.Payment.findAll({ + where: { confirmed: false }, + lock: transaction.LOCK.UPDATE, + transaction + }); + + await Promise.all( + payments.map(async payment => { + await processPayment(payment, transaction); + return; + }) + ); + } catch (e) { + transaction.rollback(); + } + + await transaction.commit(); break; } diff --git a/sendCoins.js b/sendCoins.js index 7eebdc8a..997af0dd 100644 --- a/sendCoins.js +++ b/sendCoins.js @@ -24,14 +24,13 @@ module.exports = (app, bc, db, emit) => async (req, res) => { try { await db.transaction(async transaction => { - let { balance } = await db.User.findOne( - { - where: { - username: req.user.username - } + let { balance } = await db.User.findOne({ + where: { + username: req.user.username }, - { transaction } - ); + lock: transaction.LOCK.UPDATE, + transaction + }); if (amount !== balance && amount + fee > balance) { l("amount exceeds balance", amount, fee, balance); diff --git a/stripe.js b/stripe.js index ba1f68f7..090def4b 100644 --- a/stripe.js +++ b/stripe.js @@ -1,4 +1,5 @@ const config = require("./config"); +const l = console.log; module.exports = (auth, app, db, emit) => { app.post("/buy", auth, async (req, res) => { @@ -33,7 +34,7 @@ module.exports = (auth, app, db, emit) => { res.send(`Bought ${amount}`); } catch (e) { - console.log(e); + l(e); res.status(500).send(e); } }); -- cgit v1.2.3