Skip to content

Commit 532b6bb

Browse files
Merge pull request #18 from DanielSchiavini/journal
fix: Save evm context after errors
2 parents bfd1451 + 999d1ca commit 532b6bb

File tree

5 files changed

+42
-16
lines changed

5 files changed

+42
-16
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ build-prod:
1313

1414
test: build
1515
poetry run pytest -s tests/*
16+
17+
lint:
18+
cargo clippy --workspace --all-targets --all-features
19+
cargo fmt --all

src/evm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,9 @@ impl EVM {
373373
let evm_context: EvmContext<DB> =
374374
replace(&mut self.context, EvmContext::new(DB::new_memory()));
375375
let (result, evm_context) =
376-
call_evm(evm_context, self.handler_cfg, self.tracing, is_static)?;
376+
call_evm(evm_context, self.handler_cfg, self.tracing, is_static);
377377
self.context = evm_context;
378-
self.result = Some(result.clone());
379-
Ok(result)
378+
self.result = result.as_ref().ok().cloned();
379+
result
380380
}
381381
}

src/executor.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use crate::database::DB;
2-
use crate::utils::pyerr;
1+
use std::mem::replace;
2+
33
use pyo3::exceptions::PyRuntimeError;
44
use pyo3::PyResult;
55
use revm::inspectors::TracerEip3155;
@@ -12,18 +12,20 @@ use revm::{
1212
};
1313
use revm_interpreter::primitives::HandlerCfg;
1414
use revm_interpreter::{gas, CallInputs, CreateInputs, SuccessOrHalt};
15-
use std::mem::replace;
15+
16+
use crate::database::DB;
17+
use crate::utils::pyerr;
1618

1719
/// Calls the EVM with the given context and handler configuration.
1820
pub(crate) fn call_evm(
1921
evm_context: EvmContext<DB>,
2022
handler_cfg: HandlerCfg,
2123
tracing: bool,
2224
is_static: bool,
23-
) -> PyResult<(ExecutionResult, EvmContext<DB>)> {
25+
) -> (PyResult<ExecutionResult>, EvmContext<DB>) {
2426
if tracing {
2527
let tracer = TracerEip3155::new(Box::new(crate::pystdout::PySysStdout {}));
26-
let evm = Evm::builder()
28+
let mut evm = Evm::builder()
2729
.with_context_with_handler_cfg(ContextWithHandlerCfg {
2830
cfg: handler_cfg,
2931
context: Context {
@@ -33,9 +35,9 @@ pub(crate) fn call_evm(
3335
})
3436
.append_handler_register(inspector_handle_register)
3537
.build();
36-
run_evm(evm, is_static)
38+
(run_evm(&mut evm, is_static), evm.context.evm)
3739
} else {
38-
let evm = Evm::builder()
40+
let mut evm = Evm::builder()
3941
.with_context_with_handler_cfg(ContextWithHandlerCfg {
4042
cfg: handler_cfg,
4143
context: Context {
@@ -44,15 +46,12 @@ pub(crate) fn call_evm(
4446
},
4547
})
4648
.build();
47-
run_evm(evm, is_static)
49+
(run_evm(&mut evm, is_static), evm.context.evm)
4850
}
4951
}
5052

5153
/// Calls the given evm. This is originally a copy of revm::Evm::transact, but it calls our own output function
52-
fn run_evm<EXT>(
53-
mut evm: Evm<'_, EXT, DB>,
54-
is_static: bool,
55-
) -> PyResult<(ExecutionResult, EvmContext<DB>)> {
54+
fn run_evm<EXT>(evm: &mut Evm<'_, EXT, DB>, is_static: bool) -> PyResult<ExecutionResult> {
5655
let logs_i = evm.context.evm.journaled_state.logs.len();
5756

5857
evm.handler
@@ -137,7 +136,7 @@ fn run_evm<EXT>(
137136
let logs = ctx.evm.journaled_state.logs[logs_i..].to_vec();
138137

139138
// Returns output of transaction.
140-
Ok((output(ctx, result, logs)?, evm.context.evm))
139+
output(ctx, result, logs)
141140
}
142141

143142
fn call_inputs<EXT>(

tests/fixtures/min.bin

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
61003e61000f60003961003e6000f35f3560e01c637ae2b5c781186100365760443610341761003a5760043560243580820382811161003a579050905060405260206040f35b5f5ffd5b5f80fd84183e8000a16576797065728300030b0012
2+
3+
@external
4+
@view
5+
def min(x: uint256, y: uint256) -> uint256:
6+
return x - y

tests/test_evm.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,3 +280,20 @@ def test_get_blobhashes(blob_hashes):
280280

281281
# the contract logs 6 blob hashes, so pad with 0s
282282
assert logged == blob_hashes + [b"\0" * 32] * (6 - len(blob_hashes))
283+
284+
285+
@pytest.mark.parametrize("kwargs", KWARG_CASES)
286+
def test_call_reverting(kwargs):
287+
evm = EVM()
288+
code = load_contract_bin("min.bin")
289+
deploy_address = evm.deploy(address, code)
290+
291+
with pytest.raises(RuntimeError) as err:
292+
evm.message_call(
293+
caller=address,
294+
to=deploy_address,
295+
value=10,
296+
)
297+
298+
assert evm.get_code(deploy_address), "The code should still be deployed after revert"
299+
assert str(err.value).startswith("Transaction(LackOfFundForMaxFee")

0 commit comments

Comments
 (0)