@nomicfoundation/edr 0.12.0-alpha.0 → 0.12.0-next.1

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.
@@ -0,0 +1,56 @@
1
+ pub mod artifact;
2
+ pub mod config;
3
+ pub mod factory;
4
+ pub mod l1;
5
+ #[cfg(feature = "op")]
6
+ pub mod op;
7
+ pub mod runner;
8
+ pub mod test_results;
9
+
10
+ use std::path::Path;
11
+
12
+ use edr_eth::Bytes;
13
+ use edr_solidity::linker::{LinkOutput, Linker};
14
+ use edr_solidity_tests::{constants::LIBRARY_DEPLOYER, contracts::ContractsByArtifact};
15
+ use foundry_compilers::artifacts::Libraries;
16
+
17
+ use crate::solidity_tests::artifact::Artifact;
18
+
19
+ pub(crate) struct LinkingOutput {
20
+ pub libs_to_deploy: Vec<Bytes>,
21
+ pub known_contracts: ContractsByArtifact,
22
+ }
23
+
24
+ impl LinkingOutput {
25
+ pub fn link(project_root: &Path, artifacts: Vec<Artifact>) -> napi::Result<Self> {
26
+ let artifact_contracts = artifacts
27
+ .into_iter()
28
+ .map(|artifact| Ok((artifact.id.try_into()?, artifact.contract.try_into()?)))
29
+ .collect::<napi::Result<Vec<_>>>()?;
30
+
31
+ let linker = Linker::new(project_root, artifact_contracts);
32
+
33
+ let LinkOutput {
34
+ libraries,
35
+ libs_to_deploy,
36
+ } = linker
37
+ .link_with_nonce_or_address(
38
+ Libraries::default(),
39
+ LIBRARY_DEPLOYER,
40
+ 0,
41
+ linker.contracts.keys(),
42
+ )
43
+ .map_err(|error| napi::Error::from_reason(error.to_string()))?;
44
+
45
+ let linked_contracts = linker
46
+ .get_linked_artifacts(&libraries)
47
+ .map_err(|error| napi::Error::from_reason(error.to_string()))?;
48
+
49
+ let known_contracts = ContractsByArtifact::new(linked_contracts);
50
+
51
+ Ok(LinkingOutput {
52
+ libs_to_deploy,
53
+ known_contracts,
54
+ })
55
+ }
56
+ }
@@ -1,4 +1,4 @@
1
- use napi::{JsFunction, bindgen_prelude::BigInt};
1
+ use napi::{bindgen_prelude::BigInt, JsFunction};
2
2
  use napi_derive::napi;
3
3
 
4
4
  /// Configuration for subscriptions.
@@ -6,7 +6,7 @@ use napi_derive::napi;
6
6
  use super::solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace};
7
7
  use crate::trace::return_data::ReturnData;
8
8
 
9
- #[napi]
9
+ #[napi(catch_unwind)]
10
10
  fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
11
11
  let entry_values = trace
12
12
  .into_iter()
package/src/trace/exit.rs CHANGED
@@ -64,24 +64,24 @@ impl From<edr_solidity::exit_code::ExitCode<edr_eth::l1::HaltReason>> for ExitCo
64
64
  ExitCode::Halt(edr_eth::l1::HaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
65
65
  ExitCode::Halt(edr_eth::l1::HaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
66
66
  ExitCode::Halt(edr_eth::l1::HaltReason::CreateCollision) => Self::CREATE_COLLISION,
67
- ExitCode::Halt(_) => Self::UNKNOWN_HALT_REASON,
67
+ _ => Self::UNKNOWN_HALT_REASON,
68
68
  }
69
69
  }
70
70
  }
71
71
 
72
72
  #[napi]
73
73
  impl Exit {
74
- #[napi(getter)]
74
+ #[napi(catch_unwind, getter)]
75
75
  pub fn kind(&self) -> ExitCode {
76
76
  self.0
77
77
  }
78
78
 
79
- #[napi]
79
+ #[napi(catch_unwind)]
80
80
  pub fn is_error(&self) -> bool {
81
81
  !matches!(self.0, ExitCode::SUCCESS)
82
82
  }
83
83
 
84
- #[napi]
84
+ #[napi(catch_unwind)]
85
85
  pub fn get_reason(&self) -> String {
86
86
  self.0.to_string()
87
87
  }
@@ -1,6 +1,11 @@
1
1
  use napi_derive::napi;
2
2
 
3
- #[napi]
4
- pub fn link_hex_string_bytecode(code: String, address: String, position: u32) -> String {
3
+ #[napi(catch_unwind)]
4
+ pub fn link_hex_string_bytecode(
5
+ code: String,
6
+ address: String,
7
+ position: u32,
8
+ ) -> napi::Result<String> {
5
9
  edr_solidity::library_utils::link_hex_string_bytecode(code, &address, position)
10
+ .map_err(|err| napi::Error::from_reason(err.to_string()))
6
11
  }
@@ -20,7 +20,7 @@ pub struct ReturnData {
20
20
 
21
21
  #[napi]
22
22
  impl ReturnData {
23
- #[napi(constructor)]
23
+ #[napi(catch_unwind, constructor)]
24
24
  pub fn new(value: Uint8Array) -> Self {
25
25
  let selector = if value.len() >= 4 {
26
26
  Some(value[0..4].try_into().unwrap())
@@ -31,7 +31,7 @@ impl ReturnData {
31
31
  Self { value, selector }
32
32
  }
33
33
 
34
- #[napi]
34
+ #[napi(catch_unwind)]
35
35
  pub fn is_empty(&self) -> bool {
36
36
  self.value.is_empty()
37
37
  }
@@ -41,35 +41,35 @@ impl ReturnData {
41
41
  .is_some_and(|value| value == selector.as_ref())
42
42
  }
43
43
 
44
- #[napi]
44
+ #[napi(catch_unwind)]
45
45
  pub fn is_error_return_data(&self) -> bool {
46
46
  self.selector == Some(Error::SELECTOR)
47
47
  }
48
48
 
49
- #[napi]
49
+ #[napi(catch_unwind)]
50
50
  pub fn is_panic_return_data(&self) -> bool {
51
51
  self.selector == Some(Panic::SELECTOR)
52
52
  }
53
53
 
54
- #[napi]
54
+ #[napi(catch_unwind)]
55
55
  pub fn decode_error(&self) -> napi::Result<String> {
56
56
  if self.is_empty() {
57
57
  return Ok(String::new());
58
58
  }
59
59
 
60
- let result = Error::abi_decode(&self.value[..], false).map_err(|_err| {
60
+ let result = Error::abi_decode(&self.value[..]).map_err(|_err| {
61
61
  napi::Error::new(
62
62
  napi::Status::InvalidArg,
63
63
  "Expected return data to be a Error(string) and contain a valid string",
64
64
  )
65
65
  })?;
66
66
 
67
- Ok(result._0)
67
+ Ok(result.0)
68
68
  }
69
69
 
70
- #[napi]
70
+ #[napi(catch_unwind)]
71
71
  pub fn decode_panic(&self) -> napi::Result<BigInt> {
72
- let result = Panic::abi_decode(&self.value[..], false).map_err(|_err| {
72
+ let result = Panic::abi_decode(&self.value[..]).map_err(|_err| {
73
73
  napi::Error::new(
74
74
  napi::Status::InvalidArg,
75
75
  "Expected return data to be a Error(string) and contain a valid string",
@@ -78,7 +78,7 @@ impl ReturnData {
78
78
 
79
79
  Ok(BigInt {
80
80
  sign_bit: false,
81
- words: result._0.as_limbs().to_vec(),
81
+ words: result.0.as_limbs().to_vec(),
82
82
  })
83
83
  }
84
84
  }
@@ -1,7 +1,9 @@
1
1
  //! Naive rewrite of `hardhat-network/stack-traces/solidity-stack-traces.ts`
2
2
  //! from Hardhat.
3
3
 
4
- use edr_eth::{U256, hex};
4
+ use std::convert::Infallible;
5
+
6
+ use edr_eth::{hex, U256};
5
7
  use napi::bindgen_prelude::{BigInt, Either24, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
6
8
  use napi_derive::napi;
7
9
  use serde::{Serialize, Serializer};
@@ -45,7 +47,7 @@ pub enum StackTraceEntryType {
45
47
  CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR,
46
48
  }
47
49
 
48
- #[napi]
50
+ #[napi(catch_unwind)]
49
51
  pub fn stack_trace_entry_type_to_string(val: StackTraceEntryType) -> &'static str {
50
52
  val.into()
51
53
  }
@@ -606,7 +608,7 @@ pub type SolidityStackTraceEntry = Either24<
606
608
  >;
607
609
 
608
610
  impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::StackTraceEntry {
609
- type Error = napi::Error;
611
+ type Error = Infallible;
610
612
 
611
613
  fn try_cast(self) -> Result<SolidityStackTraceEntry, Self::Error> {
612
614
  use edr_solidity::solidity_stack_trace::StackTraceEntry;
@@ -630,7 +632,7 @@ impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::St
630
632
  StackTraceEntry::UnrecognizedContractCallstackEntry { address } => {
631
633
  UnrecognizedContractCallstackEntryStackTraceEntry {
632
634
  type_: StackTraceEntryTypeConst,
633
- address: Uint8Array::from(address.as_slice()),
635
+ address: Uint8Array::with_data_copied(address),
634
636
  source_reference: None,
635
637
  }
636
638
  .into()
@@ -762,7 +764,7 @@ impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::St
762
764
  is_invalid_opcode_error,
763
765
  } => UnrecognizedContractErrorStackTraceEntry {
764
766
  type_: StackTraceEntryTypeConst,
765
- address: Uint8Array::from(address.as_slice()),
767
+ address: Uint8Array::with_data_copied(address),
766
768
  return_data: return_data.into(),
767
769
  is_invalid_opcode_error,
768
770
  source_reference: None,
package/src/trace.rs CHANGED
@@ -9,10 +9,7 @@ use std::sync::Arc;
9
9
 
10
10
  use edr_eth::{bytecode::opcode::OpCode, l1};
11
11
  use edr_evm::trace::BeforeMessage;
12
- use napi::{
13
- Env, JsBuffer, JsBufferValue,
14
- bindgen_prelude::{BigInt, Buffer, Either3},
15
- };
12
+ use napi::bindgen_prelude::{BigInt, Either3, Uint8Array};
16
13
  use napi_derive::napi;
17
14
 
18
15
  use crate::result::ExecutionResult;
@@ -29,11 +26,11 @@ pub mod solidity_stack_trace;
29
26
  pub struct TracingMessage {
30
27
  /// Sender address
31
28
  #[napi(readonly)]
32
- pub caller: Buffer,
29
+ pub caller: Uint8Array,
33
30
 
34
31
  /// Recipient address. None if it is a Create message.
35
32
  #[napi(readonly)]
36
- pub to: Option<Buffer>,
33
+ pub to: Option<Uint8Array>,
37
34
 
38
35
  /// Whether it's a static call
39
36
  #[napi(readonly)]
@@ -49,7 +46,7 @@ pub struct TracingMessage {
49
46
 
50
47
  /// Input data of the message
51
48
  #[napi(readonly)]
52
- pub data: JsBuffer,
49
+ pub data: Uint8Array,
53
50
 
54
51
  /// Value sent in the message
55
52
  #[napi(readonly)]
@@ -58,41 +55,37 @@ pub struct TracingMessage {
58
55
  /// Address of the code that is being executed. Can be different from `to`
59
56
  /// if a delegate call is being done.
60
57
  #[napi(readonly)]
61
- pub code_address: Option<Buffer>,
58
+ pub code_address: Option<Uint8Array>,
62
59
 
63
60
  /// Code of the contract that is being executed.
64
61
  #[napi(readonly)]
65
- pub code: Option<JsBuffer>,
62
+ pub code: Option<Uint8Array>,
66
63
  }
67
64
 
68
- impl TracingMessage {
69
- pub fn new(env: &Env, message: &BeforeMessage) -> napi::Result<Self> {
65
+ impl From<&BeforeMessage> for TracingMessage {
66
+ fn from(value: &BeforeMessage) -> Self {
70
67
  // Deconstruct to make sure all fields are handled
71
68
  let BeforeMessage {
72
69
  depth,
73
70
  caller,
74
- to: _,
71
+ to,
75
72
  is_static_call,
76
73
  gas_limit,
77
74
  data,
78
75
  value,
79
76
  code_address,
80
77
  code,
81
- } = message;
78
+ } = value;
82
79
 
83
- let data = env
84
- .create_buffer_with_data(data.to_vec())
85
- .map(JsBufferValue::into_raw)?;
80
+ let data = Uint8Array::with_data_copied(data);
86
81
 
87
- let code = code.as_ref().map_or(Ok(None), |code| {
88
- env.create_buffer_with_data(code.original_bytes().to_vec())
89
- .map(JsBufferValue::into_raw)
90
- .map(Some)
91
- })?;
82
+ let code = code
83
+ .as_ref()
84
+ .map(|code| Uint8Array::with_data_copied(code.original_bytes()));
92
85
 
93
- Ok(TracingMessage {
94
- caller: Buffer::from(caller.as_slice()),
95
- to: message.to.map(|to| Buffer::from(to.as_slice())),
86
+ TracingMessage {
87
+ caller: Uint8Array::with_data_copied(caller),
88
+ to: to.as_ref().map(Uint8Array::with_data_copied),
96
89
  gas_limit: BigInt::from(*gas_limit),
97
90
  is_static_call: *is_static_call,
98
91
  depth: *depth as u8,
@@ -101,9 +94,9 @@ impl TracingMessage {
101
94
  sign_bit: false,
102
95
  words: value.into_limbs().to_vec(),
103
96
  },
104
- code_address: code_address.map(|address| Buffer::from(address.to_vec())),
97
+ code_address: code_address.as_ref().map(Uint8Array::with_data_copied),
105
98
  code,
106
- })
99
+ }
107
100
  }
108
101
  }
109
102
 
@@ -125,7 +118,7 @@ pub struct TracingStep {
125
118
  pub stack: Vec<BigInt>,
126
119
  /// The memory at the step. None if verbose tracing is disabled.
127
120
  #[napi(readonly)]
128
- pub memory: Option<Buffer>,
121
+ pub memory: Option<Uint8Array>,
129
122
  }
130
123
 
131
124
  impl TracingStep {
@@ -139,7 +132,7 @@ impl TracingStep {
139
132
  },
140
133
  |stack| stack.iter().map(u256_to_bigint).collect(),
141
134
  );
142
- let memory = step.memory.as_ref().cloned().map(Buffer::from);
135
+ let memory = step.memory.as_ref().map(Uint8Array::with_data_copied);
143
136
 
144
137
  Self {
145
138
  depth: step.depth as u8,
@@ -179,23 +172,21 @@ impl From<Arc<edr_evm::trace::Trace<l1::HaltReason>>> for RawTrace {
179
172
 
180
173
  #[napi]
181
174
  impl RawTrace {
182
- #[napi]
183
- pub fn trace(
184
- &self,
185
- env: Env,
186
- ) -> napi::Result<Vec<Either3<TracingMessage, TracingStep, TracingMessageResult>>> {
175
+ #[napi(getter)]
176
+ pub fn trace(&self) -> Vec<Either3<TracingMessage, TracingStep, TracingMessageResult>> {
187
177
  self.inner
188
178
  .messages
189
179
  .iter()
190
180
  .map(|message| match message {
191
181
  edr_evm::trace::TraceMessage::Before(message) => {
192
- TracingMessage::new(&env, message).map(Either3::A)
182
+ Either3::A(TracingMessage::from(message))
193
183
  }
194
- edr_evm::trace::TraceMessage::Step(step) => Ok(Either3::B(TracingStep::new(step))),
195
- edr_evm::trace::TraceMessage::After(message) => ExecutionResult::new(&env, message)
196
- .map(|execution_result| Either3::C(TracingMessageResult { execution_result })),
184
+ edr_evm::trace::TraceMessage::Step(step) => Either3::B(TracingStep::new(step)),
185
+ edr_evm::trace::TraceMessage::After(message) => Either3::C(TracingMessageResult {
186
+ execution_result: ExecutionResult::from(message),
187
+ }),
197
188
  })
198
- .collect::<napi::Result<_>>()
189
+ .collect()
199
190
  }
200
191
  }
201
192
 
package/src/withdrawal.rs CHANGED
@@ -1,5 +1,5 @@
1
1
  use edr_eth::Address;
2
- use napi::bindgen_prelude::{BigInt, Buffer};
2
+ use napi::bindgen_prelude::{BigInt, Uint8Array};
3
3
  use napi_derive::napi;
4
4
 
5
5
  use crate::cast::TryCast as _;
@@ -11,7 +11,7 @@ pub struct Withdrawal {
11
11
  /// The index of the validator that generated the withdrawal
12
12
  pub validator_index: BigInt,
13
13
  /// The recipient address for withdrawal value
14
- pub address: Buffer,
14
+ pub address: Uint8Array,
15
15
  /// The value contained in withdrawal
16
16
  pub amount: BigInt,
17
17
  }
@@ -21,7 +21,7 @@ impl From<edr_eth::withdrawal::Withdrawal> for Withdrawal {
21
21
  Self {
22
22
  index: BigInt::from(withdrawal.index),
23
23
  validator_index: BigInt::from(withdrawal.validator_index),
24
- address: Buffer::from(withdrawal.address.as_slice()),
24
+ address: Uint8Array::with_data_copied(withdrawal.address),
25
25
  amount: BigInt {
26
26
  sign_bit: false,
27
27
  words: withdrawal.amount.as_limbs().to_vec(),