openzeppelin_monitor/models/blockchain/
mod.rs1use serde::{Deserialize, Serialize};
8use std::fmt;
9
10pub mod evm;
11pub mod midnight;
12pub mod solana;
13pub mod stellar;
14
15#[derive(Debug, Clone)]
17pub struct SignatureRules {
18 pub requires_parentheses: bool,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
24#[serde(deny_unknown_fields)]
25pub enum BlockChainType {
26 EVM,
28 Stellar,
30 Midnight,
32 Solana,
34}
35
36impl BlockChainType {
37 pub fn signature_rules(&self) -> SignatureRules {
43 match self {
44 BlockChainType::EVM | BlockChainType::Stellar | BlockChainType::Midnight => {
45 SignatureRules {
46 requires_parentheses: true,
47 }
48 }
49 BlockChainType::Solana => SignatureRules {
50 requires_parentheses: false,
51 },
52 }
53 }
54}
55
56impl fmt::Display for BlockChainType {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self {
59 BlockChainType::EVM => write!(f, "EVM"),
60 BlockChainType::Stellar => write!(f, "Stellar"),
61 BlockChainType::Midnight => write!(f, "Midnight"),
62 BlockChainType::Solana => write!(f, "Solana"),
63 }
64 }
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
69pub enum BlockType {
70 EVM(Box<evm::EVMBlock>),
75 Stellar(Box<stellar::StellarBlock>),
80 Midnight(Box<midnight::MidnightBlock>),
85 Solana(Box<solana::SolanaBlock>),
90}
91
92impl BlockType {
93 pub fn number(&self) -> Option<u64> {
94 match self {
95 BlockType::EVM(b) => b.number(),
96 BlockType::Stellar(b) => b.number(),
97 BlockType::Midnight(b) => b.number(),
98 BlockType::Solana(b) => b.number(),
99 }
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105#[allow(clippy::large_enum_variant)]
106pub enum TransactionType {
107 EVM(evm::EVMTransaction),
109 Stellar(Box<stellar::StellarTransaction>),
111 Midnight(midnight::MidnightTransaction),
113 Solana(Box<solana::SolanaTransaction>),
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
119#[serde(untagged)]
120pub enum ContractSpec {
121 EVM(evm::EVMContractSpec),
123 Stellar(stellar::StellarContractSpec),
125 Midnight,
127 Solana(solana::SolanaContractSpec),
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub enum MonitorMatch {
134 EVM(Box<evm::EVMMonitorMatch>),
139 Stellar(Box<stellar::StellarMonitorMatch>),
144 Midnight(Box<midnight::MidnightMonitorMatch>),
149 Solana(Box<solana::SolanaMonitorMatch>),
154}
155
156#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Default)]
158pub struct ChainConfiguration {
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub midnight: Option<midnight::MidnightMonitorConfig>,
162
163 #[serde(skip_serializing_if = "Option::is_none")]
165 pub evm: Option<evm::EVMMonitorConfig>,
166
167 #[serde(skip_serializing_if = "Option::is_none")]
169 pub stellar: Option<stellar::StellarMonitorConfig>,
170
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub solana: Option<solana::SolanaMonitorConfig>,
174}
175
176#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct ProcessedBlock {
181 pub block_number: u64,
182 pub network_slug: String,
183 pub processing_results: Vec<MonitorMatch>,
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn test_block_type_number_evm() {
192 use alloy::rpc::types::{Block, Header};
193
194 let evm_block = evm::EVMBlock::from(Block {
195 header: Header {
196 inner: alloy::consensus::Header {
197 number: 12345,
198 ..Default::default()
199 },
200 ..Default::default()
201 },
202 ..Default::default()
203 });
204
205 let block_type = BlockType::EVM(Box::new(evm_block));
206 assert_eq!(block_type.number(), Some(12345));
207 }
208
209 #[test]
210 fn test_block_type_number_solana() {
211 let solana_block = solana::SolanaBlock::from(solana::SolanaConfirmedBlock {
212 slot: 999888777,
213 blockhash: "test_hash".to_string(),
214 previous_blockhash: "prev_hash".to_string(),
215 parent_slot: 999888776,
216 block_time: Some(1234567890),
217 block_height: Some(100000),
218 transactions: vec![],
219 });
220
221 let block_type = BlockType::Solana(Box::new(solana_block));
222 assert_eq!(block_type.number(), Some(999888777));
223 }
224
225 #[test]
226 fn test_block_type_number_stellar() {
227 let stellar_block = stellar::StellarBlock::from(stellar::StellarLedgerInfo {
228 sequence: 54321,
229 hash: "stellar_hash".to_string(),
230 ledger_close_time: "2024-01-01T00:00:00Z".to_string(),
231 ledger_header: "base64header".to_string(),
232 ledger_header_json: None,
233 ledger_metadata: "base64metadata".to_string(),
234 ledger_metadata_json: None,
235 });
236
237 let block_type = BlockType::Stellar(Box::new(stellar_block));
238 assert_eq!(block_type.number(), Some(54321));
239 }
240
241 #[test]
242 fn test_block_type_number_midnight() {
243 let midnight_block = midnight::MidnightBlock::from(midnight::MidnightRpcBlock {
244 header: midnight::MidnightBlockHeader {
245 parent_hash: "0xparent_hash".to_string(),
246 number: "0x12fd1".to_string(), state_root: "0xstate_root".to_string(),
248 extrinsics_root: "0xextrinsics_root".to_string(),
249 digest: midnight::MidnightBlockDigest { logs: vec![] },
250 },
251 body: vec![],
252 transactions_index: vec![],
253 });
254
255 let block_type = BlockType::Midnight(Box::new(midnight_block));
256 assert_eq!(block_type.number(), Some(77777));
257 }
258
259 #[test]
260 fn test_blockchain_type_variants() {
261 assert_eq!(BlockChainType::EVM, BlockChainType::EVM);
263 assert_eq!(BlockChainType::Stellar, BlockChainType::Stellar);
264 assert_eq!(BlockChainType::Midnight, BlockChainType::Midnight);
265 assert_eq!(BlockChainType::Solana, BlockChainType::Solana);
266
267 assert_ne!(BlockChainType::EVM, BlockChainType::Solana);
269 assert_ne!(BlockChainType::Stellar, BlockChainType::Midnight);
270 }
271
272 #[test]
273 fn test_signature_rules() {
274 let evm_rules = BlockChainType::EVM.signature_rules();
276 assert!(evm_rules.requires_parentheses);
277
278 let stellar_rules = BlockChainType::Stellar.signature_rules();
280 assert!(stellar_rules.requires_parentheses);
281
282 let midnight_rules = BlockChainType::Midnight.signature_rules();
284 assert!(midnight_rules.requires_parentheses);
285
286 let solana_rules = BlockChainType::Solana.signature_rules();
288 assert!(!solana_rules.requires_parentheses);
289 }
290
291 #[test]
292 fn test_blockchain_type_display() {
293 assert_eq!(format!("{}", BlockChainType::EVM), "EVM");
294 assert_eq!(format!("{}", BlockChainType::Stellar), "Stellar");
295 assert_eq!(format!("{}", BlockChainType::Midnight), "Midnight");
296 assert_eq!(format!("{}", BlockChainType::Solana), "Solana");
297 }
298}