Skip to content

Commit 1feefa9

Browse files
committed
fixup! Integrate TierStore into NodeBuilder
Replace Builder::set_ephemeral_store(Arc<DynStore>) with set_ephemeral_storage_dir_path(String), constructing the SQLite store internally to mirror the backup store pattern. Remove BackupStorePathConflict since all three stores use distinct DB file names and cannot collide even in the same directory.
1 parent 8dfa964 commit 1feefa9

3 files changed

Lines changed: 29 additions & 59 deletions

File tree

src/builder.rs

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -151,21 +151,12 @@ impl std::fmt::Debug for LogWriterConfig {
151151
}
152152
}
153153

154-
#[derive(Default)]
154+
#[derive(Default, Debug)]
155155
struct TierStoreConfig {
156-
ephemeral: Option<Arc<DynStore>>,
156+
ephemeral_storage_dir_path: Option<PathBuf>,
157157
backup_storage_dir_path: Option<PathBuf>,
158158
}
159159

160-
impl std::fmt::Debug for TierStoreConfig {
161-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162-
f.debug_struct("TierStoreConfig")
163-
.field("ephemeral", &self.ephemeral.as_ref().map(|_| "Arc<DynStore>"))
164-
.field("backup_storage_dir_path", &self.backup_storage_dir_path)
165-
.finish()
166-
}
167-
}
168-
169160
/// An error encountered during building a [`Node`].
170161
///
171162
/// [`Node`]: crate::Node
@@ -212,11 +203,7 @@ pub enum BuildError {
212203
AsyncPaymentsConfigMismatch,
213204
/// An attempt to setup a DNS Resolver failed.
214205
DNSResolverSetupFailed,
215-
/// The configured backup storage path conflicts with the primary storage path.
216-
///
217-
/// Backup storage must use a distinct local directory so that the primary and
218-
/// backup stores do not point to the same SQLite database.
219-
BackupStorePathConflict,
206+
220207
}
221208

