From 8cfc430b01733428c697e189fabaef242031c1ca Mon Sep 17 00:00:00 2001 From: Dusk1e <135010814+Dusk1e@users.noreply.github.com> Date: Sat, 12 Sep 2026 19:30:52 +0300 Subject: [PATCH] fix(consensus-db): declare count with Self::Error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every method across the six repository traits and the pruning service is declared with Self::Error. PendingProposalsRepository::count is the one exception: it hardcodes StoreError. That is a compile error rather than a style point. The trait cannot be implemented by anything whose Error is not StoreError — an implementor returning its own error type from count fails with E0271. It also leaves the generated mock, built with Error = std::io::Error, returning io::Error from enforce_limit and StoreError from count. The blanket impl for &T carried the same signature and now forwards Self::Error as well. Store is unaffected, its Error already is StoreError. --- .../src/repositories/pending_proposals.rs | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/crates/consensus-db/src/repositories/pending_proposals.rs b/crates/consensus-db/src/repositories/pending_proposals.rs index 45ab98bc..b4e8e271 100644 --- a/crates/consensus-db/src/repositories/pending_proposals.rs +++ b/crates/consensus-db/src/repositories/pending_proposals.rs @@ -32,7 +32,7 @@ pub trait PendingProposalsRepository { ) -> Result, Self::Error>; /// Return the total number of stored pending proposal parts. - async fn count(&self) -> Result; + async fn count(&self) -> Result; } impl PendingProposalsRepository for &T @@ -51,7 +51,7 @@ where .await } - async fn count(&self) -> Result { + async fn count(&self) -> Result { (**self).count().await } } @@ -68,7 +68,46 @@ impl PendingProposalsRepository for Store { .await } - async fn count(&self) -> Result { + async fn count(&self) -> Result { self.get_pending_proposal_parts_count().await } } + +#[cfg(test)] +mod tests { + use super::*; + + #[derive(Debug, thiserror::Error)] + #[error("count failed")] + struct CountError; + + /// An implementor whose error type is not `StoreError`, which is the point + /// of the associated `Error` type. + struct FailingCount; + + impl PendingProposalsRepository for FailingCount { + type Error = CountError; + + async fn enforce_limit( + &self, + _max_pending_proposals: usize, + _current_height: Height, + ) -> Result, Self::Error> { + Ok(Vec::new()) + } + + async fn count(&self) -> Result { + Err(CountError) + } + } + + #[tokio::test] + async fn count_reports_the_implementor_error_type() { + let repo = FailingCount; + assert!(matches!(repo.count().await, Err(CountError))); + + // The blanket impl for `&T` forwards the same error type. + let by_ref = &repo; + assert!(matches!(by_ref.count().await, Err(CountError))); + } +}