//! Reporter wrapper that forwards finalization events to the //! simulation harness. //! //! Custom [`EngineDefinition`](super::engine::EngineDefinition) //! implementations should include a [`MonitorReporter`] in their //! reporter chain so the harness can track finalization progress. use super::tracker::FinalizationUpdate; use commonware_actor::Feedback; use commonware_consensus::{Block, Reporter, marshal::Update}; use commonware_cryptography::PublicKey; use commonware_utils::channel::mpsc; /// Wraps another [`Reporter`] and forwards marshal [`Update`] /// finalization events to the simulation harness via a monitor channel. /// /// Place this in the marshal reporter chain so it intercepts /// [`Update::Tip`] events before delegation. #[derive(Clone)] pub struct MonitorReporter { inner: R, monitor: mpsc::UnboundedSender>, pk: P, } impl MonitorReporter { /// Create a new monitor reporter. /// /// - `pk`: the public key of the validator this reporter belongs to. /// - `monitor`: channel for sending finalization updates to the harness. /// - `inner`: the wrapped reporter to delegate to after interception. pub const fn new( pk: P, monitor: mpsc::UnboundedSender>, inner: R, ) -> Self { Self { inner, monitor, pk } } } impl Reporter for MonitorReporter where P: PublicKey, B: Block, R: Reporter>, { type Activity = Update; fn report(&mut self, activity: Self::Activity) -> Feedback { if let Update::Tip(round, height, ref digest) = activity { let _ = self.monitor.send(FinalizationUpdate { pk: self.pk.clone(), round, height, block_digest: digest.as_ref().to_vec(), }); } self.inner.report(activity) } }