fix 1.23.8: ladder harness-style wallet serve for coin settle

This commit is contained in:
Hernâni Marques 2026-08-29 02:40:48 +02:00
parent 2451c66173
commit ba899dd8b5
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
8 changed files with 233 additions and 22 deletions

View file

@ -10,8 +10,8 @@
# Flow (bank landings):
# 1) GET /intro/auto-account.json → personal *account-* (balance 0)
# 2) Mint pool withdrawals as explorer + confirm when selected
# 3) wallet-cli accept-uri only (no run-until-done)
# 4) bank confirm when selected; settle = balance + transfer_done
# 3) wallet-cli accept-uri via harness-style advanced serve (no run-until-done)
# 4) bank confirm when selected; settle = balance + transfer_done (serve keeps shepherd)
# 5) pay via free-amount template (GOA: goa-free) or private orders
#
# Modes (LADDER_MODE):
@ -89,6 +89,9 @@ elapsed_ms() {
: "${LADDER_MAX_SEED:=}"
# After withdraw, wait for spendable available>0 before pay (secs total; shows countdown)
: "${LADDER_PAY_WAIT_AVAILABLE_S:=180}"
# Harness-style long-lived wallet daemon (advanced serve). 1=on (default).
# Without serve, coins often stay pendingIncoming after bank transfer_done.
: "${LADDER_WALLET_SERVE:=1}"
# Historic libeufin-ish absolute ceiling used as default LADDER_MAX_AMOUNT on GOA
LADDER_ABS_CEILING="4503599627370496"
@ -225,13 +228,18 @@ ladder_over() {
}
wcli() {
# taler-helper-sqlite3 is Python ≥3.11; prefer Homebrew/local python on macOS
# so Apple /usr/bin/python3 3.9 does not FATAL the sqlite backend (no reservePub).
# Prefer harness-style serve socket (long-lived shepherd); else one-shot --wallet-db.
# PATH: taler-helper-sqlite3 needs Python ≥3.11 (Homebrew/local on macOS).
local _path="${PATH:-}"
case ":${_path}:" in
*:/opt/homebrew/bin:*) ;;
*) _path="/opt/homebrew/bin:/usr/local/bin:${_path}" ;;
*) _path="/opt/homebrew/bin:/usr/local/bin:${HOME}/.local/bin:${_path}" ;;
esac
PATH="$_path"
if command -v wallet_serve_wcli >/dev/null 2>&1; then
wallet_serve_wcli "$@"
return $?
fi
if [ -n "${CLI_JS:-}" ] && [ -f "$CLI_JS" ]; then
PATH="$_path" node "$CLI_JS" --wallet-db="$WDB" --no-throttle "$@"
else
@ -481,6 +489,8 @@ source "$ROOT/metrics.sh"
# Payment module (classic + max-search payable)
# shellcheck source=ladder/lib_pay.sh
source "$ROOT/ladder/lib_pay.sh"
# shellcheck source=ladder/lib_wallet_serve.sh
source "$ROOT/ladder/lib_wallet_serve.sh"
METRICS_DIR="$REPORT_DIR"
ALT_UNITS_FILE="${REPORT_DIR}/alt_unit_names.json"
export METRICS_DIR CUR WDB CLI_JS ALT_UNITS_FILE
@ -578,18 +588,31 @@ wallet_prepare() {
local label="${1:-wallet}"
WDB="$SCRATCH/wallet-${label}.sqlite3"
export WDB
if [ ! -f "$WDB" ]; then
wcli exchanges add "$EX" >"$SCRATCH/ex-add-$label.out" 2>&1 || true
wcli exchanges update "$EX" >"$SCRATCH/ex-upd-$label.out" 2>&1 || true
wcli exchanges accept-tos "$EX" >"$SCRATCH/ex-tos-$label.out" 2>&1 || true
# Start harness-style daemon once per DB (shepherd stays up for wirewatch settle).
if [ ! -f "$WDB" ] || [ -z "${WSERVE_PID:-}" ] || ! kill -0 "${WSERVE_PID:-0}" 2>/dev/null; then
wallet_serve_install_trap
if wallet_serve_start; then
if [ -n "${WSERVE_PID:-}" ] && [ -S "${WSOCK:-}" ]; then
ok "wallet serve" "pid=$WSERVE_PID sock=$WSOCK (harness-style; no run-until-done)"
fi
else
if [ "${LADDER_WALLET_SERVE:-1}" = "1" ]; then
warn wallet "wallet serve unavailable" "problem: advanced serve did not come up — falling back to one-shot CLI (coins may stay pendingIncoming). See $SCRATCH/wallet-serve.log"
fi
fi
fi
# ToS / exchange — via serve socket when up
wcli exchanges add "$EX" >"$SCRATCH/ex-add-$label.out" 2>&1 || true
wcli exchanges update "$EX" >"$SCRATCH/ex-upd-$label.out" 2>&1 || true
wcli exchanges accept-tos "$EX" >"$SCRATCH/ex-tos-$label.out" 2>&1 || true
}
t0=$(now_ms)
rm -f "$SCRATCH/wallet-main.sqlite3"
wallet_serve_stop 2>/dev/null || true
wallet_prepare "main"
ms_tos=$(elapsed_ms "$t0")
ok "wallet exchange + ToS (${ms_tos}ms) — cumulative DB for withdraw+pay (no run-until-done)"
ok "wallet exchange + ToS (${ms_tos}ms) — cumulative DB for withdraw+pay (serve=${LADDER_WALLET_SERVE:-1})"
: "${LADDER_MAX_RUNGS:=99}"
if [ "${LADDER_MODE}" = "max" ]; then
@ -664,10 +687,11 @@ ladder_withdraw_rung() {
# mint from explorer pool
t0=$(now_ms)
# e2e/harness: pass exchange_url so bank binds the op to our exchange
code=$(curl -sS -m 30 -o "$SCRATCH/wd-$tag.json" -w '%{http_code}' \
-H "Authorization: Bearer ${TOK}" \
-H 'Content-Type: application/json' \
-d "{\"amount\":\"${AMT}\"}" \
-d "{\"amount\":\"${AMT}\",\"exchange_url\":\"${EX}\"}" \
"${BANK}/accounts/${EXP_USER}/withdrawals")
ms_mint=$(elapsed_ms "$t0")
WID=$(python3 -c 'import json;d=json.load(open("'"$SCRATCH"'/wd-'"$tag"'.json"));print(d.get("withdrawal_id") or "")' 2>/dev/null || true)
@ -960,11 +984,14 @@ sys.exit(0 if Decimal(sys.argv[1]) > Decimal(sys.argv[2]) else 1)
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("transfer_done"), d.get("status"))' 2>/dev/null || echo "?")
if echo "$xfer" | grep -qi True; then
bank_done=1
# nudge wallet to pick up wire (bounded; not run-until-done)
# With harness-style serve, shepherd is already running — poll balance only.
# One-shot CLI: bounded run-pending (never run-until-done).
wcli transactions >"$SCRATCH/tx-settle-$tag.out" 2>&1 || true
if command -v timeout >/dev/null 2>&1 || command -v gtimeout >/dev/null 2>&1; then
_to=$(command -v gtimeout 2>/dev/null || command -v timeout)
"$_to" 8 wcli advanced run-pending >"$SCRATCH/run-pending-settle.out" 2>&1 || true
if [ -z "${WSERVE_PID:-}" ] || [ ! -S "${WSOCK:-}" ]; then
if command -v timeout >/dev/null 2>&1 || command -v gtimeout >/dev/null 2>&1; then
_to=$(command -v gtimeout 2>/dev/null || command -v timeout)
"$_to" 8 wcli advanced run-pending >"$SCRATCH/run-pending-settle.out" 2>&1 || true
fi
fi
# after bank done, still prefer coins; allow remaining rounds for available
note="bank transfer_done waiting coins avail=${after} $xfer"