Skip to content

Comments

backport: feat(ui): add sync status panel to wallet screen#642

Open
lklimek wants to merge 23 commits intov1.0-devfrom
zk-extract/sync-status-panel
Open

backport: feat(ui): add sync status panel to wallet screen#642
lklimek wants to merge 23 commits intov1.0-devfrom
zk-extract/sync-status-panel

Conversation

@lklimek
Copy link
Contributor

@lklimek lklimek commented Feb 24, 2026

Summary

  • Adds a compact sync status panel between wallet selection and wallet detail panel
  • Core line shows: RPC connected/disconnected, or SPV with phase-specific progress (Headers/Filter Headers/Filters/Blocks with %)
  • Platform line shows: address count, sync block height, and relative "time ago" since last sync
  • Adds format_unix_time_ago() / format_duration_ago() time formatting helpers

Test plan

Manual test scenarios: docs/ai-design/2026-02-24-sync-status-panel/manual-test-scenarios.md

  • Panel visible when HD wallet selected, hidden otherwise
  • RPC mode: shows Connected/Disconnected
  • SPV mode: shows sync phase with progress percentage
  • Platform: shows address count, height, time-ago
  • Wallet switching updates panel
  • Light/dark mode theming

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

  • New Features

    • Added Sync Status Panel to Wallets screen showing Core (RPC/SPV) and per-wallet Platform sync status, SPV progress text, and time-ago formatting for last sync timestamps (visible in developer mode).
    • Connection status label now distinguishes unbanned endpoints.
  • Bug Fixes

    • Prevent stale transaction state on broadcast failures in asset lock flows.
    • Replace crash-prone signing/unwraps with robust error handling.
  • Documentation

    • Added comprehensive manual test scenarios for the Sync Status Panel.

lklimek and others added 2 commits February 24, 2026 10:25
…ount

Replace hardcoded 3000 duff fee with dynamic fee calculation that accounts
for actual number of inputs. Estimates tx size using standard component
sizes (P2PKH input ~148B, output ~34B, header ~10B, payload ~60B) and
uses max(3000, estimated_size) to always meet the min relay fee.

Properly handles fee shortfall when allow_take_fee_from_amount is set,
and returns clear error messages for insufficient funds.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek self-assigned this Feb 24, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

Adds a detailed manual test plan for the Sync Status Panel; strengthens error handling in asset lock and signing code by replacing unwraps with propagated errors and cleanup on broadcast failure; tweaks numeric precision for fee logging; adjusts wallet fee/change handling flow; clarifies connection labels; and implements an SPV-aware sync status panel with per-wallet caching and time-ago formatting.

Changes

Cohort / File(s) Summary
Documentation & Tests
docs/ai-design/2026-02-24-sync-status-panel/manual-test-scenarios.md
Adds 25 manual test scenarios and an edge-cases table covering Core/SPV states, SPV phases, time-ago formats, wallet switching, visuals, progress, and DB refactor verification.
Asset Lock Broadcast & Mutex Safety
src/backend_task/core/create_asset_lock.rs
Replaces panic-prone Mutex unwraps with fallible locks; on broadcast failure, removes tx_id from waiting map to avoid stale state and returns formatted errors.
UTXO / Sighash Error Handling
src/model/wallet/asset_lock_transaction.rs
Replaces expect/unwrap with ok_or_else/map_err and propagates errors for missing UTXOs and sighash failures; collects sighashes as Result and narrows borrow scopes.
Fee Logging Precision
src/backend_task/identity/top_up_identity.rs
Changes fee-difference logging to use i128 to avoid overflow for large values.
Wallet Funding / Change Strategy
src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs
Reorders numbered steps and derives a fresh change address earlier; handles both "fee deducted from output" and "fee not deducted" flows with appropriate outputs and ReduceOutput application.
Connection Status Labels
src/context/connection_status.rs
Clarifies endpoint label to "Available ({available} unbanned / {total} total endpoints)"; adjusts SPV header text to "Ready"/"Syncing"/"Disconnected" and label ordering.
Wallets UI: SPV + Platform Sync Panel
src/ui/wallets/wallets_screen/mod.rs
Adds platform_sync_info: Option<(u64,u64)>, caching refresh on wallet select/refresh and platform-balance updates; adds time-ago helpers, SPV progress helpers, and render_sync_status integrated into the wallets screen (visible in dev mode).

Sequence Diagram(s)

