feat: add backup and restore functionality (#65)

This commit is contained in:
yse
2024-04-25 09:40:32 +02:00
committed by GitHub
parent 8f35cee0a1
commit ecc211e090
11 changed files with 170 additions and 61 deletions

20
cli/Cargo.lock generated
View File

@@ -581,9 +581,9 @@ checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b"
[[package]]
name = "fallible-iterator"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fallible-streaming-iterator"
@@ -803,9 +803,9 @@ dependencies = [
[[package]]
name = "hashlink"
version = "0.8.4"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee"
dependencies = [
"hashbrown",
]
@@ -1023,9 +1023,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libsqlite3-sys"
version = "0.26.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
dependencies = [
"pkg-config",
"vcpkg",
@@ -1590,9 +1590,9 @@ dependencies = [
[[package]]
name = "rusqlite"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
dependencies = [
"bitflags 2.5.0",
"fallible-iterator",
@@ -1604,9 +1604,9 @@ dependencies = [
[[package]]
name = "rusqlite_migration"
version = "1.0.2"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef7dd29a4426624704d5966416682fb7ab3682f724986e9e3893eaca44accabc"
checksum = "55709bc01054c69e2f1cefdc886642b5e6376a8db3c86f761be0c423eebf178b"
dependencies = [
"log",
"rusqlite",

View File

@@ -39,6 +39,13 @@ pub(crate) enum Command {
GetInfo,
/// Empties the encrypted wallet transaction cache
EmptyCache,
/// Backs up the current pending swaps
Backup,
/// Retrieve a list of backups
Restore {
#[arg(short, long)]
backup_path: Option<String>,
},
}
#[derive(Helper, Completer, Hinter, Validator)]
@@ -146,6 +153,14 @@ pub(crate) fn handle_command(
wallet.empty_wallet_cache()?;
command_result!("Cache emptied successfully")
}
Command::Backup => {
wallet.backup()?;
command_result!("Backup created successfully!")
}
Command::Restore { backup_path } => {
wallet.restore(backup_path)?;
command_result!("Backup restored successfully!")
}
})
}

103
lib/Cargo.lock generated
View File

@@ -413,9 +413,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.92"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2678b2e3449475e95b0aa6f9b506a28e61b3dc8996592b983695e8ebb58a8b41"
checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
[[package]]
name = "cfg-if"
@@ -628,9 +628,9 @@ dependencies = [
[[package]]
name = "fallible-iterator"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "fallible-streaming-iterator"
@@ -871,9 +871,9 @@ dependencies = [
[[package]]
name = "hashlink"
version = "0.8.4"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
checksum = "692eaaf7f7607518dd3cef090f1474b61edc5301d8012f09579920df68b725ee"
dependencies = [
"hashbrown",
]
@@ -1082,9 +1082,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libsqlite3-sys"
version = "0.26.0"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
dependencies = [
"pkg-config",
"vcpkg",
@@ -1500,9 +1500,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.79"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
@@ -1699,9 +1699,9 @@ dependencies = [
[[package]]
name = "rusqlite"
version = "0.29.0"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2"
checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
dependencies = [
"bitflags 2.5.0",
"fallible-iterator",
@@ -1713,9 +1713,9 @@ dependencies = [
[[package]]
name = "rusqlite_migration"
version = "1.0.2"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef7dd29a4426624704d5966416682fb7ab3682f724986e9e3893eaca44accabc"
checksum = "55709bc01054c69e2f1cefdc886642b5e6376a8db3c86f761be0c423eebf178b"
dependencies = [
"log",
"rusqlite",
@@ -1742,9 +1742,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.10"
version = "0.21.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4"
dependencies = [
"log",
"ring",
@@ -1917,9 +1917,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [
"serde_derive",
]
@@ -1945,9 +1945,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [
"proc-macro2",
"quote",
@@ -1956,9 +1956,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.115"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
dependencies = [
"itoa",
"ryu",
@@ -2051,9 +2051,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "2.0.58"
version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687"
checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
@@ -2701,7 +2701,7 @@ version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.4",
"windows-targets 0.52.5",
]
[[package]]
@@ -2721,17 +2721,18 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm 0.52.4",
"windows_aarch64_msvc 0.52.4",
"windows_i686_gnu 0.52.4",
"windows_i686_msvc 0.52.4",
"windows_x86_64_gnu 0.52.4",
"windows_x86_64_gnullvm 0.52.4",
"windows_x86_64_msvc 0.52.4",
"windows_aarch64_gnullvm 0.52.5",
"windows_aarch64_msvc 0.52.5",
"windows_i686_gnu 0.52.5",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.5",
"windows_x86_64_gnu 0.52.5",
"windows_x86_64_gnullvm 0.52.5",
"windows_x86_64_msvc 0.52.5",
]
[[package]]
@@ -2742,9 +2743,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
@@ -2754,9 +2755,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
@@ -2766,9 +2767,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
@@ -2778,9 +2785,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
@@ -2790,9 +2797,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
@@ -2802,9 +2809,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
@@ -2814,9 +2821,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.4"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winreg"

View File

@@ -15,4 +15,4 @@ uniffi = "0.27.1"
uniffi_macros = "0.27.1"
[patch.crates-io]
secp256k1-zkp = {git = "https://github.com/BlockstreamResearch/rust-secp256k1-zkp.git", rev = "60e631c24588a0c9e271badd61959294848c665d"}
secp256k1-zkp = {git = "https://github.com/BlockstreamResearch/rust-secp256k1-zkp.git", rev = "60e631c24588a0c9e271badd61959294848c665d"}

View File

@@ -64,6 +64,14 @@ impl BindingWallet {
) -> Result<ReceivePaymentResponse, PaymentError> {
self.ln_sdk.receive_payment(&req)
}
pub fn backup(&self) -> Result<(), LsSdkError> {
self.ln_sdk.backup().map_err(Into::into)
}
pub fn restore(&self, backup_path: Option<String>) -> Result<(), LsSdkError> {
self.ln_sdk.restore(backup_path).map_err(Into::into)
}
}
uniffi::include_scaffolding!("ls_sdk");

View File

@@ -76,4 +76,10 @@ interface BindingWallet {
[Throws=PaymentError]
ReceivePaymentResponse receive_payment(PrepareReceiveResponse req);
[Throws=LsSdkError]
void backup();
[Throws=LsSdkError]
void restore(string? backup_path);
};

View File

@@ -14,11 +14,11 @@ log = "0.4.20"
lwk_common = "0.3.0"
lwk_signer = "0.3.0"
lwk_wollet = "0.3.0"
rusqlite = "0.29"
rusqlite = { version = "0.31", features = ["backup"] }
rusqlite_migration = "1.0"
serde = { version = "1.0.197", features = ["derive"] }
thiserror = { workspace = true }
[dev-dependencies]
tempdir = "0.3.7"
uuid = { version = "1.8.0", features = ["v4"] }
uuid = { version = "1.8.0", features = ["v4"] }

View File

@@ -8,6 +8,20 @@ Your system must have the sqlite3 development files installed:
# On Debian
sudo apt install libsqlite3-dev
```
## Features
### Backup/Restore
The wallet provides the ability to `backup` and `restore` ongoing swaps via the corresponding methods:
```rust
let mnemonic = "...";
let data_dir = None;
let network = Network::Liquid;
let breez_wallet = Wallet::init(mnemonic, data_dir, network)?;
breez_wallet.backup()?; // Backs up the pending swaps under `{data_dir}/backup{-testnet}.sql`. Overwrites previous versions.
let backup_path = None; // Can also be Some(String), a path pointing to the database. Default is `{data_dir}/backup{-testnet}.sql`
breez_wallet.restore(backup_path)?; // Restores the specified backup
```
## Tests
In order to run tests, you can execute `cargo test -- --nocapture --test-threads 1`. This is due to the fact that currently tests require some degree of interaction (e.g. adding the funding invoice) in order to work, and thus should be run with a single thread (sequentially).

View File

@@ -0,0 +1,45 @@
use anyhow::Result;
use rusqlite::{backup::Backup, Connection};
use std::path::{Path, PathBuf};
use super::Persister;
use crate::Network;
impl Persister {
pub(crate) fn get_backup_path(&self) -> PathBuf {
self.main_db_dir.join(match self.network {
Network::Liquid => "backup.sql",
Network::LiquidTestnet => "backup-testnet.sql",
})
}
pub(crate) fn backup(&self) -> Result<()> {
let con = self.get_connection()?;
let backup_file = match self.network {
Network::Liquid => "backup.sql",
Network::LiquidTestnet => "backup-testnet.sql",
};
con.backup(
rusqlite::DatabaseName::Main,
self.main_db_dir.join(backup_file),
None,
)?;
Ok(())
}
pub(crate) fn restore_from_backup<P>(&self, backup_path: P) -> Result<()>
where
P: AsRef<Path>,
{
let src_con = self.get_connection()?;
let mut dst_con = Connection::open(backup_path)?;
let backup = Backup::new(&src_con, &mut dst_con)?;
backup.run_to_completion(5, std::time::Duration::from_millis(250), None)?;
Ok(())
}
}

View File

@@ -1,3 +1,4 @@
mod backup;
mod migrations;
use std::{collections::HashMap, fs::create_dir_all, path::PathBuf, str::FromStr};

View File

@@ -1,6 +1,7 @@
use std::{
fs,
path::PathBuf,
str::FromStr,
sync::{Arc, Mutex},
thread,
time::Duration,
@@ -581,4 +582,16 @@ impl Wallet {
Ok(())
}
pub fn restore(&self, backup_path: Option<String>) -> Result<()> {
let backup_path = match backup_path {
Some(p) => PathBuf::from_str(&p)?,
None => self.persister.get_backup_path(),
};
self.persister.restore_from_backup(backup_path)
}
pub fn backup(&self) -> Result<()> {
self.persister.backup()
}
}