docs(platform-wallet): clarify broadcast retry contract#3996
Conversation
…e-send variants Address CodeRabbit follow-ups on dashpay#3985: - TransactionBroadcaster::broadcast doc no longer claims every Err is safe to retry: TransactionBroadcast/SpvError are pre-send rejections (release reservations and retry); any other Err is ambiguous and the reservation must be kept. - send_to_addresses_releases_reservation_on_broadcast_failure now exercises both pre-send variants allowlisted by broadcast_failure_is_pre_send via a parameterized FailFirstBroadcaster, keeping the BIP44/BIP32 coverage and retry assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughDocumentation for ChangesBroadcast error contract and test coverage
Estimated code review effort: 2 (Simple) | ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Review complete (commit 7958536) |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Docs+test-only follow-up that tightens the TransactionBroadcaster::broadcast contract and extends the reservation-release test to cover both allowlisted pre-send variants (TransactionBroadcast, SpvError) across BIP44/BIP32 accounts. Verified the doc language matches broadcast_failure_is_pre_send and both broadcaster impls only emit variants within the allowlist. One suggestion: the new contract states 'the network never accepted the transaction' more strongly than DapiBroadcaster/SpvBroadcaster actually guarantee, since both collapse transport-level errors (post-send timeouts, connection drops) into the same variants used for genuine pre-send rejections.
Source: reviewers opus/opus, sonnet5/claude-sonnet-5, codex/gpt-5.5[high] for general; verifier opus/opus. Failed lanes: codex/gpt-5.5[high] general.
🟡 1 suggestion(s)
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `packages/rs-platform-wallet/src/broadcaster.rs`:
- [SUGGESTION] packages/rs-platform-wallet/src/broadcaster.rs:23-29: Contract claims a pre-send-only guarantee stronger than the implementations enforce
The revised doc says `TransactionBroadcast`/`SpvError` mean the submission was "rejected pre-send — the network never accepted the transaction", but both concrete implementations of this trait collapse post-send transport errors into these same variants:
- `DapiBroadcaster::broadcast` (broadcaster.rs:66-68) maps *any* error from `self.sdk.execute(...).into_inner()` — including a gRPC timeout or connection reset that could occur after Core has already accepted/relayed the transaction — to `PlatformWalletError::TransactionBroadcast`.
- `SpvRuntime::broadcast_transaction` (spv/runtime.rs:104-107) wraps *any* error from `client.broadcast_transaction(tx)` (multi-peer P2P send) as `PlatformWalletError::SpvError`, with no distinction between "rejected before propagation" and "lost the connection after some peers received it".
Callers relying on this contract will release reservations and retry on a genuine post-send transport failure, opening a narrow double-spend window. Because the entire point of this PR is to formalize the pre-send/ambiguous distinction, softening the language (e.g., "the broadcaster observed a rejection before the transaction was propagated to the network; note that transport-level failures that occur after propagation are currently also reported through these variants — see follow-up") would better match reality. The underlying fix — richer error variants from the broadcasters — is out of scope here.
| /// Error contract: | ||
| /// [`TransactionBroadcast`](PlatformWalletError::TransactionBroadcast) and | ||
| /// [`SpvError`](PlatformWalletError::SpvError) mean the submission was | ||
| /// rejected pre-send — the network never accepted the transaction — so | ||
| /// callers may release its reserved inputs and retry. Any other `Err` is | ||
| /// ambiguous: the transaction may already have been accepted, so callers | ||
| /// must keep the reservation rather than risk a double-spend on retry. |
There was a problem hiding this comment.
🟡 Suggestion: Contract claims a pre-send-only guarantee stronger than the implementations enforce
The revised doc says TransactionBroadcast/SpvError mean the submission was "rejected pre-send — the network never accepted the transaction", but both concrete implementations of this trait collapse post-send transport errors into these same variants:
DapiBroadcaster::broadcast(broadcaster.rs:66-68) maps any error fromself.sdk.execute(...).into_inner()— including a gRPC timeout or connection reset that could occur after Core has already accepted/relayed the transaction — toPlatformWalletError::TransactionBroadcast.SpvRuntime::broadcast_transaction(spv/runtime.rs:104-107) wraps any error fromclient.broadcast_transaction(tx)(multi-peer P2P send) asPlatformWalletError::SpvError, with no distinction between "rejected before propagation" and "lost the connection after some peers received it".
Callers relying on this contract will release reservations and retry on a genuine post-send transport failure, opening a narrow double-spend window. Because the entire point of this PR is to formalize the pre-send/ambiguous distinction, softening the language (e.g., "the broadcaster observed a rejection before the transaction was propagated to the network; note that transport-level failures that occur after propagation are currently also reported through these variants — see follow-up") would better match reality. The underlying fix — richer error variants from the broadcasters — is out of scope here.
source: ['claude']
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@thepastaclaw let's limit this only to doc changes, no code / test changes please. |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Docs-only follow-up that softens the TransactionBroadcaster::broadcast error contract from a factual claim about network state to a prescriptive requirement on implementations. This addresses the prior review's overclaim concern. No new defects; the pre-existing implementation gap in DapiBroadcaster/SpvBroadcaster is out of scope for a docs-only PR.
Source: reviewers opus/opus, sonnet5/claude-sonnet-5, codex/gpt-5.5[high] (failed: no JSON object with findings/summary found) for general; verifier opus/opus.
Maintainer requested this PR be limited to documentation changes. Restore wallet/core/broadcast.rs to the base branch version, keeping only the softened error-contract docs in broadcaster.rs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Adjusted this to docs-only per your request. The PR now only changes |
There was a problem hiding this comment.
Code Review
Correction: I over-scoped the first body for this review to a parent-branch diff artifact instead of the PR's actual base branch. Rechecked against the current PR diff for 7958536c, which only changes packages/rs-platform-wallet/src/broadcaster.rs.
No carried-forward prior findings: the previous ab8805fe review found none. The latest delta removes the code/test expansion and keeps the PR docs-only per maintainer request. I found no in-scope issues in the current head. The broader DAPI/SPV error-classification gap is an implementation follow-up outside this doc-only PR.
Source: reviewers opus/opus, sonnet5/claude-sonnet-5, codex/gpt-5.5[high] for general; verifier opus/opus.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Closing this helper PR as superseded. The target branch now includes |
Follow-up for CodeRabbit comments on #3985.
Changes:
TransactionBroadcaster::broadcasterror contract so only pre-send/not-accepted errors are retry-safe and ambiguous errors keep reservations.send_to_addresses_releases_reservation_on_broadcast_failuretest to cover both pre-send variants allowlisted bybroadcast_failure_is_pre_send:TransactionBroadcastandSpvError, across BIP44 and BIP32 accounts.Validation:
cargo test -p platform-wallet --lib wallet::core::broadcastcargo fmt --checkgit diff --check HEAD~1..HEADCloses CodeRabbit follow-up comments on #3985.
Summary by CodeRabbit
Documentation
Tests