sequenceDiagram
    participant UI as Wallets Screen UI
    participant Cache as platform_sync_info Cache
    participant DB as Database
    participant SPV as SPV Service

    UI->>DB: request platform sync info (seed_hash)
    DB-->>Cache: return (last_sync_timestamp, last_sync_height)
    Cache-->>UI: cache platform_sync_info

    UI->>SPV: query SPV status & progress
    SPV-->>UI: return SpvStatus / SpvSyncProgress

    UI->>UI: format time-ago & progress text
    UI->>UI: render_sync_status (Core line + Platform line)

    Note over UI,DB: on wallet refresh or platform-balance update
    UI->>DB: refresh platform sync info
    DB-->>Cache: update cached values
    Cache-->>UI: re-render sync status
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through code with tiny paws,
Replaced the panics, fixed the flaws.
Syncs now whisper time-ago tales,
SPV strides with steady scales.
Hooray — the panel hums and never stalls! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 43.48% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a sync status panel to the wallet screen UI, which aligns with the substantial UI modifications across the codebase.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch zk-extract/sync-status-panel

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

lklimek and others added 2 commits February 24, 2026 11:27
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
lklimek and others added 14 commits February 24, 2026 12:15
…d signed

Previously, `asset_lock_transaction_from_private_key` called
`take_unspent_utxos_for` which immediately removed selected UTXOs from
`Wallet.utxos`. Since fee recalculation and signing happen afterward,
any failure at those steps (fee shortfall, missing private key, change
address derivation error) would permanently drop UTXOs — especially
dangerous in SPV mode where there is no Core RPC reload fallback.

Fix:
- Add `select_unspent_utxos_for` (`&self`, non-mutating) that performs
  the same UTXO selection logic without removing anything.
- Add `remove_selected_utxos` (`&mut self`) for explicit removal.
- Refactor `take_unspent_utxos_for` to delegate to these two methods
  (no behavior change for existing callers).
- In `asset_lock_transaction_from_private_key`, use
  `select_unspent_utxos_for` for selection and only call
  `remove_selected_utxos` after the full tx is built and signed.

Co-authored-by: lklimek <842586+lklimek@users.noreply.github.com>
# Conflicts:
#	docs/ai-design/2026-02-24-asset-lock-fee-fix/manual-test-scenarios.md
#	src/model/wallet/asset_lock_transaction.rs
…ce recalc into remove_selected_utxos

Previously, every backend task caller had to manually: (1) remove UTXOs
from the in-memory map, (2) drop them from the database, and (3)
recalculate affected address balances.  This was error-prone — the
payment transaction builders were missing the balance recalculation
entirely.

Now `remove_selected_utxos` accepts an optional `&AppContext` and
handles all three steps atomically.  The redundant cleanup blocks in
5 backend task callers are removed.  Also applies the safe
select-then-commit UTXO pattern to `build_standard_payment_transaction`
and `build_multi_recipient_payment_transaction`, fixing the same
UTXO-loss-on-signing-failure bug that was previously fixed only for
asset lock transactions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add checked arithmetic to UTXO selection (amount + fee overflow safety)
- Replace hardcoded fee in single-UTXO path with calculate_asset_lock_fee
- Add UTXO selection retry when real fee exceeds initial estimate
- Document write-lock invariant on select_unspent_utxos_for
- Replace .unwrap() with .map_err() on wallet write locks
- Restrict Database::shared_connection visibility to pub(crate)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…Network directly

Replace Option<&AppContext> with concrete dependencies (&Database, Network),
removing the need for take_unspent_utxos_for. Extract balance recalculation
into a private helper reused by both remove_selected_utxos and the existing
AppContext-based wrapper.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Refresh platform sync info cache after wallet refresh completes
- Add broadcast failure cleanup in create_asset_lock (remove stale
  finality tracking entries, replace mutex .unwrap() with .map_err())
- Replace .expect() with proper error propagation in signing loops
- Use i128 for fee logging subtraction to prevent overflow
- Renumber step comments sequentially after refactoring

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek marked this pull request as ready for review February 24, 2026 17:12
@lklimek lklimek requested review from Copilot February 24, 2026 17:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a sync status panel to the wallet screen showing real-time Core and Platform synchronization status. The panel displays Core connection state (RPC connected/disconnected or SPV sync progress with phase-specific percentages) and Platform sync information (address count, sync height, and time since last sync). The PR also includes several bug fixes: improved error handling in asset lock transactions, more descriptive connection status text, corrected comment numbering, and a fix for integer overflow in fee calculation logging.

