diff --git a/scripts/taler-monitoring/check_e2e.sh b/scripts/taler-monitoring/check_e2e.sh index 2cbf8c4..5566039 100755 --- a/scripts/taler-monitoring/check_e2e.sh +++ b/scripts/taler-monitoring/check_e2e.sh @@ -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)