eth_valkyoth_protocol/receipt/
error.rs1use core::fmt;
2
3use eth_valkyoth_codec::{DecodeError, DecodeErrorCategory};
4
5#[non_exhaustive]
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum ReceiptField {
9 Payload,
11 StatusOrStateRoot,
13 CumulativeGasUsed,
15 LogsBloom,
17 Logs,
19 LogAddress,
21 LogTopics,
23 LogData,
25}
26
27#[non_exhaustive]
29#[derive(Clone, Copy, Debug, Eq, PartialEq)]
30pub enum ReceiptDecodeError {
31 EmptyInput,
33 UnsupportedReceiptType {
35 type_byte: u8,
37 },
38 ScalarPrefix {
40 prefix: u8,
42 },
43 ReservedPrefix,
45 WrongFieldCount {
47 expected: usize,
49 found: usize,
51 },
52 InvalidLogFieldCount {
54 found: usize,
56 },
57 FieldDecode {
59 field: ReceiptField,
61 source: DecodeError,
63 },
64 InvalidStatusOrStateRoot {
66 found: usize,
68 },
69 InvalidLogsBloomLength {
71 found: usize,
73 },
74 InvalidLogAddressLength {
76 found: usize,
78 },
79 InvalidLogTopicLength {
81 found: usize,
83 },
84}
85
86impl ReceiptDecodeError {
87 #[must_use]
89 pub const fn code(self) -> &'static str {
90 match self {
91 Self::EmptyInput => "ETH_RECEIPT_EMPTY_INPUT",
92 Self::UnsupportedReceiptType { .. } => "ETH_RECEIPT_UNSUPPORTED_TYPE",
93 Self::ScalarPrefix { .. } => "ETH_RECEIPT_SCALAR_PREFIX",
94 Self::ReservedPrefix => "ETH_RECEIPT_RESERVED_PREFIX",
95 Self::WrongFieldCount { .. } => "ETH_RECEIPT_WRONG_FIELD_COUNT",
96 Self::InvalidLogFieldCount { .. } => "ETH_RECEIPT_INVALID_LOG_FIELD_COUNT",
97 Self::FieldDecode { source, .. } => source.code(),
98 Self::InvalidStatusOrStateRoot { .. } => "ETH_RECEIPT_INVALID_STATUS_OR_ROOT",
99 Self::InvalidLogsBloomLength { .. } => "ETH_RECEIPT_INVALID_BLOOM_LENGTH",
100 Self::InvalidLogAddressLength { .. } => "ETH_RECEIPT_INVALID_LOG_ADDRESS_LENGTH",
101 Self::InvalidLogTopicLength { .. } => "ETH_RECEIPT_INVALID_LOG_TOPIC_LENGTH",
102 }
103 }
104
105 #[must_use]
107 pub const fn message(self) -> &'static str {
108 match self {
109 Self::EmptyInput => "receipt input is empty",
110 Self::UnsupportedReceiptType { .. } => {
111 "receipt type is not supported by this receipt decoder"
112 }
113 Self::ScalarPrefix { .. } => "receipt envelope starts with an RLP scalar prefix",
114 Self::ReservedPrefix => "receipt envelope starts with the reserved 0xff prefix",
115 Self::WrongFieldCount { .. } => "receipt must contain exactly four RLP fields",
116 Self::InvalidLogFieldCount { .. } => "receipt log must contain exactly three fields",
117 Self::FieldDecode { .. } => "receipt field failed bounded decoding",
118 Self::InvalidStatusOrStateRoot { .. } => {
119 "receipt status/root field must be status 0 or 1, or a 32-byte root"
120 }
121 Self::InvalidLogsBloomLength { .. } => "receipt logs bloom must be exactly 256 bytes",
122 Self::InvalidLogAddressLength { .. } => "receipt log address must be exactly 20 bytes",
123 Self::InvalidLogTopicLength { .. } => "receipt log topic must be exactly 32 bytes",
124 }
125 }
126
127 #[must_use]
129 pub const fn category(self) -> ReceiptDecodeErrorCategory {
130 match self {
131 Self::UnsupportedReceiptType { .. } => ReceiptDecodeErrorCategory::Unsupported,
132 Self::EmptyInput
133 | Self::ScalarPrefix { .. }
134 | Self::ReservedPrefix
135 | Self::WrongFieldCount { .. }
136 | Self::InvalidLogFieldCount { .. }
137 | Self::InvalidStatusOrStateRoot { .. }
138 | Self::InvalidLogsBloomLength { .. }
139 | Self::InvalidLogAddressLength { .. }
140 | Self::InvalidLogTopicLength { .. } => ReceiptDecodeErrorCategory::MalformedInput,
141 Self::FieldDecode { source, .. } => match source.category() {
142 DecodeErrorCategory::MalformedInput => ReceiptDecodeErrorCategory::MalformedInput,
143 DecodeErrorCategory::ResourceExhaustion => {
144 ReceiptDecodeErrorCategory::ResourceExhaustion
145 }
146 _ => ReceiptDecodeErrorCategory::MalformedInput,
147 },
148 }
149 }
150}
151
152impl fmt::Display for ReceiptDecodeError {
153 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
154 formatter.write_str(self.message())
155 }
156}
157
158#[cfg(feature = "std")]
159impl std::error::Error for ReceiptDecodeError {}
160
161#[non_exhaustive]
163#[derive(Clone, Copy, Debug, Eq, PartialEq)]
164pub enum ReceiptDecodeErrorCategory {
165 MalformedInput,
167 Unsupported,
169 ResourceExhaustion,
171}