1use alloc::{boxed::Box, string::String};
2use core::error::Error;
3
4use miden_objects::{
5 AccountError, Digest, Felt, ProvenTransactionError, TransactionInputError,
6 TransactionOutputError, account::AccountId, assembly::diagnostics::reporting::PrintDiagnostic,
7 block::BlockNumber, crypto::merkle::SmtProofError, note::NoteId,
8};
9use miden_verifier::VerificationError;
10use thiserror::Error;
11use vm_processor::ExecutionError;
12
13#[derive(Debug, Error)]
17pub enum TransactionExecutorError {
18 #[error("failed to fetch transaction inputs from the data store")]
19 FetchTransactionInputsFailed(#[source] DataStoreError),
20 #[error("foreign account inputs for ID {0} are not anchored on reference block")]
21 ForeignAccountNotAnchoredInReference(AccountId),
22 #[error(
23 "execution options' cycles must be between {min_cycles} and {max_cycles}, but found {actual}"
24 )]
25 InvalidExecutionOptionsCycles {
26 min_cycles: u32,
27 max_cycles: u32,
28 actual: u32,
29 },
30 #[error("failed to create transaction inputs")]
31 InvalidTransactionInputs(#[source] TransactionInputError),
32 #[error("failed to process account update commitment: {0}")]
33 AccountUpdateCommitment(&'static str),
34 #[error(
35 "account delta commitment computed in transaction kernel ({in_kernel_commitment}) does not match account delta computed via the host ({host_commitment})"
36 )]
37 InconsistentAccountDeltaCommitment {
38 in_kernel_commitment: Digest,
39 host_commitment: Digest,
40 },
41 #[error("input account ID {input_id} does not match output account ID {output_id}")]
42 InconsistentAccountId {
43 input_id: AccountId,
44 output_id: AccountId,
45 },
46 #[error("expected account nonce delta to be {expected}, found {actual}")]
47 InconsistentAccountNonceDelta { expected: Felt, actual: Felt },
48 #[error("account witness provided for account ID {0} is invalid")]
49 InvalidAccountWitness(AccountId, #[source] SmtProofError),
50 #[error(
51 "input note {0} was created in a block past the transaction reference block number ({1})"
52 )]
53 NoteBlockPastReferenceBlock(NoteId, BlockNumber),
54 #[error("failed to create transaction host")]
55 TransactionHostCreationFailed(#[source] TransactionHostError),
56 #[error("failed to construct transaction outputs")]
57 TransactionOutputConstructionFailed(#[source] TransactionOutputError),
58 #[error("failed to execute transaction kernel program:\n{}", PrintDiagnostic::new(.0))]
61 TransactionProgramExecutionFailed(ExecutionError),
62}
63
64#[derive(Debug, Error)]
68pub enum TransactionProverError {
69 #[error("failed to apply account delta")]
70 AccountDeltaApplyFailed(#[source] AccountError),
71 #[error("failed to construct transaction outputs")]
72 TransactionOutputConstructionFailed(#[source] TransactionOutputError),
73 #[error("failed to build proven transaction")]
74 ProvenTransactionBuildFailed(#[source] ProvenTransactionError),
75 #[error("failed to execute transaction kernel program:\n{}", PrintDiagnostic::new(.0))]
78 TransactionProgramExecutionFailed(ExecutionError),
79 #[error("failed to create transaction host")]
80 TransactionHostCreationFailed(#[source] TransactionHostError),
81 #[error("{error_msg}")]
83 Other {
84 error_msg: Box<str>,
85 source: Option<Box<dyn Error + Send + Sync + 'static>>,
87 },
88}
89
90impl TransactionProverError {
91 pub fn other(message: impl Into<String>) -> Self {
94 let message: String = message.into();
95 Self::Other { error_msg: message.into(), source: None }
96 }
97
98 pub fn other_with_source(
101 message: impl Into<String>,
102 source: impl Error + Send + Sync + 'static,
103 ) -> Self {
104 let message: String = message.into();
105 Self::Other {
106 error_msg: message.into(),
107 source: Some(Box::new(source)),
108 }
109 }
110}
111
112#[derive(Debug, Error)]
116pub enum TransactionVerifierError {
117 #[error("failed to verify transaction")]
118 TransactionVerificationFailed(#[source] VerificationError),
119 #[error("transaction proof security level is {actual} but must be at least {expected_minimum}")]
120 InsufficientProofSecurityLevel { actual: u32, expected_minimum: u32 },
121}
122
123#[derive(Debug, Error)]
127pub enum TransactionHostError {
128 #[error("{0}")]
129 AccountProcedureIndexMapError(String),
130 #[error("failed to create account procedure info")]
131 AccountProcedureInfoCreationFailed(#[source] AccountError),
132}
133
134#[derive(Debug, Error)]
138pub enum DataStoreError {
139 #[error("account with id {0} not found in data store")]
140 AccountNotFound(AccountId),
141 #[error("block with number {0} not found in data store")]
142 BlockNotFound(BlockNumber),
143 #[error("{error_msg}")]
146 Other {
147 error_msg: Box<str>,
148 source: Option<Box<dyn Error + Send + Sync + 'static>>,
150 },
151}
152
153impl DataStoreError {
154 pub fn other(message: impl Into<String>) -> Self {
156 let message: String = message.into();
157 Self::Other { error_msg: message.into(), source: None }
158 }
159
160 pub fn other_with_source(
163 message: impl Into<String>,
164 source: impl Error + Send + Sync + 'static,
165 ) -> Self {
166 let message: String = message.into();
167 Self::Other {
168 error_msg: message.into(),
169 source: Some(Box::new(source)),
170 }
171 }
172}
173
174#[derive(Debug, Error)]
178pub enum AuthenticationError {
179 #[error("signature rejected: {0}")]
180 RejectedSignature(String),
181 #[error("unknown public key: {0}")]
182 UnknownPublicKey(String),
183 #[error("{error_msg}")]
186 Other {
187 error_msg: Box<str>,
188 source: Option<Box<dyn Error + Send + Sync + 'static>>,
190 },
191}
192
193impl AuthenticationError {
194 pub fn other(message: impl Into<String>) -> Self {
197 let message: String = message.into();
198 Self::Other { error_msg: message.into(), source: None }
199 }
200
201 pub fn other_with_source(
204 message: impl Into<String>,
205 source: impl Error + Send + Sync + 'static,
206 ) -> Self {
207 let message: String = message.into();
208 Self::Other {
209 error_msg: message.into(),
210 source: Some(Box::new(source)),
211 }
212 }
213}
214
215#[cfg(test)]
216mod error_assertions {
217 use super::*;
218
219 fn _assert_error_is_send_sync_static<E: core::error::Error + Send + Sync + 'static>(_: E) {}
221
222 fn _assert_data_store_error_bounds(err: DataStoreError) {
223 _assert_error_is_send_sync_static(err);
224 }
225
226 fn _assert_authentication_error_bounds(err: AuthenticationError) {
227 _assert_error_is_send_sync_static(err);
228 }
229}