Skip to content

Commit 894e0e5

Browse files
committed
fix(dash-spv): mark client stopped when force_resync fails mid-teardown
If `storage.clear()` or `build_managers()` fails after `force_resync` has already torn down the coordinator and disconnected the network, the client was left with `running` set but a drained coordinator, so `run`'s `tick` reported no error and spun forever without surfacing the failure. Factor the body into `force_resync_body` and, on failure while `was_running`, drain the coordinator (also cleaning up any tasks a failed `start`/`connect` restart spawned) and flip `running` to false so `run` exits and the error surfaces. A later `force_resync` retries the rebuild cleanly. Addresses CodeRabbit review comment on PR #856 #856 (comment)
1 parent ffa8322 commit 894e0e5

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

dash-spv/src/client/lifecycle.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,26 @@ impl<W: WalletInterface, N: NetworkManager, S: StorageManager> DashSpvClient<W,
231231
/// the `run` monitoring loop and every progress and event subscriber stay connected across
232232
/// the resync instead of tearing down. Flipping `running` would make `run` exit and never
233233
/// come back, silently freezing all outward progress.
234+
///
235+
/// A failure after the initial teardown is unrecoverable: storage has been wiped and the old
236+
/// chain data is gone, so there is no prior state to restore. Rather than leave `running` set
237+
/// with a drained coordinator (whose `tick` reports no error and would spin `run` forever), the
238+
/// error path drains anything a partial restart may have spawned and marks the client stopped,
239+
/// so `run` exits and the failure surfaces. A later `force_resync` retries the rebuild cleanly.
234240
pub async fn force_resync(&self) -> Result<()> {
235241
let was_running = self.is_running();
236242

243+
let result = self.force_resync_body(was_running).await;
244+
245+
if was_running && result.is_err() {
246+
let _ = self.sync_coordinator.lock().await.shutdown().await;
247+
self.running.send_replace(false);
248+
}
249+
250+
result
251+
}
252+
253+
async fn force_resync_body(&self, was_running: bool) -> Result<()> {
237254
// Tear down the running sync without touching `running`, so the `run` loop keeps
238255
// monitoring. Drain the coordinator's manager tasks and drop the network connection.
239256
if was_running {

0 commit comments

Comments
 (0)