Commit fc34338
fix: rebroadcast tx on proof timeout instead of marking invalid (#8)
* fix: rebroadcast transactions instead of marking invalid on proof timeout
When a transaction was successfully broadcast but not yet mined, the
system previously marked it 'invalid' after max failed proof checks.
This caused a double-spend: reviewStatus restored the inputs to
spendable, they were spent again, and when the original tx was mined
the wallet had two conflicting transactions.
Fix 1 (TaskCheckForProofs): reset to 'unsent' + attempts=0 instead of
'invalid' when the proof-attempt limit is exceeded. TaskSendWaiting
picks up 'unsent' reqs and rebroadcasts them automatically.
Fix 2 (EntityProvenTx.fromReq): same rebroadcast logic for the
secondary threshold (attempts > 8, age > 60 min) to prevent an earlier
bypass of the main limit.
Fix 3 (reviewStatus): add a guard to Step 2 so inputs are only
restored to spendable when there is no live ProvenTxReq (in
unmined/callback/unconfirmed/sending/unsent status) for the same txid.
Defense-in-depth to prevent double-spend even if a req reaches 'failed'.
Fix 4 (Monitor): increase unprovenAttemptsLimitTest from 10 to 100,
giving ~24h of testnet blocks before a rebroadcast cycle.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add wasBroadcast flag and maxRebroadcastAttempts circuit breaker (Phases 2 & 4)
Phase 2: Add `wasBroadcast` and `rebroadcastAttempts` schema columns to
`proven_tx_reqs` (migration 2026-04-30-001). Set `wasBroadcast = true`
when a req transitions to 'unmined' via broadcast success
(attemptToPostReqsToNetwork) or ARC SSE event. Use the flag in
TaskCheckForProofs and EntityProvenTx.fromReq so that proof-timeout
resets only happen for genuinely broadcast transactions; unbroadcast reqs
are still marked invalid.
Phase 4: Add `maxRebroadcastAttempts: number` (default 0 = unlimited) to
MonitorOptions. The proof-timeout path in TaskCheckForProofs increments
`rebroadcastAttempts` each cycle; once the circuit-breaker limit is
reached the req is marked invalid even for a broadcast tx.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* testing plan
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
* exclude dist
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
* update pnpm
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
* make sure they all pass
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
* fix wallet proof timeout rebroadcast recovery
* fix(docs-site): add path '/' to layout route so vite-react-ssg emits dist/index.html
Without an explicit `path: '/'` on the root layout route, vite-react-ssg cannot
discover the root pre-render target and never writes dist/index.html, causing
pagefind and check-built-links to fail. Child paths converted to relative (no
leading slash) and root index.md mapped to an index route per React Router v6
convention. Also adds `test -f dist/index.html` guard before pagefind to produce
a clear error instead of a cryptic SSG crash.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix ci recursive workspace builds
* chore: ignore .worktrees/ directory
* test: allow slower mongo memory startup
* ci: allow required native dependency builds
* Update .github/workflows/conformance.yml
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(wallet): harden input restoration guard
* fix(ci): repair version and conformance checks
* fix(wallet): rethrow unexpected purge beef errors
* docs(wallet): summarize rebroadcast recovery PR
---------
Signed-off-by: Deggen <d.kellenschwiler@bsvassociation.org>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>1 parent 055fbe2 commit fc34338
31 files changed
Lines changed: 1603 additions & 324 deletions
File tree
- .github/workflows
- docs-site
- src
- packages
- overlays/topics/src/__tests__
- wallet/wallet-toolbox
- src
- monitor
- tasks
- storage
- methods
- schema
- entities
- __tests
- tables
- test
- monitor
- storage
- utils
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
36 | | - | |
| 35 | + | |
| 36 | + | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
44 | | - | |
| 43 | + | |
| 44 | + | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
31 | 38 | | |
32 | 39 | | |
33 | 40 | | |
| 41 | + | |
34 | 42 | | |
35 | 43 | | |
36 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
28 | 33 | | |
29 | 34 | | |
30 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
89 | | - | |
90 | | - | |
| 91 | + | |
| 92 | + | |
91 | 93 | | |
92 | 94 | | |
93 | 95 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
185 | 187 | | |
186 | 188 | | |
187 | 189 | | |
188 | | - | |
189 | | - | |
| 190 | + | |
| 191 | + | |
190 | 192 | | |
191 | 193 | | |
192 | 194 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
| |||
263 | 265 | | |
264 | 266 | | |
265 | 267 | | |
266 | | - | |
267 | | - | |
| 268 | + | |
| 269 | + | |
268 | 270 | | |
269 | 271 | | |
270 | 272 | | |
| |||
0 commit comments