aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2023-11-13 01:13:55 -0800
committerAdam Soltys <[email protected]>2023-11-13 01:13:55 -0800
commit545820baa7bf625fdb4abc7ec94154049391b710 (patch)
tree61abc5a4cbc1187efa4a068e20f4d63114e9d585
parentd03320dea293fbc9a434273665fc37bc93418192 (diff)
downloadcoinos-server-545820baa7bf625fdb4abc7ec94154049391b710.tar.gz
coinos-server-545820baa7bf625fdb4abc7ec94154049391b710.zip
use lua script for debit
-rw-r--r--lib/db.js37
-rw-r--r--lib/payments.js32
-rw-r--r--package.json2
-rw-r--r--pnpm-lock.yaml66
4 files changed, 79 insertions, 58 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,
diff --git a/package.json b/package.json
index 1ccc886a..9140c0b0 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"pino-pretty": "^7.0.0",
"pump": "^3.0.0",
"readable-stream-clone": "^0.0.7",
- "redis": "^4.3.1",
+ "redis": "^4.6.10",
"sharp": "^0.31.1",
"uuid": "8",
"web-push": "^3.4.4",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index dbb53ded..12c7e44b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -93,8 +93,8 @@ dependencies:
specifier: ^0.0.7
version: 0.0.7
redis:
- specifier: ^4.3.1
- version: 4.3.1
+ specifier: ^4.6.10
+ version: 4.6.10
sharp:
specifier: ^0.31.1
version: 0.31.1
@@ -768,53 +768,53 @@ packages:
'@otplib/plugin-thirty-two': 12.0.1
dev: false
- resolution: {integrity: sha512-EBw7Ag1hPgFzdznK2PBblc1kdlj5B5Cw3XwI9/oG7tSn85/HKy3X9xHy/8tm/eNXJYHLXHJL/pkwBpFMVVefkw==}
+ resolution: {integrity: sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==}
peerDependencies:
'@redis/client': ^1.0.0
dependencies:
- '@redis/client': 1.3.0
+ '@redis/client': 1.5.11
dev: false
- resolution: {integrity: sha512-XCFV60nloXAefDsPnYMjHGtvbtHR8fV5Om8cQ0JYqTNbWcQo/4AryzJ2luRj4blveWazRK/j40gES8M7Cp6cfQ==}
+ resolution: {integrity: sha512-cV7yHcOAtNQ5x/yQl7Yw1xf53kO0FNDTdDU6bFIMbW6ljB7U7ns0YRM+QIkpoqTAt6zK5k9Fq0QWlUbLcq9AvA==}
engines: {node: '>=14'}
dependencies:
- cluster-key-slot: 1.1.0
- generic-pool: 3.8.2
+ cluster-key-slot: 1.1.2
+ generic-pool: 3.9.0
yallist: 4.0.0
dev: false
- resolution: {integrity: sha512-oDE4myMCJOCVKYMygEMWuriBgqlS5FqdWerikMoJxzmmTUErnTRRgmIDa2VcgytACZMFqpAOWDzops4DOlnkfQ==}
+ resolution: {integrity: sha512-16yZWngxyXPd+MJxeSr0dqh2AIOi8j9yXKcKCwVaKDbH3HTuETpDVPcLujhFYVPtYrngSco31BUcSa9TH31Gqg==}
peerDependencies:
'@redis/client': ^1.0.0
dependencies:
- '@redis/client': 1.3.0
+ '@redis/client': 1.5.11
dev: false
- resolution: {integrity: sha512-LUZE2Gdrhg0Rx7AN+cZkb1e6HjoSKaeeW8rYnt89Tly13GBI5eP4CwDVr+MY8BAYfCg4/N15OUrtLoona9uSgw==}
+ resolution: {integrity: sha512-rcZO3bfQbm2zPRpqo82XbW8zg4G/w4W3tI7X8Mqleq9goQjAGLL7q/1n1ZX4dXEAmORVZ4s1+uKLaUOg7LrUhw==}
peerDependencies:
'@redis/client': ^1.0.0
dependencies:
- '@redis/client': 1.3.0
+ '@redis/client': 1.5.11
dev: false
- resolution: {integrity: sha512-NyFZEVnxIJEybpy+YskjgOJRNsfTYqaPbK/Buv6W2kmFNaRk85JiqjJZA5QkRmWvGbyQYwoO5QfDi2wHskKrQQ==}
+ resolution: {integrity: sha512-hPP8w7GfGsbtYEJdn4n7nXa6xt6hVZnnDktKW4ArMaFQ/m/aR7eFvsLQmG/mn1Upq99btPJk+F27IQ2dYpCoUg==}
peerDependencies:
'@redis/client': ^1.0.0
dependencies:
- '@redis/client': 1.3.0
+ '@redis/client': 1.5.11
dev: false
- resolution: {integrity: sha512-OFp0q4SGrTH0Mruf6oFsHGea58u8vS/iI5+NpYdicaM+7BgqBZH8FFvNZ8rYYLrUO/QRqMq72NpXmxLVNcdmjA==}
+ resolution: {integrity: sha512-IFjIgTusQym2B5IZJG3XKr5llka7ey84fw/NOYqESP5WUfQs9zz1ww/9+qoz4ka/S6KcGBodzlCeZ5UImKbscg==}
peerDependencies:
'@redis/client': ^1.0.0
dependencies:
- '@redis/client': 1.3.0
+ '@redis/client': 1.5.11
dev: false
/@sindresorhus/[email protected]:
@@ -1603,8 +1603,8 @@ packages:
safe-buffer: 5.2.1
dev: false
- resolution: {integrity: sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw==}
+ resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==}
engines: {node: '>=0.10.0'}
dev: false
@@ -2117,8 +2117,8 @@ packages:
wide-align: 1.1.5
dev: false
- resolution: {integrity: sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==}
+ resolution: {integrity: sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==}
engines: {node: '>= 4'}
dev: false
@@ -3205,15 +3205,15 @@ packages:
engines: {node: '>= 12.13.0'}
dev: false
- resolution: {integrity: sha512-cM7yFU5CA6zyCF7N/+SSTcSJQSRMEKN0k0Whhu6J7n9mmXRoXugfWDBo5iOzGwABmsWKSwGPTU5J4Bxbl+0mrA==}
+ resolution: {integrity: sha512-mmbyhuKgDiJ5TWUhiKhBssz+mjsuSI/lSZNPI9QvZOYzWvYGejtb+W3RlDDf8LD6Bdl5/mZeG8O1feUGhXTxEg==}
dependencies:
- '@redis/bloom': 1.0.2(@redis/[email protected])
- '@redis/client': 1.3.0
- '@redis/graph': 1.0.1(@redis/[email protected])
- '@redis/json': 1.0.4(@redis/[email protected])
- '@redis/search': 1.1.0(@redis/[email protected])
- '@redis/time-series': 1.0.3(@redis/[email protected])
+ '@redis/bloom': 1.2.0(@redis/[email protected])
+ '@redis/client': 1.5.11
+ '@redis/graph': 1.1.0(@redis/[email protected])
+ '@redis/json': 1.0.6(@redis/[email protected])
+ '@redis/search': 1.1.5(@redis/[email protected])
+ '@redis/time-series': 1.0.5(@redis/[email protected])
dev: false