diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/db.js | 37 | ||||
| -rw-r--r-- | lib/payments.js | 32 |
2 files changed, 45 insertions, 24 deletions
@@ -1,9 +1,42 @@ import config from "$config"; import { sleep } from "$lib/utils"; -import { createClient } from "redis"; +import { createClient, defineScript } from "redis"; import { warn } from "$lib/logging"; -export const db = createClient({ url: config.db }); +let SCRIPT = ` +local balanceKey = KEYS[1] +local creditKey = KEYS[2] +local amount = tonumber(ARGV[1]) +local tip = tonumber(ARGV[2]) +local fee = tonumber(ARGV[3]) +local ourfee = tonumber(ARGV[4]) + +local balance = tonumber(redis.call('get', balanceKey) or '0') +local credit = tonumber(redis.call('get', creditKey) or '0') + +local covered = math.min(credit, ourfee) +ourfee = ourfee - covered + +if balance < amount + tip + fee + ourfee then + return {err = 'Insufficient funds'} +end + +redis.call('decrby', creditKey, tostring(math.floor(covered))) +redis.call('decrby', balanceKey, tostring(math.floor(amount + tip + fee + ourfee))) + +return {ok = 'ok'} +`; + +let debit = defineScript({ + NUMBER_OF_KEYS: 2, + SCRIPT, + transformArguments: (...args) => args.map(a => a.toString()) +}); + +export const db = createClient({ + url: config.db, + scripts: { debit } +}); await db.connect(); export default db; diff --git a/lib/payments.js b/lib/payments.js index e1ed5d0b..f39e2937 100644 --- a/lib/payments.js +++ b/lib/payments.js @@ -63,29 +63,17 @@ export let debit = async ( ? Math.round(amount * config.fee) : 0; - await t(`balance:${uid}`, async (balance, db) => { - await t(`credit:${type}:${uid}`, async (credit, db) => { - let covered = Math.min(credit, ourfee) || 0; - ourfee -= covered; + let r = await db.debit( + `balance:${uid}`, + `credit:${type}:${uid}`, + amount || 0, + tip || 0, + fee || 0, + ourfee || 0 + ); + - l( - "debiting", - user.username, - balance, - amount, - tip, - fee, - ourfee, - amount + fee + ourfee + tip - ); - if (balance < amount + tip + fee + ourfee) fail("Insufficient funds"); - await db - .multi() - .decrBy(`credit:${type}:${uid}`, covered) - .decrBy(`balance:${uid}`, amount + tip + fee + ourfee) - .exec(); - }); - }); + if (r !== "ok") fail("Insufficient funds"); let p = { id, |
