Skip to content
Open
9 changes: 9 additions & 0 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use lightning_dns_resolver::OMDomainResolver;
use vss_client::headers::VssHeaderProvider;

use crate::chain::ChainSource;
use crate::channel::SpliceTracker;
#[cfg(feature = "chain-bitcoind")]
use crate::config::BitcoindRestClientConfig;
use crate::config::{
Expand Down Expand Up @@ -2565,6 +2566,13 @@ fn build_with_store_internal(
})
});

let splice_tracker = Arc::new(SpliceTracker::new(
Arc::clone(&channel_manager),
Arc::clone(&wallet),
Arc::clone(&pending_payment_store),
Arc::clone(&logger),
));

#[cfg(cycle_tests)]
let mut _leak_checker = crate::LeakChecker(Vec::new());
#[cfg(cycle_tests)]
Expand Down Expand Up @@ -2616,6 +2624,7 @@ fn build_with_store_internal(
payment_store,
forwarding_store,
forwarded_payment_aggregation_retention_secs,
splice_tracker,
lnurl_auth,
is_running,
node_metrics,
Expand Down
1,670 changes: 1,670 additions & 0 deletions src/channel/mod.rs

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,10 @@ pub(crate) const CHANNEL_TX_FACTS_MAX_RECORD_BYTES: usize = 128 * 1024;
// Records are dropped only once the channels they belong to have resolved, so between prunes a
// counterparty opening and closing channels, or replacing a negotiated funding again and again,
// drives the store's growth. Past this many records the store is full and the transactions
// it would have described go unclassified, which is bounded loss of detail rather than unbounded
// storage.
// it would have described go unclassified, which is bounded loss of detail rather than
// unbounded storage. An interactive funding round this node is about to sign is admitted beside
// them: how many of those there are is this node's own decision, and refusing one would cost a
// figure that is never corrected rather than a detail.
pub(crate) const CHANNEL_TX_FACTS_MAX_RECORDS: usize = 100_000;

// The number of pages of channel transaction provenance records one chain tip change examines.
Expand Down
24 changes: 8 additions & 16 deletions src/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,12 @@ where
self.mutate_with(id, |current| async move { Ok(f(current.as_ref())) }).await
}

async fn mutate_with<F, Fut>(&self, id: &SO::Id, f: F) -> Result<Option<SO>, Error>
/// Like [`Self::mutate`], but allows the transformation to await fallible reads.
///
/// The mutation lock remains held while `f` runs. This is useful when the new state must be
/// decided from an async read of another store without letting a concurrent writer invalidate
/// that decision. Callers must keep cross-store lock ordering consistent to avoid deadlocks.
pub(crate) async fn mutate_with<F, Fut>(&self, id: &SO::Id, f: F) -> Result<Option<SO>, Error>
where
F: FnOnce(Option<SO>) -> Fut,
Fut: Future<Output = Result<Option<SO>, Error>>,
Expand All @@ -470,19 +475,6 @@ where
Ok(Some(new_object))
}

/// Like [`Self::mutate`], but allows the transformation to await fallible reads.
///
/// The mutation lock remains held while `f` runs. This is useful when the new state must be
/// decided from an async read of another store without letting a concurrent writer invalidate
/// that decision. Callers must keep cross-store lock ordering consistent to avoid deadlocks.
pub(crate) async fn mutate_async<F, Fut>(&self, id: &SO::Id, f: F) -> Result<Option<SO>, Error>
where
F: FnOnce(Option<SO>) -> Fut,
Fut: Future<Output = Result<Option<SO>, Error>>,
{
self.mutate_with(id, f).await
}

/// Returns whether an object is stored under `id`.
pub(crate) async fn contains_key(&self, id: &SO::Id) -> Result<bool, Error> {
let _guard = self.mutation_lock.read().await;
Expand Down Expand Up @@ -1260,7 +1252,7 @@ mod tests {
}

#[tokio::test]
async fn mutate_async_awaits_fallible_reads() {
async fn mutate_with_awaits_fallible_reads() {
let store: Arc<DynStore> = Arc::new(DynStoreWrapper(InMemoryStore::new()));
let logger = Arc::new(TestLogger::new());
let id = TestObjectId { id: [42u8; 4] };
Expand All @@ -1285,7 +1277,7 @@ mod tests {
);

let result = data_store
.mutate_async(&id, |existing| async move {
.mutate_with(&id, |existing| async move {
let mut updated = existing.unwrap();
updated.data = other_store.get(&other_id).await?.unwrap().data;
Ok(Some(updated))
Expand Down
Loading
Loading