aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/db.js37
-rw-r--r--lib/payments.js32
2 files changed, 45 insertions, 24 deletions
diff --git a/lib/db.js b/lib/db.js
index b22af94a..197697a0 100644
--- a/lib/db.js
+++ b/lib/db.js
@@ -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,