Changes:

  • Adds a compact sync status panel to the wallets screen with Core and Platform status lines, showing RPC/SPV connection state and platform sync details with relative timestamps
  • Improves error handling in asset lock transaction building by replacing panics with proper error propagation
  • Includes comprehensive manual test scenarios documentation covering 25+ test cases and 6 edge cases

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/ui/wallets/wallets_screen/mod.rs Adds sync status panel rendering, platform sync info caching, time formatting helpers, and integrates with screen lifecycle
src/model/wallet/asset_lock_transaction.rs Replaces expect() panics with proper error handling using ok_or_else() and map_err()
src/context/connection_status.rs Updates status text to be more descriptive (e.g., "Ready" instead of "SPV synced", more detailed endpoint counts)
src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs Fixes step comment numbering from 7-8 to 6-7-8
src/backend_task/identity/top_up_identity.rs Changes fee difference calculation to use i128 cast to handle negative differences
src/backend_task/core/create_asset_lock.rs Adds broadcast error handling with cleanup of finality tracking and uses map_err for mutex locks
docs/ai-design/2026-02-24-sync-status-panel/manual-test-scenarios.md Comprehensive manual test documentation with 25 test scenarios and 6 edge cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@lklimek
Copy link
Contributor Author

lklimek commented Feb 24, 2026

In SPV mode, I keep having Platform: Addresses: never synced. We need to investigate that.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs (2)

82-86: Inconsistent error handling: lock().unwrap() vs lock().map_err()?.

Line 84 still uses lock().unwrap() on transactions_waiting_for_finality, while the same operation in create_asset_lock.rs (lines 36–39, 93–96) was updated in this PR to use lock().map_err(|e| e.to_string())?. For consistency and to avoid a panic on a poisoned lock, consider aligning this call.

Proposed fix
-            let mut proofs = self.transactions_waiting_for_finality.lock().unwrap();
+            let mut proofs = self
+                .transactions_waiting_for_finality
+                .lock()
+                .map_err(|e| e.to_string())?;

