Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion crates/context/interface/src/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::{
cell::{Ref, RefCell},
ops::Range,
};
use std::{rc::Rc, vec::Vec};
use std::{rc::Rc, string::String, vec::Vec};

/// Non-empty, item-pooling Vec.
#[derive(Debug, Clone)]
Expand Down Expand Up @@ -202,6 +202,19 @@ pub trait LocalContextTr {

/// Clear the local context.
fn clear(&mut self);

/// Set the error message for a precompile error, if any.
///
/// This is used to bubble up precompile error messages when the
/// transaction directly targets a precompile (depth == 1).
fn set_precompile_error_context(&mut self, _output: String) {}

/// Take and clear the precompile error context, if present.
///
/// Returns `Some(String)` if a precompile error message was recorded.
fn take_precompile_error_context(&mut self) -> Option<String> {
None
}
}

#[cfg(test)]
Expand Down
4 changes: 3 additions & 1 deletion crates/context/interface/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ pub enum SuccessReason {
/// Indicates that the EVM has experienced an exceptional halt.
///
/// This causes execution to immediately end with all gas being consumed.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum HaltReason {
/// Out of gas error.
Expand All @@ -591,6 +591,8 @@ pub enum HaltReason {
CreateCollision,
/// Precompile error.
PrecompileError,
/// Precompile error with message from context.
PrecompileErrorWithContext(String),
/// Nonce overflow.
NonceOverflow,
/// Create init code size exceeds limit (runtime).
Expand Down
14 changes: 13 additions & 1 deletion crates/context/src/local.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
//! Local context that is filled by execution.
use context_interface::LocalContextTr;
use core::cell::RefCell;
use std::{rc::Rc, vec::Vec};
use std::{rc::Rc, string::String, vec::Vec};

/// Local context that is filled by execution.
#[derive(Clone, Debug)]
pub struct LocalContext {
/// Interpreter shared memory buffer. A reused memory buffer for calls.
pub shared_memory_buffer: Rc<RefCell<Vec<u8>>>,
/// Optional precompile error message to bubble up.
precompile_error_message: Option<String>,
}

impl Default for LocalContext {
fn default() -> Self {
Self {
shared_memory_buffer: Rc::new(RefCell::new(Vec::with_capacity(1024 * 4))),
precompile_error_message: None,
}
}
}
Expand All @@ -22,11 +25,20 @@ impl LocalContextTr for LocalContext {
fn clear(&mut self) {
// Sets len to 0 but it will not shrink to drop the capacity.
unsafe { self.shared_memory_buffer.borrow_mut().set_len(0) };
self.precompile_error_message = None;
}

fn shared_memory_buffer(&self) -> &Rc<RefCell<Vec<u8>>> {
&self.shared_memory_buffer
}

fn set_precompile_error_context(&mut self, output: String) {
self.precompile_error_message = Some(output);
}

fn take_precompile_error_context(&mut self) -> Option<String> {
self.precompile_error_message.take()
}
}

impl LocalContext {
Expand Down
44 changes: 22 additions & 22 deletions crates/ee-tests/src/op_revm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ fn test_halted_tx_call_bn254_pair_granite() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bn254 invalid pair length"
));

compare_or_save_op_testdata("test_halted_tx_call_bn254_pair_granite.json", &output);
Expand Down Expand Up @@ -300,9 +300,9 @@ fn test_halted_tx_call_bls12_381_g1_add_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 g1 add input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -379,9 +379,9 @@ fn test_halted_tx_call_bls12_381_g1_msm_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 g1 msm input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -448,9 +448,9 @@ fn test_halted_tx_call_bls12_381_g1_msm_wrong_input_layout() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 fp 64 top bytes of input are not zero"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -522,9 +522,9 @@ fn test_halted_tx_call_bls12_381_g2_add_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 g2 add input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -601,9 +601,9 @@ fn test_halted_tx_call_bls12_381_g2_msm_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 g2 msm input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -670,9 +670,9 @@ fn test_halted_tx_call_bls12_381_g2_msm_wrong_input_layout() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 fp 64 top bytes of input are not zero"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -744,9 +744,9 @@ fn test_halted_tx_call_bls12_381_pairing_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 pairing input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -810,9 +810,9 @@ fn test_tx_call_bls12_381_pairing_wrong_input_layout() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 fp 64 top bytes of input are not zero"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -894,9 +894,9 @@ fn test_halted_tx_call_bls12_381_map_fp_to_g1_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 map fp to g1 input length error"
));

compare_or_save_op_testdata(
Expand Down Expand Up @@ -978,9 +978,9 @@ fn test_halted_tx_call_bls12_381_map_fp2_to_g2_input_wrong_size() {
assert!(matches!(
output.result,
ExecutionResult::Halt {
reason: OpHaltReason::Base(HaltReason::PrecompileError),
reason: OpHaltReason::Base(HaltReason::PrecompileErrorWithContext(ref msg)),
..
}
} if msg == "bls12-381 map fp2 to g2 input length error"
));

compare_or_save_op_testdata(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 21375,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 g1 add input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 35560,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 g1 msm input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 35560,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 fp 64 top bytes of input are not zero"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 21600,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 g2 add input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 48108,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 g2 msm input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 48108,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 fp 64 top bytes of input are not zero"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 46848,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 map fp2 to g2 input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 27524,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 map fp to g1 input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 97444,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 pairing input length error"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 97444,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bls12-381 fp 64 top bytes of input are not zero"
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"Halt": {
"gas_used": 1824024,
"reason": {
"Base": "PrecompileError"
"Base": {
"PrecompileErrorWithContext": "bn254 invalid pair length"
}
}
}
},
Expand Down
20 changes: 17 additions & 3 deletions crates/handler/src/post_execution.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::FrameResult;
use context_interface::{
journaled_state::JournalTr,
result::{ExecutionResult, HaltReasonTr},
Block, Cfg, ContextTr, Database, Transaction,
result::{ExecutionResult, HaltReason, HaltReasonTr},
Block, Cfg, ContextTr, Database, LocalContextTr, Transaction,
};
use interpreter::{Gas, InitialAndFloorGas, SuccessOrHalt};
use primitives::{hardfork::SpecId, U256};
Expand Down Expand Up @@ -106,7 +106,21 @@ pub fn output<CTX: ContextTr<Journal: JournalTr>, HALTREASON: HaltReasonTr>(
gas_used,
output: output.into_data(),
},
SuccessOrHalt::Halt(reason) => ExecutionResult::Halt { reason, gas_used },
SuccessOrHalt::Halt(reason) => {
// Bubble up precompile errors from context when available
if matches!(
instruction_result.result,
interpreter::InstructionResult::PrecompileError
) {
if let Some(message) = context.local_mut().take_precompile_error_context() {
return ExecutionResult::Halt {
reason: HALTREASON::from(HaltReason::PrecompileErrorWithContext(message)),
gas_used,
};
}
}
ExecutionResult::Halt { reason, gas_used }
}
// Only two internal return flags.
flag @ (SuccessOrHalt::FatalExternalError | SuccessOrHalt::Internal(_)) => {
panic!(
Expand Down
Loading
Loading