feat(network): give the "no peers" banner an honest detail and a Restart action
The no-peers banner headline ("Connected, but no network peers") was followed
by a detail line that just repeated connection_status ("Connected"/"Peers: 0"),
reading as a contradiction, and it offered no action at the exact moment the
wallet looks synced but is silently stalled at a stale height.
- NoPeers now clears the passthrough detail; App renders a translated,
actionable hint (node_banner_no_peers_detail) for this reason instead.
- When the embedded daemon is the node, offer a Restart button (re-triggers
peer discovery via the -addnode seeds); an external node stays action-less
since it is the user's own to restart.
- Update + extend the evaluator unit tests (external = no action/empty detail;
embedded = RestartNode).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+14
-1
@@ -3535,6 +3535,9 @@ void testNodeStatusBanner()
|
||||
EXPECT_TRUE(!evaluateNodeStatusBanner(in).show);
|
||||
}
|
||||
// Connected but no peer-derived tip (0 peers) once chain info is in → amber "no peers" banner.
|
||||
// An external node (no embedded controller) gets no action button, and the detail is cleared:
|
||||
// connection_status ("Peers: 0"/"Connected") would contradict the headline, so App renders a
|
||||
// translated actionable hint for this reason instead.
|
||||
{
|
||||
NodeBannerInputs in;
|
||||
in.connected = true; in.tip_known = false; in.blocks = 3262059;
|
||||
@@ -3544,7 +3547,17 @@ void testNodeStatusBanner()
|
||||
EXPECT_TRUE(s.severity == NodeBannerSeverity::Warning);
|
||||
EXPECT_TRUE(s.reason == NodeBannerReason::NoPeers);
|
||||
EXPECT_TRUE(s.action == NodeBannerAction::None);
|
||||
EXPECT_EQ(s.detail, std::string("Peers: 0"));
|
||||
EXPECT_TRUE(s.detail.empty());
|
||||
}
|
||||
// ...but with the embedded daemon running, offer a Restart (re-triggers peer discovery).
|
||||
{
|
||||
NodeBannerInputs in;
|
||||
in.connected = true; in.tip_known = false; in.blocks = 3262059;
|
||||
in.using_embedded_daemon = true; in.has_daemon_controller = true; in.daemon_running = true;
|
||||
NodeBannerState s = evaluateNodeStatusBanner(in);
|
||||
EXPECT_TRUE(s.reason == NodeBannerReason::NoPeers);
|
||||
EXPECT_TRUE(s.action == NodeBannerAction::RestartNode);
|
||||
EXPECT_TRUE(s.detail.empty());
|
||||
}
|
||||
// Connected, tip unknown, but no chain info yet (blocks==0) → no banner (avoid startup flicker).
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user