zksync_error/
identifier.rs1use crate::error::domains::AnvilZksyncCode;
5use crate::error::domains::CompilerCode;
6use crate::error::domains::CoreCode;
7use crate::error::domains::FoundryCode;
8use crate::error::domains::HardhatCode;
9use crate::error::NamedError;
10use crate::kind::DomainCode;
11use crate::kind::Kind;
12#[cfg(not(feature = "std"))]
13use alloc::{format, string::String};
14#[cfg_attr(feature = "use_serde", derive(serde::Serialize, serde::Deserialize))]
15#[derive(Clone, Debug, Eq, PartialEq)]
16pub struct StructuredErrorCode {
17 pub domain_code: u32,
18 pub component_code: u32,
19 pub error_code: u32,
20}
21impl StructuredErrorCode {
22 pub fn encode(&self) -> u32 {
23 self.domain_code * 10000 + self.component_code * 1000 + self.error_code
24 }
25 pub fn decode(raw_code: u32) -> Self {
26 let error_code = raw_code % 1000;
27 let component_code = (raw_code / 1000) % 10;
28 let domain_code = (raw_code / 10000) % 10;
29 StructuredErrorCode {
30 domain_code,
31 component_code,
32 error_code,
33 }
34 }
35}
36#[derive(Clone, Debug, Eq, PartialEq)]
37#[cfg_attr(feature = "use_serde", derive(serde::Serialize, serde::Deserialize))]
38pub struct Identifier {
39 pub kind: Kind,
40 pub code: u32,
41}
42impl Identifier {
43 pub fn new(kind: Kind, code: u32) -> Self {
44 Self { kind, code }
45 }
46 pub fn encode(&self) -> u32 {
47 let domain_code: u32 = self.kind.domain_code();
48 let component_code: u32 = self.kind.component_code();
49 domain_code * 10000 + component_code * 1000 + self.code
50 }
51 pub fn decode(code: StructuredErrorCode) -> Option<Self> {
52 let StructuredErrorCode {
53 domain_code,
54 component_code,
55 error_code,
56 } = code;
57 let domain = DomainCode::from_repr(domain_code)?;
58 let kind: Kind = match domain {
59 DomainCode::AnvilZksync => {
60 Kind::AnvilZksync(AnvilZksyncCode::from_repr(component_code)?)
61 }
62 DomainCode::Compiler => Kind::Compiler(CompilerCode::from_repr(component_code)?),
63 DomainCode::Core => Kind::Core(CoreCode::from_repr(component_code)?),
64 DomainCode::Foundry => Kind::Foundry(FoundryCode::from_repr(component_code)?),
65 DomainCode::Hardhat => Kind::Hardhat(HardhatCode::from_repr(component_code)?),
66 };
67 Some(Identifier {
68 kind,
69 code: error_code,
70 })
71 }
72}
73pub trait Identifying {
74 fn get_identifier_repr(&self) -> String;
75}
76impl Identifying for Identifier {
77 fn get_identifier_repr(&self) -> String {
78 format!("[{}-{}]", self.kind.get_identifier_repr(), self.code)
79 }
80}
81impl Identifying for Kind {
82 fn get_identifier_repr(&self) -> String {
83 match self {
84 Kind::AnvilZksync(AnvilZksyncCode::AnvilEnvironment) => "anvil_zksync-env",
85 Kind::AnvilZksync(AnvilZksyncCode::AnvilGeneric) => "anvil_zksync-generic",
86 Kind::AnvilZksync(AnvilZksyncCode::AnvilNode) => "anvil_zksync-node",
87 Kind::AnvilZksync(AnvilZksyncCode::GasEstimation) => "anvil_zksync-gas_estim",
88 Kind::AnvilZksync(AnvilZksyncCode::Halt) => "anvil_zksync-halt",
89 Kind::AnvilZksync(AnvilZksyncCode::Revert) => "anvil_zksync-revert",
90 Kind::AnvilZksync(AnvilZksyncCode::StateLoader) => "anvil_zksync-state",
91 Kind::AnvilZksync(AnvilZksyncCode::TransactionValidation) => "anvil_zksync-tx_invalid",
92 Kind::Compiler(CompilerCode::LLVM_EVM) => "compiler-llvm+evm",
93 Kind::Compiler(CompilerCode::LLVM_Era) => "compiler-llvm+era",
94 Kind::Compiler(CompilerCode::Solc) => "compiler-solc",
95 Kind::Compiler(CompilerCode::SolcFork) => "compiler-solc+fork",
96 Kind::Compiler(CompilerCode::Zksolc) => "compiler-zksolc",
97 Kind::Compiler(CompilerCode::Zkvyper) => "compiler-zkvyper",
98 Kind::Core(CoreCode::API) => "core-api",
99 Kind::Core(CoreCode::EraVM) => "core-eravm",
100 Kind::Core(CoreCode::ExecutionPlatform) => "core-exec",
101 Kind::Core(CoreCode::Sequencer) => "core-seq",
102 Kind::Foundry(FoundryCode::FoundryUpstream) => "foundry-upstream",
103 Kind::Foundry(FoundryCode::FoundryZksync) => "foundry-zksync",
104 Kind::Hardhat(HardhatCode::HardhatUpstream) => "hardhat-upstream",
105 Kind::Hardhat(HardhatCode::HardhatZksync) => "hardhat-zksync",
106 }
107 .into()
108 }
109}
110impl NamedError for Identifier {
111 fn get_error_name(&self) -> String {
112 match self.kind {
113 Kind::AnvilZksync(AnvilZksyncCode::AnvilEnvironment) => {
114 crate::error::definitions::AnvilEnvironmentCode::from_repr(self.code)
115 .expect("Internal error")
116 .get_error_name()
117 }
118 Kind::AnvilZksync(AnvilZksyncCode::AnvilGeneric) => {
119 crate::error::definitions::AnvilGenericCode::from_repr(self.code)
120 .expect("Internal error")
121 .get_error_name()
122 }
123 Kind::AnvilZksync(AnvilZksyncCode::AnvilNode) => {
124 crate::error::definitions::AnvilNodeCode::from_repr(self.code)
125 .expect("Internal error")
126 .get_error_name()
127 }
128 Kind::AnvilZksync(AnvilZksyncCode::GasEstimation) => {
129 crate::error::definitions::GasEstimationCode::from_repr(self.code)
130 .expect("Internal error")
131 .get_error_name()
132 }
133 Kind::AnvilZksync(AnvilZksyncCode::Halt) => {
134 crate::error::definitions::HaltCode::from_repr(self.code)
135 .expect("Internal error")
136 .get_error_name()
137 }
138 Kind::AnvilZksync(AnvilZksyncCode::Revert) => {
139 crate::error::definitions::RevertCode::from_repr(self.code)
140 .expect("Internal error")
141 .get_error_name()
142 }
143 Kind::AnvilZksync(AnvilZksyncCode::StateLoader) => {
144 crate::error::definitions::StateLoaderCode::from_repr(self.code)
145 .expect("Internal error")
146 .get_error_name()
147 }
148 Kind::AnvilZksync(AnvilZksyncCode::TransactionValidation) => {
149 crate::error::definitions::TransactionValidationCode::from_repr(self.code)
150 .expect("Internal error")
151 .get_error_name()
152 }
153 Kind::Compiler(CompilerCode::LLVM_EVM) => {
154 crate::error::definitions::LLVM_EVMCode::from_repr(self.code)
155 .expect("Internal error")
156 .get_error_name()
157 }
158 Kind::Compiler(CompilerCode::LLVM_Era) => {
159 crate::error::definitions::LLVM_EraCode::from_repr(self.code)
160 .expect("Internal error")
161 .get_error_name()
162 }
163 Kind::Compiler(CompilerCode::Solc) => {
164 crate::error::definitions::SolcCode::from_repr(self.code)
165 .expect("Internal error")
166 .get_error_name()
167 }
168 Kind::Compiler(CompilerCode::SolcFork) => {
169 crate::error::definitions::SolcForkCode::from_repr(self.code)
170 .expect("Internal error")
171 .get_error_name()
172 }
173 Kind::Compiler(CompilerCode::Zksolc) => {
174 crate::error::definitions::ZksolcCode::from_repr(self.code)
175 .expect("Internal error")
176 .get_error_name()
177 }
178 Kind::Compiler(CompilerCode::Zkvyper) => {
179 crate::error::definitions::ZkvyperCode::from_repr(self.code)
180 .expect("Internal error")
181 .get_error_name()
182 }
183 Kind::Core(CoreCode::API) => crate::error::definitions::APICode::from_repr(self.code)
184 .expect("Internal error")
185 .get_error_name(),
186 Kind::Core(CoreCode::EraVM) => {
187 crate::error::definitions::EraVMCode::from_repr(self.code)
188 .expect("Internal error")
189 .get_error_name()
190 }
191 Kind::Core(CoreCode::ExecutionPlatform) => {
192 crate::error::definitions::ExecutionPlatformCode::from_repr(self.code)
193 .expect("Internal error")
194 .get_error_name()
195 }
196 Kind::Core(CoreCode::Sequencer) => {
197 crate::error::definitions::SequencerCode::from_repr(self.code)
198 .expect("Internal error")
199 .get_error_name()
200 }
201 Kind::Foundry(FoundryCode::FoundryUpstream) => {
202 crate::error::definitions::FoundryUpstreamCode::from_repr(self.code)
203 .expect("Internal error")
204 .get_error_name()
205 }
206 Kind::Foundry(FoundryCode::FoundryZksync) => {
207 crate::error::definitions::FoundryZksyncCode::from_repr(self.code)
208 .expect("Internal error")
209 .get_error_name()
210 }
211 Kind::Hardhat(HardhatCode::HardhatUpstream) => {
212 crate::error::definitions::HardhatUpstreamCode::from_repr(self.code)
213 .expect("Internal error")
214 .get_error_name()
215 }
216 Kind::Hardhat(HardhatCode::HardhatZksync) => {
217 crate::error::definitions::HardhatZksyncCode::from_repr(self.code)
218 .expect("Internal error")
219 .get_error_name()
220 }
221 }
222 }
223}
224#[cfg(feature = "runtime_documentation")]
225impl crate::documentation::Documented for Identifier {
226 type Documentation = &'static zksync_error_description::ErrorDocumentation;
227 fn get_documentation(
228 &self,
229 ) -> Result<Option<Self::Documentation>, crate::documentation::DocumentationError> {
230 use crate::documentation::model;
231 let repr = &self.get_identifier_repr();
232 match model.errors.get(repr) {
233 Some(metadata) => Ok(metadata.documentation.as_ref()),
234 None => Err(crate::documentation::DocumentationError::IncompleteModel(
235 format!("Can not fetch description for error {repr}."),
236 )),
237 }
238 }
239}