stratus/eth/primitives/
logs_bloom.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::ops::Deref;
use std::ops::DerefMut;

use ethereum_types::Bloom;

use crate::alias::AlloyBloom;
use crate::eth::primitives::Log;
use crate::gen_newtype_from;

#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
#[serde(transparent)]
pub struct LogsBloom(pub Bloom);

impl LogsBloom {
    pub fn accrue_log(&mut self, log: &Log) {
        self.accrue(ethereum_types::BloomInput::Raw(log.address.as_ref()));
        for topic in log.topics_non_empty() {
            self.accrue(ethereum_types::BloomInput::Raw(topic.as_ref()));
        }
    }
}

impl Deref for LogsBloom {
    type Target = Bloom;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for LogsBloom {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

// -----------------------------------------------------------------------------
// Conversions: Other -> Self
// -----------------------------------------------------------------------------
gen_newtype_from!(self = LogsBloom, other = [u8; 256], Bloom);

impl From<AlloyBloom> for LogsBloom {
    fn from(value: AlloyBloom) -> Self {
        let bytes: [u8; 256] = *value.0;
        Self(Bloom::from(bytes))
    }
}

// -----------------------------------------------------------------------------
// Conversions: Self -> Other
// -----------------------------------------------------------------------------

impl From<LogsBloom> for Bloom {
    fn from(value: LogsBloom) -> Self {
        value.0
    }
}

impl From<LogsBloom> for [u8; 256] {
    fn from(value: LogsBloom) -> Self {
        value.0 .0
    }
}

impl From<LogsBloom> for AlloyBloom {
    fn from(value: LogsBloom) -> Self {
        AlloyBloom::from(value.0 .0)
    }
}

#[cfg(test)]
mod tests {
    use hex_literal::hex;

    use super::*;

    #[test]
    fn compute_bloom() {
        let log1 = Log {
            address: hex!("c6d1efd908ef6b69da0749600f553923c465c812").into(),
            topic0: Some(hex!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef").into()),
            topic1: Some(hex!("000000000000000000000000d1ff9b395856e5a6810f626eca09d61d34fce3b8").into()),
            topic2: Some(hex!("000000000000000000000000081d2c5b26db6f6e0944e4725b3b61b26e25dd8a").into()),
            topic3: None,
            data: hex!("0000000000000000000000000000000000000000000000000000000005f5e100").as_ref().into(),
        };
        let log2 = Log {
            address: hex!("b1f571b3254c99a0a562124738f0193de2b2b2a9").into(),
            topic0: Some(hex!("8d995e7fbf7a5ef41cee9e6936368925d88e07af89306bb78a698551562e683c").into()),
            topic1: Some(hex!("000000000000000000000000081d2c5b26db6f6e0944e4725b3b61b26e25dd8a").into()),
            topic2: None,
            topic3: None,
            data: hex!(
                "0000000000000000000000000000000000000000000000000000000000004dca00000000\
                0000000000000000000000000000000000000000000000030c9281f0"
            )
            .as_ref()
            .into(),
        };
        let mut bloom = LogsBloom::default();
        bloom.accrue_log(&log1);
        bloom.accrue_log(&log2);

        let expected: LogsBloom = hex!(
            "000000000400000000000000000000000000000000000000000000000000\
        00000000000000000000000000000000000000080000000000000000000000000000000000000000000000000008\
        00008400202000000000002000000000000000000000000000000010000000000000000000000000040000000000\
        00100000000000000000000000000000000000000000000000000000000000000000000000001000000000000100\
        00000000000000000000000000000000000000000000080000000002000000000000000000000000000000002000\
        000000440000000000000000000000000000000000000000000000000000000000000000000000000000"
        )
        .into();

        assert_eq!(bloom, expected);
    }
}