Skip to content

Commit 628327c

Browse files
authored
feat: add custom error to context (bluealloy#2197)
* feat: add custom error to context * nits * add string
1 parent 73e6b83 commit 628327c

File tree

6 files changed

+56
-26
lines changed

6 files changed

+56
-26
lines changed

crates/context/interface/src/context.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub use crate::journaled_state::StateLoad;
22
use crate::{Block, Cfg, Database, JournalTr, Transaction};
33
use auto_impl::auto_impl;
44
use primitives::U256;
5+
use std::string::String;
56

67
#[auto_impl(&mut, Box)]
78
pub trait ContextTr {
@@ -20,10 +21,26 @@ pub trait ContextTr {
2021
fn db(&mut self) -> &mut Self::Db;
2122
fn db_ref(&self) -> &Self::Db;
2223
fn chain(&mut self) -> &mut Self::Chain;
23-
fn error(&mut self) -> &mut Result<(), <Self::Db as Database>::Error>;
24+
fn error(&mut self) -> &mut Result<(), ContextError<<Self::Db as Database>::Error>>;
2425
fn tx_journal(&mut self) -> (&mut Self::Tx, &mut Self::Journal);
2526
}
2627

28+
/// Inner Context error used for Interpreter to set error without returning it frm instruction
29+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
30+
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31+
pub enum ContextError<DbError> {
32+
/// Database error.
33+
Db(DbError),
34+
/// Custom string error.
35+
Custom(String),
36+
}
37+
38+
impl<DbError> From<DbError> for ContextError<DbError> {
39+
fn from(value: DbError) -> Self {
40+
Self::Db(value)
41+
}
42+
}
43+
2744
/// Represents the result of an `sstore` operation.
2845
#[derive(Clone, Debug, Default, PartialEq, Eq)]
2946
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

crates/context/src/context.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{block::BlockEnv, cfg::CfgEnv, journaled_state::Journal, tx::TxEnv};
2-
use context_interface::ContextSetters;
3-
use context_interface::{Block, Cfg, ContextTr, JournalTr, Transaction};
4-
use database_interface::DatabaseRef;
5-
use database_interface::WrapDatabaseRef;
6-
use database_interface::{Database, EmptyDB};
2+
use context_interface::{
3+
context::{ContextError, ContextSetters},
4+
Block, Cfg, ContextTr, JournalTr, Transaction,
5+
};
6+
use database_interface::{Database, DatabaseRef, EmptyDB, WrapDatabaseRef};
77
use derive_where::derive_where;
88
use primitives::hardfork::SpecId;
99

@@ -28,7 +28,7 @@ pub struct Context<
2828
/// Inner context.
2929
pub chain: CHAIN,
3030
/// Error that happened during execution.
31-
pub error: Result<(), <DB as Database>::Error>,
31+
pub error: Result<(), ContextError<DB::Error>>,
3232
}
3333

3434
impl<
@@ -79,7 +79,7 @@ impl<
7979
&mut self.chain
8080
}
8181

