Skip to content

Add local signer backup recovery flow#715

Open
ihordiachenko wants to merge 10 commits intomainfrom
feature/state_backup
Open

Add local signer backup recovery flow#715
ihordiachenko wants to merge 10 commits intomainfrom
feature/state_backup

Conversation

@ihordiachenko
Copy link
Copy Markdown
Collaborator

@ihordiachenko ihordiachenko commented May 1, 2026

Adds opt-in local VLS signer backups with CLI inspection/conversion tooling. There are two available backup strategies:

  • new-channels-only: default, low I/O, snapshots when a channel first becomes recoverable.
  • periodic: snapshots new recoverable channels and then refreshes after configured recoverable-channel updates, with more disk writes

Backups can be created through:

 glcli signer run --backup-path, inspected with inspect-backup

Backups can be converted to CLN recoverchannel input with:

glcli signer convert-backup --format cln --path <backup file>

Tradeoffs

  • Backups are best-effort during signer operation: write failures are logged and do not interrupt signing. The backup file is created only after a snapshot trigger, not immediately at startup.
  • Peer addresses are stored from Greenlight’s peerlist alongside VLS state to close the main recovery-data gap.
  • Only v1 channels supported for now

@ihordiachenko ihordiachenko requested a review from cdecker May 1, 2026 12:04
@ihordiachenko ihordiachenko force-pushed the feature/state_backup branch from bf8917e to c557661 Compare May 1, 2026 12:07
@ihordiachenko ihordiachenko marked this pull request as ready for review May 1, 2026 12:12
Copy link
Copy Markdown
Collaborator

@cdecker cdecker left a comment

Choose a reason for hiding this comment

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

Hm, not quite sure this is the direction we should go. Calling the client API from the signer is not necessary as far as I can see. The idea was to just take a snapshot of the signer state, which contains all the relevant information to recover on its own, whereas this change is a sprawling change, injecting new client connections in a variety of places, and adding strong coupling.

The original issue had the following line:

Conclusion: VLS state contains all SCB data plus much more. Storing VLS state snapshots should be sufficient for disaster recovery.

Comment on lines +5 to +6
use std::io::Write;
use std::path::Path;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This would prevent us from compiling in no_std environments, of which we target wasm as well as embedded environments. This means we need to gate the use and functionality behind a #[cfg(...)] guard, so we can exclude these parts for no_std envs.


mod approver;
mod auth;
mod backup;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We likely need to #[cfg(...)] guard to the mod, then we have a nice and clean separation.

async fn process_request(
&self,
req: HsmRequest,
mut node_client: Option<&mut crate::node::ClnClient>,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't quite understand the logic behind pushing a backup side-effect into the processing itself, when we can do snapshot comparison in the caller.

Comment thread libs/gl-client/src/signer/mod.rs Outdated
}
}

fn backup_peerlist_client(&self, channel: Channel) -> Result<Option<node::ClnClient>, Error> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Not sure why we need a node::ClnClient here at all, we have all the necessary data in the signerstate already, so let's just extract from there.

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.

2 participants