signet_test_utils/specs/
notif_spec.rs1use crate::{chain::Chain, specs::HostBlockSpec};
2use alloy::consensus::BlobTransactionSidecar;
3use signet_types::primitives::TransactionSigned;
4use std::{collections::BTreeMap, sync::Arc};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum ExExNotification {
9 Committed {
11 new: Arc<Chain>,
13 },
14 Reorged {
16 old: Arc<Chain>,
18 new: Arc<Chain>,
20 },
21 Reverted {
23 old: Arc<Chain>,
25 },
26}
27
28impl ExExNotification {
29 pub fn committed_chain(&self) -> Option<&Arc<Chain>> {
31 match self {
32 ExExNotification::Committed { new } => Some(new),
33 ExExNotification::Reorged { new, .. } => Some(new),
34 ExExNotification::Reverted { .. } => None,
35 }
36 }
37
38 pub fn reverted_chain(&self) -> Option<&Arc<Chain>> {
40 match self {
41 ExExNotification::Reorged { old, .. } => Some(old),
42 ExExNotification::Reverted { old } => Some(old),
43 ExExNotification::Committed { .. } => None,
44 }
45 }
46}
47
48#[derive(Debug, Default)]
50pub struct NotificationSpec {
51 pub old: Vec<HostBlockSpec>,
53 pub new: Vec<HostBlockSpec>,
55}
56
57impl NotificationSpec {
58 pub fn commit_single_block(block: HostBlockSpec) -> Self {
60 Self { old: vec![], new: vec![block] }
61 }
62
63 pub fn revert_single_block(block: HostBlockSpec) -> Self {
65 Self { old: vec![block], new: vec![] }
66 }
67
68 pub fn commit(mut self, block: HostBlockSpec) -> Self {
70 self.new.push(block);
71 self
72 }
73
74 pub fn revert(mut self, block: HostBlockSpec) -> Self {
76 self.old.push(block);
77 self
78 }
79
80 pub fn to_exex_notification(&self) -> NotificationWithSidecars {
82 let mut sidecars = BTreeMap::new();
83
84 let old_chain = if !self.old.is_empty() {
86 let num = self.old[0].block_number();
87 let (mut chain, _sidecar) = self.old[0].to_chain();
88
89 for (i, block) in self.old.iter().enumerate().skip(1) {
91 block.set_block_number(num + i as u64);
92 chain.append_block(block.recovered_block(), block.execution_outcome());
93 }
94 Some(chain)
95 } else {
96 None
97 };
98
99 let new_chain = if !self.new.is_empty() {
100 let num = self.new[0].block_number();
101 let (mut chain, sidecar) = self.new[0].to_chain();
102 if let Some(sidecar) = sidecar {
104 let tx = self.new[0].sealed_block().transactions().last().unwrap().clone();
105 sidecars.insert(num, (sidecar, tx));
106 }
107
108 for (i, block) in self.new.iter().enumerate().skip(1) {
110 block.set_block_number(num + i as u64);
111
112 let execution_outcome = block.execution_outcome();
113
114 if let Some(sidecar) = block.sidecar.clone() {
116 let tx = block.sealed_block().transactions().last().unwrap().clone();
117 sidecars.insert(block.block_number(), (sidecar, tx));
118 }
119
120 chain.append_block(block.recovered_block(), execution_outcome)
121 }
122
123 Some(chain)
124 } else {
125 None
126 };
127
128 match (old_chain, new_chain) {
129 (Some(old_chain), Some(new_chain)) => NotificationWithSidecars {
130 notification: ExExNotification::Reorged {
131 old: Arc::new(old_chain),
132 new: Arc::new(new_chain),
133 },
134 sidecars,
135 },
136 (Some(old_chain), None) => NotificationWithSidecars {
137 notification: ExExNotification::Reverted { old: Arc::new(old_chain) },
138 sidecars,
139 },
140 (None, Some(new_chain)) => NotificationWithSidecars {
141 notification: ExExNotification::Committed { new: Arc::new(new_chain) },
142 sidecars,
143 },
144 (None, None) => panic!("missing old and new chains"),
145 }
146 }
147}
148
149#[derive(Debug, Clone)]
151pub struct NotificationWithSidecars {
152 pub notification: ExExNotification,
154 pub sidecars: BTreeMap<u64, (BlobTransactionSidecar, TransactionSigned)>,
156}
157
158impl NotificationWithSidecars {
159 pub fn commit_single_block(block: HostBlockSpec) -> Self {
161 NotificationSpec::commit_single_block(block).to_exex_notification()
162 }
163
164 pub fn revert_single_block(block: HostBlockSpec) -> Self {
166 NotificationSpec::revert_single_block(block).to_exex_notification()
167 }
168}