@nomicfoundation/edr 0.12.0-next.1 → 0.12.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  use std::{collections::HashMap, path::PathBuf};
2
2
 
3
3
  use derive_more::Debug;
4
- use edr_eth::hex;
4
+ use edr_primitives::hex;
5
5
  use edr_solidity_tests::{
6
6
  executors::invariant::InvariantConfig,
7
7
  fuzz::FuzzConfig,
@@ -109,7 +109,7 @@ pub struct SolidityTestRunnerConfigArgs {
109
109
  /// Defaults to false.
110
110
  pub disable_block_gas_limit: Option<bool>,
111
111
  /// The memory limit of the EVM in bytes.
112
- /// Defaults to 33_554_432 (2^25 = 32MiB).
112
+ /// Defaults to `33_554_432` (2^25 = 32MiB).
113
113
  #[serde(serialize_with = "serialize_optional_bigint_as_struct")]
114
114
  pub memory_limit: Option<BigInt>,
115
115
  /// The predeploys applied in local mode. Defaults to no predeploys.
@@ -143,6 +143,8 @@ pub struct SolidityTestRunnerConfigArgs {
143
143
  /// If an invariant config setting is not set, but a corresponding fuzz
144
144
  /// config value is set, then the fuzz config value will be used.
145
145
  pub invariant: Option<InvariantConfigArgs>,
146
+ /// Whether to collect stack traces.
147
+ pub collect_stack_traces: Option<CollectStackTraces>,
146
148
  /// Controls which test results should include execution traces. Defaults to
147
149
  /// None.
148
150
  pub include_traces: Option<IncludeTraces>,
@@ -153,6 +155,11 @@ pub struct SolidityTestRunnerConfigArgs {
153
155
  /// A regex pattern to filter tests. If provided, only test methods that
154
156
  /// match the pattern will be executed and reported as a test result.
155
157
  pub test_pattern: Option<String>,
158
+ /// Controls whether to generate a gas report after running the tests.
159
+ /// Enabling this also enables collection of all traces and EVM isolation
160
+ /// mode.
161
+ /// Defaults to false.
162
+ pub generate_gas_report: Option<bool>,
156
163
  }
157
164
 
158
165
  impl SolidityTestRunnerConfigArgs {
@@ -194,9 +201,11 @@ impl SolidityTestRunnerConfigArgs {
194
201
  prompt_timeout,
195
202
  fuzz,
196
203
  invariant,
204
+ collect_stack_traces,
197
205
  include_traces,
198
206
  observability,
199
207
  test_pattern,
208
+ generate_gas_report,
200
209
  } = self;
201
210
 
202
211
  let test_pattern = TestFilterConfig {
@@ -296,8 +305,13 @@ impl SolidityTestRunnerConfigArgs {
296
305
  cheatcode,
297
306
  fuzz,
298
307
  invariant,
308
+ collect_stack_traces: collect_stack_traces.map_or(
309
+ edr_solidity_tests::CollectStackTraces::OnFailure,
310
+ edr_solidity_tests::CollectStackTraces::from,
311
+ ),
299
312
  on_collected_coverage_fn,
300
313
  test_pattern,
314
+ generate_gas_report,
301
315
  };
302
316
 
303
317
  Ok(config)
@@ -657,24 +671,55 @@ impl From<PathPermission> for foundry_cheatcodes::PathPermission {
657
671
  }
658
672
  }
659
673
 
660
- /// Determines the status of file system access
674
+ /**
675
+ * Determines the level of file system access for the given path.
676
+ *
677
+ * Exact path matching is used for file permissions. Prefix matching is used
678
+ * for directory permissions.
679
+ *
680
+ * Giving write access to configuration files, source files or executables
681
+ * in a project is considered dangerous, because it can be used by malicious
682
+ * Solidity dependencies to escape the EVM sandbox. It is therefore
683
+ * recommended to give write access to specific safe files only. If write
684
+ * access to a directory is needed, please make sure that it doesn't contain
685
+ * configuration files, source files or executables neither in the top level
686
+ * directory, nor in any subdirectories.
687
+ */
661
688
  #[napi]
662
689
  #[derive(Debug, serde::Serialize)]
663
690
  pub enum FsAccessPermission {
664
- /// FS access is allowed with `read` + `write` permission
665
- ReadWrite,
666
- /// Only reading is allowed
667
- Read,
668
- /// Only writing is allowed
669
- Write,
691
+ /// Allows reading and writing the file
692
+ ReadWriteFile,
693
+ /// Only allows reading the file
694
+ ReadFile,
695
+ /// Only allows writing the file
696
+ WriteFile,
697
+ /// Allows reading and writing all files in the directory and its
698
+ /// subdirectories
699
+ DangerouslyReadWriteDirectory,
700
+ /// Allows reading all files in the directory and its subdirectories
701
+ ReadDirectory,
702
+ /// Allows writing all files in the directory and its subdirectories
703
+ DangerouslyWriteDirectory,
670
704
  }
671
705
 
672
706
  impl From<FsAccessPermission> for foundry_cheatcodes::FsAccessPermission {
673
707
  fn from(value: FsAccessPermission) -> Self {
674
708
  match value {
675
- FsAccessPermission::ReadWrite => foundry_cheatcodes::FsAccessPermission::ReadWrite,
676
- FsAccessPermission::Read => foundry_cheatcodes::FsAccessPermission::Read,
677
- FsAccessPermission::Write => foundry_cheatcodes::FsAccessPermission::Write,
709
+ FsAccessPermission::ReadWriteFile => {
710
+ foundry_cheatcodes::FsAccessPermission::ReadWriteFile
711
+ }
712
+ FsAccessPermission::ReadFile => foundry_cheatcodes::FsAccessPermission::ReadFile,
713
+ FsAccessPermission::WriteFile => foundry_cheatcodes::FsAccessPermission::WriteFile,
714
+ FsAccessPermission::DangerouslyReadWriteDirectory => {
715
+ foundry_cheatcodes::FsAccessPermission::DangerouslyReadWriteDirectory
716
+ }
717
+ FsAccessPermission::ReadDirectory => {
718
+ foundry_cheatcodes::FsAccessPermission::ReadDirectory
719
+ }
720
+ FsAccessPermission::DangerouslyWriteDirectory => {
721
+ foundry_cheatcodes::FsAccessPermission::DangerouslyWriteDirectory
722
+ }
678
723
  }
679
724
  }
680
725
  }
@@ -690,6 +735,29 @@ pub struct AddressLabel {
690
735
  pub label: String,
691
736
  }
692
737
 
738
+ /// A type that controls when stack traces are collected.
739
+ #[napi]
740
+ #[derive(Debug, serde::Serialize)]
741
+ pub enum CollectStackTraces {
742
+ /// Always collects stack traces, adding performance overhead.
743
+ Always,
744
+ /// Only collects stack traces upon failure, re-executing the test. This
745
+ /// minimizes performance overhead.
746
+ ///
747
+ /// Not all tests can be re-executed since certain cheatcodes contain
748
+ /// non-deterministic side-effects.
749
+ OnFailure,
750
+ }
751
+
752
+ impl From<CollectStackTraces> for edr_solidity_tests::CollectStackTraces {
753
+ fn from(value: CollectStackTraces) -> Self {
754
+ match value {
755
+ CollectStackTraces::Always => edr_solidity_tests::CollectStackTraces::Always,
756
+ CollectStackTraces::OnFailure => edr_solidity_tests::CollectStackTraces::OnFailure,
757
+ }
758
+ }
759
+ }
760
+
693
761
  /// Configuration for [`SolidityTestRunnerConfigArgs::include_traces`] that
694
762
  /// controls execution trace decoding and inclusion in test results.
695
763
  #[napi]
@@ -1,14 +1,14 @@
1
1
  use std::{collections::BTreeMap, sync::Arc};
2
2
 
3
- use edr_eth::Bytes;
4
3
  use edr_napi_core::solidity::{
5
4
  config::{TestRunnerConfig, TracingConfigWithBuffers},
6
5
  SyncTestRunner, SyncTestRunnerFactory,
7
6
  };
7
+ use edr_primitives::Bytes;
8
8
  use edr_solidity::artifacts::ArtifactId;
9
9
  use edr_solidity_tests::{
10
10
  contracts::ContractsByArtifact, decode::RevertDecoder, evm_context::L1EvmBuilder,
11
- multi_runner::TestContract, revm::context::TxEnv, MultiContractRunner,
11
+ multi_runner::TestContract, MultiContractRunner,
12
12
  };
13
13
  use napi::tokio;
14
14
  use napi_derive::napi;
@@ -33,14 +33,14 @@ impl SyncTestRunnerFactory for L1TestRunnerFactory {
33
33
  let runner = tokio::task::block_in_place(|| {
34
34
  runtime
35
35
  .block_on(MultiContractRunner::<
36
- edr_eth::l1::BlockEnv,
36
+ edr_chain_l1::BlockEnv,
37
37
  (),
38
38
  L1EvmBuilder,
39
- edr_eth::l1::HaltReason,
40
- edr_eth::l1::SpecId,
39
+ edr_chain_l1::HaltReason,
40
+ edr_chain_l1::Hardfork,
41
41
  _,
42
- edr_eth::l1::InvalidTransaction,
43
- TxEnv,
42
+ edr_chain_l1::InvalidTransaction,
43
+ edr_chain_l1::TxEnv,
44
44
  >::new(
45
45
  config.try_into()?,
46
46
  contracts,
@@ -1,11 +1,11 @@
1
1
  use std::{collections::BTreeMap, sync::Arc};
2
2
 
3
- use edr_eth::Bytes;
4
3
  use edr_napi_core::solidity::{
5
4
  config::{TestRunnerConfig, TracingConfigWithBuffers},
6
5
  SyncTestRunner, SyncTestRunnerFactory,
7
6
  };
8
7
  use edr_op::solidity_tests::OpEvmBuilder;
8
+ use edr_primitives::Bytes;
9
9
  use edr_solidity::artifacts::ArtifactId;
10
10
  use edr_solidity_tests::{
11
11
  contracts::ContractsByArtifact, decode::RevertDecoder, multi_runner::TestContract,
@@ -34,14 +34,14 @@ impl SyncTestRunnerFactory for OpTestRunnerFactory {
34
34
  let runner = tokio::task::block_in_place(|| {
35
35
  runtime
36
36
  .block_on(MultiContractRunner::<
37
- edr_eth::l1::BlockEnv,
37
+ edr_op::BlockEnv,
38
38
  _,
39
39
  OpEvmBuilder,
40
- edr_op::OpHaltReason,
41
- edr_op::OpSpecId,
40
+ edr_op::HaltReason,
41
+ edr_op::Hardfork,
42
42
  _,
43
43
  edr_op::transaction::InvalidTransaction,
44
- edr_op::transaction::OpTxEnv<edr_eth::l1::TxEnv>,
44
+ edr_op::transaction::OpTxEnv<edr_chain_l1::TxEnv>,
45
45
  >::new(
46
46
  config.try_into()?,
47
47
  contracts,
@@ -1,6 +1,6 @@
1
1
  use std::sync::{Mutex, OnceLock};
2
2
 
3
- use edr_eth::spec::HaltReasonTrait;
3
+ use edr_evm_spec::HaltReasonTrait;
4
4
  use edr_napi_core::solidity::config::TracingConfigWithBuffers;
5
5
  use edr_solidity::{
6
6
  artifacts::BuildInfoConfigWithBuffers,
@@ -18,6 +18,7 @@ use napi_derive::napi;
18
18
 
19
19
  use crate::{
20
20
  cast::TryCast,
21
+ gas_report::GasReport,
21
22
  solidity_tests::{artifact::ArtifactId, config::IncludeTraces},
22
23
  trace::{solidity_stack_trace::SolidityStackTraceEntry, u256_to_bigint},
23
24
  };
@@ -42,7 +43,7 @@ pub struct ValueSnapshotEntry {
42
43
  pub value: String,
43
44
  }
44
45
 
45
- /// See [edr_solidity_tests::result::SuiteResult]
46
+ /// See [`edr_solidity_tests::result::SuiteResult`]
46
47
  #[napi]
47
48
  #[derive(Clone, Debug)]
48
49
  pub struct SuiteResult {
@@ -50,13 +51,13 @@ pub struct SuiteResult {
50
51
  /// callback
51
52
  #[napi(readonly)]
52
53
  pub id: ArtifactId,
53
- /// See [edr_solidity_tests::result::SuiteResult::duration]
54
+ /// See [`edr_solidity_tests::result::SuiteResult::duration`]
54
55
  #[napi(readonly)]
55
56
  pub duration_ns: BigInt,
56
- /// See [edr_solidity_tests::result::SuiteResult::test_results]
57
+ /// See [`edr_solidity_tests::result::SuiteResult::test_results`]
57
58
  #[napi(readonly)]
58
59
  pub test_results: Vec<TestResult>,
59
- /// See [edr_solidity_tests::result::SuiteResult::warnings]
60
+ /// See [`edr_solidity_tests::result::SuiteResult::warnings`]
60
61
  #[napi(readonly)]
61
62
  pub warnings: Vec<String>,
62
63
  }
@@ -80,29 +81,29 @@ impl SuiteResult {
80
81
  }
81
82
  }
82
83
 
83
- /// See [edr_solidity_tests::result::TestResult]
84
+ /// See [`edr_solidity_tests::result::TestResult`]
84
85
  #[napi]
85
86
  #[derive(Clone, Debug)]
86
87
  pub struct TestResult {
87
88
  /// The name of the test.
88
89
  #[napi(readonly)]
89
90
  pub name: String,
90
- /// See [edr_solidity_tests::result::TestResult::status]
91
+ /// See [`edr_solidity_tests::result::TestResult::status`]
91
92
  #[napi(readonly)]
92
93
  pub status: TestStatus,
93
- /// See [edr_solidity_tests::result::TestResult::reason]
94
+ /// See [`edr_solidity_tests::result::TestResult::reason`]
94
95
  #[napi(readonly)]
95
96
  pub reason: Option<String>,
96
- /// See [edr_solidity_tests::result::TestResult::counterexample]
97
+ /// See [`edr_solidity_tests::result::TestResult::counterexample`]
97
98
  #[napi(readonly)]
98
99
  pub counterexample: Option<Either<BaseCounterExample, CounterExampleSequence>>,
99
- /// See [edr_solidity_tests::result::TestResult::decoded_logs]
100
+ /// See [`edr_solidity_tests::result::TestResult::decoded_logs`]
100
101
  #[napi(readonly)]
101
102
  pub decoded_logs: Vec<String>,
102
- /// See [edr_solidity_tests::result::TestResult::kind]
103
+ /// See [`edr_solidity_tests::result::TestResult::kind`]
103
104
  #[napi(readonly)]
104
105
  pub kind: Either3<StandardTestKind, FuzzTestKind, InvariantTestKind>,
105
- /// See [edr_solidity_tests::result::TestResult::duration]
106
+ /// See [`edr_solidity_tests::result::TestResult::duration`]
106
107
  #[napi(readonly)]
107
108
  pub duration_ns: BigInt,
108
109
  /// Groups of value snapshot entries (incl. gas).
@@ -335,7 +336,7 @@ impl From<edr_solidity_tests::result::TestStatus> for TestStatus {
335
336
  }
336
337
  }
337
338
 
338
- /// See [edr_solidity_tests::result::TestKind::Standard]
339
+ /// See [`edr_solidity_tests::result::TestKind::Standard`]
339
340
  #[napi(object)]
340
341
  #[derive(Debug, Clone)]
341
342
  pub struct StandardTestKind {
@@ -344,22 +345,22 @@ pub struct StandardTestKind {
344
345
  pub consumed_gas: BigInt,
345
346
  }
346
347
 
347
- /// See [edr_solidity_tests::result::TestKind::Fuzz]
348
+ /// See [`edr_solidity_tests::result::TestKind::Fuzz`]
348
349
  #[napi(object)]
349
350
  #[derive(Debug, Clone)]
350
351
  pub struct FuzzTestKind {
351
- /// See [edr_solidity_tests::result::TestKind::Fuzz]
352
+ /// See [`edr_solidity_tests::result::TestKind::Fuzz`]
352
353
  #[napi(readonly)]
353
354
  pub runs: BigInt,
354
- /// See [edr_solidity_tests::result::TestKind::Fuzz]
355
+ /// See [`edr_solidity_tests::result::TestKind::Fuzz`]
355
356
  #[napi(readonly)]
356
357
  pub mean_gas: BigInt,
357
- /// See [edr_solidity_tests::result::TestKind::Fuzz]
358
+ /// See [`edr_solidity_tests::result::TestKind::Fuzz`]
358
359
  #[napi(readonly)]
359
360
  pub median_gas: BigInt,
360
361
  }
361
362
 
362
- /// See [edr_solidity_tests::fuzz::FuzzCase]
363
+ /// See [`edr_solidity_tests::fuzz::FuzzCase`]
363
364
  #[napi(object)]
364
365
  #[derive(Clone)]
365
366
  pub struct FuzzCase {
@@ -383,17 +384,17 @@ impl Debug for FuzzCase {
383
384
  }
384
385
  }
385
386
 
386
- /// See [edr_solidity_tests::result::TestKind::Invariant]
387
+ /// See [`edr_solidity_tests::result::TestKind::Invariant`]
387
388
  #[napi(object)]
388
389
  #[derive(Debug, Clone)]
389
390
  pub struct InvariantTestKind {
390
- /// See [edr_solidity_tests::result::TestKind::Invariant]
391
+ /// See [`edr_solidity_tests::result::TestKind::Invariant`]
391
392
  #[napi(readonly)]
392
393
  pub runs: BigInt,
393
- /// See [edr_solidity_tests::result::TestKind::Invariant]
394
+ /// See [`edr_solidity_tests::result::TestKind::Invariant`]
394
395
  #[napi(readonly)]
395
396
  pub calls: BigInt,
396
- /// See [edr_solidity_tests::result::TestKind::Invariant]
397
+ /// See [`edr_solidity_tests::result::TestKind::Invariant`]
397
398
  #[napi(readonly)]
398
399
  pub reverts: BigInt,
399
400
  }
@@ -409,26 +410,26 @@ pub struct CounterExampleSequence {
409
410
  pub sequence: Vec<BaseCounterExample>,
410
411
  }
411
412
 
412
- /// See [edr_solidity_tests::fuzz::BaseCounterExample]
413
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample`]
413
414
  #[napi(object)]
414
415
  #[derive(Clone)]
415
416
  pub struct BaseCounterExample {
416
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::sender]
417
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::sender`]
417
418
  #[napi(readonly)]
418
419
  pub sender: Option<Uint8Array>,
419
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::addr]
420
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::addr`]
420
421
  #[napi(readonly)]
421
422
  pub address: Option<Uint8Array>,
422
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::calldata]
423
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::calldata`]
423
424
  #[napi(readonly)]
424
425
  pub calldata: Uint8Array,
425
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::contract_name]
426
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::contract_name`]
426
427
  #[napi(readonly)]
427
428
  pub contract_name: Option<String>,
428
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::signature]
429
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::signature`]
429
430
  #[napi(readonly)]
430
431
  pub signature: Option<String>,
431
- /// See [edr_solidity_tests::fuzz::BaseCounterExample::args]
432
+ /// See [`edr_solidity_tests::fuzz::BaseCounterExample::args`]
432
433
  #[napi(readonly)]
433
434
  pub args: Option<String>,
434
435
  }
@@ -470,9 +471,10 @@ pub struct CallTrace {
470
471
  pub gas_used: BigInt,
471
472
  /// The amount of native token that was included with the call.
472
473
  pub value: BigInt,
473
- /// The target of the call. Provided as a contract name if known, otherwise
474
- /// a checksum address.
475
- pub contract: String,
474
+ /// The target address of the call.
475
+ pub address: String,
476
+ /// The name of the contract that is the target of the call, if known.
477
+ pub contract: Option<String>,
476
478
  /// The input (calldata) to the call. If it encodes a known function call,
477
479
  /// it will be decoded into the function name and a list of arguments.
478
480
  /// For example, `{ name: "ownerOf", arguments: ["1"] }`. Note that the
@@ -541,12 +543,8 @@ impl CallTrace {
541
543
  /// Instantiates a `CallTrace` with the details from a node and the supplied
542
544
  /// children.
543
545
  fn new(node: &traces::CallTraceNode, children: Vec<Either<CallTrace, LogTrace>>) -> Self {
544
- let contract = node
545
- .trace
546
- .decoded
547
- .label
548
- .clone()
549
- .unwrap_or(node.trace.address.to_checksum(None));
546
+ let contract = node.trace.decoded.label.clone();
547
+ let address = node.trace.address.to_checksum(None);
550
548
 
551
549
  let inputs = match &node.trace.decoded.call_data {
552
550
  Some(traces::DecodedCallData { signature, args }) => {
@@ -579,6 +577,7 @@ impl CallTrace {
579
577
  gas_used: node.trace.gas_used.into(),
580
578
  value: u256_to_bigint(&node.trace.value),
581
579
  contract,
580
+ address,
582
581
  inputs,
583
582
  outputs,
584
583
  children,
@@ -606,7 +605,10 @@ impl CallTrace {
606
605
  loop {
607
606
  // We will break out of the loop before the stack goes empty.
608
607
  let mut item = stack.pop().unwrap();
609
- let node = &arena.nodes()[item.arena_index];
608
+ let node = arena
609
+ .nodes()
610
+ .get(item.arena_index)
611
+ .expect("Arena index should be valid");
610
612
 
611
613
  if item.visited {
612
614
  let mut logs = node
@@ -620,11 +622,20 @@ impl CallTrace {
620
622
  .iter()
621
623
  .filter_map(|ord| match *ord {
622
624
  traces::TraceMemberOrder::Log(i) => {
623
- let log = logs[i].take().unwrap();
625
+ let log = logs
626
+ .get_mut(i)
627
+ .expect("Log index should be valid")
628
+ .take()
629
+ .unwrap();
624
630
  Some(Either::B(log))
625
631
  }
626
632
  traces::TraceMemberOrder::Call(i) => {
627
- let child_trace = item.child_traces[i].take().unwrap();
633
+ let child_trace = item
634
+ .child_traces
635
+ .get_mut(i)
636
+ .expect("Child trace index should be valid")
637
+ .take()
638
+ .unwrap();
628
639
  Some(Either::A(child_trace))
629
640
  }
630
641
  traces::TraceMemberOrder::Step(_) => None,
@@ -634,7 +645,9 @@ impl CallTrace {
634
645
  let trace = CallTrace::new(node, children);
635
646
 
636
647
  if let Some(parent_stack_index) = item.parent_stack_index {
637
- let parent = &mut stack[parent_stack_index];
648
+ let parent = stack
649
+ .get_mut(parent_stack_index)
650
+ .expect("Parent stack index should be valid");
638
651
  parent.child_traces.push(Some(trace));
639
652
  } else {
640
653
  return trace;
@@ -705,3 +718,19 @@ impl From<traces::CallKind> for CallKind {
705
718
  }
706
719
  }
707
720
  }
721
+
722
+ /// The result of a Solidity test run.
723
+ #[napi(object)]
724
+ pub struct SolidityTestResult {
725
+ /// Gas report, if it was generated.
726
+ #[napi(readonly)]
727
+ pub gas_report: Option<GasReport>,
728
+ }
729
+
730
+ impl From<edr_solidity_tests::multi_runner::SolidityTestResult> for SolidityTestResult {
731
+ fn from(value: edr_solidity_tests::multi_runner::SolidityTestResult) -> Self {
732
+ Self {
733
+ gas_report: value.gas_report.map(GasReport::from),
734
+ }
735
+ }
736
+ }
@@ -9,7 +9,7 @@ pub mod test_results;
9
9
 
10
10
  use std::path::Path;
11
11
 
12
- use edr_eth::Bytes;
12
+ use edr_primitives::Bytes;
13
13
  use edr_solidity::linker::{LinkOutput, Linker};
14
14
  use edr_solidity_tests::{constants::LIBRARY_DEPLOYER, contracts::ContractsByArtifact};
15
15
  use foundry_compilers::artifacts::Libraries;
@@ -1,6 +1,6 @@
1
1
  //! Port of `hardhat-network/stack-traces/debug.ts` from Hardhat.
2
2
 
3
- use napi::bindgen_prelude::Either24;
3
+ use napi::bindgen_prelude::Either25;
4
4
  use napi_derive::napi;
5
5
 
6
6
  use super::solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace};
@@ -11,31 +11,32 @@ fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
11
11
  let entry_values = trace
12
12
  .into_iter()
13
13
  .map(|entry| match entry {
14
- Either24::A(entry) => serde_json::to_value(entry),
15
- Either24::B(entry) => serde_json::to_value(entry),
16
- Either24::C(entry) => serde_json::to_value(entry),
17
- Either24::D(entry) => serde_json::to_value(entry),
18
- Either24::F(entry) => serde_json::to_value(entry),
19
- Either24::G(entry) => serde_json::to_value(entry),
20
- Either24::H(entry) => serde_json::to_value(entry),
21
- Either24::I(entry) => serde_json::to_value(entry),
22
- Either24::J(entry) => serde_json::to_value(entry),
23
- Either24::K(entry) => serde_json::to_value(entry),
24
- Either24::L(entry) => serde_json::to_value(entry),
25
- Either24::M(entry) => serde_json::to_value(entry),
26
- Either24::N(entry) => serde_json::to_value(entry),
27
- Either24::O(entry) => serde_json::to_value(entry),
28
- Either24::P(entry) => serde_json::to_value(entry),
29
- Either24::Q(entry) => serde_json::to_value(entry),
30
- Either24::R(entry) => serde_json::to_value(entry),
31
- Either24::S(entry) => serde_json::to_value(entry),
32
- Either24::T(entry) => serde_json::to_value(entry),
33
- Either24::U(entry) => serde_json::to_value(entry),
34
- Either24::V(entry) => serde_json::to_value(entry),
35
- Either24::W(entry) => serde_json::to_value(entry),
36
- Either24::X(entry) => serde_json::to_value(entry),
14
+ Either25::A(entry) => serde_json::to_value(entry),
15
+ Either25::B(entry) => serde_json::to_value(entry),
16
+ Either25::C(entry) => serde_json::to_value(entry),
17
+ Either25::D(entry) => serde_json::to_value(entry),
18
+ Either25::F(entry) => serde_json::to_value(entry),
19
+ Either25::G(entry) => serde_json::to_value(entry),
20
+ Either25::H(entry) => serde_json::to_value(entry),
21
+ Either25::I(entry) => serde_json::to_value(entry),
22
+ Either25::J(entry) => serde_json::to_value(entry),
23
+ Either25::K(entry) => serde_json::to_value(entry),
24
+ Either25::L(entry) => serde_json::to_value(entry),
25
+ Either25::M(entry) => serde_json::to_value(entry),
26
+ Either25::N(entry) => serde_json::to_value(entry),
27
+ Either25::O(entry) => serde_json::to_value(entry),
28
+ Either25::P(entry) => serde_json::to_value(entry),
29
+ Either25::Q(entry) => serde_json::to_value(entry),
30
+ Either25::R(entry) => serde_json::to_value(entry),
31
+ Either25::S(entry) => serde_json::to_value(entry),
32
+ Either25::T(entry) => serde_json::to_value(entry),
33
+ Either25::U(entry) => serde_json::to_value(entry),
34
+ Either25::V(entry) => serde_json::to_value(entry),
35
+ Either25::W(entry) => serde_json::to_value(entry),
36
+ Either25::X(entry) => serde_json::to_value(entry),
37
+ Either25::Y(entry) => serde_json::to_value(entry),
37
38
  // Decode the error message from the return data
38
- Either24::E(entry @ RevertErrorStackTraceEntry { .. }) => {
39
+ Either25::E(entry @ RevertErrorStackTraceEntry { .. }) => {
39
40
  use serde::de::Error;
40
41
 
41
42
  let decoded_error_msg = ReturnData::new(entry.return_data.clone())
@@ -45,7 +46,9 @@ fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
45
46
  })?;
46
47
 
47
48
  let mut value = serde_json::to_value(entry)?;
48
- value["message"] = decoded_error_msg.into();
49
+ if let Some(obj) = value.as_object_mut() {
50
+ obj.insert("message".to_string(), decoded_error_msg.into());
51
+ }
49
52
  Ok(value)
50
53
  }
51
54
  })
package/src/trace/exit.rs CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  use std::fmt;
5
5
 
6
+ use edr_evm_spec::EvmHaltReason;
6
7
  use napi_derive::napi;
7
8
 
8
9
  #[napi]
@@ -50,20 +51,20 @@ impl fmt::Display for ExitCode {
50
51
  }
51
52
 
52
53
  #[allow(clippy::fallible_impl_from)] // naively ported for now
53
- impl From<edr_solidity::exit_code::ExitCode<edr_eth::l1::HaltReason>> for ExitCode {
54
- fn from(code: edr_solidity::exit_code::ExitCode<edr_eth::l1::HaltReason>) -> Self {
54
+ impl From<edr_solidity::exit_code::ExitCode<EvmHaltReason>> for ExitCode {
55
+ fn from(code: edr_solidity::exit_code::ExitCode<EvmHaltReason>) -> Self {
55
56
  use edr_solidity::exit_code::ExitCode;
56
57
 
57
58
  match code {
58
59
  ExitCode::Success => Self::SUCCESS,
59
60
  ExitCode::Revert => Self::REVERT,
60
- ExitCode::Halt(edr_eth::l1::HaltReason::OutOfGas(_)) => Self::OUT_OF_GAS,
61
- ExitCode::Halt(edr_eth::l1::HaltReason::OpcodeNotFound | edr_eth::l1::HaltReason::InvalidFEOpcode
61
+ ExitCode::Halt(EvmHaltReason::OutOfGas(_)) => Self::OUT_OF_GAS,
62
+ ExitCode::Halt(EvmHaltReason::OpcodeNotFound | EvmHaltReason::InvalidFEOpcode
62
63
  // Returned when an opcode is not implemented for the hardfork
63
- | edr_eth::l1::HaltReason::NotActivated) => Self::INVALID_OPCODE,
64
- ExitCode::Halt(edr_eth::l1::HaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
65
- ExitCode::Halt(edr_eth::l1::HaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
66
- ExitCode::Halt(edr_eth::l1::HaltReason::CreateCollision) => Self::CREATE_COLLISION,
64
+ | EvmHaltReason::NotActivated) => Self::INVALID_OPCODE,
65
+ ExitCode::Halt(EvmHaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
66
+ ExitCode::Halt(EvmHaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
67
+ ExitCode::Halt(EvmHaltReason::CreateCollision) => Self::CREATE_COLLISION,
67
68
  _ => Self::UNKNOWN_HALT_REASON,
68
69
  }
69
70
  }