Skip to content

Fixes #712 - #714

Merged
kingsznhone merged 3 commits into
michaelhly:masterfrom
kingsznhone:master
Oct 22, 2026
Merged

kingsznhone merged 3 commits into
michaelhly:masterfrom
kingsznhone:master

Conversation

@kingsznhone

Copy link
Copy Markdown
Collaborator

Problem

  1. With AsyncClient(url, commitment=Confirmed), passing any TxOpts made send_transaction run preflight and wait for confirmation at Finalized, ignoring the client commitment. TxOpts.preflight_commitment defaulted to Finalized, so the opts.preflight_commitment or self._commitment fallback in core.py never took effect. A transaction that was already confirmed could be polled until timeout and reported as UnconfirmedTxError, which invites a resend. Only opts=None used the client commitment.
  2. In confirm_transaction, when the block height passed last_valid_block_height, TransactionExpiredBlockheightExceededError was raised without a final status check. A transaction that landed between the last status poll and the block height check was wrongly reported as expired.

Changes

  • TxOpts.preflight_commitment now defaults to None and falls back to the client commitment. The confirmation target in _send_raw_transaction_post_send_args uses the same fallback.
  • confirm_transaction does one last get_signature_statuses check before raising TransactionExpiredBlockheightExceededError, and returns normally if the target commitment has been reached.
  • The repeated status check is factored into a local helper, reached_commitment.
  • The default-value assertion in test_pydantic_models.py is updated.

Notes

  • Behavior change: TxOpts().preflight_commitment is now None instead of Finalized. Callers who relied on the implicit Finalized should pass it explicitly.
  • Out of scope, from send_transaction with TxOpts confirms at finalized, ignoring the client commitment #712:
    • Transient RPC errors (e.g. 429) in the confirm loop. getSignatureStatuses / getBlockHeight errors still propagate as SolanaRpcException. Retry/backoff for rate limiting is intentionally not added to the client, since it adds complexity and hides a misconfiguration. Callers are expected to size their RPC plan and request rate accordingly, and AsyncClient(rate_limit=...) exists for this purpose. On such an error, the signature returned by send_transaction is not available to the caller, so they should look it up (e.g. via get_signature_statuses) before deciding whether to resend.
    • Attaching the signature to confirm-phase errors, and a separate confirm_commitment option on TxOpts.

Testing

  • pytest tests/unit passes and ruff check is clean.
  • Integration tests were not run.
  • No new test covers the two fixed scenarios yet.

@codecov

codecov Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.29%. Comparing base (dc6ad8e) to head (c497067).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #714      +/-   ##
==========================================
- Coverage   95.31%   95.29%   -0.02%     
==========================================
  Files          25       25              
  Lines        1919     1913       -6     
==========================================
- Hits         1829     1823       -6     
  Misses         90       90              
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kingsznhone
kingsznhone merged commit aee730b into michaelhly:master Oct 22, 2026
9 checks passed
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