Skip to content

Commit e803c4a

Browse files
committed
Merge branch 'master' into dani/parallel-fuzz
2 parents edcc7d1 + aa40ad2 commit e803c4a

File tree

9 files changed

+92
-40
lines changed

9 files changed

+92
-40
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/anvil/src/eth/backend/mem/inspector.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ where
138138
});
139139
}
140140

141+
#[allow(clippy::redundant_clone)]
142+
fn log(&mut self, ecx: &mut CTX, log: Log) {
143+
call_inspectors!([&mut self.tracer, &mut self.log_collector], |inspector| {
144+
inspector.log(ecx, log.clone());
145+
});
146+
}
147+
141148
#[allow(clippy::redundant_clone)]
142149
fn log_full(&mut self, interp: &mut Interpreter, ecx: &mut CTX, log: Log) {
143150
call_inspectors!([&mut self.tracer, &mut self.log_collector], |inspector| {

crates/cheatcodes/src/inspector.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,19 +1197,27 @@ impl Inspector<EthEvmContext<&mut dyn DatabaseExt>> for Cheatcodes {
11971197
}
11981198
}
11991199

1200+
fn log(&mut self, _ecx: Ecx, log: Log) {
1201+
if !self.expected_emits.is_empty()
1202+
&& let Some(err) = expect::handle_expect_emit(self, &log, None)
1203+
{
1204+
// Because we do not have access to the interpreter here, we cannot fail the test
1205+
// immediately. In most cases the failure will still be caught on `call_end`.
1206+
// In the rare case it is not, we log the error here.
1207+
let _ = sh_err!("{err:?}");
1208+
}
1209+
1210+
// `recordLogs`
1211+
record_logs(&mut self.recorded_logs, &log);
1212+
}
1213+
12001214
fn log_full(&mut self, interpreter: &mut Interpreter, _ecx: Ecx, log: Log) {
12011215
if !self.expected_emits.is_empty() {
1202-
expect::handle_expect_emit(self, &log, interpreter);
1216+
expect::handle_expect_emit(self, &log, Some(interpreter));
12031217
}
12041218

12051219
// `recordLogs`
1206-
if let Some(storage_recorded_logs) = &mut self.recorded_logs {
1207-
storage_recorded_logs.push(Vm::Log {
1208-
topics: log.data.topics().to_vec(),
1209-
data: log.data.data.clone(),
1210-
emitter: log.address,
1211-
});
1212-
}
1220+
record_logs(&mut self.recorded_logs, &log);
12131221
}
12141222

12151223
fn call(&mut self, ecx: Ecx, inputs: &mut CallInputs) -> Option<CallOutcome> {
@@ -2436,6 +2444,17 @@ fn access_is_call(kind: crate::Vm::AccountAccessKind) -> bool {
24362444
)
24372445
}
24382446

2447+
/// Records a log into the recorded logs vector, if it exists.
2448+
fn record_logs(recorded_logs: &mut Option<Vec<Vm::Log>>, log: &Log) {
2449+
if let Some(storage_recorded_logs) = recorded_logs {
2450+
storage_recorded_logs.push(Vm::Log {
2451+
topics: log.data.topics().to_vec(),
2452+
data: log.data.data.clone(),
2453+
emitter: log.address,
2454+
});
2455+
}
2456+
}
2457+
24392458
/// Appends an AccountAccess that resumes the recording of the current context.
24402459
fn append_storage_access(
24412460
last: &mut Vec<AccountAccess>,

crates/cheatcodes/src/test/expect.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -793,8 +793,12 @@ fn expect_emit(
793793
pub(crate) fn handle_expect_emit(
794794
state: &mut Cheatcodes,
795795
log: &alloy_primitives::Log,
796-
interpreter: &mut Interpreter,
797-
) {
796+
mut interpreter: Option<&mut Interpreter>,
797+
) -> Option<&'static str> {
798+
// This function returns an optional string indicating a failure reason.
799+
// If the string is `Some`, it indicates that the expectation failed with the provided reason.
800+
let mut should_fail = None;
801+
798802
// Fill or check the expected emits.
799803
// We expect for emit checks to be filled as they're declared (from oldest to newest),
800804
// so we fill them and push them to the back of the queue.
@@ -806,7 +810,7 @@ pub(crate) fn handle_expect_emit(
806810
// This allows a contract to arbitrarily emit more events than expected (additive behavior),
807811
// as long as all the previous events were matched in the order they were expected to be.
808812
if state.expected_emits.iter().all(|(expected, _)| expected.found) {
809-
return;
813+
return should_fail;
810814
}
811815

812816
// Check count=0 expectations against this log - fail immediately if violated
@@ -818,14 +822,19 @@ pub(crate) fn handle_expect_emit(
818822
// Check revert address
819823
&& (expected_emit.address.is_none() || expected_emit.address == Some(log.address))
820824
{
821-
// This event was emitted but we expected it NOT to be (count=0)
822-
// Fail immediately
823-
interpreter.bytecode.set_action(InterpreterAction::new_return(
824-
InstructionResult::Revert,
825-
Error::encode("log emitted 1 time, expected 0"),
826-
interpreter.gas,
827-
));
828-
return;
825+
if let Some(interpreter) = &mut interpreter {
826+
// This event was emitted but we expected it NOT to be (count=0)
827+
// Fail immediately
828+
interpreter.bytecode.set_action(InterpreterAction::new_return(
829+
InstructionResult::Revert,
830+
Error::encode("log emitted but expected 0 times"),
831+
interpreter.gas,
832+
));
833+
} else {
834+
should_fail = Some("log emitted but expected 0 times");
835+
}
836+
837+
return should_fail;
829838
}
830839
}
831840

@@ -850,7 +859,7 @@ pub(crate) fn handle_expect_emit(
850859
if !should_fill_logs
851860
&& state.expected_emits.iter().all(|(emit, _)| emit.found || emit.count == 0)
852861
{
853-
return;
862+
return should_fail;
854863
}
855864

856865
let (mut event_to_fill_or_check, mut count_map) = state
@@ -867,14 +876,17 @@ pub(crate) fn handle_expect_emit(
867876
state
868877
.expected_emits
869878
.insert(index_to_fill_or_check, (event_to_fill_or_check, count_map));
870-
} else {
879+
} else if let Some(interpreter) = &mut interpreter {
871880
interpreter.bytecode.set_action(InterpreterAction::new_return(
872881
InstructionResult::Revert,
873882
Error::encode("use vm.expectEmitAnonymous to match anonymous events"),
874883
interpreter.gas,
875884
));
885+
} else {
886+
should_fail = Some("use vm.expectEmitAnonymous to match anonymous events");
876887
}
877-
return;
888+
889+
return should_fail;
878890
};
879891

880892
// Increment/set `count` for `log.address` and `log.data`
@@ -953,6 +965,8 @@ pub(crate) fn handle_expect_emit(
953965
// appear.
954966
state.expected_emits.push_front((event_to_fill_or_check, count_map));
955967
}
968+
969+
should_fail
956970
}
957971

958972
/// Handles expected emits specified by the `expectEmit` cheatcodes.

crates/evm/evm/src/inspectors/logs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use revm::{
66
Inspector,
77
context::ContextTr,
88
interpreter::{
9-
CallInputs, CallOutcome, Gas, InstructionResult, Interpreter, InterpreterResult,
9+
CallInputs, CallOutcome, Gas, InstructionResult, InterpreterResult,
1010
interpreter::EthInterpreter,
1111
},
1212
};
@@ -50,7 +50,7 @@ impl<CTX> Inspector<CTX, EthInterpreter> for LogCollector
5050
where
5151
CTX: ContextTr,
5252
{
53-
fn log_full(&mut self, _interp: &mut Interpreter, _context: &mut CTX, log: Log) {
53+
fn log(&mut self, _context: &mut CTX, log: Log) {
5454
self.logs.push(log);
5555
}
5656

crates/evm/evm/src/inspectors/stack.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,14 @@ impl Inspector<EthEvmContext<&mut dyn DatabaseExt>> for InspectorStackRefMut<'_>
908908
self.step_end_inlined(interpreter, ecx);
909909
}
910910

911+
#[allow(clippy::redundant_clone)]
912+
fn log(&mut self, ecx: &mut EthEvmContext<&mut dyn DatabaseExt>, log: Log) {
913+
call_inspectors!(
914+
[&mut self.tracer, &mut self.log_collector, &mut self.cheatcodes, &mut self.printer],
915+
|inspector| inspector.log(ecx, log.clone()),
916+
);
917+
}
918+
911919
#[allow(clippy::redundant_clone)]
912920
fn log_full(
913921
&mut self,
@@ -1195,6 +1203,10 @@ impl Inspector<EthEvmContext<&mut dyn DatabaseExt>> for InspectorStack {
11951203
self.as_mut().initialize_interp(interpreter, ecx)
11961204
}
11971205

1206+
fn log(&mut self, ecx: &mut EthEvmContext<&mut dyn DatabaseExt>, log: Log) {
1207+
self.as_mut().log(ecx, log)
1208+
}
1209+
11981210
fn log_full(
11991211
&mut self,
12001212
interpreter: &mut Interpreter,

crates/forge/assets/solidity/workflowTemplate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
permissions:
1818
contents: read
1919
steps:
20-
- uses: actions/checkout@v5
20+
- uses: actions/checkout@v6
2121
with:
2222
persist-credentials: false
2323
submodules: recursive

crates/forge/assets/vyper/workflowTemplate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
permissions:
1818
contents: read
1919
steps:
20-
- uses: actions/checkout@v5
20+
- uses: actions/checkout@v6
2121
with:
2222
persist-credentials: false
2323
submodules: recursive

crates/forge/tests/cli/failure_assertions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ Suite result: FAILED. 0 passed; 15 failed; 0 skipped; [ELAPSED]
231231
[FAIL: log != expected log] testShouldFailCountEmitsFromAddress() ([GAS])
232232
[FAIL: log != expected log] testShouldFailCountLessEmits() ([GAS])
233233
[FAIL: log != expected Something] testShouldFailEmitSomethingElse() ([GAS])
234-
[FAIL: log emitted 1 time, expected 0] testShouldFailNoEmit() ([GAS])
235-
[FAIL: log emitted 1 time, expected 0] testShouldFailNoEmitFromAddress() ([GAS])
234+
[FAIL: log emitted but expected 0 times] testShouldFailNoEmit() ([GAS])
235+
[FAIL: log emitted but expected 0 times] testShouldFailNoEmitFromAddress() ([GAS])
236236
Suite result: FAILED. 0 passed; 5 failed; 0 skipped; [ELAPSED]
237237
...
238238
"#,

0 commit comments

Comments
 (0)