Skip to content

feat(uxf): swap-roundtrip soak + demo playbook (#437) - #439

Merged
vrogojin merged 2 commits into
mainfrom
feat/issue-437-swap-roundtrip-soak
Jun 8, 2026
Merged

feat(uxf): swap-roundtrip soak + demo playbook (#437)#439
vrogojin merged 2 commits into
mainfrom
feat/issue-437-swap-roundtrip-soak

Conversation

@vrogojin

@vrogojin vrogojin commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Ships the SWAP analog of the existing transfer / accounting / recovery soak trios. Two artifacts:

  • manual-test-swap-roundtrip.sh — soak script asserting the full propose → accept → deposit → completed flow on real testnet.

    • Scenario A (default, ~8 min): happy-path 50 UCT ↔ 5 ETH atomic swap. Integer-only smallest-unit delta assertions on all four legs (alice -50 UCT +5 ETH, bob +50 UCT -5 ETH) + poison-pill scan across every step log. Asymmetric faucet (alice 100 UCT only, bob 100 ETH only) is deliberate — no fallback liquidity that could mask a UCT/ETH cross-talk bug.
    • Scenario B (~3 min): acceptor declines via sphere swap reject --reason "…". Both sides observe cancelled + verified no balance change.
    • Scenario C (~2 min): proposer rescinds via sphere swap cancel before counterparty accepts. Pre-announce branch — deposits_returned: false in the JSON output is the cleanest signal that no escrow round-trip happened.
    • Parametrized via SCENARIO=A|AB|ABC (default AB) and ESCROW= (default @escrow-testnet); shares the same KEEP=1 / SWAP_TEST_DIR= / SUFFIX= env contract as the other soaks.
  • docs/DEMO-PLAYBOOK-SWAP-ROUNDTRIP.md — presenter-friendly companion walking the same flow live in front of an audience (~20 min for A+B, ~14 min for A alone). Sections mirror the soak with talk tracks at each step, an at-a-glance table, an exit-code contract reference for swap wait, a 9-row failure-mode table, a command quick-reference + presenter cheat sheet.

Dependency

Both artifacts depend on the three new CLI commands shipped by sphere-cli PR #44: `swap reject --reason`, `swap cancel --timeout` (state-aware), `swap wait`. The playbook's §0 dependency check documents how to confirm the running binary has them.

Test plan

  • `bash -n manual-test-swap-roundtrip.sh` → no syntax errors
  • Manual review of the soak's grep patterns against the CLI's actual output shapes (e.g., `swap list` prints first 8 hex chars only — soak uses `${SWAP:0:8}` accordingly).
  • End-to-end run of `manual-test-swap-roundtrip.sh` against real testnet escrow (requires a reachable escrow service and `sphere` CLI built from sphere-cli feat: optional password encryption for wallet storage #44).
  • Spot-read of the demo playbook by a presenter.

Out of scope (per issue #437 §6)

  • NFT swaps (v1 swap is coin-only by SDK design).
  • Multi-asset swap deals (single coin per party today).
  • Escrow-service-side changes (`/escrow-service` is upstream of this).
  • Cross-device sync of swap state (covered incidentally by `manual-test-full-recovery.sh`).
  • Multi-hop / atomic-swap chains.

Closes (the soak + playbook half of) #437.

vrogojin added 2 commits June 8, 2026 16:37
Add the SWAP analog of the existing transfer / accounting / recovery
trios:

- manual-test-swap-roundtrip.sh — soak script asserting the propose →
  accept → deposit → completed flow on real testnet. Scenario A is the
  happy-path 50 UCT for 5 ETH atomic swap with integer-only smallest-unit
  net-delta assertions on all four legs (alice -50 UCT +5 ETH, bob +50
  UCT -5 ETH) plus a poison-pill scan across every step log. Asymmetric
  faucet (alice 100 UCT only, bob 100 ETH only) is deliberate — there's
  no fallback liquidity that could mask a UCT/ETH cross-talk bug.
  Scenario B exercises `sphere swap reject --reason` (acceptor declines,
  both sides observe cancelled, no balance change). Scenario C exercises
  pre-announce `sphere swap cancel` (proposer rescinds; deposits_returned
  is false because the local-only branch was taken — the JSON output's
  cleanest signal that no escrow round-trip happened). Soak is
  parametrized by `SCENARIO=A|AB|ABC` (default AB) and `ESCROW=` (default
  `@escrow-testnet`); shares the same `KEEP=1` / `SWAP_TEST_DIR=` /
  `SUFFIX=` env contract as the other soaks.

- docs/DEMO-PLAYBOOK-SWAP-ROUNDTRIP.md — presenter-friendly companion
  walking the same flow live in front of an audience (~20 min for A+B,
  ~14 min for A alone). Sections mirror the soak with talk tracks at
  each step, an at-a-glance table, an exit-code contract reference for
  `swap wait`, a 9-row failure-mode table, and a command quick-reference
  + presenter cheat sheet.

Both artifacts depend on sphere-cli's swap-reject/swap-cancel/swap-wait
commands shipped under sphere-sdk#437 — the playbook §0 documents the
dependency check.
Pre-merge code-review findings on the soak + playbook:

- Soak Scenarios B and C's assert_grep patterns target the human
  renderer's `key : value` form (unquoted), but the calls passed
  `--json`, which produces double-quoted JSON keys instead. The
  patterns never matched and both scenarios would always assert FAIL.
  Drop `--json` from the swap-reject + swap-cancel calls — the soak
  only needs presence checks, and the human renderer is what the
  patterns are written against.

- Reversed stderr redirect on 7 sync calls (`2>&1 > file` instead of
  `> file 2>&1`): the former duplicates stderr to the terminal then
  redirects stdout to the file, so sync errors silently disappear.
  Fix all seven (the two log-capturing ones at §4 and §6 plus the
  five `>/dev/null` sites in Scenarios B and C).

- Add §2.5 escrow liveness pre-flight (`sphere swap ping $ESCROW`)
  so an unreachable escrow surfaces as a clear "escrow not online"
  message rather than the misleading "couldn't extract swap_id"
  cascade at §3. Mirrors the pattern in
  manual-test-accounting-roundtrip.sh.

- Add a load-bearing comment in §7 documenting the pipefail +
  subshell + tee exit-code contract — easy to break under future
  edits if the reader doesn't know why it works.

- Playbook §4 and §9 polling loops used `${SWAP:0:16}` against
  `sphere swap list` output, but the list table only renders the
  first 8 hex chars. The pattern would never match and presenters
  following the playbook would loop the full 60s before the
  proposal "appears". Same fix the soak already had.

Soak `bash -n` passes; 127/127 unit tests still green.
@vrogojin
vrogojin merged commit 50fd512 into main Jun 8, 2026
3 checks passed
@vrogojin
vrogojin deleted the feat/issue-437-swap-roundtrip-soak branch June 8, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant