release 1.18.3: Bank withdraw wording (was ATM for CHF-style note amounts)

Rename user-facing e2e "ATM withdraw" to "Bank withdraw". The ladder
amounts (20/50/100/200/…) were labeled ATM because they match typical
CHF cash-note sizes (Bankomat), not because anything hits a physical ATM.
Keep E2E_ATM_MAX as alias of E2E_BANK_WITHDRAW_MAX; keep e2e.atm-* group ids.
This commit is contained in:
Hernâni Marques 2026-07-19 09:06:06 +02:00
parent 4bdb08bf3c
commit efb9047a67
No known key found for this signature in database
GPG key ID: CB5738652768F7E9
9 changed files with 58 additions and 55 deletions

View file

@ -8,7 +8,7 @@ source "$ROOT/lib.sh"
# shellcheck source=metrics.sh
source "$ROOT/metrics.sh"
: "${E2E_TIMEOUT:=180}" # ATM ladder + wirewatch lag needs room (was 55 — too tight)
: "${E2E_TIMEOUT:=180}" # Bank withdraw ladder + wirewatch lag needs room (was 55 — too tight)
: "${E2E_PAY_SECS:=22}" # hard reserve for handle-uri + settle (do not starve pay)
: "${E2E_SETTLE_ROUNDS:=18}"
: "${E2E_SETTLE_SLEEP:=3}"
@ -226,18 +226,20 @@ except Exception: print("")' 2>/dev/null || true)
# ---------------------------------------------------------------------------
# Variable amounts
# Withdraw = typical ATM notes only (Bankomat): 20 / 50 / 100 / 200 …
# Withdraw = typical bank cash-note amounts (CHF-style: was called ATM): 20 / 50 / 100 / 200 …
# Pay = several smaller purchase amounts
# Env:
# E2E_WITHDRAW_VALUES="20 50 100" # bare numbers → prefixed with CUR
# E2E_PAY_VALUES="0.01 0.05 0.5 1 2 5"
# E2E_VARIABLE=0 # single fixed WITHDRAW_AMT / PAY_AMT
# E2E_ATM_MAX=N # try at most N ATM withdraws (budget)
# E2E_BANK_WITHDRAW_MAX=N # try at most N bank withdraws (budget)
# E2E_ATM_MAX=N # legacy alias of E2E_BANK_WITHDRAW_MAX
# ---------------------------------------------------------------------------
: "${E2E_VARIABLE:=1}"
: "${E2E_ATM_MAX:=5}"
: "${E2E_BANK_WITHDRAW_MAX:=${E2E_ATM_MAX:-5}}"
E2E_ATM_MAX="${E2E_ATM_MAX:-$E2E_BANK_WITHDRAW_MAX}" # legacy alias
if [ "$E2E_REMOTE" = "1" ]; then
# remote: still ATM-shaped; TESTPAYSAN needs larger notes for shop pays
# remote: still bank cash-note shaped; TESTPAYSAN needs larger notes for shop pays
if [ "$CUR" = "TESTPAYSAN" ]; then
: "${E2E_WITHDRAW_VALUES:=20 50}"
# farmer shop template face values (oeufs-6=5, fromage=8.5, jus=6)
@ -247,7 +249,7 @@ if [ "$E2E_REMOTE" = "1" ]; then
: "${E2E_PAY_VALUES:=0.01 0.05 0.1 1}"
fi
else
# local GOA: classic ATM notes + 4200 for paivana paywall template
# local GOA: classic bank cash-note amounts + 4200 for paivana paywall template
: "${E2E_WITHDRAW_VALUES:=20 50 100 200 4200}"
: "${E2E_PAY_VALUES:=0.01 0.05 0.1 0.5 1 2 5 10}"
fi
@ -284,7 +286,7 @@ if [ "$E2E_VARIABLE" != "1" ]; then
fi
fi
# Credit = sum of planned ATM withdraws + small buffer for fees
# Credit = sum of planned Bank withdraws + small buffer for fees
CREDIT_AMT=$(python3 -c '
import sys
cur=sys.argv[1]
@ -301,7 +303,7 @@ print("%s:%g" % (cur, s + buf))
WITHDRAW_AMT=$(printf '%s' "$WITHDRAW_LIST" | awk '{print $1}')
PAY_AMT=$(printf '%s' "$PAY_LIST" | awk '{print $1}')
# More wall time when running ATM ladder
# More wall time when running Bank withdraw ladder
if [ "$E2E_VARIABLE" = "1" ]; then
n_w=$(printf '%s' "$WITHDRAW_LIST" | wc -w | tr -d ' ')
n_p=$(printf '%s' "$PAY_LIST" | wc -w | tr -d ' ')
@ -309,9 +311,9 @@ if [ "$E2E_VARIABLE" = "1" ]; then
if [ "${E2E_TIMEOUT}" -lt "$need" ]; then
E2E_TIMEOUT=$need
fi
# cap ATM attempts but always keep CUR:4200 if listed (paivana)
# cap bank withdraw attempts but always keep CUR:4200 if listed (paivana)
WITHDRAW_LIST=$(
printf '%s' "$WITHDRAW_LIST" | tr ' ' '\n' | awk -v max="$E2E_ATM_MAX" -v big="${CUR}:4200" '
printf '%s' "$WITHDRAW_LIST" | tr ' ' '\n' | awk -v max="$E2E_BANK_WITHDRAW_MAX" -v big="${CUR}:4200" '
NF==0 { next }
$0==big { has=1; next }
{ small[++n]=$0 }
@ -413,7 +415,7 @@ else
fi
info "e2e mode" "$([ "$E2E_REMOTE" = "1" ] && echo "remote/public domain (no SSH)" || echo "local koopa stack")"
info "currency" "$CUR"
info "ATM withdraw ladder" "$WITHDRAW_LIST (credit $CREDIT_AMT)"
info "Bank withdraw ladder" "$WITHDRAW_LIST (credit $CREDIT_AMT)"
info "pay ladder" "$PAY_LIST"
info "e2e budget" "${E2E_TIMEOUT}s"
@ -863,7 +865,7 @@ else
warn "wallet accept ToS" "$(tail -c 80 "$SCRATCH/ex-tos.out" | tr '\n' ' ')"
fi
fi
# Empty wallet baseline before ATM / pay load
# Empty wallet baseline before bank withdraw / pay load
metrics_report_coins "wallet-ready" || true
wd_status() {
@ -901,15 +903,15 @@ fake_incoming_speedup() {
fi
}
# One ATM-style withdraw: create → accept → select → confirm → settle
# One bank withdraw: create → accept → select → confirm → settle
# returns 0 on wallet balance increase, 1 on soft fail (ladder continues)
e2e_one_withdraw() {
WITHDRAW_AMT="$1"
local tag
tag=$(printf '%s' "$WITHDRAW_AMT" | tr '.:' '__')
section "e2e · ATM withdraw $WITHDRAW_AMT · $(format_amount_alt "$WITHDRAW_AMT")"
e2e_over && { warn "ATM withdraw" "budget exhausted — skip $WITHDRAW_AMT"; return 1; }
metrics_report_coins "before-ATM-${tag}" || true
section "e2e · Bank withdraw $WITHDRAW_AMT · $(format_amount_alt "$WITHDRAW_AMT")"
e2e_over && { warn "Bank withdraw" "budget exhausted — skip $WITHDRAW_AMT"; return 1; }
metrics_report_coins "before-bank-wd-${tag}" || true
curl -sS -m 15 -o "$SCRATCH/wd-$tag.json" -H "Authorization: Bearer $UT" \
-H 'Content-Type: application/json' \
@ -919,10 +921,10 @@ e2e_one_withdraw() {
URI=$(python3 -c 'import json;d=json.load(open("'"$SCRATCH"'/wd-'"$tag"'.json"));print(d.get("taler_withdraw_uri") or "")' 2>/dev/null || true)
URI_CLEAN=$(python3 -c 'import json;u=json.load(open("'"$SCRATCH"'/wd-'"$tag"'.json")).get("taler_withdraw_uri") or "";print(u.replace(":443/","/"))' 2>/dev/null || true)
if [ -z "$WID" ] || [ -z "$URI_CLEAN" ]; then
warn "ATM withdraw $WITHDRAW_AMT" "create failed — $(head -c 80 "$SCRATCH/wd-$tag.json" | tr '\n' ' ')"
warn "Bank withdraw $WITHDRAW_AMT" "create failed — $(head -c 80 "$SCRATCH/wd-$tag.json" | tr '\n' ' ')"
return 1
fi
ok "ATM withdrawal created $WITHDRAW_AMT ($WID)"
ok "Bank withdrawal created $WITHDRAW_AMT ($WID)"
cp "$SCRATCH/wd-$tag.json" "$SCRATCH/wd.json"
USE_URI="$URI"
@ -933,7 +935,7 @@ e2e_one_withdraw() {
&& wcli withdraw accept-uri --exchange "${EXCHANGE_PUBLIC}/" "$URI_CLEAN" >"$SCRATCH/accept-$tag.out" 2>&1; then
ok "wallet accept $WITHDRAW_AMT (no :443)"
else
warn "ATM withdraw $WITHDRAW_AMT" "accept-uri failed — $(tail -c 100 "$SCRATCH/accept-$tag.out" | tr '\n' ' ')"
warn "Bank withdraw $WITHDRAW_AMT" "accept-uri failed — $(tail -c 100 "$SCRATCH/accept-$tag.out" | tr '\n' ' ')"
return 1
fi
cp "$SCRATCH/accept-$tag.out" "$SCRATCH/accept.out"
@ -975,7 +977,7 @@ else:
fi
fi
if [ "$st" != "selected" ] && [ "$st" != "confirmed" ]; then
warn "ATM withdraw $WITHDRAW_AMT" "not selected (status=${st:-?})"
warn "Bank withdraw $WITHDRAW_AMT" "not selected (status=${st:-?})"
return 1
fi
if [ "$st" != "confirmed" ]; then
@ -984,32 +986,32 @@ else:
"$BANK/accounts/${USER}/withdrawals/${WID}/confirm")
case "$code" in
200|204) ok "bank confirm $WITHDRAW_AMT" ;;
*) warn "ATM withdraw $WITHDRAW_AMT" "confirm HTTP $code"; return 1 ;;
*) warn "Bank withdraw $WITHDRAW_AMT" "confirm HTTP $code"; return 1 ;;
esac
fi
fake_incoming_speedup
# Short per-ATM settle: poll balance + bank transfer_done only (never run-until-done)
# Short per-withdraw settle: poll balance + bank transfer_done only (never run-until-done)
local ok_bal=0 r av xfer
for r in 1 2 3 4 5 6 8 10; do
wcli_bal_snap "$SCRATCH/bal-$tag.out" || wcli balance >"$SCRATCH/bal-$tag.out" 2>&1 || true
av=$(wallet_avail_num "$SCRATCH/bal-$tag.out")
if python3 -c "import sys; sys.exit(0 if float(sys.argv[1]) > 0 else 1)" "$av" 2>/dev/null; then
ok_bal=1
ok "wallet funded after ATM $WITHDRAW_AMT" "avail=${CUR}:${av}"
ok "wallet funded after bank withdraw $WITHDRAW_AMT" "avail=${CUR}:${av}"
info "balance" "$(fmt_bal "$SCRATCH/bal-$tag.out")"
break
fi
xfer=$(curl -sS -m 8 "$BANK/taler-integration/withdrawal-operation/${WID}" 2>/dev/null \
| 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
ok "ATM $WITHDRAW_AMT bank transfer_done" "wallet avail=${CUR}:${av} ($xfer) — no run-until-done"
ok "Bank withdraw $WITHDRAW_AMT bank transfer_done" "wallet avail=${CUR}:${av} ($xfer) — no run-until-done"
ok_bal=1
break
fi
sleep 2
done
metrics_report_coins "after-ATM-${tag}" || true
metrics_report_coins "after-bank-wd-${tag}" || true
if [ "$ok_bal" = "1" ]; then
metrics_record_flow withdrawn "$WITHDRAW_AMT" || true
return 0
@ -1017,10 +1019,10 @@ else:
# Bank side often already confirmed — treat as timing lag, not hard fail
st=$(wd_status)
if [ "$st" = "confirmed" ]; then
warn "ATM withdraw $WITHDRAW_AMT" "bank confirmed; wallet not funded yet (settlement timing — will recheck later)"
warn "Bank withdraw $WITHDRAW_AMT" "bank confirmed; wallet not funded yet (settlement timing — will recheck later)"
return 2
fi
warn "ATM withdraw $WITHDRAW_AMT" "no wallet balance yet (status=${st:-?})"
warn "Bank withdraw $WITHDRAW_AMT" "no wallet balance yet (status=${st:-?})"
return 1
}
@ -1336,7 +1338,7 @@ sys.exit(1)
# ---------------------------------------------------------------------------
set_group atm
section "e2e · ATM withdraw ladder"
section "e2e · Bank withdraw ladder"
# ---------------------------------------------------------------------------
WITHDRAW_OK=0
WITHDRAW_OK_N=0
@ -1344,7 +1346,7 @@ WITHDRAW_LAG_N=0
WITHDRAW_FAIL_N=0
WITHDRAW_REPORT=""
for WITHDRAW_AMT in $WITHDRAW_LIST; do
e2e_over && { warn "ATM ladder" "time budget low — stopping more ATM withdraws (not a protocol error)"; break; }
e2e_over && { warn "Bank withdraw ladder" "time budget low — stopping more Bank withdraws (not a protocol error)"; break; }
set +e
e2e_one_withdraw "$WITHDRAW_AMT"
wc=$?
@ -1365,26 +1367,26 @@ for WITHDRAW_AMT in $WITHDRAW_LIST; do
;;
esac
done
info "ATM withdraw summary" "$WITHDRAW_REPORT (ok=$WITHDRAW_OK_N lag=$WITHDRAW_LAG_N fail=$WITHDRAW_FAIL_N)"
info "Bank withdraw summary" "$WITHDRAW_REPORT (ok=$WITHDRAW_OK_N lag=$WITHDRAW_LAG_N fail=$WITHDRAW_FAIL_N)"
set_group load
section "e2e · load snapshot (after ATM withdraws)"
section "e2e · load snapshot (after Bank withdraws)"
metrics_report_load "${METRICS_DIR}/load-after-withdraw.json" "after-withdraw" || true
cp -f "${METRICS_DIR}/load-after-withdraw.json" "${METRICS_DIR}/load-after.json" 2>/dev/null || true
metrics_report_coins "after-ATM-ladder" || true
metrics_report_coins "after-bank-wd-ladder" || true
# Settlement catch-up: bank may have confirmed while wallet was still empty
set_group settle
section "e2e · wallet settlement (timing)"
if ! wait_wallet_balance 0 "${E2E_SETTLE_ROUNDS}" "${E2E_SETTLE_SLEEP}"; then
if [ "$WITHDRAW_LAG_N" -gt 0 ] || [ "$WITHDRAW_OK_N" -gt 0 ]; then
warn "settlement timing" "ATM path reached bank confirm (lag=$WITHDRAW_LAG_N ok=$WITHDRAW_OK_N) but wallet empty after wait — TIME lag, not protocol error"
warn "settlement timing" "bank withdraw path reached bank confirm (lag=$WITHDRAW_LAG_N ok=$WITHDRAW_OK_N) but wallet empty after wait — TIME lag, not protocol error"
fi
fi
av_now=$(wallet_avail_num)
if python3 -c "import sys; sys.exit(0 if float(sys.argv[1]) > 0 else 1)" "$av_now" 2>/dev/null; then
WITHDRAW_OK=1
if [ "$WITHDRAW_OK_N" = "0" ]; then
warn "settlement timing" "coins arrived after ATM ladder (${CUR}:${av_now}) — earlier 'FAIL' was timing lag"
warn "settlement timing" "coins arrived after Bank withdraw ladder (${CUR}:${av_now}) — earlier 'FAIL' was timing lag"
WITHDRAW_REPORT="${WITHDRAW_REPORT} → late-OK avail=${CUR}:${av_now}"
fi
ok "spendable balance for payments" "${CUR}:${av_now}"
@ -1403,7 +1405,7 @@ else
WITHDRAW_OK=1
warn "settlement timing" "coins present after dig wait (${CUR}:${av_now}) — timing, not blocker"
else
blocker "withdraw-settle" "no spendable ${CUR} after ATM ladder + settle wait ($WITHDRAW_LIST)"
blocker "withdraw-settle" "no spendable ${CUR} after Bank withdraw ladder + settle wait ($WITHDRAW_LIST)"
section "e2e · report"
info "WITHDRAW" "$WITHDRAW_REPORT — no coins after extended wait"
info "PAY" "SKIPPED (no spendable balance after settle wait)"
@ -1596,7 +1598,7 @@ set_group paivana
section "e2e · paivana paywall (template GOA:4200)"
# ---------------------------------------------------------------------------
# Public paywall: https://paivana.hacktivism.ch → 302 to merchant template "paivana".
# Requires spendable ≥ 4200 GOA (ATM ladder includes GOA:4200 by default).
# Requires spendable ≥ 4200 GOA (Bank withdraw ladder includes GOA:4200 by default).
: "${PAIVANA_PUBLIC:=https://paivana.hacktivism.ch}"
: "${E2E_PAIVANA:=1}"
: "${E2E_PAIVANA_TEMPLATE:=paivana}"
@ -1630,11 +1632,11 @@ else
;;
esac
# Ensure wallet can cover 4200 (extra ATM if ladder did not fund enough)
# Ensure wallet can cover 4200 (extra bank withdraw if ladder did not fund enough)
pay_need=$(python3 -c 'import sys; print(float(sys.argv[1].split(":",1)[-1]))' "$E2E_PAIVANA_AMOUNT" 2>/dev/null || echo 4200)
av_now=$(wallet_avail_num)
if ! python3 -c "import sys; sys.exit(0 if float(sys.argv[1]) + 1e-9 >= float(sys.argv[2]) else 1)" "$av_now" "$pay_need" 2>/dev/null; then
info "paivana" "avail ${CUR}:${av_now} < ${pay_need}ATM withdraw ${E2E_PAIVANA_AMOUNT}"
info "paivana" "avail ${CUR}:${av_now} < ${pay_need}Bank withdraw ${E2E_PAIVANA_AMOUNT}"
e2e_over && warn "paivana" "budget low before 4200 withdraw"
set +e
e2e_one_withdraw "$E2E_PAIVANA_AMOUNT"
@ -1687,7 +1689,7 @@ fi
set_group report
section "e2e · report"
info "user" "$USER"
info "ATM withdraws" "$WITHDRAW_REPORT"
info "Bank withdraws" "$WITHDRAW_REPORT"
info "payments" "$PAY_REPORT"
info "shop" "${SHOP_REPORT:-(n/a)}"
info "paivana" "${PAIVANA_REPORT:-(n/a)}"