Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,11 @@ 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, and the funding
// transaction it builds for a channel it opens, are 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