snowbridge_ethereum/
receipt.rs1use crate::{Bloom, Log};
4use codec::{Decode, Encode};
5use sp_runtime::RuntimeDebug;
6use sp_std::prelude::*;
7
8#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug)]
9pub struct Receipt {
10 pub post_state_or_status: Vec<u8>,
11 pub cumulative_gas_used: u64,
12 pub bloom: Bloom,
13 pub logs: Vec<Log>,
14}
15
16impl Receipt {
17 pub fn contains_log(&self, log: &Log) -> bool {
18 self.logs.iter().any(|l| l == log)
19 }
20
21 fn decode_list(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
22 let mut iter = rlp.iter();
23
24 let post_state_or_status: Vec<u8> = match iter.next() {
25 Some(data) => data.as_val()?,
26 None => return Err(rlp::DecoderError::Custom("Expected receipt post state or status")),
27 };
28
29 let cumulative_gas_used: u64 = match iter.next() {
30 Some(data) => data.as_val()?,
31 None => return Err(rlp::DecoderError::Custom("Expected receipt cumulative gas used")),
32 };
33
34 let bloom: Bloom = match iter.next() {
35 Some(data) => data.as_val()?,
36 None => return Err(rlp::DecoderError::Custom("Expected receipt bloom")),
37 };
38
39 let logs: Vec<Log> = match iter.next() {
40 Some(data) => data.as_list()?,
41 None => return Err(rlp::DecoderError::Custom("Expected receipt logs")),
42 };
43
44 Ok(Self { post_state_or_status, cumulative_gas_used, bloom, logs })
45 }
46}
47
48impl rlp::Decodable for Receipt {
49 fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
50 if rlp.is_data() {
51 let data = rlp.as_raw();
53 match data[0] {
54 1 | 2 => {
56 let receipt_rlp = &rlp::Rlp::new(&data[1..]);
57 if !receipt_rlp.is_list() {
58 return Err(rlp::DecoderError::RlpExpectedToBeList)
59 }
60 Self::decode_list(&rlp::Rlp::new(&data[1..]))
61 },
62 _ => Err(rlp::DecoderError::Custom("Unsupported receipt type")),
63 }
64 } else if rlp.is_list() {
65 Self::decode_list(rlp)
67 } else {
68 Err(rlp::DecoderError::RlpExpectedToBeList)
69 }
70 }
71}
72
73#[cfg(test)]
74mod tests {
75
76 use super::Receipt;
77 use hex_literal::hex;
78
79 const RAW_RECEIPT: [u8; 1242] = hex!(
80 "
81 f904d701830652f0b901000420000000000000000000008002000000000001000000000001000000
82 00000000000000000000000000000000000000020000000800000000000000002000000000000000
83 00000000000008000000220000000000400010000000000000000000000000000000000000000000
84 00000000000000000004000000001000010000000000080000000000400000000000000000000000
85 00000800000040000000000200000000000200000000000000000000000000000000000000000000
86 04000000000002000000000100000000000000000000000000001000000002000020000010200000
87 000000010000000000000000000000000000000000000010000000f903ccf89b9421130f34829b4c
88 343142047a28ce96ec07814b15f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a116
89 28f55a4df523b3efa00000000000000000000000007d843005c7433c16b27ff939cb37471541561e
90 bda0000000000000000000000000e9c1281aae66801fa35ec404d5f2aea393ff6988a00000000000
91 0000000000000000000000000000000000000000000005d09b7380f89b9421130f34829b4c343142
92 047a28ce96ec07814b15f863a08c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200a
93 c8c7c3b925a00000000000000000000000007d843005c7433c16b27ff939cb37471541561ebda000
94 00000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488da0ffffffffffffffff
95 ffffffffffffffffffffffffffffffffffffffcc840c6920f89b94c02aaa39b223fe8d0a0e5c4f27
96 ead9083c756cc2f863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523
97 b3efa0000000000000000000000000e9c1281aae66801fa35ec404d5f2aea393ff6988a000000000
98 00000000000000007a250d5630b4cf539739df2c5dacb4c659f2488da00000000000000000000000
99 0000000000000000000000000003e973b5a5d1078ef87994e9c1281aae66801fa35ec404d5f2aea3
100 93ff6988e1a01c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1b840
101 000000000000000000000000000000000000000000000000000001f1420ad1d40000000000000000
102 000000000000000000000000000000014ad400879d159a38f8fc94e9c1281aae66801fa35ec404d5
103 f2aea393ff6988f863a0d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159
104 d822a00000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488da000000000
105 00000000000000007a250d5630b4cf539739df2c5dacb4c659f2488db88000000000000000000000
106 000000000000000000000000000000000005d415f332000000000000000000000000000000000000
107 00000000000000000000000000000000000000000000000000000000000000000000000000000000
108 00000000000000000000000000000000000000000000000000000000000003e973b5a5d1078ef87a
109 94c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2f842a07fcf532c15f0a6db0bd6d0e038bea71d
110 30d808c7d98cb3bf7268a95bf5081b65a00000000000000000000000007a250d5630b4cf539739df
111 2c5dacb4c659f2488da000000000000000000000000000000000000000000000000003e973b5a5d1
112 078e
113 "
114 );
115
116 #[test]
117 fn decode_legacy_receipt() {
118 let receipt: Receipt = rlp::decode(&RAW_RECEIPT).unwrap();
119 assert_eq!(receipt.post_state_or_status, vec!(1));
120 assert_eq!(receipt.cumulative_gas_used, 414448);
121 assert_eq!(
122 receipt.bloom,
123 (&hex!(
124 "
125 042000000000000000000000800200000000000100000000000100000000000000000000
126 000000000000000000000000020000000800000000000000002000000000000000000000
127 000000080000002200000000004000100000000000000000000000000000000000000000
128 000000000000000000000400000000100001000000000008000000000040000000000000
129 000000000000000800000040000000000200000000000200000000000000000000000000
130 000000000000000000040000000000020000000001000000000000000000000000000010
131 000000020000200000102000000000000100000000000000000000000000000000000000
132 10000000
133 "
134 ))
135 .into(),
136 );
137 assert_eq!(receipt.logs.len(), 6);
138 }
139}