stratus/eth/primitives/
logs_bloom.rs1use std::ops::Deref;
2use std::ops::DerefMut;
3
4use alloy_primitives::Bloom;
5use alloy_primitives::BloomInput;
6
7use crate::eth::primitives::Log;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
10#[serde(transparent)]
11pub struct LogsBloom(pub Bloom);
12
13impl LogsBloom {
14 pub fn accrue_log(&mut self, log: &Log) {
15 self.accrue(BloomInput::Raw(log.address.as_ref()));
16 for topic in log.topics_non_empty() {
17 self.accrue(BloomInput::Raw(topic.as_ref()));
18 }
19 }
20}
21
22impl Deref for LogsBloom {
23 type Target = Bloom;
24
25 fn deref(&self) -> &Self::Target {
26 &self.0
27 }
28}
29
30impl DerefMut for LogsBloom {
31 fn deref_mut(&mut self) -> &mut Self::Target {
32 &mut self.0
33 }
34}
35
36impl From<[u8; 256]> for LogsBloom {
41 fn from(value: [u8; 256]) -> Self {
42 Self(Bloom::from(value))
43 }
44}
45
46impl From<Bloom> for LogsBloom {
47 fn from(value: Bloom) -> Self {
48 let bytes: [u8; 256] = *value.0;
49 Self(Bloom::from(bytes))
50 }
51}
52
53impl From<LogsBloom> for Bloom {
58 fn from(value: LogsBloom) -> Self {
59 value.0
60 }
61}
62
63impl From<LogsBloom> for [u8; 256] {
64 fn from(value: LogsBloom) -> Self {
65 value.0.into_array()
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use hex_literal::hex;
72
73 use super::*;
74
75 #[test]
76 fn compute_bloom() {
77 let log1 = Log {
78 address: hex!("c6d1efd908ef6b69da0749600f553923c465c812").into(),
79 topic0: Some(hex!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef").into()),
80 topic1: Some(hex!("000000000000000000000000d1ff9b395856e5a6810f626eca09d61d34fce3b8").into()),
81 topic2: Some(hex!("000000000000000000000000081d2c5b26db6f6e0944e4725b3b61b26e25dd8a").into()),
82 topic3: None,
83 data: hex!("0000000000000000000000000000000000000000000000000000000005f5e100").as_ref().into(),
84 };
85 let log2 = Log {
86 address: hex!("b1f571b3254c99a0a562124738f0193de2b2b2a9").into(),
87 topic0: Some(hex!("8d995e7fbf7a5ef41cee9e6936368925d88e07af89306bb78a698551562e683c").into()),
88 topic1: Some(hex!("000000000000000000000000081d2c5b26db6f6e0944e4725b3b61b26e25dd8a").into()),
89 topic2: None,
90 topic3: None,
91 data: hex!(
92 "0000000000000000000000000000000000000000000000000000000000004dca00000000\
93 0000000000000000000000000000000000000000000000030c9281f0"
94 )
95 .as_ref()
96 .into(),
97 };
98 let mut bloom = LogsBloom::default();
99 bloom.accrue_log(&log1);
100 bloom.accrue_log(&log2);
101
102 let expected: LogsBloom = hex!(
103 "000000000400000000000000000000000000000000000000000000000000\
104 00000000000000000000000000000000000000080000000000000000000000000000000000000000000000000008\
105 00008400202000000000002000000000000000000000000000000010000000000000000000000000040000000000\
106 00100000000000000000000000000000000000000000000000000000000000000000000000001000000000000100\
107 00000000000000000000000000000000000000000000080000000002000000000000000000000000000000002000\
108 000000440000000000000000000000000000000000000000000000000000000000000000000000000000"
109 )
110 .into();
111
112 assert_eq!(bloom, expected);
113 }
114}