Based on learnings, error handling refactoring is needed across the codebase, particularly to avoid panics with .expect() and instead propagate errors properly using the ? operator.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs` around
lines 82 - 86, Replace the panic-prone call to
transactions_waiting_for_finality.lock().unwrap() with fallible error
propagation consistent with other modules: acquire the mutex with
transactions_waiting_for_finality.lock().map_err(|e| e.to_string())? and then
perform proofs.insert(tx_id, None); so the function (the block in
fund_platform_address_from_wallet_utxos where the "Step 2" registration occurs)
returns an Err instead of panicking when the lock is poisoned, matching the
pattern used in create_asset_lock.rs.

109-118: try_lock() in cleanup may skip cleanup unnecessarily.

Line 113 uses try_lock() which will fail not only on a poisoned lock but also if another thread momentarily holds the mutex. The analogous cleanup in create_asset_lock.rs (lines 52, 105) uses lock() which waits for the mutex. Since this is an error-recovery path, it's better to wait briefly rather than risk leaving a stale entry in the finality map.

Proposed fix
-            if let Ok(mut proofs) = self.transactions_waiting_for_finality.try_lock() {
+            if let Ok(mut proofs) = self.transactions_waiting_for_finality.lock() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs` around
lines 109 - 118, The cleanup path after broadcast_raw_transaction currently uses
transactions_waiting_for_finality.try_lock(), which can fail transiently and
skip removing tx_id; change it to acquire the mutex with
transactions_waiting_for_finality.lock().await (or blocking lock() as used in
create_asset_lock.rs) so the code waits for the lock and reliably removes the
entry, then proceed to call
db.delete_asset_lock_transaction(tx_id.as_byte_array()) and return the error as
before; ensure you reference the same mutex (transactions_waiting_for_finality)
and tx_id removal logic to mirror the safe cleanup in create_asset_lock.rs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs`:
- Around line 82-86: Replace the panic-prone call to
transactions_waiting_for_finality.lock().unwrap() with fallible error
propagation consistent with other modules: acquire the mutex with
transactions_waiting_for_finality.lock().map_err(|e| e.to_string())? and then
perform proofs.insert(tx_id, None); so the function (the block in
fund_platform_address_from_wallet_utxos where the "Step 2" registration occurs)
returns an Err instead of panicking when the lock is poisoned, matching the
pattern used in create_asset_lock.rs.
- Around line 109-118: The cleanup path after broadcast_raw_transaction
currently uses transactions_waiting_for_finality.try_lock(), which can fail
transiently and skip removing tx_id; change it to acquire the mutex with
transactions_waiting_for_finality.lock().await (or blocking lock() as used in
create_asset_lock.rs) so the code waits for the lock and reliably removes the
entry, then proceed to call
db.delete_asset_lock_transaction(tx_id.as_byte_array()) and return the error as
before; ensure you reference the same mutex (transactions_waiting_for_finality)
and tx_id removal logic to mirror the safe cleanup in create_asset_lock.rs.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a13ded and 6ffb0ee.

📒 Files selected for processing (7)
  • docs/ai-design/2026-02-24-sync-status-panel/manual-test-scenarios.md
  • src/backend_task/core/create_asset_lock.rs
  • src/backend_task/identity/top_up_identity.rs
  • src/backend_task/wallet/fund_platform_address_from_wallet_utxos.rs
  • src/context/connection_status.rs
  • src/model/wallet/asset_lock_transaction.rs
  • src/ui/wallets/wallets_screen/mod.rs

@PastaPastaPasta
Copy link
Member

Screenshot 2026-02-24 at 19 25 17 Screenshot 2026-02-24 at 19 25 35 Screenshot 2026-02-24 at 19 27 55

Concept NACK. I don't think it makes sense to show this on the wallets page; this is relevant to most DET operations.

Maybe instead we enhance the sync indicator in top left to also show progress, but I don't like this approach.

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept NACK

lklimek and others added 2 commits February 25, 2026 09:55
The PlatformAddressBalances task result handler updated wallet balances
but did not refresh the platform_sync_info cache, causing the UI to
display "never synced" until the wallet was reselected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Core/Platform sync status panel is now hidden by default and only
visible when developer mode is enabled. It uses a collapsible header
so developers can expand/collapse it as needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/ui/wallets/wallets_screen/mod.rs`:
- Around line 179-184: The current chain that builds platform_sync_info
(starting from selected_wallet.as_ref().and_then(|w| w.read().ok().map(|g|
g.seed_hash())).and_then(|hash|
app_context.db.get_platform_sync_info(&hash).ok()).map(|(ts, checkpoint,
_terminal)| (ts, checkpoint)).filter(|(ts, _)| *ts > 0)) throws away valid
cached checkpoint data when ts == 0; remove or change the final .filter(|(ts,
_)| *ts > 0) so that platform_sync_info preserves the (ts, checkpoint) tuple
even if ts == 0 (or replace the filter with a check that only discards when both
ts == 0 and checkpoint indicates no data), and update any downstream handling
(e.g., code that renders "Addresses: never synced") to consider checkpoint
presence rather than assuming ts > 0 is required for valid sync info; locate
this logic around selected_wallet, platform_sync_info, seed_hash and
app_context.db.get_platform_sync_info to apply the change.
- Around line 120-121: The platform_sync_info cache is only updated in
select_hd_wallet, causing stale sync state when selected_wallet is reassigned
elsewhere (e.g., post-removal or fallback reselection paths); add a single
helper (e.g., refresh_platform_sync_info or set_selected_wallet) that both
assigns selected_wallet and updates platform_sync_info (using the same logic as
in select_hd_wallet) and replace all direct assignments to selected_wallet
across code paths with calls to this helper so the sync panel always reflects
the newly selected wallet.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ffb0ee and 0406d47.

📒 Files selected for processing (1)
  • src/ui/wallets/wallets_screen/mod.rs

@lklimek
Copy link
Contributor Author

lklimek commented Feb 25, 2026

🔍 Audit Summary — PR #642

Reviewed by: Claude Code with a 3-agent team:

  • rust-developer — Code quality, idiomatic patterns, error handling, lock safety
  • security-engineer — Security audit, OWASP classification, state consistency
  • project-reviewer — Convention adherence, cross-file consistency, test coverage

Overall risk: Low. No critical or high-severity issues. The PR improves codebase robustness (panic removal, Mutex error handling) while adding a well-gated diagnostic UI panel.


Findings

