Skip to content

Commit aa4e673

Browse files
committed
Expose PostgreSQL lease contention as a build error
Return KVStoreAlreadyInUse when PostgreSQL lease acquisition reports an occupied store, allowing applications to retry node construction. Keep other setup errors as KVStoreSetupFailed and avoid logging expected contention as a setup failure. Document the new error on both builder interfaces and verify it in the PostgreSQL integration test. Keep lease collision and schema rollback coverage at the store level.
1 parent 904ef71 commit aa4e673

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

‎src/builder.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ pub enum BuildError {
212212
///
213213
/// [`KVStore`]: lightning::util::persist::KVStore
214214
KVStoreSetupFailed,
215+
/// The configured [`KVStore`] is already in use by another node.
216+
KVStoreAlreadyInUse,
215217
/// We failed to setup the onchain wallet.
216218
WalletSetupFailed,
217219
/// We failed to setup the logger.
@@ -254,6 +256,7 @@ impl fmt::Display for BuildError {
254256
Self::WriteFailed => write!(f, "Failed to write to store."),
255257
Self::StoragePathAccessFailed => write!(f, "Failed to access the given storage path."),
256258
Self::KVStoreSetupFailed => write!(f, "Failed to setup KVStore."),
259+
Self::KVStoreAlreadyInUse => write!(f, "KVStore is already in use by another node."),
257260
Self::WalletSetupFailed => write!(f, "Failed to setup onchain wallet."),
258261
Self::LoggerSetupFailed => write!(f, "Failed to setup the logger."),
259262
Self::ChainSourceSetupFailed => write!(f, "Failed to setup the chain source."),
@@ -735,6 +738,9 @@ impl NodeBuilder {
735738
/// The given `kv_table_name` will be used or default to
736739
/// [`DEFAULT_KV_TABLE_NAME`](io::postgres_store::DEFAULT_KV_TABLE_NAME).
737740
///
741+
/// Returns [`BuildError::KVStoreAlreadyInUse`] while another store holds the lease. Callers may
742+
/// retry building after a delay.
743+
///
738744
/// # Warning
739745
///
740746
/// This acquires an exclusive lease for the selected KV table before reading persisted node
@@ -765,6 +771,9 @@ impl NodeBuilder {
765771
Some(Arc::clone(&logger)),
766772
))
767773
.map_err(|e| {
774+
if e.kind() == lightning::io::ErrorKind::AlreadyExists {
775+
return BuildError::KVStoreAlreadyInUse;
776+
}
768777
log_error!(logger, "Failed to set up Postgres store: {e}");
769778
BuildError::KVStoreSetupFailed
770779
})?;
@@ -1332,6 +1341,9 @@ impl Builder {
13321341
/// The given `kv_table_name` will be used or default to
13331342
/// [`DEFAULT_KV_TABLE_NAME`](io::postgres_store::DEFAULT_KV_TABLE_NAME).
13341343
///
1344+
/// Returns [`BuildError::KVStoreAlreadyInUse`] while another store holds the lease. Callers may
1345+
/// retry building after a delay.
1346+
///
13351347
/// # Warning
13361348
///
13371349
/// This acquires an exclusive lease for the selected KV table before reading persisted node

‎tests/integration_tests_postgres.rs‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
mod common;
1111

1212
use common::{configure_chain_source, drop_table, random_chain_source, test_connection_string};
13-
use ldk_node::Builder;
13+
use ldk_node::{BuildError, Builder};
1414

1515
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
1616
async fn channel_full_cycle_with_postgres_store() {
@@ -32,6 +32,14 @@ async fn channel_full_cycle_with_postgres_store() {
3232
None,
3333
)
3434
.unwrap();
35+
let result = builder_a.build_with_postgres_store(
36+
config_a.node_entropy.into(),
37+
test_connection_string(),
38+
None,
39+
Some("channel_cycle_a".to_string()),
40+
None,
41+
);
42+
assert!(matches!(result, Err(BuildError::KVStoreAlreadyInUse)));
3543
node_a.start().unwrap();
3644

3745
println!("\n== Node B ==");

0 commit comments

Comments
 (0)