222209
impl fmt::Display for BuildError {
@@ -254,12 +241,7 @@ impl fmt::Display for BuildError {
254241
Self::DNSResolverSetupFailed => {
255242
write!(f, "An attempt to setup a DNS resolver has failed.")
256243
},
257-
Self::BackupStorePathConflict => {
258-
write!(
259-
f,
260-
"The configured backup storage path conflicts with the primary storage path."
261-
)
262-
},
244+
263245
}
264246
}
265247
}
@@ -652,10 +634,6 @@ impl NodeBuilder {
652634
/// Writes and removals for primary-backed data only succeed once both the
653635
/// primary and backup SQLite stores complete successfully.
654636
///
655-
/// The configured path must point to a distinct local directory from the
656-
/// primary storage path. If the backup path equals the primary storage path,
657-
/// building will fail with [`BuildError::BackupStorePathConflict`].
658-
///
659637
/// If not set, durable data will be stored only in the primary store.
660638
///
661639
/// [`SQLITE_BACKUP_DB_FILE_NAME`]: crate::io::sqlite_store::SQLITE_BACKUP_DB_FILE_NAME
@@ -665,16 +643,17 @@ impl NodeBuilder {
665643
self
666644
}
667645

668-
/// Configures the ephemeral store for non-critical, frequently-accessed data.
646+
/// Configures the ephemeral storage directory path for non-critical, frequently-accessed data.
669647
///
670-
/// When building with tiered storage, this store is used for ephemeral data like
671-
/// the network graph and scorer data to reduce latency for reads. Data stored here
672-
/// can be rebuilt if lost.
648+
/// When set, a local SQLite store is created at this path for ephemeral data like
649+
/// the network graph and scorer. Data stored here can be rebuilt if lost.
673650
///
674651
/// If not set, non-critical data will be stored in the primary store.
675-
pub fn set_ephemeral_store(&mut self, ephemeral_store: Arc<DynStore>) -> &mut Self {
652+
pub fn set_ephemeral_storage_dir_path(
653+
&mut self, ephemeral_storage_dir_path: String,
654+
) -> &mut Self {
676655
let tier_store_config = self.tier_store_config.get_or_insert(TierStoreConfig::default());
677-
tier_store_config.ephemeral = Some(ephemeral_store);
656+
tier_store_config.ephemeral_storage_dir_path = Some(ephemeral_storage_dir_path.into());
678657
self
679658
}
680659

@@ -883,9 +862,9 @@ impl NodeBuilder {
883862
/// The provided `kv_store` will be used as the primary storage backend. Optionally,
884863
/// an ephemeral store for frequently-accessed non-critical data (e.g., network graph, scorer)
885864
/// and a local SQLite backup store for disaster recovery can be configured via
886-
/// [`set_ephemeral_store`] and [`set_backup_storage_dir_path`].
865+
/// [`set_ephemeral_storage_dir_path`] and [`set_backup_storage_dir_path`].
887866
///
888-
/// [`set_ephemeral_store`]: Self::set_ephemeral_store
867+
/// [`set_ephemeral_storage_dir_path`]: Self::set_ephemeral_storage_dir_path
889868
/// [`set_backup_storage_dir_path`]: Self::set_backup_storage_dir_path
890869
pub fn build_with_store<S: KVStore + Send + Sync + 'static>(
891870
&self, node_entropy: NodeEntropy, kv_store: S,
@@ -919,18 +898,21 @@ impl NodeBuilder {
919898
let primary_store = Arc::new(DynStoreWrapper(kv_store));
920899
let mut tier_store = TierStore::new(primary_store, Arc::clone(&logger));
921900
if let Some(config) = ts_config {
922-
config.ephemeral.as_ref().map(|s| tier_store.set_ephemeral_store(Arc::clone(s)));
923-
if let Some(backup_storage_dir_path) = config.backup_storage_dir_path.as_ref() {
924-
let primary_storage_dir_path = PathBuf::from(&self.config.storage_dir_path);
925-
if primary_storage_dir_path == *backup_storage_dir_path {
926-
log_error!(
927-
logger,
928-
"Backup storage path must differ from primary storage path: {}",
929-
backup_storage_dir_path.display()
930-
);
931-
return Err(BuildError::BackupStorePathConflict);
932-
}
901+
if let Some(ephemeral_storage_dir_path) = config.ephemeral_storage_dir_path.as_ref() {
902+
let ephemeral_store = SqliteStore::new(
903+
ephemeral_storage_dir_path.clone(),
904+
Some(io::sqlite_store::SQLITE_EPHEMERAL_DB_FILE_NAME.to_string()),
905+
Some(io::sqlite_store::KV_TABLE_NAME.to_string()),
906+
)
907+
.map_err(|e| {
908+
log_error!(logger, "Failed to setup ephemeral SQLite store: {}", e);
909+
BuildError::KVStoreSetupFailed
910+
})?;
911+
let ephemeral_store: Arc<DynStore> = Arc::new(DynStoreWrapper(ephemeral_store));
912+
tier_store.set_ephemeral_store(ephemeral_store);
913+
}
933914

915+
if let Some(backup_storage_dir_path) = config.backup_storage_dir_path.as_ref() {
934916
let backup_store = SqliteStore::new(
935917
backup_storage_dir_path.clone(),
936918
Some(io::sqlite_store::SQLITE_BACKUP_DB_FILE_NAME.to_string()),

src/io/sqlite_store/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ mod migrations;
2626
pub const SQLITE_DB_FILE_NAME: &str = "ldk_node_data.sqlite";
2727
/// LDK Node's backup database file name.
2828
pub const SQLITE_BACKUP_DB_FILE_NAME: &str = "ldk_node_data_backup.sqlite";
29+
/// LDK Node's ephemeral database file name.
30+
pub const SQLITE_EPHEMERAL_DB_FILE_NAME: &str = "ldk_node_data_ephemeral.sqlite";
2931
/// LDK Node's table in which we store all data.
3032
pub const KV_TABLE_NAME: &str = "ldk_node_data";
3133

tests/integration_tests_rust.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,18 +3214,4 @@ async fn builder_configures_sqlite_backup_store() {
32143214
}
32153215
}
32163216

3217-
#[cfg(not(feature = "uniffi"))]
3218-
#[test]
3219-
fn sqlite_backup_rejects_primary_storage_path() {
3220-
let mut config = random_config(false);
3221-
config.store_type = TestStoreType::Sqlite;
3222-
3223-
let primary_dir = config.node_config.storage_dir_path.clone();
32243217

3225-
setup_builder!(builder, config.node_config.clone());
3226-
builder.set_backup_storage_dir_path(primary_dir);
3227-
3228-
let res = builder.build(config.node_entropy.into());
3229-
3230-
assert!(matches!(res, Err(ldk_node::BuildError::BackupStorePathConflict)));
3231-
}

0 commit comments

Comments
 (0)