ops: GOA auto-confirm DB-selected withdrawals + debt-headroom filter
This commit is contained in:
parent
65bcddc185
commit
281873a955
1 changed files with 51 additions and 2 deletions
|
|
@ -1,6 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Auto-confirm bank withdrawals for the community demo pool ONLY (explorer).
|
# Auto-confirm bank withdrawals for the community demo pool ONLY (explorer).
|
||||||
#
|
#
|
||||||
|
# Discovery: (1) landing watch files (withdraw.uri / withdraw-watch.ids),
|
||||||
|
# (2) libeufin DB via local psql (selected && !confirmed && username=explorer).
|
||||||
|
# Watch-file-only misses webui/wallet-selected ops not in the last WATCH_MAX
|
||||||
|
# IDs — DB scan is required (same idea as testpaysan; here in-CTR, no podman).
|
||||||
|
#
|
||||||
# Run once: auto-confirm-withdrawals.sh
|
# Run once: auto-confirm-withdrawals.sh
|
||||||
# Loop: auto-confirm-withdrawals.sh --loop [SECS]
|
# Loop: auto-confirm-withdrawals.sh --loop [SECS]
|
||||||
#
|
#
|
||||||
|
|
@ -9,6 +14,8 @@
|
||||||
# BANK_USER (default explorer)
|
# BANK_USER (default explorer)
|
||||||
# BANK_PASS or /root/bank-explorer-password.txt
|
# BANK_PASS or /root/bank-explorer-password.txt
|
||||||
# LANDING_DIR (default /var/www/bank-landing)
|
# LANDING_DIR (default /var/www/bank-landing)
|
||||||
|
# DB_NAME (default libeufin)
|
||||||
|
# DB_LIMIT max selected IDs from DB per tick (default 40)
|
||||||
# ALLOW_NON_EXPLORER=1
|
# ALLOW_NON_EXPLORER=1
|
||||||
# WATCH_MAX max IDs kept in withdraw-watch.ids after prune (default 80)
|
# WATCH_MAX max IDs kept in withdraw-watch.ids after prune (default 80)
|
||||||
# QUIET=1 less skip noise (default 1 in --loop)
|
# QUIET=1 less skip noise (default 1 in --loop)
|
||||||
|
|
@ -22,6 +29,8 @@ LANDING_DIR="${LANDING_DIR:-/var/www/bank-landing}"
|
||||||
WATCH_FILE="${LANDING_DIR}/withdraw-watch.ids"
|
WATCH_FILE="${LANDING_DIR}/withdraw-watch.ids"
|
||||||
URI_FILE="${LANDING_DIR}/withdraw.uri"
|
URI_FILE="${LANDING_DIR}/withdraw.uri"
|
||||||
WATCH_MAX="${WATCH_MAX:-80}"
|
WATCH_MAX="${WATCH_MAX:-80}"
|
||||||
|
DB_NAME="${DB_NAME:-libeufin}"
|
||||||
|
DB_LIMIT="${DB_LIMIT:-40}"
|
||||||
LOCK_FILE="${LOCK_FILE:-/var/run/auto-confirm-withdrawals.lock}"
|
LOCK_FILE="${LOCK_FILE:-/var/run/auto-confirm-withdrawals.lock}"
|
||||||
LOOP=0
|
LOOP=0
|
||||||
SLEEP=2
|
SLEEP=2
|
||||||
|
|
@ -96,6 +105,45 @@ known_ids() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Selected, not yet confirmed, owner = explorer only (runs inside goa CTR).
|
||||||
|
db_selected_explorer_ids() {
|
||||||
|
if ! command -v psql >/dev/null 2>&1; then
|
||||||
|
qlog "psql missing — skip DB discovery"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if ! id -u postgres >/dev/null 2>&1; then
|
||||||
|
qlog "postgres user missing — skip DB discovery"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
# Prefer affordable amounts (newest-first often hits oversized junk that
|
||||||
|
# exceeds explorer debt headroom → HTTP 409 Insufficient funds forever).
|
||||||
|
su -s /bin/bash postgres -c "psql -d ${DB_NAME} -At -c \"
|
||||||
|
WITH explorer AS (
|
||||||
|
SELECT a.bank_account_id, a.has_debt, a.balance, a.max_debt
|
||||||
|
FROM libeufin_bank.bank_accounts a
|
||||||
|
JOIN libeufin_bank.customers c ON c.customer_id = a.owning_customer_id
|
||||||
|
WHERE c.username = '${USER}'
|
||||||
|
LIMIT 1
|
||||||
|
),
|
||||||
|
headroom AS (
|
||||||
|
SELECT CASE WHEN has_debt THEN (max_debt).val - (balance).val
|
||||||
|
ELSE (max_debt).val + (balance).val END AS val
|
||||||
|
FROM explorer
|
||||||
|
)
|
||||||
|
SELECT w.withdrawal_uuid::text
|
||||||
|
FROM libeufin_bank.taler_withdrawal_operations w
|
||||||
|
JOIN explorer e ON e.bank_account_id = w.wallet_bank_account
|
||||||
|
CROSS JOIN headroom h
|
||||||
|
WHERE w.selection_done = true
|
||||||
|
AND w.confirmation_done = false
|
||||||
|
AND w.aborted = false
|
||||||
|
AND (w.amount).val <= h.val
|
||||||
|
ORDER BY (w.amount).val ASC, (w.amount).frac ASC, w.creation_date DESC
|
||||||
|
LIMIT ${DB_LIMIT};
|
||||||
|
\"" 2>/dev/null \
|
||||||
|
| grep -E '^[0-9a-fA-F-]{36}$' || true
|
||||||
|
}
|
||||||
|
|
||||||
# Keep file small: drop confirmed/aborted; keep pending/selected + tail
|
# Keep file small: drop confirmed/aborted; keep pending/selected + tail
|
||||||
prune_watch() {
|
prune_watch() {
|
||||||
[ -f "$WATCH_FILE" ] || return 0
|
[ -f "$WATCH_FILE" ] || return 0
|
||||||
|
|
@ -172,16 +220,17 @@ once() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cap work per loop: last WATCH_MAX ids only (newest at end of file)
|
# Watch files (landing) + DB selected(!confirmed) explorer ops
|
||||||
ids=$( {
|
ids=$( {
|
||||||
[ -f "$URI_FILE" ] && basename "$(tr -d '\n' <"$URI_FILE")"
|
[ -f "$URI_FILE" ] && basename "$(tr -d '\n' <"$URI_FILE")"
|
||||||
if [ -f "$WATCH_FILE" ]; then
|
if [ -f "$WATCH_FILE" ]; then
|
||||||
grep -E '^[0-9a-fA-F-]{36}$' "$WATCH_FILE" | awk 'NF && !seen[$0]++' | tail -n "$WATCH_MAX"
|
grep -E '^[0-9a-fA-F-]{36}$' "$WATCH_FILE" | awk 'NF && !seen[$0]++' | tail -n "$WATCH_MAX"
|
||||||
fi
|
fi
|
||||||
|
db_selected_explorer_ids
|
||||||
} | awk 'NF && !seen[$0]++' )
|
} | awk 'NF && !seen[$0]++' )
|
||||||
|
|
||||||
if [ -z "$ids" ]; then
|
if [ -z "$ids" ]; then
|
||||||
qlog "no withdrawal ids to watch"
|
qlog "no withdrawal ids (selected or watched)"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue