@nomicfoundation/edr 0.6.5 → 0.8.0

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,271 +1,11 @@
1
1
  //! Port of `hardhat-network/stack-traces/debug.ts` from Hardhat.
2
2
 
3
- use edr_eth::U256;
4
- use edr_evm::{hex, interpreter::OpCode};
5
- use edr_solidity::build_model::JumpType;
6
- use napi::{
7
- bindgen_prelude::{Either24, Either3, Either4},
8
- Either, Env,
9
- };
3
+ use napi::bindgen_prelude::Either24;
10
4
  use napi_derive::napi;
11
5
 
12
- use super::{
13
- message_trace::{CallMessageTrace, CreateMessageTrace, PrecompileMessageTrace},
14
- solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace},
15
- };
6
+ use super::solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace};
16
7
  use crate::trace::return_data::ReturnData;
17
8
 
18
- const MARGIN_SPACE: usize = 6;
19
-
20
- #[napi]
21
- fn print_message_trace(
22
- trace: Either3<PrecompileMessageTrace, CallMessageTrace, CreateMessageTrace>,
23
- depth: Option<u32>,
24
- env: Env,
25
- ) -> napi::Result<()> {
26
- let trace = match &trace {
27
- Either3::A(precompile) => Either3::A(precompile),
28
- Either3::B(call) => Either3::B(call),
29
- Either3::C(create) => Either3::C(create),
30
- };
31
-
32
- let depth = depth.unwrap_or(0);
33
-
34
- print_message_trace_inner(trace, depth, env)
35
- }
36
-
37
- fn print_message_trace_inner(
38
- trace: Either3<&PrecompileMessageTrace, &CallMessageTrace, &CreateMessageTrace>,
39
- depth: u32,
40
- env: Env,
41
- ) -> napi::Result<()> {
42
- println!();
43
-
44
- match trace {
45
- Either3::A(precompile) => print_precompile_trace(precompile, depth),
46
- Either3::B(call) => print_call_trace(call, depth, env)?,
47
- Either3::C(create) => print_create_trace(create, depth, env)?,
48
- }
49
-
50
- println!();
51
-
52
- Ok(())
53
- }
54
-
55
- fn print_precompile_trace(trace: &PrecompileMessageTrace, depth: u32) {
56
- let margin = " ".repeat(depth as usize * MARGIN_SPACE);
57
-
58
- let value = U256::from_limbs_slice(&trace.value.words);
59
-
60
- println!("{margin}Precompile trace");
61
-
62
- println!("{margin} precompile number: {}", trace.precompile);
63
- println!("{margin} value: {value}");
64
- println!(
65
- "{margin} calldata: {}",
66
- hex::encode_prefixed(&*trace.calldata)
67
- );
68
-
69
- if trace.exit.is_error() {
70
- println!("{margin} error: {}", trace.exit.get_reason());
71
- }
72
-
73
- println!(
74
- "{margin} returnData: {}",
75
- hex::encode_prefixed(&*trace.return_data)
76
- );
77
- }
78
-
79
- fn print_call_trace(trace: &CallMessageTrace, depth: u32, env: Env) -> napi::Result<()> {
80
- let margin = " ".repeat(depth as usize * MARGIN_SPACE);
81
-
82
- println!("{margin}Call trace");
83
-
84
- if let Some(bytecode) = &trace.bytecode {
85
- let contract = bytecode.contract.borrow();
86
- let file = contract.location.file();
87
- let file = file.borrow();
88
-
89
- println!(
90
- "{margin} calling contract: {}:{}",
91
- file.source_name, contract.name
92
- );
93
- } else {
94
- println!(
95
- "{margin} unrecognized contract code: {:?}",
96
- hex::encode_prefixed(&*trace.code)
97
- );
98
- println!(
99
- "{margin} contract: {}",
100
- hex::encode_prefixed(&*trace.address)
101
- );
102
- }
103
-
104
- println!(
105
- "{margin} value: {}",
106
- U256::from_limbs_slice(&trace.value.words)
107
- );
108
- println!(
109
- "{margin} calldata: {}",
110
- hex::encode_prefixed(&*trace.calldata)
111
- );
112
-
113
- if trace.exit.is_error() {
114
- println!("{margin} error: {}", trace.exit.get_reason());
115
- }
116
-
117
- println!(
118
- "{margin} returnData: {}",
119
- hex::encode_prefixed(&*trace.return_data)
120
- );
121
-
122
- trace_steps(Either::A(trace), depth, env)
123
- }
124
-
125
- fn print_create_trace(trace: &CreateMessageTrace, depth: u32, env: Env) -> napi::Result<()> {
126
- let margin = " ".repeat(depth as usize * MARGIN_SPACE);
127
-
128
- println!("{margin}Create trace");
129
-
130
- if let Some(bytecode) = &trace.bytecode {
131
- let contract = bytecode.contract.borrow();
132
-
133
- println!("{margin} deploying contract: {}", contract.name);
134
- println!("{margin} code: {}", hex::encode_prefixed(&*trace.code));
135
- } else {
136
- println!(
137
- "{margin} unrecognized deployment code: {}",
138
- hex::encode_prefixed(&*trace.code)
139
- );
140
- }
141
-
142
- println!(
143
- "{margin} value: {}",
144
- U256::from_limbs_slice(&trace.value.words)
145
- );
146
-
147
- if let Some(Either::A(deployed_contract)) = &trace.deployed_contract {
148
- println!(
149
- "{margin} contract address: {}",
150
- hex::encode_prefixed(deployed_contract)
151
- );
152
- }
153
-
154
- if trace.exit.is_error() {
155
- println!("{margin} error: {}", trace.exit.get_reason());
156
- // The return data is the deployed-bytecode if there was no error, so we don't
157
- // show it
158
- println!(
159
- "{margin} returnData: {}",
160
- hex::encode_prefixed(&*trace.return_data)
161
- );
162
- }
163
-
164
- trace_steps(Either::B(trace), depth, env)?;
165
-
166
- Ok(())
167
- }
168
-
169
- fn trace_steps(
170
- trace: Either<&CallMessageTrace, &CreateMessageTrace>,
171
- depth: u32,
172
- env: Env,
173
- ) -> napi::Result<()> {
174
- let margin = " ".repeat(depth as usize * MARGIN_SPACE);
175
-
176
- println!("{margin} steps:");
177
- println!();
178
-
179
- let (bytecode, steps) = match &trace {
180
- Either::A(call) => (&call.bytecode, &call.steps),
181
- Either::B(create) => (&create.bytecode, &create.steps),
182
- };
183
-
184
- for step in steps {
185
- let step = match step {
186
- Either4::A(step) => step,
187
- trace @ (Either4::B(..) | Either4::C(..) | Either4::D(..)) => {
188
- let trace = match trace {
189
- Either4::A(..) => unreachable!(),
190
- Either4::B(precompile) => Either3::A(precompile),
191
- Either4::C(call) => Either3::B(call),
192
- Either4::D(create) => Either3::C(create),
193
- };
194
-
195
- print_message_trace_inner(trace, depth + 1, env)?;
196
- continue;
197
- }
198
- };
199
-
200
- let pc = format!("{:>5}", format!("{:03}", step.pc));
201
-
202
- if let Some(bytecode) = bytecode {
203
- let inst = bytecode.get_instruction(step.pc)?;
204
-
205
- let location = inst
206
- .location
207
- .as_ref()
208
- .map(|inst_location| {
209
- let inst_location = &inst_location;
210
- let file = inst_location.file();
211
- let file = file.borrow();
212
-
213
- let mut location_str = file.source_name.clone();
214
-
215
- if let Some(func) = inst_location.get_containing_function() {
216
- let file = func.location.file();
217
- let file = file.borrow();
218
-
219
- let source_name = func
220
- .contract_name
221
- .as_ref()
222
- .unwrap_or_else(|| &file.source_name);
223
-
224
- location_str += &format!(":{source_name}:{}", func.name);
225
- }
226
- location_str +=
227
- &format!(" - {}:{}", inst_location.offset, inst_location.length);
228
-
229
- napi::Result::Ok(location_str)
230
- })
231
- .transpose()?
232
- .unwrap_or_default();
233
-
234
- if matches!(inst.opcode, OpCode::JUMP | OpCode::JUMPI) {
235
- let jump = if inst.jump_type == JumpType::NotJump {
236
- "".to_string()
237
- } else {
238
- format!("({})", inst.jump_type)
239
- };
240
-
241
- let entry = format!("{margin} {pc} {opcode} {jump}", opcode = inst.opcode);
242
-
243
- println!("{entry:<50}{location}");
244
- } else if inst.opcode.is_push() {
245
- let entry = format!(
246
- "{margin} {pc} {opcode} {push_data}",
247
- opcode = inst.opcode,
248
- push_data = inst
249
- .push_data
250
- .as_deref()
251
- .map(hex::encode_prefixed)
252
- .unwrap_or_default()
253
- );
254
-
255
- println!("{entry:<50}{location}");
256
- } else {
257
- let entry = format!("{margin} {pc} {opcode}", opcode = inst.opcode);
258
-
259
- println!("{entry:<50}{location}");
260
- }
261
- } else {
262
- println!("{margin} {pc}");
263
- }
264
- }
265
-
266
- Ok(())
267
- }
268
-
269
9
  #[napi]
270
10
  fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
271
11
  let entry_values = trace
package/src/trace/exit.rs CHANGED
@@ -51,9 +51,9 @@ impl fmt::Display for ExitCode {
51
51
  }
52
52
 
53
53
  #[allow(clippy::fallible_impl_from)] // naively ported for now
54
- impl From<edr_solidity::message_trace::ExitCode> for ExitCode {
55
- fn from(code: edr_solidity::message_trace::ExitCode) -> Self {
56
- use edr_solidity::message_trace::ExitCode;
54
+ impl From<edr_solidity::exit_code::ExitCode> for ExitCode {
55
+ fn from(code: edr_solidity::exit_code::ExitCode) -> Self {
56
+ use edr_solidity::exit_code::ExitCode;
57
57
 
58
58
  match code {
59
59
  ExitCode::Success => Self::SUCCESS,
@@ -1,6 +1,6 @@
1
1
  use std::rc::Rc;
2
2
 
3
- use edr_solidity::build_model::Bytecode;
3
+ use edr_solidity::build_model::ContractMetadata;
4
4
  use napi_derive::napi;
5
5
  use serde::Serialize;
6
6
 
@@ -9,20 +9,20 @@ use serde::Serialize;
9
9
  // NOTE: Needed, because we store the resolved `Bytecode` in the MessageTrace
10
10
  // JS plain objects and those need a dedicated (class) type.
11
11
  #[napi]
12
- pub struct BytecodeWrapper(pub(crate) Rc<Bytecode>);
12
+ pub struct BytecodeWrapper(pub(crate) Rc<ContractMetadata>);
13
13
 
14
14
  impl BytecodeWrapper {
15
- pub fn new(bytecode: Rc<Bytecode>) -> Self {
15
+ pub fn new(bytecode: Rc<ContractMetadata>) -> Self {
16
16
  Self(bytecode)
17
17
  }
18
18
 
19
- pub fn inner(&self) -> &Rc<Bytecode> {
19
+ pub fn inner(&self) -> &Rc<ContractMetadata> {
20
20
  &self.0
21
21
  }
22
22
  }
23
23
 
24
24
  impl std::ops::Deref for BytecodeWrapper {
25
- type Target = Bytecode;
25
+ type Target = ContractMetadata;
26
26
 
27
27
  fn deref(&self) -> &Self::Target {
28
28
  &self.0
@@ -8,6 +8,7 @@ use napi_derive::napi;
8
8
  use serde::{Serialize, Serializer};
9
9
 
10
10
  use super::model::ContractFunctionType;
11
+ use crate::{cast::TryCast, trace::u256_to_bigint};
11
12
 
12
13
  #[napi]
13
14
  #[repr(u8)]
@@ -77,6 +78,20 @@ pub struct SourceReference {
77
78
  pub range: Vec<u32>,
78
79
  }
79
80
 
81
+ impl From<edr_solidity::solidity_stack_trace::SourceReference> for SourceReference {
82
+ fn from(value: edr_solidity::solidity_stack_trace::SourceReference) -> Self {
83
+ let (range_start, range_end) = value.range;
84
+ Self {
85
+ source_name: value.source_name,
86
+ source_content: value.source_content,
87
+ contract: value.contract,
88
+ function: value.function,
89
+ line: value.line,
90
+ range: vec![range_start, range_end],
91
+ }
92
+ }
93
+ }
94
+
80
95
  /// A [`StackTraceEntryType`] constant that is convertible to/from a
81
96
  /// `napi_value`.
82
97
  ///
@@ -113,16 +128,6 @@ impl<const ENTRY_TYPE: u8> ToNapiValue for StackTraceEntryTypeConst<ENTRY_TYPE>
113
128
  }
114
129
  }
115
130
 
116
- impl<const ENTRY_TYPE: u8> StackTraceEntryTypeConst<ENTRY_TYPE> {
117
- #[allow(clippy::unused_self)] // less verbose than <value as ...>::as_value()
118
- const fn as_value(&self) -> StackTraceEntryType {
119
- match StackTraceEntryType::from_repr(ENTRY_TYPE) {
120
- Some(val) => val,
121
- None => panic!("Invalid StackTraceEntryType value"),
122
- }
123
- }
124
- }
125
-
126
131
  impl<const ENTRY_TYPE: u8> Serialize for StackTraceEntryTypeConst<ENTRY_TYPE> {
127
132
  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
128
133
  where
@@ -599,76 +604,215 @@ pub type SolidityStackTraceEntry = Either24<
599
604
  ContractCallRunOutOfGasError,
600
605
  >;
601
606
 
607
+ impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::StackTraceEntry {
608
+ type Error = napi::Error;
609
+
610
+ fn try_cast(self) -> Result<SolidityStackTraceEntry, Self::Error> {
611
+ use edr_solidity::solidity_stack_trace::StackTraceEntry;
612
+ let result = match self {
613
+ StackTraceEntry::CallstackEntry {
614
+ source_reference,
615
+ function_type,
616
+ } => CallstackEntryStackTraceEntry {
617
+ type_: StackTraceEntryTypeConst,
618
+ source_reference: source_reference.into(),
619
+ function_type: function_type.into(),
620
+ }
621
+ .into(),
622
+ StackTraceEntry::UnrecognizedCreateCallstackEntry => {
623
+ UnrecognizedCreateCallstackEntryStackTraceEntry {
624
+ type_: StackTraceEntryTypeConst,
625
+ source_reference: None,
626
+ }
627
+ .into()
628
+ }
629
+ StackTraceEntry::UnrecognizedContractCallstackEntry { address } => {
630
+ UnrecognizedContractCallstackEntryStackTraceEntry {
631
+ type_: StackTraceEntryTypeConst,
632
+ address: Uint8Array::from(address.as_slice()),
633
+ source_reference: None,
634
+ }
635
+ .into()
636
+ }
637
+ StackTraceEntry::PrecompileError { precompile } => PrecompileErrorStackTraceEntry {
638
+ type_: StackTraceEntryTypeConst,
639
+ precompile,
640
+ source_reference: None,
641
+ }
642
+ .into(),
643
+ StackTraceEntry::RevertError {
644
+ return_data,
645
+ source_reference,
646
+ is_invalid_opcode_error,
647
+ } => RevertErrorStackTraceEntry {
648
+ type_: StackTraceEntryTypeConst,
649
+ return_data: return_data.into(),
650
+ source_reference: source_reference.into(),
651
+ is_invalid_opcode_error,
652
+ }
653
+ .into(),
654
+ StackTraceEntry::PanicError {
655
+ error_code,
656
+ source_reference,
657
+ } => PanicErrorStackTraceEntry {
658
+ type_: StackTraceEntryTypeConst,
659
+ error_code: u256_to_bigint(&error_code),
660
+ source_reference: source_reference.map(std::convert::Into::into),
661
+ }
662
+ .into(),
663
+ StackTraceEntry::CustomError {
664
+ message,
665
+ source_reference,
666
+ } => CustomErrorStackTraceEntry {
667
+ type_: StackTraceEntryTypeConst,
668
+ message,
669
+ source_reference: source_reference.into(),
670
+ }
671
+ .into(),
672
+ StackTraceEntry::FunctionNotPayableError {
673
+ value,
674
+ source_reference,
675
+ } => FunctionNotPayableErrorStackTraceEntry {
676
+ type_: StackTraceEntryTypeConst,
677
+ value: u256_to_bigint(&value),
678
+ source_reference: source_reference.into(),
679
+ }
680
+ .into(),
681
+ StackTraceEntry::InvalidParamsError { source_reference } => {
682
+ InvalidParamsErrorStackTraceEntry {
683
+ type_: StackTraceEntryTypeConst,
684
+ source_reference: source_reference.into(),
685
+ }
686
+ .into()
687
+ }
688
+ StackTraceEntry::FallbackNotPayableError {
689
+ value,
690
+ source_reference,
691
+ } => FallbackNotPayableErrorStackTraceEntry {
692
+ type_: StackTraceEntryTypeConst,
693
+ value: u256_to_bigint(&value),
694
+ source_reference: source_reference.into(),
695
+ }
696
+ .into(),
697
+ StackTraceEntry::FallbackNotPayableAndNoReceiveError {
698
+ value,
699
+ source_reference,
700
+ } => FallbackNotPayableAndNoReceiveErrorStackTraceEntry {
701
+ type_: StackTraceEntryTypeConst,
702
+ value: u256_to_bigint(&value),
703
+ source_reference: source_reference.into(),
704
+ }
705
+ .into(),
706
+ StackTraceEntry::UnrecognizedFunctionWithoutFallbackError { source_reference } => {
707
+ UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry {
708
+ type_: StackTraceEntryTypeConst,
709
+ source_reference: source_reference.into(),
710
+ }
711
+ .into()
712
+ }
713
+ StackTraceEntry::MissingFallbackOrReceiveError { source_reference } => {
714
+ MissingFallbackOrReceiveErrorStackTraceEntry {
715
+ type_: StackTraceEntryTypeConst,
716
+ source_reference: source_reference.into(),
717
+ }
718
+ .into()
719
+ }
720
+ StackTraceEntry::ReturndataSizeError { source_reference } => {
721
+ ReturndataSizeErrorStackTraceEntry {
722
+ type_: StackTraceEntryTypeConst,
723
+ source_reference: source_reference.into(),
724
+ }
725
+ .into()
726
+ }
727
+ StackTraceEntry::NoncontractAccountCalledError { source_reference } => {
728
+ NonContractAccountCalledErrorStackTraceEntry {
729
+ type_: StackTraceEntryTypeConst,
730
+ source_reference: source_reference.into(),
731
+ }
732
+ .into()
733
+ }
734
+ StackTraceEntry::CallFailedError { source_reference } => {
735
+ CallFailedErrorStackTraceEntry {
736
+ type_: StackTraceEntryTypeConst,
737
+ source_reference: source_reference.into(),
738
+ }
739
+ .into()
740
+ }
741
+ StackTraceEntry::DirectLibraryCallError { source_reference } => {
742
+ DirectLibraryCallErrorStackTraceEntry {
743
+ type_: StackTraceEntryTypeConst,
744
+ source_reference: source_reference.into(),
745
+ }
746
+ .into()
747
+ }
748
+ StackTraceEntry::UnrecognizedCreateError {
749
+ return_data,
750
+ is_invalid_opcode_error,
751
+ } => UnrecognizedCreateErrorStackTraceEntry {
752
+ type_: StackTraceEntryTypeConst,
753
+ return_data: return_data.into(),
754
+ is_invalid_opcode_error,
755
+ source_reference: None,
756
+ }
757
+ .into(),
758
+ StackTraceEntry::UnrecognizedContractError {
759
+ address,
760
+ return_data,
761
+ is_invalid_opcode_error,
762
+ } => UnrecognizedContractErrorStackTraceEntry {
763
+ type_: StackTraceEntryTypeConst,
764
+ address: Uint8Array::from(address.as_slice()),
765
+ return_data: return_data.into(),
766
+ is_invalid_opcode_error,
767
+ source_reference: None,
768
+ }
769
+ .into(),
770
+ StackTraceEntry::OtherExecutionError { source_reference } => {
771
+ OtherExecutionErrorStackTraceEntry {
772
+ type_: StackTraceEntryTypeConst,
773
+ source_reference: source_reference.map(std::convert::Into::into),
774
+ }
775
+ .into()
776
+ }
777
+ StackTraceEntry::UnmappedSolc0_6_3RevertError { source_reference } => {
778
+ UnmappedSolc063RevertErrorStackTraceEntry {
779
+ type_: StackTraceEntryTypeConst,
780
+ source_reference: source_reference.map(std::convert::Into::into),
781
+ }
782
+ .into()
783
+ }
784
+ StackTraceEntry::ContractTooLargeError { source_reference } => {
785
+ ContractTooLargeErrorStackTraceEntry {
786
+ type_: StackTraceEntryTypeConst,
787
+ source_reference: source_reference.map(std::convert::Into::into),
788
+ }
789
+ .into()
790
+ }
791
+ StackTraceEntry::InternalFunctionCallstackEntry {
792
+ pc,
793
+ source_reference,
794
+ } => InternalFunctionCallStackEntry {
795
+ type_: StackTraceEntryTypeConst,
796
+ pc,
797
+ source_reference: source_reference.into(),
798
+ }
799
+ .into(),
800
+ StackTraceEntry::ContractCallRunOutOfGasError { source_reference } => {
801
+ ContractCallRunOutOfGasError {
802
+ type_: StackTraceEntryTypeConst,
803
+ source_reference: source_reference.map(std::convert::Into::into),
804
+ }
805
+ .into()
806
+ }
807
+ };
808
+ Ok(result)
809
+ }
810
+ }
811
+
602
812
  #[allow(dead_code)]
603
813
  // Same as above, but for the `SolidityStackTrace` type.
604
814
  pub type SolidityStackTrace = Vec<SolidityStackTraceEntry>;
605
815
 
606
- pub trait SolidityStackTraceEntryExt {
607
- fn type_(&self) -> StackTraceEntryType;
608
- fn source_reference(&self) -> Option<&SourceReference>;
609
- }
610
-
611
- impl SolidityStackTraceEntryExt for SolidityStackTraceEntry {
612
- fn type_(&self) -> StackTraceEntryType {
613
- match self {
614
- Either24::A(entry) => entry.type_.as_value(),
615
- Either24::B(entry) => entry.type_.as_value(),
616
- Either24::C(entry) => entry.type_.as_value(),
617
- Either24::D(entry) => entry.type_.as_value(),
618
- Either24::E(entry) => entry.type_.as_value(),
619
- Either24::F(entry) => entry.type_.as_value(),
620
- Either24::G(entry) => entry.type_.as_value(),
621
- Either24::H(entry) => entry.type_.as_value(),
622
- Either24::I(entry) => entry.type_.as_value(),
623
- Either24::J(entry) => entry.type_.as_value(),
624
- Either24::K(entry) => entry.type_.as_value(),
625
- Either24::L(entry) => entry.type_.as_value(),
626
- Either24::M(entry) => entry.type_.as_value(),
627
- Either24::N(entry) => entry.type_.as_value(),
628
- Either24::O(entry) => entry.type_.as_value(),
629
- Either24::P(entry) => entry.type_.as_value(),
630
- Either24::Q(entry) => entry.type_.as_value(),
631
- Either24::R(entry) => entry.type_.as_value(),
632
- Either24::S(entry) => entry.type_.as_value(),
633
- Either24::T(entry) => entry.type_.as_value(),
634
- Either24::U(entry) => entry.type_.as_value(),
635
- Either24::V(entry) => entry.type_.as_value(),
636
- Either24::W(entry) => entry.type_.as_value(),
637
- Either24::X(entry) => entry.type_.as_value(),
638
- }
639
- }
640
-
641
- #[allow(clippy::unnecessary_lazy_evaluations)] // guards against potential variant reordering
642
- fn source_reference(&self) -> Option<&SourceReference> {
643
- match self {
644
- Either24::A(entry) => Some(&entry.source_reference),
645
- Either24::B(entry) => entry.source_reference.and_then(|_: ()| None),
646
- Either24::C(entry) => entry.source_reference.and_then(|_: ()| None),
647
- Either24::D(entry) => entry.source_reference.and_then(|_: ()| None),
648
- Either24::E(entry) => Some(&entry.source_reference),
649
- Either24::F(entry) => entry.source_reference.as_ref(),
650
- Either24::G(entry) => Some(&entry.source_reference),
651
- Either24::H(entry) => Some(&entry.source_reference),
652
- Either24::I(entry) => Some(&entry.source_reference),
653
- Either24::J(entry) => Some(&entry.source_reference),
654
- Either24::K(entry) => Some(&entry.source_reference),
655
- Either24::L(entry) => Some(&entry.source_reference),
656
- Either24::M(entry) => Some(&entry.source_reference),
657
- Either24::N(entry) => Some(&entry.source_reference),
658
- Either24::O(entry) => Some(&entry.source_reference),
659
- Either24::P(entry) => Some(&entry.source_reference),
660
- Either24::Q(entry) => Some(&entry.source_reference),
661
- Either24::R(entry) => entry.source_reference.and_then(|_: ()| None),
662
- Either24::S(entry) => entry.source_reference.and_then(|_: ()| None),
663
- Either24::T(entry) => entry.source_reference.as_ref(),
664
- Either24::U(entry) => entry.source_reference.as_ref(),
665
- Either24::V(entry) => entry.source_reference.as_ref(),
666
- Either24::W(entry) => Some(&entry.source_reference),
667
- Either24::X(entry) => entry.source_reference.as_ref(),
668
- }
669
- }
670
- }
671
-
672
816
  const _: () = {
673
817
  const fn assert_to_from_napi_value<T: FromNapiValue + ToNapiValue>() {}
674
818
  assert_to_from_napi_value::<SolidityStackTraceEntry>();
package/src/trace.rs CHANGED
@@ -16,20 +16,13 @@ use napi_derive::napi;
16
16
 
17
17
  use crate::result::ExecutionResult;
18
18
 
19
- mod compiler;
20
19
  mod library_utils;
21
- mod model;
22
20
 
23
21
  mod debug;
24
- mod error_inferrer;
25
22
  mod exit;
26
- mod mapped_inlined_internal_functions_heuristics;
27
- mod message_trace;
23
+ mod model;
28
24
  mod return_data;
29
- mod solidity_stack_trace;
30
- mod solidity_tracer;
31
- mod vm_trace_decoder;
32
- mod vm_tracer;
25
+ pub mod solidity_stack_trace;
33
26
 
34
27
  #[napi(object)]
35
28
  pub struct TracingMessage {
@@ -149,7 +142,7 @@ impl TracingStep {
149
142
 
150
143
  Self {
151
144
  depth: step.depth as u8,
152
- pc: BigInt::from(step.pc),
145
+ pc: BigInt::from(u64::from(step.pc)),
153
146
  opcode: OpCode::name_by_op(step.opcode).to_string(),
154
147
  stack,
155
148
  memory,
@@ -157,7 +150,7 @@ impl TracingStep {
157
150
  }
158
151
  }
159
152
 
160
- fn u256_to_bigint(v: &edr_evm::U256) -> BigInt {
153
+ pub(crate) fn u256_to_bigint(v: &edr_evm::U256) -> BigInt {
161
154
  BigInt {
162
155
  sign_bit: false,
163
156
  words: v.into_limbs().to_vec(),
@@ -203,3 +196,10 @@ impl RawTrace {
203
196
  .collect::<napi::Result<_>>()
204
197
  }
205
198
  }
199
+
200
+ #[napi]
201
+ /// Returns the latest version of solc that EDR officially
202
+ /// supports and is tested against.
203
+ pub fn get_latest_supported_solc_version() -> String {
204
+ "0.8.28".to_string()
205
+ }