From a9ef68e0fa5866780af3898e2c59a503ba1403b1 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Mon, 29 Sep 2025 17:59:01 +0200 Subject: [PATCH 1/4] Remove unused trait --- substrate/client/statement-store/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/substrate/client/statement-store/src/lib.rs b/substrate/client/statement-store/src/lib.rs index e58440eccbbe8..4f295eb4101e1 100644 --- a/substrate/client/statement-store/src/lib.rs +++ b/substrate/client/statement-store/src/lib.rs @@ -488,12 +488,7 @@ impl Store { where Block: BlockT, Block::Hash: From, - Client: ProvideRuntimeApi - + HeaderBackend - + sc_client_api::ExecutorProvider - + Send - + Sync - + 'static, + Client: ProvideRuntimeApi + HeaderBackend + Send + Sync + 'static, Client::Api: ValidateStatement, { let store = Arc::new(Self::new(path, options, client, keystore, prometheus)?); From 1b5a0a25e2d292dfac6e8b63f998e5dc1e89ca58 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Tue, 30 Sep 2025 17:35:14 +0200 Subject: [PATCH 2/4] Fix the deadlock during statements gossiping --- substrate/client/statement-store/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/substrate/client/statement-store/src/lib.rs b/substrate/client/statement-store/src/lib.rs index 4f295eb4101e1..d9b43e26e4e68 100644 --- a/substrate/client/statement-store/src/lib.rs +++ b/substrate/client/statement-store/src/lib.rs @@ -759,7 +759,7 @@ impl StatementStore for Store { fn statements(&self) -> Result> { let index = self.index.read(); let mut result = Vec::with_capacity(index.entries.len()); - for h in self.index.read().entries.keys() { + for h in index.entries.keys() { let encoded = self.db.get(col::STATEMENTS, h).map_err(|e| Error::Db(e.to_string()))?; if let Some(encoded) = encoded { if let Ok(statement) = Statement::decode(&mut encoded.as_slice()) { From 6df5b37345391d174b1215b37d99558e38ac8511 Mon Sep 17 00:00:00 2001 From: Andrei Eres Date: Tue, 30 Sep 2025 11:58:40 +0200 Subject: [PATCH 3/4] Remove unnecessary readings during maintenance --- substrate/client/statement-store/src/lib.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/substrate/client/statement-store/src/lib.rs b/substrate/client/statement-store/src/lib.rs index d9b43e26e4e68..a31258c3616b1 100644 --- a/substrate/client/statement-store/src/lib.rs +++ b/substrate/client/statement-store/src/lib.rs @@ -666,21 +666,25 @@ impl Store { /// Perform periodic store maintenance pub fn maintain(&self) { log::trace!(target: LOG_TARGET, "Started store maintenance"); - let deleted = self.index.write().maintain(self.timestamp()); + let (deleted, active_count, expired_count): (Vec<_>, usize, usize) = { + let mut index = self.index.write(); + let deleted = index.maintain(self.timestamp()); + (deleted, index.entries.len(), index.expired.len()) + }; let deleted: Vec<_> = deleted.into_iter().map(|hash| (col::EXPIRED, hash.to_vec(), None)).collect(); - let count = deleted.len() as u64; + let deleted_count = deleted.len() as u64; if let Err(e) = self.db.commit(deleted) { log::warn!(target: LOG_TARGET, "Error writing to the statement database: {:?}", e); } else { - self.metrics.report(|metrics| metrics.statements_pruned.inc_by(count)); + self.metrics.report(|metrics| metrics.statements_pruned.inc_by(deleted_count)); } log::trace!( target: LOG_TARGET, "Completed store maintenance. Purged: {}, Active: {}, Expired: {}", - count, - self.index.read().entries.len(), - self.index.read().expired.len() + deleted_count, + active_count, + expired_count ); } From 4bfda69f190915b23a8442c07cbadc086de41ef1 Mon Sep 17 00:00:00 2001 From: "cmd[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Sep 2025 16:25:15 +0000 Subject: [PATCH 4/4] Add prdoc --- prdoc/pr_9868.prdoc | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 prdoc/pr_9868.prdoc diff --git a/prdoc/pr_9868.prdoc b/prdoc/pr_9868.prdoc new file mode 100644 index 0000000000000..e59101e133296 --- /dev/null +++ b/prdoc/pr_9868.prdoc @@ -0,0 +1,9 @@ +title: Fix the deadlock during statements gossiping +doc: +- audience: Node Dev + description: |- + During high load the statement store experiences deadlock-like behavior: every second statements were gossiping, locking the index which possibly caused the deadlock. After the fix, the observed behavior no longer occurs. + +crates: +- name: sc-statement-store + bump: patch