@nomicfoundation/edr 0.10.0 → 0.12.0-alpha.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.
- package/Cargo.toml +26 -23
- package/index.d.ts +145 -76
- package/index.js +31 -3
- package/package.json +16 -14
- package/src/account.rs +41 -11
- package/src/block.rs +1 -1
- package/src/call_override.rs +1 -1
- package/src/cast.rs +54 -2
- package/src/chains/generic.rs +51 -0
- package/src/chains/l1.rs +260 -0
- package/src/chains/op.rs +368 -0
- package/src/chains.rs +7 -0
- package/src/config.rs +393 -67
- package/src/context.rs +135 -17
- package/src/lib.rs +28 -14
- package/src/log.rs +2 -2
- package/src/logger.rs +54 -1152
- package/src/provider/factory.rs +22 -0
- package/src/provider/response.rs +70 -0
- package/src/provider.rs +55 -322
- package/src/result.rs +44 -44
- package/src/scenarios.rs +12 -18
- package/src/subscription.rs +32 -0
- package/src/trace/exit.rs +8 -9
- package/src/trace/return_data.rs +1 -1
- package/src/trace/solidity_stack_trace.rs +5 -4
- package/src/trace.rs +9 -7
- package/src/withdrawal.rs +1 -1
- package/src/provider/config.rs +0 -291
- package/src/subscribe.rs +0 -63
package/src/result.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use edr_evm::trace::AfterMessage;
|
|
2
2
|
use napi::{
|
|
3
|
-
bindgen_prelude::{BigInt, Buffer, Either3},
|
|
4
3
|
Either, Env, JsBuffer, JsBufferValue,
|
|
4
|
+
bindgen_prelude::{BigInt, Buffer, Either3},
|
|
5
5
|
};
|
|
6
6
|
use napi_derive::napi;
|
|
7
7
|
|
|
@@ -19,18 +19,18 @@ pub enum SuccessReason {
|
|
|
19
19
|
EofReturnContract,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
impl From<
|
|
23
|
-
fn from(eval:
|
|
22
|
+
impl From<edr_eth::result::SuccessReason> for SuccessReason {
|
|
23
|
+
fn from(eval: edr_eth::result::SuccessReason) -> Self {
|
|
24
24
|
match eval {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
edr_eth::result::SuccessReason::Stop => Self::Stop,
|
|
26
|
+
edr_eth::result::SuccessReason::Return => Self::Return,
|
|
27
|
+
edr_eth::result::SuccessReason::SelfDestruct => Self::SelfDestruct,
|
|
28
|
+
edr_eth::result::SuccessReason::EofReturnContract => Self::EofReturnContract,
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
impl From<SuccessReason> for
|
|
33
|
+
impl From<SuccessReason> for edr_eth::result::SuccessReason {
|
|
34
34
|
fn from(value: SuccessReason) -> Self {
|
|
35
35
|
match value {
|
|
36
36
|
SuccessReason::Stop => Self::Stop,
|
|
@@ -105,55 +105,55 @@ pub enum ExceptionalHalt {
|
|
|
105
105
|
/// Aud data is smaller then already present data size.
|
|
106
106
|
EofAuxDataTooSmall,
|
|
107
107
|
/// EOF Subroutine stack overflow
|
|
108
|
-
|
|
108
|
+
SubRoutineStackOverflow,
|
|
109
109
|
/// Check for target address validity is only done inside subcall.
|
|
110
110
|
InvalidEXTCALLTarget,
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
impl From<
|
|
114
|
-
fn from(halt:
|
|
113
|
+
impl From<edr_eth::l1::HaltReason> for ExceptionalHalt {
|
|
114
|
+
fn from(halt: edr_eth::l1::HaltReason) -> Self {
|
|
115
115
|
match halt {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
edr_eth::l1::HaltReason::OutOfGas(..) => ExceptionalHalt::OutOfGas,
|
|
117
|
+
edr_eth::l1::HaltReason::OpcodeNotFound => ExceptionalHalt::OpcodeNotFound,
|
|
118
|
+
edr_eth::l1::HaltReason::InvalidFEOpcode => ExceptionalHalt::InvalidFEOpcode,
|
|
119
|
+
edr_eth::l1::HaltReason::InvalidJump => ExceptionalHalt::InvalidJump,
|
|
120
|
+
edr_eth::l1::HaltReason::NotActivated => ExceptionalHalt::NotActivated,
|
|
121
|
+
edr_eth::l1::HaltReason::StackUnderflow => ExceptionalHalt::StackUnderflow,
|
|
122
|
+
edr_eth::l1::HaltReason::StackOverflow => ExceptionalHalt::StackOverflow,
|
|
123
|
+
edr_eth::l1::HaltReason::OutOfOffset => ExceptionalHalt::OutOfOffset,
|
|
124
|
+
edr_eth::l1::HaltReason::CreateCollision => ExceptionalHalt::CreateCollision,
|
|
125
|
+
edr_eth::l1::HaltReason::PrecompileError => ExceptionalHalt::PrecompileError,
|
|
126
|
+
edr_eth::l1::HaltReason::NonceOverflow => ExceptionalHalt::NonceOverflow,
|
|
127
|
+
edr_eth::l1::HaltReason::CreateContractSizeLimit => {
|
|
128
128
|
ExceptionalHalt::CreateContractSizeLimit
|
|
129
129
|
}
|
|
130
|
-
|
|
130
|
+
edr_eth::l1::HaltReason::CreateContractStartingWithEF => {
|
|
131
131
|
ExceptionalHalt::CreateContractStartingWithEF
|
|
132
132
|
}
|
|
133
|
-
|
|
133
|
+
edr_eth::l1::HaltReason::CreateInitCodeSizeLimit => {
|
|
134
134
|
ExceptionalHalt::CreateInitCodeSizeLimit
|
|
135
135
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
ExceptionalHalt::
|
|
136
|
+
edr_eth::l1::HaltReason::EofAuxDataOverflow => ExceptionalHalt::EofAuxDataOverflow,
|
|
137
|
+
edr_eth::l1::HaltReason::EofAuxDataTooSmall => ExceptionalHalt::EofAuxDataTooSmall,
|
|
138
|
+
edr_eth::l1::HaltReason::SubRoutineStackOverflow => {
|
|
139
|
+
ExceptionalHalt::SubRoutineStackOverflow
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
|
144
|
-
|
|
|
145
|
-
|
|
|
146
|
-
|
|
|
141
|
+
edr_eth::l1::HaltReason::InvalidEXTCALLTarget => ExceptionalHalt::InvalidEXTCALLTarget,
|
|
142
|
+
edr_eth::l1::HaltReason::OverflowPayment
|
|
143
|
+
| edr_eth::l1::HaltReason::StateChangeDuringStaticCall
|
|
144
|
+
| edr_eth::l1::HaltReason::CallNotAllowedInsideStatic
|
|
145
|
+
| edr_eth::l1::HaltReason::OutOfFunds
|
|
146
|
+
| edr_eth::l1::HaltReason::CallTooDeep => {
|
|
147
147
|
unreachable!("Internal halts that can be only found inside Inspector: {halt:?}")
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
impl From<ExceptionalHalt> for
|
|
153
|
+
impl From<ExceptionalHalt> for edr_eth::l1::HaltReason {
|
|
154
154
|
fn from(value: ExceptionalHalt) -> Self {
|
|
155
155
|
match value {
|
|
156
|
-
ExceptionalHalt::OutOfGas => Self::OutOfGas(
|
|
156
|
+
ExceptionalHalt::OutOfGas => Self::OutOfGas(edr_eth::l1::OutOfGasError::Basic),
|
|
157
157
|
ExceptionalHalt::OpcodeNotFound => Self::OpcodeNotFound,
|
|
158
158
|
ExceptionalHalt::InvalidFEOpcode => Self::InvalidFEOpcode,
|
|
159
159
|
ExceptionalHalt::InvalidJump => Self::InvalidJump,
|
|
@@ -169,7 +169,7 @@ impl From<ExceptionalHalt> for edr_evm::HaltReason {
|
|
|
169
169
|
ExceptionalHalt::CreateInitCodeSizeLimit => Self::CreateInitCodeSizeLimit,
|
|
170
170
|
ExceptionalHalt::EofAuxDataOverflow => Self::EofAuxDataOverflow,
|
|
171
171
|
ExceptionalHalt::EofAuxDataTooSmall => Self::EofAuxDataTooSmall,
|
|
172
|
-
ExceptionalHalt::
|
|
172
|
+
ExceptionalHalt::SubRoutineStackOverflow => Self::SubRoutineStackOverflow,
|
|
173
173
|
ExceptionalHalt::InvalidEXTCALLTarget => Self::InvalidEXTCALLTarget,
|
|
174
174
|
}
|
|
175
175
|
}
|
|
@@ -195,14 +195,14 @@ pub struct ExecutionResult {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
impl ExecutionResult {
|
|
198
|
-
pub fn new(env: &Env, message: &AfterMessage) -> napi::Result<Self> {
|
|
198
|
+
pub fn new(env: &Env, message: &AfterMessage<edr_eth::l1::HaltReason>) -> napi::Result<Self> {
|
|
199
199
|
let AfterMessage {
|
|
200
200
|
execution_result,
|
|
201
201
|
contract_address,
|
|
202
202
|
} = message;
|
|
203
203
|
|
|
204
204
|
let result = match execution_result {
|
|
205
|
-
|
|
205
|
+
edr_eth::result::ExecutionResult::Success {
|
|
206
206
|
reason,
|
|
207
207
|
gas_used,
|
|
208
208
|
gas_refunded,
|
|
@@ -220,14 +220,14 @@ impl ExecutionResult {
|
|
|
220
220
|
gas_refunded: BigInt::from(*gas_refunded),
|
|
221
221
|
logs,
|
|
222
222
|
output: match output {
|
|
223
|
-
|
|
223
|
+
edr_eth::result::Output::Call(return_value) => {
|
|
224
224
|
let return_value = env
|
|
225
225
|
.create_buffer_with_data(return_value.to_vec())
|
|
226
226
|
.map(JsBufferValue::into_raw)?;
|
|
227
227
|
|
|
228
228
|
Either::A(CallOutput { return_value })
|
|
229
229
|
}
|
|
230
|
-
|
|
230
|
+
edr_eth::result::Output::Create(return_value, address) => {
|
|
231
231
|
let return_value = env
|
|
232
232
|
.create_buffer_with_data(return_value.to_vec())
|
|
233
233
|
.map(JsBufferValue::into_raw)?;
|
|
@@ -240,7 +240,7 @@ impl ExecutionResult {
|
|
|
240
240
|
},
|
|
241
241
|
})
|
|
242
242
|
}
|
|
243
|
-
|
|
243
|
+
edr_eth::result::ExecutionResult::Revert { gas_used, output } => {
|
|
244
244
|
let output = env
|
|
245
245
|
.create_buffer_with_data(output.to_vec())
|
|
246
246
|
.map(JsBufferValue::into_raw)?;
|
|
@@ -250,7 +250,7 @@ impl ExecutionResult {
|
|
|
250
250
|
output,
|
|
251
251
|
})
|
|
252
252
|
}
|
|
253
|
-
|
|
253
|
+
edr_eth::result::ExecutionResult::Halt { reason, gas_used } => Either3::C(HaltResult {
|
|
254
254
|
reason: ExceptionalHalt::from(*reason),
|
|
255
255
|
gas_used: BigInt::from(*gas_used),
|
|
256
256
|
}),
|
package/src/scenarios.rs
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
2
2
|
|
|
3
|
-
use
|
|
3
|
+
use edr_scenarios::ScenarioConfig;
|
|
4
4
|
use napi::tokio::{fs::File, io::AsyncWriteExt, sync::Mutex};
|
|
5
|
-
use rand::{distributions::Alphanumeric
|
|
6
|
-
use serde::Serialize;
|
|
5
|
+
use rand::{Rng, distributions::Alphanumeric};
|
|
7
6
|
|
|
8
7
|
const SCENARIO_FILE_PREFIX: &str = "EDR_SCENARIO_PREFIX";
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/// Creates a scenario file with the provided configuration.
|
|
10
|
+
pub async fn scenario_file(
|
|
11
|
+
chain_type: String,
|
|
12
|
+
provider_config: edr_napi_core::provider::Config,
|
|
13
13
|
logger_enabled: bool,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
pub(crate) async fn scenario_file(
|
|
17
|
-
provider_config: &edr_provider::ProviderConfig,
|
|
18
|
-
logger_enabled: bool,
|
|
19
|
-
) -> Result<Option<Mutex<File>>, napi::Error> {
|
|
14
|
+
) -> napi::Result<Option<Mutex<File>>> {
|
|
20
15
|
if let Ok(scenario_prefix) = std::env::var(SCENARIO_FILE_PREFIX) {
|
|
21
16
|
let timestamp = SystemTime::now()
|
|
22
17
|
.duration_since(UNIX_EPOCH)
|
|
@@ -32,8 +27,9 @@ pub(crate) async fn scenario_file(
|
|
|
32
27
|
File::create(format!("{scenario_prefix}_{timestamp}_{suffix}.json")).await?;
|
|
33
28
|
|
|
34
29
|
let config = ScenarioConfig {
|
|
35
|
-
|
|
30
|
+
chain_type: Some(chain_type),
|
|
36
31
|
logger_enabled,
|
|
32
|
+
provider_config: provider_config.into(),
|
|
37
33
|
};
|
|
38
34
|
let mut line = serde_json::to_string(&config)?;
|
|
39
35
|
line.push('\n');
|
|
@@ -45,11 +41,9 @@ pub(crate) async fn scenario_file(
|
|
|
45
41
|
}
|
|
46
42
|
}
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
request
|
|
51
|
-
) -> napi::Result<()> {
|
|
52
|
-
let mut line = serde_json::to_string(request)?;
|
|
44
|
+
/// Writes a JSON-RPC request to the scenario file.
|
|
45
|
+
pub async fn write_request(scenario_file: &Mutex<File>, request: &str) -> napi::Result<()> {
|
|
46
|
+
let mut line = request.to_string();
|
|
53
47
|
line.push('\n');
|
|
54
48
|
{
|
|
55
49
|
let mut scenario_file = scenario_file.lock().await;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
use napi::{JsFunction, bindgen_prelude::BigInt};
|
|
2
|
+
use napi_derive::napi;
|
|
3
|
+
|
|
4
|
+
/// Configuration for subscriptions.
|
|
5
|
+
#[napi(object)]
|
|
6
|
+
pub struct SubscriptionConfig {
|
|
7
|
+
/// Callback to be called when a new event is received.
|
|
8
|
+
#[napi(ts_type = "(event: SubscriptionEvent) => void")]
|
|
9
|
+
pub subscription_callback: JsFunction,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
impl From<edr_napi_core::subscription::Config> for SubscriptionConfig {
|
|
13
|
+
fn from(config: edr_napi_core::subscription::Config) -> Self {
|
|
14
|
+
Self {
|
|
15
|
+
subscription_callback: config.subscription_callback,
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
impl From<SubscriptionConfig> for edr_napi_core::subscription::Config {
|
|
21
|
+
fn from(config: SubscriptionConfig) -> Self {
|
|
22
|
+
Self {
|
|
23
|
+
subscription_callback: config.subscription_callback,
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#[napi(object)]
|
|
29
|
+
pub struct SubscriptionEvent {
|
|
30
|
+
pub filter_id: BigInt,
|
|
31
|
+
pub result: serde_json::Value,
|
|
32
|
+
}
|
package/src/trace/exit.rs
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
use std::fmt;
|
|
5
5
|
|
|
6
|
-
use edr_evm::HaltReason;
|
|
7
6
|
use napi_derive::napi;
|
|
8
7
|
|
|
9
8
|
#[napi]
|
|
@@ -51,20 +50,20 @@ impl fmt::Display for ExitCode {
|
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
#[allow(clippy::fallible_impl_from)] // naively ported for now
|
|
54
|
-
impl From<edr_solidity::exit_code::ExitCode
|
|
55
|
-
fn from(code: edr_solidity::exit_code::ExitCode) -> Self {
|
|
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 {
|
|
56
55
|
use edr_solidity::exit_code::ExitCode;
|
|
57
56
|
|
|
58
57
|
match code {
|
|
59
58
|
ExitCode::Success => Self::SUCCESS,
|
|
60
59
|
ExitCode::Revert => Self::REVERT,
|
|
61
|
-
ExitCode::Halt(HaltReason::OutOfGas(_)) => Self::OUT_OF_GAS,
|
|
62
|
-
ExitCode::Halt(HaltReason::OpcodeNotFound | HaltReason::InvalidFEOpcode
|
|
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
|
|
63
62
|
// Returned when an opcode is not implemented for the hardfork
|
|
64
|
-
| HaltReason::NotActivated) => Self::INVALID_OPCODE,
|
|
65
|
-
ExitCode::Halt(HaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
|
|
66
|
-
ExitCode::Halt(HaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
|
|
67
|
-
ExitCode::Halt(HaltReason::CreateCollision) => Self::CREATE_COLLISION,
|
|
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,
|
|
68
67
|
ExitCode::Halt(_) => Self::UNKNOWN_HALT_REASON,
|
|
69
68
|
}
|
|
70
69
|
}
|
package/src/trace/return_data.rs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//! Naive rewrite of `hardhat-network/stack-traces/solidity-stack-traces.ts`
|
|
2
2
|
//! from Hardhat.
|
|
3
3
|
|
|
4
|
-
use edr_eth::U256;
|
|
5
|
-
use edr_evm::hex;
|
|
4
|
+
use edr_eth::{U256, hex};
|
|
6
5
|
use napi::bindgen_prelude::{BigInt, Either24, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
|
|
7
6
|
use napi_derive::napi;
|
|
8
7
|
use serde::{Serialize, Serializer};
|
|
@@ -107,7 +106,8 @@ impl<const ENTRY_TYPE: u8> FromNapiValue for StackTraceEntryTypeConst<ENTRY_TYPE
|
|
|
107
106
|
env: napi::sys::napi_env,
|
|
108
107
|
napi_val: napi::sys::napi_value,
|
|
109
108
|
) -> napi::Result<Self> {
|
|
110
|
-
|
|
109
|
+
// SAFETY: The safety concern is propagated in the function signature.
|
|
110
|
+
let inner: u8 = unsafe { FromNapiValue::from_napi_value(env, napi_val) }?;
|
|
111
111
|
|
|
112
112
|
if inner != ENTRY_TYPE {
|
|
113
113
|
return Err(napi::Error::new(
|
|
@@ -124,7 +124,8 @@ impl<const ENTRY_TYPE: u8> ToNapiValue for StackTraceEntryTypeConst<ENTRY_TYPE>
|
|
|
124
124
|
env: napi::sys::napi_env,
|
|
125
125
|
_val: Self,
|
|
126
126
|
) -> napi::Result<napi::sys::napi_value> {
|
|
127
|
-
|
|
127
|
+
// SAFETY: The safety concern is propagated in the function signature.
|
|
128
|
+
unsafe { u8::to_napi_value(env, ENTRY_TYPE) }
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
|
package/src/trace.rs
CHANGED
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
use std::sync::Arc;
|
|
9
9
|
|
|
10
|
-
use
|
|
10
|
+
use edr_eth::{bytecode::opcode::OpCode, l1};
|
|
11
|
+
use edr_evm::trace::BeforeMessage;
|
|
11
12
|
use napi::{
|
|
12
|
-
bindgen_prelude::{BigInt, Buffer, Either3},
|
|
13
13
|
Env, JsBuffer, JsBufferValue,
|
|
14
|
+
bindgen_prelude::{BigInt, Buffer, Either3},
|
|
14
15
|
};
|
|
15
16
|
use napi_derive::napi;
|
|
16
17
|
|
|
@@ -150,7 +151,7 @@ impl TracingStep {
|
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
pub(crate) fn u256_to_bigint(v: &
|
|
154
|
+
pub(crate) fn u256_to_bigint(v: &edr_eth::U256) -> BigInt {
|
|
154
155
|
BigInt {
|
|
155
156
|
sign_bit: false,
|
|
156
157
|
words: v.into_limbs().to_vec(),
|
|
@@ -165,13 +166,14 @@ pub struct TracingMessageResult {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
#[napi]
|
|
169
|
+
#[derive(Clone)]
|
|
168
170
|
pub struct RawTrace {
|
|
169
|
-
|
|
171
|
+
inner: Arc<edr_evm::trace::Trace<l1::HaltReason>>,
|
|
170
172
|
}
|
|
171
173
|
|
|
172
|
-
impl RawTrace {
|
|
173
|
-
|
|
174
|
-
Self { inner }
|
|
174
|
+
impl From<Arc<edr_evm::trace::Trace<l1::HaltReason>>> for RawTrace {
|
|
175
|
+
fn from(value: Arc<edr_evm::trace::Trace<l1::HaltReason>>) -> Self {
|
|
176
|
+
Self { inner: value }
|
|
175
177
|
}
|
|
176
178
|
}
|
|
177
179
|
|