# Severity Location Description
1 🟡 Medium create_asset_lock.rs:43-56 UTXO state inconsistency on broadcast failure — Comment says "we trigger a wallet refresh" but code does not. UTXOs removed from memory but never spent on-chain → incorrect balance until manual refresh. [A04:2021]
2 🟡 Medium wallets_screen/mod.rs:1305-1347 Missing masternodes sync phase + duplicated SPV phase logicspv_active_phase_text omits the Masternodes phase (present in NetworkChooserScreen::format_sync_progress) and duplicates phase interpretation logic. Users see generic "syncing..." during masternodes phase.
3 🟡 Medium wallets_screen/mod.rs:820-843 Utility functions trapped on screen structformat_unix_time_ago/format_duration_ago are pure functions with no self dependency. Should live in a shared utility module for reuse.
4 🟡 Medium create_asset_lock.rs:52 Silent Mutex poisoning in cleanup path — Happy path propagates lock errors, but cleanup uses if let Ok(...) which silently ignores poisoned Mutex. Should at minimum log a warning. [A04:2021]
5 🟢 Low wallets_screen/mod.rs No unit tests for new helper functionsformat_duration_ago, simple_progress_pct, spv_active_phase_text are pure logic, trivially testable, but have no tests.
6 🟢 Low manual-test-scenarios.md TS-25 references work not in this PR — Describes shared_connection removal, but Database::shared_connection() still exists and the diff doesn't touch it.

Pre-existing / Outside-diff observations

# Severity Description
P1 🟡 Medium 11 remaining .unwrap() on transactions_waiting_for_finality Mutex across transaction_processing.rs, register_identity.rs, top_up_identity.rs, fund_platform_address_from_wallet_utxos.rs. Any panic there poisons the Mutex for the new graceful callers. Track as follow-up.

✅ Positive observations

  • Panic removal in signing code (asset_lock_transaction.rs) — .expect() → proper Result propagation with descriptive error messages. Excellent hardening.
  • Broadcast failure cleanup — Removing stale transactions_waiting_for_finality entries on failure prevents phantom "waiting for finality" states.
  • Dev-mode gating — Sync panel behind is_developer_mode() + collapsible. Good UX design.
  • i64i128 cast for fee diff logging prevents overflow on large credit values.
  • saturating_sub for time calculations — Prevents underflow on clock skew.
  • Division-by-zero guard in simple_progress_pct with target == 0 check.
  • Connection status tooltip improvement — "5 unbanned / 10 total" is clearer than "5/10".
  • Manual test scenarios are thorough (24 cases + edge cases table) and correctly placed per project conventions.

Redundancy analysis

3 agents produced 18 raw findings. After deduplication: 6 unique actionable findings + 1 pre-existing observation. Redundancy ratio: 39% (7 findings flagged by 2+ agents). Key overlap areas: Mutex handling strategy, SPV phase logic concerns, and time formatting edge cases.


🤖 Reviewed by Claudius the Magnificent AI Agent | rust-developer · security-engineer · project-reviewer

}

/// Get a text summary of the active SPV sync phase.
fn spv_active_phase_text(sync_progress: &Option<SpvSyncProgress>) -> String {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MediumDuplicated SPV phase logic + missing Masternodes phase

NetworkChooserScreen::format_sync_progress (network_chooser_screen.rs ~L1961) already interprets SpvSyncProgress phases and includes a Masternodes phase that this function omits. During a fresh sync where masternodes is the active phase, users see generic "syncing..." instead of a meaningful label.

Consider:

  1. Extract shared SPV phase interpretation into a utility (e.g., src/ui/spv_helpers.rs) that both screens call
  2. Or at minimum, add masternodes handling here and document the intentional simplification

lklimek and others added 2 commits February 25, 2026 11:14
- Centralize wallet selection via set_selected_hd_wallet() helper to
  keep platform_sync_info cache consistent across all code paths
- Add tracing::warn! for Mutex poisoning in asset lock cleanup paths
- Fix misleading comment about wallet refresh on broadcast failure
- Remove TS-25 from manual test scenarios (not part of this PR)

Refs: #657

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Consolidate duplicated SPV sync phase formatting into a shared
`spv_phase_summary()` function in `connection_status.rs`. The wallet
screen now uses this shared function instead of its own copy. The
network screen retains its richer operator-facing formatter.

The connection indicator tooltip now shows detailed sync progress
(e.g. "SPV: Headers: 12345 / 27000 (45%)") instead of bare
"SPV: Syncing" when in SPV mode.

Also adjust refresh polling rates: 4s when connected, 1s when
disconnected (was 10s/2s).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

3 participants