aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/db.ts22
-rw-r--r--lib/payments.ts16
2 files changed, 15 insertions, 23 deletions
diff --git a/lib/db.ts b/lib/db.ts
index a047f291..57b53037 100644
--- a/lib/db.ts
+++ b/lib/db.ts
@@ -28,7 +28,6 @@ return ourfee
`;
const REVERSE = `
--- Keys
local paymentKey = KEYS[1]
local balanceKey = KEYS[2]
local creditKey = KEYS[3]
@@ -36,35 +35,20 @@ local hashKey = KEYS[4]
local paymentsKey = KEYS[5]
local pid = KEYS[6]
--- Arguments
local total = tonumber(ARGV[1])
local credit = tonumber(ARGV[2])
local hash = ARGV[3]
--- Hardcoded TTL for the processing state (in milliseconds)
-local processingTTL = 5000
-
--- Generate a unique lock identifier for this script instance
-local uniqueId = tostring(redis.call('incr', 'lock:counter')) .. ':' .. redis.call('time')[2]
-
--- Attempt to atomically claim the payment with a lock
-local lockSet = redis.call('set', paymentKey, uniqueId, 'NX', 'PX', processingTTL)
-
-if lockSet then
- -- Remove the lock immediately to prevent re-entry
+if redis.call('exists', paymentKey) == 1 then
redis.call('del', paymentKey)
-
- -- Proceed with processing
+ redis.call('srem', 'pending', hash)
redis.call('incrby', balanceKey, total)
redis.call('incrby', creditKey, credit)
redis.call('del', hashKey)
redis.call('lrem', paymentsKey, 0, pid)
- redis.call('srem', 'pending', hash)
-
return pid
else
- -- Another process holds the lock; throw an error
- error("Payment has already been reversed")
+ error("Payment has already been reversed" .. paymentKey)
end
`;
diff --git a/lib/payments.ts b/lib/payments.ts
index 76a7d1fa..d9808f3a 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -758,11 +758,15 @@ export const check = async () => {
const failed = !pays.length || pays.every((p) => p.status === "failed");
const completed = pays.find((p) => p.status === "complete");
- if (completed) await finalize(completed, p);
- else if (failed) await reverse(p);
+ try {
+ if (completed) await finalize(completed, p);
+ else if (failed) await reverse(p);
+ } catch(e) {
+ err("failed to finalize", p.id, e.message);
+ }
}
} catch (e) {
- console.log("payment check failed", e);
+ err("payment check failed", e.message);
}
setTimeout(check, 2000);
@@ -792,10 +796,14 @@ const finalize = async (r, p) => {
};
const reverse = async (p) => {
- const total = Math.abs(p.amount) + p.fee;
+ await sleep(Math.floor(Math.random() * (1500 - 500 + 1)) + 500);
+
+ const total = Math.abs(p.amount) + p.fee + p.ourfee;
const ourfee = p.ourfee || 0;
const credit = Math.round(total * config.fee) - ourfee;
+ l("reversing", p.id, p.amount, p.fee, total, ourfee, credit);
+
await db.reverse(
`payment:${p.id}`,
`balance:${p.uid}`,