Skip to content

Commit

Permalink
Configurable cache dir (#567)
Browse files Browse the repository at this point in the history
* Add a configurable cache dir

* Fix UDL field position
  • Loading branch information
dangeross authored Nov 18, 2024
1 parent f65a8ae commit 802e9ee
Show file tree
Hide file tree
Showing 16 changed files with 84 additions and 17 deletions.
4 changes: 4 additions & 0 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ pub(crate) struct Args {
#[clap(short, long)]
pub(crate) data_dir: Option<String>,

#[clap(short, long)]
pub(crate) cache_dir: Option<String>,

#[clap(short, long)]
pub(crate) log_file: Option<String>,

Expand Down Expand Up @@ -75,6 +78,7 @@ async fn main() -> Result<()> {
.map(|var| var.into_string().expect("Expected valid API key string"));
let mut config = LiquidSdk::default_config(network, breez_api_key)?;
config.working_dir = data_dir_str;
config.cache_dir = args.cache_dir;
let sdk = LiquidSdk::connect(ConnectRequest {
mnemonic: mnemonic.to_string(),
config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import breez_sdk_liquid_notification.job.Job
import breez_sdk_liquid_notification.job.LnurlPayInfoJob
import breez_sdk_liquid_notification.job.LnurlPayInvoiceJob
import breez_sdk_liquid_notification.job.SwapUpdatedJob
import kotlin.io.path.Path
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -110,6 +111,10 @@ abstract class ForegroundService : SdkForegroundService, EventListener, Service(

// Connect to SDK if source intent has data message with valid payload
getConnectRequest()?.let { connectRequest ->
if (connectRequest.config.cacheDir == null) {
connectRequest.config.cacheDir = Path(connectRequest.config.workingDir, "pluginCache").toString()
}

getJobFromIntent(intent)?.also { job ->
launchSdkConnection(connectRequest, job)
} ?: run {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ typedef struct wire_cst_config {
struct wire_cst_list_prim_u_8_strict *bitcoin_electrum_url;
struct wire_cst_list_prim_u_8_strict *mempoolspace_url;
struct wire_cst_list_prim_u_8_strict *working_dir;
struct wire_cst_list_prim_u_8_strict *cache_dir;
int32_t network;
uint64_t payment_timeout_sec;
uint32_t zero_conf_min_fee_rate_msat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ open class SDKNotificationService: UNNotificationServiceExtension {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

guard let connectRequest = self.getConnectRequest() else {
guard var connectRequest = self.getConnectRequest() else {
if let content = bestAttemptContent {
contentHandler(content)
}
return
}

if connectRequest.config.cacheDir == nil {
connectRequest.config.cacheDir = URL(filePath: connectRequest.config.workingDir).appendingPathComponent("pluginCache").path
}

if let currentTask = self.getTaskFromNotification() {
self.currentTask = currentTask
Expand Down
1 change: 1 addition & 0 deletions lib/bindings/src/breez_sdk_liquid.udl
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ dictionary Config {
u64 payment_timeout_sec;
u32 zero_conf_min_fee_rate_msat;
string? breez_api_key;
string? cache_dir;
u64? zero_conf_max_amount_sat;
};

Expand Down
7 changes: 7 additions & 0 deletions lib/core/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2283,6 +2283,7 @@ impl SseDecode for crate::model::Config {
let mut var_bitcoinElectrumUrl = <String>::sse_decode(deserializer);
let mut var_mempoolspaceUrl = <String>::sse_decode(deserializer);
let mut var_workingDir = <String>::sse_decode(deserializer);
let mut var_cacheDir = <Option<String>>::sse_decode(deserializer);
let mut var_network = <crate::model::LiquidNetwork>::sse_decode(deserializer);
let mut var_paymentTimeoutSec = <u64>::sse_decode(deserializer);
let mut var_zeroConfMinFeeRateMsat = <u32>::sse_decode(deserializer);
Expand All @@ -2293,6 +2294,7 @@ impl SseDecode for crate::model::Config {
bitcoin_electrum_url: var_bitcoinElectrumUrl,
mempoolspace_url: var_mempoolspaceUrl,
working_dir: var_workingDir,
cache_dir: var_cacheDir,
network: var_network,
payment_timeout_sec: var_paymentTimeoutSec,
zero_conf_min_fee_rate_msat: var_zeroConfMinFeeRateMsat,
Expand Down Expand Up @@ -4324,6 +4326,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::Config {
self.bitcoin_electrum_url.into_into_dart().into_dart(),
self.mempoolspace_url.into_into_dart().into_dart(),
self.working_dir.into_into_dart().into_dart(),
self.cache_dir.into_into_dart().into_dart(),
self.network.into_into_dart().into_dart(),
self.payment_timeout_sec.into_into_dart().into_dart(),
self.zero_conf_min_fee_rate_msat
Expand Down Expand Up @@ -6293,6 +6296,7 @@ impl SseEncode for crate::model::Config {
<String>::sse_encode(self.bitcoin_electrum_url, serializer);
<String>::sse_encode(self.mempoolspace_url, serializer);
<String>::sse_encode(self.working_dir, serializer);
<Option<String>>::sse_encode(self.cache_dir, serializer);
<crate::model::LiquidNetwork>::sse_encode(self.network, serializer);
<u64>::sse_encode(self.payment_timeout_sec, serializer);
<u32>::sse_encode(self.zero_conf_min_fee_rate_msat, serializer);
Expand Down Expand Up @@ -8236,6 +8240,7 @@ mod io {
bitcoin_electrum_url: self.bitcoin_electrum_url.cst_decode(),
mempoolspace_url: self.mempoolspace_url.cst_decode(),
working_dir: self.working_dir.cst_decode(),
cache_dir: self.cache_dir.cst_decode(),
network: self.network.cst_decode(),
payment_timeout_sec: self.payment_timeout_sec.cst_decode(),
zero_conf_min_fee_rate_msat: self.zero_conf_min_fee_rate_msat.cst_decode(),
Expand Down Expand Up @@ -9593,6 +9598,7 @@ mod io {
bitcoin_electrum_url: core::ptr::null_mut(),
mempoolspace_url: core::ptr::null_mut(),
working_dir: core::ptr::null_mut(),
cache_dir: core::ptr::null_mut(),
network: Default::default(),
payment_timeout_sec: Default::default(),
zero_conf_min_fee_rate_msat: Default::default(),
Expand Down Expand Up @@ -11497,6 +11503,7 @@ mod io {
bitcoin_electrum_url: *mut wire_cst_list_prim_u_8_strict,
mempoolspace_url: *mut wire_cst_list_prim_u_8_strict,
working_dir: *mut wire_cst_list_prim_u_8_strict,
cache_dir: *mut wire_cst_list_prim_u_8_strict,
network: i32,
payment_timeout_sec: u64,
zero_conf_min_fee_rate_msat: u32,
Expand Down
16 changes: 12 additions & 4 deletions lib/core/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ pub struct Config {
pub bitcoin_electrum_url: String,
/// The mempool.space API URL, has to be in the format: `https://mempool.space/api`
pub mempoolspace_url: String,
/// Directory in which all SDK files (DB, log, cache) are stored.
/// Directory in which the DB and log files are stored.
///
/// Prefix can be a relative or absolute path to this directory.
pub working_dir: String,
/// Directory in which the Liquid wallet cache is stored. Defaults to `working_dir`
pub cache_dir: Option<String>,
pub network: LiquidNetwork,
/// Send payment timeout. See [crate::sdk::LiquidSdk::send_payment]
pub payment_timeout_sec: u64,
Expand All @@ -59,6 +61,7 @@ impl Config {
bitcoin_electrum_url: "bitcoin-mainnet.blockstream.info:50002".to_string(),
mempoolspace_url: "https://mempool.space/api".to_string(),
working_dir: ".".to_string(),
cache_dir: None,
network: LiquidNetwork::Mainnet,
payment_timeout_sec: 15,
zero_conf_min_fee_rate_msat: DEFAULT_ZERO_CONF_MIN_FEE_RATE_MAINNET,
Expand All @@ -73,6 +76,7 @@ impl Config {
bitcoin_electrum_url: "bitcoin-testnet.blockstream.info:50002".to_string(),
mempoolspace_url: "https://mempool.space/testnet/api".to_string(),
working_dir: ".".to_string(),
cache_dir: None,
network: LiquidNetwork::Testnet,
payment_timeout_sec: 15,
zero_conf_min_fee_rate_msat: DEFAULT_ZERO_CONF_MIN_FEE_RATE_TESTNET,
Expand All @@ -81,8 +85,12 @@ impl Config {
}
}

pub(crate) fn get_wallet_working_dir(&self, fingerprint_hex: String) -> anyhow::Result<String> {
Ok(PathBuf::from(self.working_dir.clone())
pub(crate) fn get_wallet_dir(
&self,
base_dir: &str,
fingerprint_hex: &str,
) -> anyhow::Result<String> {
Ok(PathBuf::from(base_dir)
.join(match self.network {
LiquidNetwork::Mainnet => "mainnet",
LiquidNetwork::Testnet => "testnet",
Expand Down Expand Up @@ -459,7 +467,7 @@ pub struct GetInfoResponse {
pub pending_send_sat: u64,
/// Incoming amount that is pending from ongoing Receive swaps
pub pending_receive_sat: u64,
/// The wallet's fingerprint. It is used to build the working directory in [Config::get_wallet_working_dir].
/// The wallet's fingerprint. It is used to build the working directory in [Config::get_wallet_dir].
pub fingerprint: String,
/// The wallet's pubkey. Used to verify signed messages.
pub pubkey: String,
Expand Down
8 changes: 6 additions & 2 deletions lib/core/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,18 @@ impl LiquidSdk {
fs::create_dir_all(&config.working_dir)?;
let fingerprint_hex: String =
Xpub::decode(signer.xpub()?.as_slice())?.identifier()[0..4].to_hex();
let working_dir = config.get_wallet_working_dir(fingerprint_hex)?;
let working_dir = config.get_wallet_dir(&config.working_dir, &fingerprint_hex)?;
let cache_dir = config.get_wallet_dir(
config.cache_dir.as_ref().unwrap_or(&config.working_dir),
&fingerprint_hex,
)?;

let persister = Arc::new(Persister::new(&working_dir, config.network)?);
persister.init()?;

let onchain_wallet = Arc::new(LiquidOnchainWallet::new(
config.clone(),
&working_dir,
&cache_dir,
persister.clone(),
signer.clone(),
)?);
Expand Down
8 changes: 7 additions & 1 deletion lib/core/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::fs;
use std::fs::{self, create_dir_all};
use std::io::Write;
use std::path::PathBuf;
use std::{path::Path, str::FromStr, sync::Arc};

use anyhow::{anyhow, Result};
Expand Down Expand Up @@ -109,6 +110,11 @@ impl LiquidOnchainWallet {
let signer = crate::signer::SdkLwkSigner::new(user_signer.clone())?;
let wollet = Self::create_wallet(&config, working_dir, &signer)?;

let working_dir_buf = PathBuf::from_str(working_dir)?;
if !working_dir_buf.exists() {
create_dir_all(&working_dir_buf)?;
}

Ok(Self {
config,
persister,
Expand Down
16 changes: 10 additions & 6 deletions packages/dart/lib/src/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1652,17 +1652,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
Config dco_decode_config(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 9) throw Exception('unexpected arr length: expect 9 but see ${arr.length}');
if (arr.length != 10) throw Exception('unexpected arr length: expect 10 but see ${arr.length}');
return Config(
liquidElectrumUrl: dco_decode_String(arr[0]),
bitcoinElectrumUrl: dco_decode_String(arr[1]),
mempoolspaceUrl: dco_decode_String(arr[2]),
workingDir: dco_decode_String(arr[3]),
network: dco_decode_liquid_network(arr[4]),
paymentTimeoutSec: dco_decode_u_64(arr[5]),
zeroConfMinFeeRateMsat: dco_decode_u_32(arr[6]),
zeroConfMaxAmountSat: dco_decode_opt_box_autoadd_u_64(arr[7]),
breezApiKey: dco_decode_opt_String(arr[8]),
cacheDir: dco_decode_opt_String(arr[4]),
network: dco_decode_liquid_network(arr[5]),
paymentTimeoutSec: dco_decode_u_64(arr[6]),
zeroConfMinFeeRateMsat: dco_decode_u_32(arr[7]),
zeroConfMaxAmountSat: dco_decode_opt_box_autoadd_u_64(arr[8]),
breezApiKey: dco_decode_opt_String(arr[9]),
);
}

Expand Down Expand Up @@ -3440,6 +3441,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_bitcoinElectrumUrl = sse_decode_String(deserializer);
var var_mempoolspaceUrl = sse_decode_String(deserializer);
var var_workingDir = sse_decode_String(deserializer);
var var_cacheDir = sse_decode_opt_String(deserializer);
var var_network = sse_decode_liquid_network(deserializer);
var var_paymentTimeoutSec = sse_decode_u_64(deserializer);
var var_zeroConfMinFeeRateMsat = sse_decode_u_32(deserializer);
Expand All @@ -3450,6 +3452,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
bitcoinElectrumUrl: var_bitcoinElectrumUrl,
mempoolspaceUrl: var_mempoolspaceUrl,
workingDir: var_workingDir,
cacheDir: var_cacheDir,
network: var_network,
paymentTimeoutSec: var_paymentTimeoutSec,
zeroConfMinFeeRateMsat: var_zeroConfMinFeeRateMsat,
Expand Down Expand Up @@ -5355,6 +5358,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_String(self.bitcoinElectrumUrl, serializer);
sse_encode_String(self.mempoolspaceUrl, serializer);
sse_encode_String(self.workingDir, serializer);
sse_encode_opt_String(self.cacheDir, serializer);
sse_encode_liquid_network(self.network, serializer);
sse_encode_u_64(self.paymentTimeoutSec, serializer);
sse_encode_u_32(self.zeroConfMinFeeRateMsat, serializer);
Expand Down
3 changes: 3 additions & 0 deletions packages/dart/lib/src/frb_generated.io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.bitcoin_electrum_url = cst_encode_String(apiObj.bitcoinElectrumUrl);
wireObj.mempoolspace_url = cst_encode_String(apiObj.mempoolspaceUrl);
wireObj.working_dir = cst_encode_String(apiObj.workingDir);
wireObj.cache_dir = cst_encode_opt_String(apiObj.cacheDir);
wireObj.network = cst_encode_liquid_network(apiObj.network);
wireObj.payment_timeout_sec = cst_encode_u_64(apiObj.paymentTimeoutSec);
wireObj.zero_conf_min_fee_rate_msat = cst_encode_u_32(apiObj.zeroConfMinFeeRateMsat);
Expand Down Expand Up @@ -5613,6 +5614,8 @@ final class wire_cst_config extends ffi.Struct {

external ffi.Pointer<wire_cst_list_prim_u_8_strict> working_dir;

external ffi.Pointer<wire_cst_list_prim_u_8_strict> cache_dir;

@ffi.Int32()
external int network;

Expand Down
10 changes: 8 additions & 2 deletions packages/dart/lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,13 @@ class Config {
/// The mempool.space API URL, has to be in the format: `https://mempool.space/api`
final String mempoolspaceUrl;

/// Directory in which all SDK files (DB, log, cache) are stored.
/// Directory in which the DB and log files are stored.
///
/// Prefix can be a relative or absolute path to this directory.
final String workingDir;

/// Directory in which the Liquid wallet cache is stored. Defaults to `working_dir`
final String? cacheDir;
final LiquidNetwork network;

/// Send payment timeout. See [crate::sdk::LiquidSdk::send_payment]
Expand All @@ -143,6 +146,7 @@ class Config {
required this.bitcoinElectrumUrl,
required this.mempoolspaceUrl,
required this.workingDir,
this.cacheDir,
required this.network,
required this.paymentTimeoutSec,
required this.zeroConfMinFeeRateMsat,
Expand All @@ -156,6 +160,7 @@ class Config {
bitcoinElectrumUrl.hashCode ^
mempoolspaceUrl.hashCode ^
workingDir.hashCode ^
cacheDir.hashCode ^
network.hashCode ^
paymentTimeoutSec.hashCode ^
zeroConfMinFeeRateMsat.hashCode ^
Expand All @@ -171,6 +176,7 @@ class Config {
bitcoinElectrumUrl == other.bitcoinElectrumUrl &&
mempoolspaceUrl == other.mempoolspaceUrl &&
workingDir == other.workingDir &&
cacheDir == other.cacheDir &&
network == other.network &&
paymentTimeoutSec == other.paymentTimeoutSec &&
zeroConfMinFeeRateMsat == other.zeroConfMinFeeRateMsat &&
Expand Down Expand Up @@ -211,7 +217,7 @@ class GetInfoResponse {
/// Incoming amount that is pending from ongoing Receive swaps
final BigInt pendingReceiveSat;

/// The wallet's fingerprint. It is used to build the working directory in [Config::get_wallet_working_dir].
/// The wallet's fingerprint. It is used to build the working directory in [Config::get_wallet_dir].
final String fingerprint;

/// The wallet's pubkey. Used to verify signed messages.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4372,6 +4372,8 @@ final class wire_cst_config extends ffi.Struct {

external ffi.Pointer<wire_cst_list_prim_u_8_strict> working_dir;

external ffi.Pointer<wire_cst_list_prim_u_8_strict> cache_dir;

@ffi.Int32()
external int network;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ fun asConfig(config: ReadableMap): Config? {
val paymentTimeoutSec = config.getDouble("paymentTimeoutSec").toULong()
val zeroConfMinFeeRateMsat = config.getInt("zeroConfMinFeeRateMsat").toUInt()
val breezApiKey = if (hasNonNullKey(config, "breezApiKey")) config.getString("breezApiKey") else null
val cacheDir = if (hasNonNullKey(config, "cacheDir")) config.getString("cacheDir") else null
val zeroConfMaxAmountSat =
if (hasNonNullKey(
config,
Expand All @@ -280,6 +281,7 @@ fun asConfig(config: ReadableMap): Config? {
paymentTimeoutSec,
zeroConfMinFeeRateMsat,
breezApiKey,
cacheDir,
zeroConfMaxAmountSat,
)
}
Expand All @@ -294,6 +296,7 @@ fun readableMapOf(config: Config): ReadableMap =
"paymentTimeoutSec" to config.paymentTimeoutSec,
"zeroConfMinFeeRateMsat" to config.zeroConfMinFeeRateMsat,
"breezApiKey" to config.breezApiKey,
"cacheDir" to config.cacheDir,
"zeroConfMaxAmountSat" to config.zeroConfMaxAmountSat,
)

Expand Down
10 changes: 9 additions & 1 deletion packages/react-native/ios/BreezSDKLiquidMapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,13 @@ enum BreezSDKLiquidMapper {
}
breezApiKey = breezApiKeyTmp
}
var cacheDir: String?
if hasNonNilKey(data: config, key: "cacheDir") {
guard let cacheDirTmp = config["cacheDir"] as? String else {
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "cacheDir"))
}
cacheDir = cacheDirTmp
}
var zeroConfMaxAmountSat: UInt64?
if hasNonNilKey(data: config, key: "zeroConfMaxAmountSat") {
guard let zeroConfMaxAmountSatTmp = config["zeroConfMaxAmountSat"] as? UInt64 else {
Expand All @@ -322,7 +329,7 @@ enum BreezSDKLiquidMapper {
zeroConfMaxAmountSat = zeroConfMaxAmountSatTmp
}

return Config(liquidElectrumUrl: liquidElectrumUrl, bitcoinElectrumUrl: bitcoinElectrumUrl, mempoolspaceUrl: mempoolspaceUrl, workingDir: workingDir, network: network, paymentTimeoutSec: paymentTimeoutSec, zeroConfMinFeeRateMsat: zeroConfMinFeeRateMsat, breezApiKey: breezApiKey, zeroConfMaxAmountSat: zeroConfMaxAmountSat)
return Config(liquidElectrumUrl: liquidElectrumUrl, bitcoinElectrumUrl: bitcoinElectrumUrl, mempoolspaceUrl: mempoolspaceUrl, workingDir: workingDir, network: network, paymentTimeoutSec: paymentTimeoutSec, zeroConfMinFeeRateMsat: zeroConfMinFeeRateMsat, breezApiKey: breezApiKey, cacheDir: cacheDir, zeroConfMaxAmountSat: zeroConfMaxAmountSat)
}

static func dictionaryOf(config: Config) -> [String: Any?] {
Expand All @@ -335,6 +342,7 @@ enum BreezSDKLiquidMapper {
"paymentTimeoutSec": config.paymentTimeoutSec,
"zeroConfMinFeeRateMsat": config.zeroConfMinFeeRateMsat,
"breezApiKey": config.breezApiKey == nil ? nil : config.breezApiKey,
"cacheDir": config.cacheDir == nil ? nil : config.cacheDir,
"zeroConfMaxAmountSat": config.zeroConfMaxAmountSat == nil ? nil : config.zeroConfMaxAmountSat,
]
}
Expand Down
Loading

0 comments on commit 802e9ee

Please sign in to comment.