kaspa_consensus_notify/
notification.rs

1use derive_more::Display;
2use kaspa_consensus_core::{acceptance_data::AcceptanceData, block::Block, utxo::utxo_diff::UtxoDiff};
3use kaspa_hashes::Hash;
4use kaspa_notify::{
5    events::EventType,
6    full_featured,
7    notification::Notification as NotificationTrait,
8    subscription::{
9        context::SubscriptionContext,
10        single::{OverallSubscription, UtxosChangedSubscription, VirtualChainChangedSubscription},
11        Subscription,
12    },
13};
14use std::sync::Arc;
15
16full_featured! {
17#[derive(Clone, Debug, Display)]
18pub enum Notification {
19    #[display(fmt = "BlockAdded notification: block hash {}", "_0.block.header.hash")]
20    BlockAdded(BlockAddedNotification),
21
22    #[display(fmt = "VirtualChainChanged notification: {} removed blocks, {} added blocks, {} accepted transactions", "_0.removed_chain_block_hashes.len()", "_0.added_chain_block_hashes.len()", "_0.added_chain_blocks_acceptance_data.len()")]
23    VirtualChainChanged(VirtualChainChangedNotification),
24
25    #[display(fmt = "FinalityConflict notification: violating block hash {}", "_0.violating_block_hash")]
26    FinalityConflict(FinalityConflictNotification),
27
28    #[display(fmt = "FinalityConflict notification: violating block hash {}", "_0.finality_block_hash")]
29    FinalityConflictResolved(FinalityConflictResolvedNotification),
30
31    #[display(fmt = "UtxosChanged notification")]
32    UtxosChanged(UtxosChangedNotification),
33
34    #[display(fmt = "SinkBlueScoreChanged notification: virtual selected parent blue score {}", "_0.sink_blue_score")]
35    SinkBlueScoreChanged(SinkBlueScoreChangedNotification),
36
37    #[display(fmt = "VirtualDaaScoreChanged notification: virtual DAA score {}", "_0.virtual_daa_score")]
38    VirtualDaaScoreChanged(VirtualDaaScoreChangedNotification),
39
40    #[display(fmt = "PruningPointUtxoSetOverride notification")]
41    PruningPointUtxoSetOverride(PruningPointUtxoSetOverrideNotification),
42
43    #[display(fmt = "NewBlockTemplate notification")]
44    NewBlockTemplate(NewBlockTemplateNotification),
45}
46}
47
48impl NotificationTrait for Notification {
49    fn apply_overall_subscription(&self, subscription: &OverallSubscription, _context: &SubscriptionContext) -> Option<Self> {
50        match subscription.active() {
51            true => Some(self.clone()),
52            false => None,
53        }
54    }
55
56    fn apply_virtual_chain_changed_subscription(
57        &self,
58        subscription: &VirtualChainChangedSubscription,
59        _context: &SubscriptionContext,
60    ) -> Option<Self> {
61        match subscription.active() {
62            true => {
63                // If the subscription excludes accepted transaction ids and the notification includes some
64                // then we must re-create the object and drop the ids, otherwise we can clone it as is.
65                if let Notification::VirtualChainChanged(ref payload) = self {
66                    if !subscription.include_accepted_transaction_ids() && !payload.added_chain_blocks_acceptance_data.is_empty() {
67                        return Some(Notification::VirtualChainChanged(VirtualChainChangedNotification {
68                            removed_chain_block_hashes: payload.removed_chain_block_hashes.clone(),
69                            added_chain_block_hashes: payload.added_chain_block_hashes.clone(),
70                            added_chain_blocks_acceptance_data: Arc::new(vec![]),
71                        }));
72                    }
73                }
74                Some(self.clone())
75            }
76            false => None,
77        }
78    }
79
80    fn apply_utxos_changed_subscription(
81        &self,
82        _subscription: &UtxosChangedSubscription,
83        _context: &SubscriptionContext,
84    ) -> Option<Self> {
85        // No effort is made here to apply the subscription addresses.
86        // This will be achieved farther along the notification backbone.
87        Some(self.clone())
88    }
89
90    fn event_type(&self) -> EventType {
91        self.into()
92    }
93}
94
95#[derive(Debug, Clone)]
96pub struct BlockAddedNotification {
97    pub block: Block,
98}
99
100impl BlockAddedNotification {
101    pub fn new(block: Block) -> Self {
102        Self { block }
103    }
104}
105
106#[derive(Debug, Clone)]
107pub struct VirtualChainChangedNotification {
108    pub added_chain_block_hashes: Arc<Vec<Hash>>,
109    pub removed_chain_block_hashes: Arc<Vec<Hash>>,
110    pub added_chain_blocks_acceptance_data: Arc<Vec<Arc<AcceptanceData>>>,
111}
112impl VirtualChainChangedNotification {
113    pub fn new(
114        added_chain_block_hashes: Arc<Vec<Hash>>,
115        removed_chain_block_hashes: Arc<Vec<Hash>>,
116        added_chain_blocks_acceptance_data: Arc<Vec<Arc<AcceptanceData>>>,
117    ) -> Self {
118        Self { added_chain_block_hashes, removed_chain_block_hashes, added_chain_blocks_acceptance_data }
119    }
120}
121
122#[derive(Debug, Clone, Default)]
123pub struct FinalityConflictNotification {
124    pub violating_block_hash: Hash,
125}
126
127impl FinalityConflictNotification {
128    pub fn new(violating_block_hash: Hash) -> Self {
129        Self { violating_block_hash }
130    }
131}
132
133#[derive(Debug, Clone, Default)]
134pub struct FinalityConflictResolvedNotification {
135    pub finality_block_hash: Hash,
136}
137
138impl FinalityConflictResolvedNotification {
139    pub fn new(finality_block_hash: Hash) -> Self {
140        Self { finality_block_hash }
141    }
142}
143
144#[derive(Debug, Clone)]
145pub struct UtxosChangedNotification {
146    /// Accumulated UTXO diff between the last virtual state and the current virtual state
147    pub accumulated_utxo_diff: Arc<UtxoDiff>,
148    pub virtual_parents: Arc<Vec<Hash>>,
149}
150
151impl UtxosChangedNotification {
152    pub fn new(accumulated_utxo_diff: Arc<UtxoDiff>, virtual_parents: Arc<Vec<Hash>>) -> Self {
153        Self { accumulated_utxo_diff, virtual_parents }
154    }
155}
156
157#[derive(Debug, Clone)]
158pub struct SinkBlueScoreChangedNotification {
159    pub sink_blue_score: u64,
160}
161
162impl SinkBlueScoreChangedNotification {
163    pub fn new(sink_blue_score: u64) -> Self {
164        Self { sink_blue_score }
165    }
166}
167
168#[derive(Debug, Clone)]
169pub struct VirtualDaaScoreChangedNotification {
170    pub virtual_daa_score: u64,
171}
172
173impl VirtualDaaScoreChangedNotification {
174    pub fn new(virtual_daa_score: u64) -> Self {
175        Self { virtual_daa_score }
176    }
177}
178
179#[derive(Debug, Clone, Default)]
180pub struct PruningPointUtxoSetOverrideNotification {}
181
182#[derive(Debug, Clone)]
183pub struct NewBlockTemplateNotification {}