monitoring: ATM 4200 ladder + paivana e2e

This commit is contained in:
Hernâni Marques 2026-07-17 11:04:05 +02:00
parent 9c2d3077a5
commit 4c28af91e1
No known key found for this signature in database
GPG key ID: CB5738652768F7E9

View file

@ -205,14 +205,14 @@ except Exception: print("")' 2>/dev/null || true)
# E2E_ATM_MAX=N # try at most N ATM withdraws (budget)
# ---------------------------------------------------------------------------
: "${E2E_VARIABLE:=1}"
: "${E2E_ATM_MAX:=4}"
: "${E2E_ATM_MAX:=5}"
if [ "$E2E_REMOTE" = "1" ]; then
# remote: still ATM-shaped but smaller notes; keep cheap
: "${E2E_WITHDRAW_VALUES:=10 20 50}"
: "${E2E_PAY_VALUES:=0.01 0.05 0.1 1}"
else
# local GOA: classic ATM denominations
: "${E2E_WITHDRAW_VALUES:=20 50 100 200}"
# local GOA: classic ATM notes + 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
@ -264,12 +264,24 @@ PAY_AMT=$(printf '%s' "$PAY_LIST" | awk '{print $1}')
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 ' ')
need=$(( 40 + n_w * 35 + n_p * 20 ))
need=$(( 50 + n_w * 40 + n_p * 20 + 60 )) # + room for paivana pay
if [ "${E2E_TIMEOUT}" -lt "$need" ]; then
E2E_TIMEOUT=$need
fi
# cap ATM attempts
WITHDRAW_LIST=$(printf '%s' "$WITHDRAW_LIST" | tr ' ' '\n' | head -n "$E2E_ATM_MAX" | tr '\n' ' ' | sed 's/ *$//')
# cap ATM 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" '
NF==0 { next }
$0==big { has=1; next }
{ small[++n]=$0 }
END {
keep = max - (has ? 1 : 0)
if (keep < 0) keep = 0
for (i = 1; i <= n && i <= keep; i++) printf "%s ", small[i]
if (has) printf "%s", big
print ""
}' | sed 's/ *$//'
)
fi
BANK_HOST=$(python3 -c 'from urllib.parse import urlparse; print(urlparse("'"$BANK_PUBLIC"'").hostname or "bank")' 2>/dev/null || echo bank)
@ -1196,11 +1208,104 @@ EOF
fi
fi
# ---------------------------------------------------------------------------
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).
: "${PAIVANA_PUBLIC:=https://paivana.hacktivism.ch}"
: "${E2E_PAIVANA:=1}"
: "${E2E_PAIVANA_TEMPLATE:=paivana}"
: "${E2E_PAIVANA_AMOUNT:=GOA:4200}"
: "${E2E_PAIVANA_INSTANCE:=goa-shop}"
PAIVANA_OK=0
PAIVANA_REPORT=""
if [ "$E2E_REMOTE" = "1" ] || [ "${CUR:-}" != "GOA" ] || [ "${E2E_PAIVANA}" = "0" ]; then
info "paivana" "SKIPPED (remote, non-GOA, or E2E_PAIVANA=0)"
PAIVANA_REPORT="SKIP"
else
PAIVANA_PUBLIC="${PAIVANA_PUBLIC%/}"
# HTTP: paywall front must redirect into template flow (or serve well-known)
hdr=$(curl -skS -m 12 -D - -o /dev/null "$PAIVANA_PUBLIC/" 2>/dev/null || true)
pcode=$(printf '%s' "$hdr" | awk 'BEGIN{c="000"} /^HTTP/{c=$2} END{print c}')
loc=$(printf '%s' "$hdr" | awk 'BEGIN{IGNORECASE=1} /^location:/{sub(/\r$/,""); sub(/^location:[[:space:]]*/,""); print; exit}')
case "$pcode" in
301|302|303|307|308)
if printf '%s' "$loc" | grep -qiE 'paivana|templates|well-known'; then
ok "paivana HTTP" "HTTP $pcode${loc:0:120}"
else
ok "paivana HTTP" "HTTP $pcode redirect (Location: ${loc:0:80})"
fi
;;
200)
warn "paivana HTTP" "HTTP 200 without paywall redirect — unexpected for locked site"
;;
*)
fail "paivana HTTP" "HTTP ${pcode:-000} on $PAIVANA_PUBLIC/ (want 302 to template)"
PAIVANA_REPORT="HTTP_FAIL"
;;
esac
# Ensure wallet can cover 4200 (extra ATM 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}"
e2e_over && warn "paivana" "budget low before 4200 withdraw"
set +e
e2e_one_withdraw "$E2E_PAIVANA_AMOUNT"
wc=$?
set -e
if [ "$wc" = "0" ]; then
WITHDRAW_OK=1
WITHDRAW_OK_N=$((WITHDRAW_OK_N + 1))
WITHDRAW_REPORT="${WITHDRAW_REPORT}${WITHDRAW_REPORT:+ }${E2E_PAIVANA_AMOUNT}=OK(paivana)"
elif [ "$wc" = "2" ]; then
WITHDRAW_LAG_N=$((WITHDRAW_LAG_N + 1))
WITHDRAW_REPORT="${WITHDRAW_REPORT}${WITHDRAW_REPORT:+ }${E2E_PAIVANA_AMOUNT}=LAG(paivana)"
else
WITHDRAW_FAIL_N=$((WITHDRAW_FAIL_N + 1))
WITHDRAW_REPORT="${WITHDRAW_REPORT}${WITHDRAW_REPORT:+ }${E2E_PAIVANA_AMOUNT}=FAIL(paivana)"
fi
wait_wallet_balance "$(python3 -c "print(max(0, $pay_need - 1))" 2>/dev/null || echo 4199)" 12 3 || true
av_now=$(wallet_avail_num)
fi
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
warn "paivana" "skip pay — insufficient avail ${CUR}:${av_now} (need ${pay_need})"
PAIVANA_REPORT="${PAIVANA_REPORT:+$PAIVANA_REPORT+}SKIP(bal)"
else
_E2E_INST_SAVE="$INST"
INST="${E2E_PAIVANA_INSTANCE}"
set +e
e2e_one_pay_public_template \
"${E2E_PAIVANA_TEMPLATE}" \
"Paivana paywall" \
"${E2E_PAIVANA_AMOUNT}"
pc=$?
set -e
INST="$_E2E_INST_SAVE"
unset _E2E_INST_SAVE
if [ "$pc" = "0" ]; then
PAIVANA_OK=1
PAY_OK=1
PAY_OK_N=$((PAY_OK_N + 1))
PAIVANA_REPORT="${PAIVANA_REPORT:+$PAIVANA_REPORT+}PAY_OK"
ok "paivana" "template ${E2E_PAIVANA_TEMPLATE} paid ${E2E_PAIVANA_AMOUNT}"
else
PAIVANA_REPORT="${PAIVANA_REPORT:+$PAIVANA_REPORT+}PAY_FAIL"
warn "paivana" "template pay failed (${E2E_PAIVANA_TEMPLATE} · ${E2E_PAIVANA_AMOUNT})"
fi
fi
info "paivana summary" "${PAIVANA_REPORT:-?} · instance ${E2E_PAIVANA_INSTANCE}"
fi
section "e2e · report"
info "user" "$USER"
info "ATM withdraws" "$WITHDRAW_REPORT"
info "payments" "$PAY_REPORT"
info "goa-shop" "${SHOP_REPORT:-(n/a)}"
info "paivana" "${PAIVANA_REPORT:-(n/a)}"
info "final balance" "$(fmt_bal "$SCRATCH/bal-live.out" 2>/dev/null || echo "(n/a)")"
info "scratch" "$SCRATCH"
# Success if we had coins and at least one pay, OR coins + only pay skips (nothing affordable)