nectar_postage/events.rs
1//! Batch event types for monitoring blockchain events.
2//!
3//! This module provides types for handling postage batch events from the blockchain.
4//! Any node that maintains a batch store (for stamp validation) needs to handle
5//! these events to keep their batch state synchronized with on-chain state.
6
7use crate::{Batch, BatchId};
8
9/// Events emitted by the postage stamp contract.
10///
11/// These events represent state changes to batches on-chain.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum BatchEvent {
14 /// A new batch was created.
15 Created {
16 /// The batch that was created.
17 batch: Batch,
18 },
19
20 /// A batch was topped up with additional funds.
21 TopUp {
22 /// The batch ID.
23 batch_id: BatchId,
24 /// The new normalized balance.
25 new_value: u128,
26 },
27
28 /// A batch was diluted (depth increased).
29 DepthIncrease {
30 /// The batch ID.
31 batch_id: BatchId,
32 /// The new depth.
33 new_depth: u8,
34 },
35
36 /// A batch expired.
37 Expired {
38 /// The batch ID.
39 batch_id: BatchId,
40 },
41}
42
43impl BatchEvent {
44 /// Returns the batch ID associated with this event.
45 pub const fn batch_id(&self) -> BatchId {
46 match self {
47 Self::Created { batch } => batch.id(),
48 Self::TopUp { batch_id, .. } => *batch_id,
49 Self::DepthIncrease { batch_id, .. } => *batch_id,
50 Self::Expired { batch_id } => *batch_id,
51 }
52 }
53}
54
55/// A handler for batch events.
56///
57/// Implementations receive events as they are processed from the blockchain
58/// and update internal state accordingly.
59pub trait BatchEventHandler {
60 /// The error type returned when handling fails.
61 type Error;
62
63 /// Handles a batch event.
64 ///
65 /// Implementations should update any internal state (e.g., batch store)
66 /// based on the event.
67 fn handle_event(&mut self, event: BatchEvent) -> Result<(), Self::Error>;
68
69 /// Handles a batch of events atomically.
70 ///
71 /// The default implementation calls `handle_event` for each event,
72 /// but implementations may override this for better performance
73 /// or transactional semantics.
74 fn handle_events(&mut self, events: Vec<BatchEvent>) -> Result<(), Self::Error> {
75 for event in events {
76 self.handle_event(event)?;
77 }
78 Ok(())
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use alloy_primitives::{Address, B256};
86
87 #[test]
88 fn test_batch_event_batch_id() {
89 let batch = Batch::new(
90 B256::repeat_byte(1),
91 1000,
92 100,
93 Address::ZERO,
94 20,
95 16,
96 false,
97 );
98 let batch_id = batch.id();
99
100 let created = BatchEvent::Created { batch };
101 assert_eq!(created.batch_id(), batch_id);
102
103 let topup = BatchEvent::TopUp {
104 batch_id,
105 new_value: 2000,
106 };
107 assert_eq!(topup.batch_id(), batch_id);
108
109 let depth = BatchEvent::DepthIncrease {
110 batch_id,
111 new_depth: 21,
112 };
113 assert_eq!(depth.batch_id(), batch_id);
114
115 let expired = BatchEvent::Expired { batch_id };
116 assert_eq!(expired.batch_id(), batch_id);
117 }
118}