Skip to content

fix(swap): abort TAO transfer when receipt parse fails (#297)#298

Open
RUNECTZ33 wants to merge 1 commit into
entrius:testfrom
RUNECTZ33:fix/297-tao-transfer-literal
Open

fix(swap): abort TAO transfer when receipt parse fails (#297)#298
RUNECTZ33 wants to merge 1 commit into
entrius:testfrom
RUNECTZ33:fix/297-tao-transfer-literal

Conversation

@RUNECTZ33
Copy link
Copy Markdown

Summary

Closes #297. S0 funds-stranding bug.

send_tao_transfer() and SubtensorProvider.send_tao() both fell back to the literal string 'tao_transfer' as the tx hash when parsing receipt.extrinsic_hash threw or returned empty:

except Exception:
    tx_hash = getattr(getattr(response, 'extrinsic_receipt', None), 'extrinsic_hash', '') or 'tao_transfer'

The literal then propagated through pending_swap.json, SwapConfirmSynapse.from_tx_hash, and the proof_message 'allways-swap:tao_transfer'. Validators looked up a TAO tx with the hex-decoded version of that literal, found nothing, and the user's funds stranded with no recovery path.

Change

Surface the parse failure as a clean None return at both sites. Both functions already type as Optional[Tuple[str, int]] and the swap flow caller at swap.py:1104-1106 already branches on if send_result is not None, so this fits the existing contract.

Site Before After
cli/swap_commands/swap.py:567-577 tx_hash = '...' or 'tao_transfer' clear console error + return None
chain_providers/subtensor.py:324-333 tx_hash = '...' or 'tao_transfer' bt.logging.error + return None

Both sites also guard the previously-unhandled "parse succeeded but tx_hash is empty" edge — that path used to leak through to the success branch with an empty-string hash.

Why None and not raise

Issue suggested raise RuntimeError(...). Verified at the call site (swap.py:1104):

for attempt in range(2):
    send_result = send_tao_transfer(...)
    if send_result is not None:
        ...

The retry-loop caller already understands None as a clean failure and retries up to twice. Raising would crash the CLI and lose the retry semantics. None matches the function's existing Optional[...] signature and the existing failure path immediately above (if not response.success: return None).

Scope

allways/cli/swap_commands/swap.py: +14 / -3
allways/chain_providers/subtensor.py: +15 / -3
Total: +29 / -6, two files. No new imports, no signature changes.

Test plan

  • Both files AST-parse cleanly (python3 -c "import ast; ast.parse(...)")
  • Caller pattern at swap.py:1104 confirmed to handle None (retries up to twice, then exits gracefully)
  • No grep hits for 'tao_transfer' literal anywhere else in the repo (git grep "tao_transfer" only matches the function name and the test cassette filenames)
  • No callers downstream rely on the bogus literal as a sentinel — all consumers of the returned tuple destructure into (from_tx_hash, ...) and use the hash for chain lookups, so a missing tuple correctly skips that flow

S0 funds-stranding bug: send_tao_transfer() and SubtensorProvider.send_tao
both fell back to the literal string 'tao_transfer' as the tx hash when
parsing receipt.extrinsic_hash threw or returned empty.

That literal then propagated through pending_swap.json,
SwapConfirmSynapse, and the proof_message ('allways-swap:tao_transfer').
Validators tried to look up a TAO tx with the hex-decoded version of that
literal, found nothing, and the user's funds stranded with no recovery
path.

Fix at both sites: surface the parse failure as a clean None return
(both functions already type as Optional[Tuple[str, int]] and the swap
flow caller already branches on `if send_result is not None`). Operators
get a clear log + recovery message and pending_swap.json never sees the
bogus hash.

Sites patched:
  - allways/cli/swap_commands/swap.py:567-577 (send_tao_transfer)
    Returns None instead of `('tao_transfer', 0)`. Also guards the
    'parse succeeded but tx_hash is empty' edge case.
  - allways/chain_providers/subtensor.py:324-333 (SubtensorProvider.send_tao)
    Returns None instead of substituting fallback hash + current_block.
    Also guards the empty-tx_hash edge.

Closes entrius#297
@xiao-xiao-mao xiao-xiao-mao Bot added the bug Something isn't working label May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cli: 'tao_transfer' literal string substituted as tx hash on receipt parse failure

1 participant