82-
fn error(&mut self) -> &mut Result<(), <Self::Db as Database>::Error> {
82+
fn error(&mut self) -> &mut Result<(), ContextError<<Self::Db as Database>::Error>> {
8383
&mut self.error
8484
}
8585

crates/handler/src/frame.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use crate::{
44
FrameInitOrResult, FrameOrResult, ItemOrResult,
55
};
66
use bytecode::{Eof, EOF_MAGIC_BYTES};
7+
use context::result::FromStringError;
8+
use context_interface::context::ContextError;
79
use context_interface::ContextTr;
810
use context_interface::{
911
journaled_state::{JournalCheckpoint, JournalTr},
@@ -80,7 +82,7 @@ where
8082
InterpreterTypes = EthInterpreter,
8183
>,
8284
>,
83-
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError>,
85+
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError> + FromStringError,
8486
{
8587
type Evm = EVM;
8688
type FrameInit = FrameInput;
@@ -520,7 +522,7 @@ where
520522
InterpreterTypes = EthInterpreter,
521523
>,
522524
>,
523-
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError>,
525+
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError> + FromStringError,
524526
{
525527
pub fn init_first(
526528
evm: &mut EVM,
@@ -615,7 +617,11 @@ where
615617

616618
fn return_result(&mut self, evm: &mut EVM, result: FrameResult) -> Result<(), ERROR> {
617619
self.memory.borrow_mut().free_context();
618-
core::mem::replace(evm.ctx().error(), Ok(()))?;
620+
match core::mem::replace(evm.ctx().error(), Ok(())) {
621+
Err(ContextError::Db(e)) => return Err(e.into()),
622+
Err(ContextError::Custom(e)) => return Err(ERROR::from_string(e)),
623+
Ok(_) => (),
624+
}
619625

620626
// Insert result to the top frame.
621627
match result {

crates/handler/src/handler.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ use crate::{
33
execution, post_execution, pre_execution, validation, Frame, FrameInitOrResult, FrameOrResult,
44
FrameResult, ItemOrResult,
55
};
6+
use context::result::FromStringError;
67
use context::JournalOutput;
8+
use context_interface::context::ContextError;
79
use context_interface::ContextTr;
810
use context_interface::{
911
result::{HaltReasonTr, InvalidHeader, InvalidTransaction, ResultAndState},
1012
Cfg, Database, JournalTr, Transaction,
1113
};
12-
use core::mem;
1314
use interpreter::{FrameInput, Gas, InitialAndFloorGas};
1415
use precompile::PrecompileError;
1516
use std::{vec, vec::Vec};
@@ -19,6 +20,7 @@ pub trait EvmTrError<EVM: EvmTr>:
1920
+ From<InvalidHeader>
2021
+ From<<<EVM::Context as ContextTr>::Db as Database>::Error>
2122
+ From<PrecompileError>
23+
+ FromStringError
2224
{
2325
}
2426

@@ -27,7 +29,8 @@ impl<
2729
T: From<InvalidTransaction>
2830
+ From<InvalidHeader>
2931
+ From<<<EVM::Context as ContextTr>::Db as Database>::Error>
30-
+ From<PrecompileError>,
32+
+ From<PrecompileError>
33+
+ FromStringError,
3134
> EvmTrError<EVM> for T
3235
{
3336
}
@@ -431,9 +434,13 @@ pub trait Handler {
431434
evm: &mut Self::Evm,
432435
result: <Self::Frame as Frame>::FrameResult,
433436
) -> Result<ResultAndState<Self::HaltReason>, Self::Error> {
434-
let ctx = evm.ctx();
435-
mem::replace(ctx.error(), Ok(()))?;
436-
let output = post_execution::output(ctx, result);
437+
match core::mem::replace(evm.ctx().error(), Ok(())) {
438+
Err(ContextError::Db(e)) => return Err(e.into()),
439+
Err(ContextError::Custom(e)) => return Err(Self::Error::from_string(e)),
440+
Ok(_) => (),
441+
}
442+
443+
let output = post_execution::output(evm.ctx(), result);
437444

438445
// Clear journal
439446
evm.ctx().journal().clear();

crates/inspector/src/traits.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{inspect_instructions, Inspector, JournalExt};
2-
use context::{ContextSetters, ContextTr, Evm};
2+
use context::{result::FromStringError, ContextSetters, ContextTr, Evm};
33
use handler::{
44
instructions::InstructionProvider, ContextTrDbError, EthFrame, EvmTr, Frame, FrameInitOrResult,
55
PrecompileProvider,
@@ -86,7 +86,7 @@ where
8686
InterpreterTypes = EthInterpreter,
8787
>,
8888
> + InspectorEvmTr,
89-
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError>,
89+
ERROR: From<ContextTrDbError<EVM::Context>> + From<PrecompileError> + FromStringError,
9090
{
9191
type IT = EthInterpreter;
9292

crates/interpreter/src/host.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl<CTX: ContextTr> Host for CTX {
161161
.db()
162162
.block_hash(requested_number)
163163
.map_err(|e| {
164-
*self.error() = Err(e);
164+
*self.error() = Err(e.into());
165165
})
166166
.ok()
167167
}
@@ -172,7 +172,7 @@ impl<CTX: ContextTr> Host for CTX {
172172
self.journal()
173173
.load_account_delegated(address)
174174
.map_err(|e| {
175-
*self.error() = Err(e);
175+
*self.error() = Err(e.into());
176176
})
177177
.ok()
178178
}
@@ -183,7 +183,7 @@ impl<CTX: ContextTr> Host for CTX {
183183
.load_account(address)
184184
.map(|acc| acc.map(|a| a.info.balance))
185185
.map_err(|e| {
186-
*self.error() = Err(e);
186+
*self.error() = Err(e.into());
187187
})
188188
.ok()
189189
}
@@ -193,7 +193,7 @@ impl<CTX: ContextTr> Host for CTX {
193193
self.journal()
194194
.code(address)
195195
.map_err(|e| {
196-
*self.error() = Err(e);
196+
*self.error() = Err(e.into());
197197
})
198198
.ok()
199199
}
@@ -203,7 +203,7 @@ impl<CTX: ContextTr> Host for CTX {
203203
self.journal()
204204
.code_hash(address)
205205
.map_err(|e| {
206-
*self.error() = Err(e);
206+
*self.error() = Err(e.into());
207207
})
208208
.ok()
209209
}
@@ -213,7 +213,7 @@ impl<CTX: ContextTr> Host for CTX {
213213
self.journal()
214214
.sload(address, index)
215215
.map_err(|e| {
216-
*self.error() = Err(e);
216+
*self.error() = Err(e.into());
217217
})
218218
.ok()
219219
}
@@ -230,7 +230,7 @@ impl<CTX: ContextTr> Host for CTX {
230230
self.journal()
231231
.sstore(address, index, value)
232232
.map_err(|e| {
233-
*self.error() = Err(e);
233+
*self.error() = Err(e.into());
234234
})
235235
.ok()
236236
}
@@ -259,7 +259,7 @@ impl<CTX: ContextTr> Host for CTX {
259259
self.journal()
260260
.selfdestruct(address, target)
261261
.map_err(|e| {
262-
*self.error() = Err(e);
262+
*self.error() = Err(e.into());
263263
})
264264
.ok()
265265
}

0 commit comments

Comments
 (0)