openzeppelin_monitor/utils/tests/builders/midnight/
block.rs1use crate::models::{
2 MidnightBaseTransaction, MidnightBlock, MidnightBlockDigest, MidnightBlockHeader,
3 MidnightRpcBlock, MidnightRpcTransactionEnum,
4};
5
6#[derive(Debug)]
8pub struct BlockBuilder {
9 header: MidnightBlockHeader,
10 body: Vec<MidnightRpcTransactionEnum>,
11 transactions_index: Vec<(String, String)>,
12}
13
14impl Default for BlockBuilder {
15 fn default() -> Self {
17 Self {
18 header: MidnightBlockHeader {
19 parent_hash: "0x0000000000000000000000000000000000000000000000000000000000000000"
20 .to_string(),
21 number: "0".to_string(),
22 state_root: "0x0000000000000000000000000000000000000000000000000000000000000000"
23 .to_string(),
24 extrinsics_root:
25 "0x0000000000000000000000000000000000000000000000000000000000000000".to_string(),
26 digest: MidnightBlockDigest { logs: vec![] },
27 },
28 body: vec![],
29 transactions_index: vec![],
30 }
31 }
32}
33
34impl BlockBuilder {
35 pub fn new() -> Self {
37 Self::default()
38 }
39
40 pub fn header(mut self, header: MidnightBlockHeader) -> Self {
42 self.header = header;
43 self
44 }
45
46 pub fn number(mut self, number: u64) -> Self {
48 self.header.number = format!("0x{:x}", number);
49 self
50 }
51
52 pub fn parent_hash(mut self, parent_hash: String) -> Self {
54 self.header.parent_hash = parent_hash;
55 self
56 }
57
58 pub fn body(mut self, body: Vec<MidnightRpcTransactionEnum>) -> Self {
60 self.body = body;
61 self
62 }
63
64 pub fn add_transaction(mut self, transaction: MidnightRpcTransactionEnum) -> Self {
66 self.body.push(transaction);
67 self
68 }
69
70 pub fn add_rpc_transaction(mut self, transaction: MidnightBaseTransaction) -> Self {
72 let tx_hash = transaction.clone().tx_hash;
73 let tx_operation = MidnightRpcTransactionEnum::MidnightTransaction {
74 tx_raw: "".to_string(),
75 tx: transaction,
76 };
77
78 self.body.push(tx_operation.clone());
79
80 self.transactions_index.push((tx_hash, "".to_string()));
83 self
84 }
85
86 pub fn transactions_index(mut self, transactions_index: Vec<(String, String)>) -> Self {
88 self.transactions_index = transactions_index;
89 self
90 }
91
92 pub fn build(self) -> MidnightBlock {
94 let base_block = MidnightRpcBlock {
95 header: self.header,
96 body: self.body,
97 transactions_index: self.transactions_index,
98 };
99
100 MidnightBlock::from(base_block)
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::utils::tests::builders::midnight::transaction::TransactionBuilder;
108
109 #[test]
110 fn test_builder_default() {
111 let block = BlockBuilder::new().build();
112 assert_eq!(block.header.number, "0");
113 assert_eq!(
114 block.header.parent_hash,
115 "0x0000000000000000000000000000000000000000000000000000000000000000"
116 );
117 assert_eq!(
118 block.header.state_root,
119 "0x0000000000000000000000000000000000000000000000000000000000000000"
120 );
121 assert_eq!(
122 block.header.extrinsics_root,
123 "0x0000000000000000000000000000000000000000000000000000000000000000"
124 );
125 assert!(block.body.is_empty());
126 assert!(block.transactions_index.is_empty());
127 }
128
129 #[test]
130 fn test_builder_with_header() {
131 let header = MidnightBlockHeader {
132 number: "123".to_string(),
133 parent_hash: "0xabc".to_string(),
134 ..Default::default()
135 };
136 let block = BlockBuilder::new().header(header.clone()).build();
137 assert_eq!(block.header, header);
138 }
139
140 #[test]
141 fn test_builder_with_number() {
142 let number = 123u64;
143 let block = BlockBuilder::new().number(number).build();
144 assert_eq!(block.header.number, format!("0x{:x}", number));
145 }
146
147 #[test]
148 fn test_builder_with_parent_hash() {
149 let parent_hash = "0xabc".to_string();
150 let block = BlockBuilder::new().parent_hash(parent_hash.clone()).build();
151 assert_eq!(block.header.parent_hash, parent_hash);
152 }
153
154 #[test]
155 fn test_builder_with_body() {
156 let tx1 = TransactionBuilder::new()
157 .add_call_operation("0x123".to_string(), "main".to_string())
158 .build();
159 let tx2 = TransactionBuilder::new()
160 .add_deploy_operation("0x456".to_string())
161 .build();
162
163 let body = vec![
164 MidnightRpcTransactionEnum::MidnightTransaction {
165 tx_raw: "".to_string(),
166 tx: tx1.into(),
167 },
168 MidnightRpcTransactionEnum::MidnightTransaction {
169 tx_raw: "".to_string(),
170 tx: tx2.into(),
171 },
172 ];
173
174 let block = BlockBuilder::new().body(body.clone()).build();
175 assert_eq!(block.body, body);
176 }
177
178 #[test]
179 fn test_builder_add_transaction() {
180 let tx = TransactionBuilder::new()
181 .add_call_operation("0x123".to_string(), "main".to_string())
182 .build();
183
184 let rpc_tx = MidnightRpcTransactionEnum::MidnightTransaction {
185 tx_raw: "".to_string(),
186 tx: tx.into(),
187 };
188
189 let block = BlockBuilder::new().add_transaction(rpc_tx.clone()).build();
190 assert_eq!(block.body, vec![rpc_tx]);
191 }
192
193 #[test]
194 fn test_builder_add_rpc_transaction() {
195 let tx = TransactionBuilder::new()
196 .add_call_operation("0x123".to_string(), "main".to_string())
197 .build();
198
199 let block = BlockBuilder::new()
200 .add_rpc_transaction(tx.clone().into())
201 .build();
202 assert_eq!(
203 block.body,
204 vec![MidnightRpcTransactionEnum::MidnightTransaction {
205 tx_raw: "".to_string(),
206 tx: tx.into(),
207 }]
208 );
209 }
210
211 #[test]
212 fn test_builder_with_transactions_index() {
213 let transactions_index = vec![
214 ("0x123".to_string(), "0xabc".to_string()),
215 ("0x456".to_string(), "0xdef".to_string()),
216 ];
217 let block = BlockBuilder::new()
218 .transactions_index(transactions_index.clone())
219 .build();
220 assert_eq!(block.transactions_index, transactions_index);
221 }
222
223 #[test]
224 fn test_builder_complete_block() {
225 let tx1 = TransactionBuilder::new()
227 .add_call_operation("0x123".to_string(), "main".to_string())
228 .build();
229 let tx2 = TransactionBuilder::new()
230 .add_deploy_operation("0x456".to_string())
231 .build();
232
233 let transactions_index = vec![
235 ("0x123".to_string(), "0xabc".to_string()),
236 ("0x456".to_string(), "0xdef".to_string()),
237 ];
238
239 let block = BlockBuilder::new()
241 .number(123)
242 .parent_hash("0xparent".to_string())
243 .add_rpc_transaction(tx1.into())
244 .add_rpc_transaction(tx2.into())
245 .transactions_index(transactions_index.clone())
246 .build();
247
248 assert_eq!(block.header.number, "0x7b");
250 assert_eq!(block.header.parent_hash, "0xparent");
251 assert_eq!(block.body.len(), 2);
252 assert_eq!(block.transactions_index, transactions_index);
253 }
254
255 #[test]
256 fn test_builder_multiple_transactions() {
257 let tx1 = TransactionBuilder::new()
258 .add_call_operation("0x123".to_string(), "main".to_string())
259 .build();
260 let tx2 = TransactionBuilder::new()
261 .add_deploy_operation("0x456".to_string())
262 .build();
263 let tx3 = TransactionBuilder::new()
264 .add_fallible_coins_operation()
265 .build();
266
267 let block = BlockBuilder::new()
268 .add_rpc_transaction(tx1.into())
269 .add_rpc_transaction(tx2.into())
270 .add_rpc_transaction(tx3.into())
271 .build();
272
273 assert_eq!(block.body.len(), 3);
274 }
275}