@nomicfoundation/edr 0.12.0-next.2 → 0.12.0-next.20
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/index.d.ts +220 -62
- package/index.js +5 -1
- package/package.json +12 -12
- package/src/account.rs +7 -6
- package/src/block.rs +1 -1
- package/src/call_override.rs +1 -1
- package/src/cast.rs +1 -1
- package/src/chains/generic.rs +27 -20
- package/src/chains/l1.rs +93 -81
- package/src/chains/op.rs +140 -115
- package/src/config.rs +182 -15
- package/src/context.rs +69 -73
- package/src/contract_decoder.rs +57 -0
- package/src/debug_trace.rs +2 -0
- package/src/gas_report.rs +92 -0
- package/src/lib.rs +4 -1
- package/src/log.rs +2 -2
- package/src/logger.rs +4 -2
- package/src/mock/time.rs +134 -0
- package/src/mock.rs +4 -1
- package/src/precompile.rs +7 -7
- package/src/provider/response.rs +4 -4
- package/src/provider.rs +51 -4
- package/src/result.rs +42 -83
- package/src/serde.rs +1 -1
- package/src/solidity_tests/config.rs +93 -19
- package/src/solidity_tests/l1.rs +11 -7
- package/src/solidity_tests/op.rs +11 -8
- package/src/solidity_tests/runner.rs +1 -1
- package/src/solidity_tests/test_results.rs +122 -37
- package/src/solidity_tests.rs +1 -1
- package/src/trace/debug.rs +29 -26
- package/src/trace/exit.rs +9 -8
- package/src/trace/return_data.rs +19 -7
- package/src/trace/solidity_stack_trace.rs +56 -28
- package/src/trace.rs +11 -10
- package/src/withdrawal.rs +5 -5
package/src/context.rs
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
|
-
use
|
|
4
|
-
use
|
|
5
|
-
provider::{self, SyncProviderFactory},
|
|
6
|
-
solidity,
|
|
7
|
-
};
|
|
8
|
-
use edr_solidity::contract_decoder::ContractDecoder;
|
|
3
|
+
use edr_napi_core::{provider::SyncProviderFactory, solidity};
|
|
4
|
+
use edr_primitives::HashMap;
|
|
9
5
|
use edr_solidity_tests::{
|
|
10
6
|
decode::RevertDecoder,
|
|
11
7
|
multi_runner::{SuiteResultAndArtifactId, TestContract, TestContracts},
|
|
@@ -22,14 +18,15 @@ use napi_derive::napi;
|
|
|
22
18
|
use tracing_subscriber::{prelude::*, EnvFilter, Registry};
|
|
23
19
|
|
|
24
20
|
use crate::{
|
|
25
|
-
config::{ProviderConfig, TracingConfigWithBuffers},
|
|
21
|
+
config::{resolve_configs, ConfigResolution, ProviderConfig, TracingConfigWithBuffers},
|
|
22
|
+
contract_decoder::ContractDecoder,
|
|
26
23
|
logger::LoggerConfig,
|
|
27
24
|
provider::{Provider, ProviderFactory},
|
|
28
25
|
solidity_tests::{
|
|
29
26
|
artifact::{Artifact, ArtifactId},
|
|
30
27
|
config::SolidityTestRunnerConfigArgs,
|
|
31
28
|
factory::SolidityTestRunnerFactory,
|
|
32
|
-
test_results::SuiteResult,
|
|
29
|
+
test_results::{SolidityTestResult, SuiteResult},
|
|
33
30
|
LinkingOutput,
|
|
34
31
|
},
|
|
35
32
|
subscription::SubscriptionConfig,
|
|
@@ -42,7 +39,7 @@ pub struct EdrContext {
|
|
|
42
39
|
|
|
43
40
|
#[napi]
|
|
44
41
|
impl EdrContext {
|
|
45
|
-
|
|
42
|
+
/// Creates a new [`EdrContext`] instance. Should only be called once!
|
|
46
43
|
#[napi(catch_unwind, constructor)]
|
|
47
44
|
pub fn new() -> napi::Result<Self> {
|
|
48
45
|
let context = Context::new()?;
|
|
@@ -52,7 +49,7 @@ impl EdrContext {
|
|
|
52
49
|
})
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
/// Constructs a new provider with the provided configuration.
|
|
56
53
|
#[napi(catch_unwind, ts_return_type = "Promise<Provider>")]
|
|
57
54
|
pub fn create_provider(
|
|
58
55
|
&self,
|
|
@@ -61,7 +58,7 @@ impl EdrContext {
|
|
|
61
58
|
provider_config: ProviderConfig,
|
|
62
59
|
logger_config: LoggerConfig,
|
|
63
60
|
subscription_config: SubscriptionConfig,
|
|
64
|
-
|
|
61
|
+
contract_decoder: &ContractDecoder,
|
|
65
62
|
) -> napi::Result<JsObject> {
|
|
66
63
|
let (deferred, promise) = env.create_deferred()?;
|
|
67
64
|
|
|
@@ -78,25 +75,18 @@ impl EdrContext {
|
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
let runtime = runtime::Handle::current();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
);
|
|
94
|
-
|
|
95
|
-
let contract_decoder = try_or_reject_promise!(ContractDecoder::new(&build_info_config)
|
|
96
|
-
.map_or_else(
|
|
97
|
-
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
98
|
-
|contract_decoder| Ok(Arc::new(contract_decoder))
|
|
99
|
-
));
|
|
78
|
+
|
|
79
|
+
let ConfigResolution {
|
|
80
|
+
logger_config,
|
|
81
|
+
provider_config,
|
|
82
|
+
subscription_callback,
|
|
83
|
+
} = try_or_reject_promise!(resolve_configs(
|
|
84
|
+
&env,
|
|
85
|
+
runtime.clone(),
|
|
86
|
+
provider_config,
|
|
87
|
+
logger_config,
|
|
88
|
+
subscription_config,
|
|
89
|
+
));
|
|
100
90
|
|
|
101
91
|
#[cfg(feature = "scenarios")]
|
|
102
92
|
let scenario_file =
|
|
@@ -106,31 +96,33 @@ impl EdrContext {
|
|
|
106
96
|
logger_config.enable,
|
|
107
97
|
)));
|
|
108
98
|
|
|
109
|
-
let
|
|
99
|
+
let factory = {
|
|
110
100
|
// TODO: https://github.com/NomicFoundation/edr/issues/760
|
|
111
101
|
// TODO: Don't block the JS event loop
|
|
112
102
|
let context = runtime.block_on(async { self.inner.lock().await });
|
|
113
103
|
|
|
114
|
-
try_or_reject_promise!(context.
|
|
115
|
-
&env,
|
|
116
|
-
&chain_type,
|
|
117
|
-
provider_config,
|
|
118
|
-
logger_config,
|
|
119
|
-
subscription_config.into(),
|
|
120
|
-
&contract_decoder,
|
|
121
|
-
))
|
|
104
|
+
try_or_reject_promise!(context.get_provider_factory(&chain_type))
|
|
122
105
|
};
|
|
123
106
|
|
|
107
|
+
let contract_decoder = Arc::clone(contract_decoder.as_inner());
|
|
124
108
|
runtime.clone().spawn_blocking(move || {
|
|
125
|
-
let result =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
109
|
+
let result = factory
|
|
110
|
+
.create_provider(
|
|
111
|
+
runtime.clone(),
|
|
112
|
+
provider_config,
|
|
113
|
+
logger_config,
|
|
114
|
+
subscription_callback,
|
|
115
|
+
Arc::clone(&contract_decoder),
|
|
132
116
|
)
|
|
133
|
-
|
|
117
|
+
.map(|provider| {
|
|
118
|
+
Provider::new(
|
|
119
|
+
provider,
|
|
120
|
+
runtime,
|
|
121
|
+
contract_decoder,
|
|
122
|
+
#[cfg(feature = "scenarios")]
|
|
123
|
+
scenario_file,
|
|
124
|
+
)
|
|
125
|
+
});
|
|
134
126
|
|
|
135
127
|
deferred.resolve(|_env| result);
|
|
136
128
|
});
|
|
@@ -138,7 +130,7 @@ impl EdrContext {
|
|
|
138
130
|
Ok(promise)
|
|
139
131
|
}
|
|
140
132
|
|
|
141
|
-
|
|
133
|
+
/// Registers a new provider factory for the provided chain type.
|
|
142
134
|
#[napi(catch_unwind)]
|
|
143
135
|
pub async fn register_provider_factory(
|
|
144
136
|
&self,
|
|
@@ -161,14 +153,29 @@ impl EdrContext {
|
|
|
161
153
|
Ok(())
|
|
162
154
|
}
|
|
163
155
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
156
|
+
/// Executes Solidity tests
|
|
157
|
+
///
|
|
158
|
+
/// The function will return a promise that resolves to a
|
|
159
|
+
/// [`SolidityTestResult`].
|
|
160
|
+
///
|
|
161
|
+
/// Arguments:
|
|
162
|
+
/// - `chainType`: the same chain type that was passed to
|
|
163
|
+
/// `registerProviderFactory`.
|
|
164
|
+
/// - `artifacts`: the project's compilation output artifacts. It's
|
|
165
|
+
/// important to include include all artifacts here, otherwise cheatcodes
|
|
166
|
+
/// that access artifacts and other functionality (e.g. auto-linking, gas
|
|
167
|
+
/// reports) can break.
|
|
168
|
+
/// - `testSuites`: the test suite ids that specify which test suites to
|
|
169
|
+
/// execute. The test suite artifacts must be present in `artifacts`.
|
|
170
|
+
/// - `configArgs`: solidity test runner configuration. See the struct docs
|
|
171
|
+
/// for details.
|
|
172
|
+
/// - `tracingConfig`: the build infos used for stack trace generation.
|
|
173
|
+
/// These are lazily parsed and it's important that they're passed as
|
|
174
|
+
/// Uint8 arrays for performance.
|
|
175
|
+
/// - `onTestSuiteCompletedCallback`: The progress callback will be called
|
|
176
|
+
/// with the results of each test suite as soon as it finished executing.
|
|
170
177
|
#[allow(clippy::too_many_arguments)]
|
|
171
|
-
#[napi(catch_unwind, ts_return_type = "Promise<
|
|
178
|
+
#[napi(catch_unwind, ts_return_type = "Promise<SolidityTestResult>")]
|
|
172
179
|
pub fn run_solidity_tests(
|
|
173
180
|
&self,
|
|
174
181
|
env: Env,
|
|
@@ -299,7 +306,7 @@ impl EdrContext {
|
|
|
299
306
|
.expect("Failed to join test runner factory thread"));
|
|
300
307
|
|
|
301
308
|
let runtime_for_runner = runtime.clone();
|
|
302
|
-
let
|
|
309
|
+
let test_result = try_or_reject_deferred!(runtime
|
|
303
310
|
.clone()
|
|
304
311
|
.spawn_blocking(move || {
|
|
305
312
|
test_runner.run_tests(
|
|
@@ -331,7 +338,7 @@ impl EdrContext {
|
|
|
331
338
|
.await
|
|
332
339
|
.expect("Failed to join test runner thread"));
|
|
333
340
|
|
|
334
|
-
deferred.resolve(move |_env| Ok(()));
|
|
341
|
+
deferred.resolve(move |_env| Ok(SolidityTestResult::from(test_result)));
|
|
335
342
|
});
|
|
336
343
|
|
|
337
344
|
Ok(promise)
|
|
@@ -383,8 +390,8 @@ impl Context {
|
|
|
383
390
|
}
|
|
384
391
|
|
|
385
392
|
Ok(Self {
|
|
386
|
-
provider_factories: HashMap::
|
|
387
|
-
solidity_test_runner_factories: HashMap::
|
|
393
|
+
provider_factories: HashMap::default(),
|
|
394
|
+
solidity_test_runner_factories: HashMap::default(),
|
|
388
395
|
#[cfg(feature = "tracing")]
|
|
389
396
|
_tracing_write_guard: guard,
|
|
390
397
|
})
|
|
@@ -410,23 +417,12 @@ impl Context {
|
|
|
410
417
|
|
|
411
418
|
/// Tries to create a new provider for the provided chain type and
|
|
412
419
|
/// configuration.
|
|
413
|
-
pub fn
|
|
420
|
+
pub fn get_provider_factory(
|
|
414
421
|
&self,
|
|
415
|
-
env: &napi::Env,
|
|
416
422
|
chain_type: &str,
|
|
417
|
-
|
|
418
|
-
logger_config: edr_napi_core::logger::Config,
|
|
419
|
-
subscription_config: edr_napi_core::subscription::Config,
|
|
420
|
-
contract_decoder: &Arc<ContractDecoder>,
|
|
421
|
-
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
423
|
+
) -> napi::Result<Arc<dyn SyncProviderFactory>> {
|
|
422
424
|
if let Some(factory) = self.provider_factories.get(chain_type) {
|
|
423
|
-
factory
|
|
424
|
-
env,
|
|
425
|
-
provider_config,
|
|
426
|
-
logger_config,
|
|
427
|
-
subscription_config,
|
|
428
|
-
contract_decoder.clone(),
|
|
429
|
-
)
|
|
425
|
+
Ok(Arc::clone(factory))
|
|
430
426
|
} else {
|
|
431
427
|
Err(napi::Error::new(
|
|
432
428
|
napi::Status::GenericFailure,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use napi_derive::napi;
|
|
4
|
+
|
|
5
|
+
use crate::config::TracingConfigWithBuffers;
|
|
6
|
+
|
|
7
|
+
#[napi]
|
|
8
|
+
pub struct ContractDecoder {
|
|
9
|
+
inner: Arc<edr_solidity::contract_decoder::ContractDecoder>,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
#[napi]
|
|
13
|
+
impl ContractDecoder {
|
|
14
|
+
#[doc = "Creates an empty instance."]
|
|
15
|
+
#[napi(constructor, catch_unwind)]
|
|
16
|
+
// Following TS convention for the constructor without arguments to be `new()`.
|
|
17
|
+
#[allow(clippy::new_without_default)]
|
|
18
|
+
pub fn new() -> Self {
|
|
19
|
+
Self {
|
|
20
|
+
inner: Arc::new(edr_solidity::contract_decoder::ContractDecoder::default()),
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#[doc = "Creates a new instance with the provided configuration."]
|
|
25
|
+
#[napi(factory, catch_unwind)]
|
|
26
|
+
pub fn with_contracts(config: TracingConfigWithBuffers) -> napi::Result<Self> {
|
|
27
|
+
let build_info_config = edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
|
|
28
|
+
(&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(config)).into(),
|
|
29
|
+
)
|
|
30
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
31
|
+
|
|
32
|
+
let contract_decoder =
|
|
33
|
+
edr_solidity::contract_decoder::ContractDecoder::new(&build_info_config).map_or_else(
|
|
34
|
+
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
35
|
+
|contract_decoder| Ok(Arc::new(contract_decoder)),
|
|
36
|
+
)?;
|
|
37
|
+
|
|
38
|
+
Ok(Self {
|
|
39
|
+
inner: contract_decoder,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
impl ContractDecoder {
|
|
45
|
+
/// Returns a reference to the inner contract decoder.
|
|
46
|
+
pub fn as_inner(&self) -> &Arc<edr_solidity::contract_decoder::ContractDecoder> {
|
|
47
|
+
&self.inner
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
impl From<Arc<edr_solidity::contract_decoder::ContractDecoder>> for ContractDecoder {
|
|
52
|
+
fn from(contract_decoder: Arc<edr_solidity::contract_decoder::ContractDecoder>) -> Self {
|
|
53
|
+
Self {
|
|
54
|
+
inner: contract_decoder,
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
package/src/debug_trace.rs
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
|
|
3
|
+
use napi::bindgen_prelude::BigInt;
|
|
4
|
+
use napi_derive::napi;
|
|
5
|
+
|
|
6
|
+
#[napi(object)]
|
|
7
|
+
pub struct GasReport {
|
|
8
|
+
pub contracts: HashMap<String, ContractGasReport>,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[napi(object)]
|
|
12
|
+
pub struct ContractGasReport {
|
|
13
|
+
pub deployments: Vec<DeploymentGasReport>,
|
|
14
|
+
pub functions: HashMap<String, Vec<FunctionGasReport>>,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#[napi]
|
|
18
|
+
pub enum GasReportExecutionStatus {
|
|
19
|
+
Success,
|
|
20
|
+
Revert,
|
|
21
|
+
Halt,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#[napi(object)]
|
|
25
|
+
pub struct DeploymentGasReport {
|
|
26
|
+
pub gas: BigInt,
|
|
27
|
+
pub size: BigInt,
|
|
28
|
+
pub status: GasReportExecutionStatus,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[napi(object)]
|
|
32
|
+
pub struct FunctionGasReport {
|
|
33
|
+
pub gas: BigInt,
|
|
34
|
+
pub status: GasReportExecutionStatus,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl From<edr_gas_report::GasReport> for GasReport {
|
|
38
|
+
fn from(value: edr_gas_report::GasReport) -> Self {
|
|
39
|
+
Self {
|
|
40
|
+
contracts: value
|
|
41
|
+
.into_inner()
|
|
42
|
+
.into_iter()
|
|
43
|
+
.map(|(k, v)| (k, v.into()))
|
|
44
|
+
.collect(),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
impl From<edr_gas_report::ContractGasReport> for ContractGasReport {
|
|
50
|
+
fn from(value: edr_gas_report::ContractGasReport) -> Self {
|
|
51
|
+
Self {
|
|
52
|
+
deployments: value.deployments.into_iter().map(Into::into).collect(),
|
|
53
|
+
functions: value
|
|
54
|
+
.functions
|
|
55
|
+
.into_iter()
|
|
56
|
+
.map(|(k, v)| {
|
|
57
|
+
let function_reports = v.into_iter().map(FunctionGasReport::from).collect();
|
|
58
|
+
(k, function_reports)
|
|
59
|
+
})
|
|
60
|
+
.collect(),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
impl From<edr_gas_report::GasReportExecutionStatus> for GasReportExecutionStatus {
|
|
66
|
+
fn from(value: edr_gas_report::GasReportExecutionStatus) -> Self {
|
|
67
|
+
match value {
|
|
68
|
+
edr_gas_report::GasReportExecutionStatus::Success => Self::Success,
|
|
69
|
+
edr_gas_report::GasReportExecutionStatus::Revert => Self::Revert,
|
|
70
|
+
edr_gas_report::GasReportExecutionStatus::Halt => Self::Halt,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
impl From<edr_gas_report::DeploymentGasReport> for DeploymentGasReport {
|
|
76
|
+
fn from(value: edr_gas_report::DeploymentGasReport) -> Self {
|
|
77
|
+
Self {
|
|
78
|
+
gas: BigInt::from(value.gas),
|
|
79
|
+
size: BigInt::from(value.size),
|
|
80
|
+
status: value.status.into(),
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl From<edr_gas_report::FunctionGasReport> for FunctionGasReport {
|
|
86
|
+
fn from(value: edr_gas_report::FunctionGasReport) -> Self {
|
|
87
|
+
Self {
|
|
88
|
+
gas: BigInt::from(value.gas),
|
|
89
|
+
status: value.status.into(),
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/lib.rs
CHANGED
|
@@ -17,7 +17,10 @@ pub mod chains;
|
|
|
17
17
|
pub mod config;
|
|
18
18
|
/// Types related to an EDR N-API context.
|
|
19
19
|
pub mod context;
|
|
20
|
+
/// Types for decoding smart contract data.
|
|
21
|
+
pub mod contract_decoder;
|
|
20
22
|
mod debug_trace;
|
|
23
|
+
pub mod gas_report;
|
|
21
24
|
/// Types and functions related to code coverage instrumentation.
|
|
22
25
|
pub mod instrument;
|
|
23
26
|
/// Types for EVM execution logs.
|
|
@@ -26,7 +29,7 @@ pub mod log;
|
|
|
26
29
|
pub mod logger;
|
|
27
30
|
/// Types for mocking provider behavior.
|
|
28
31
|
#[cfg(feature = "test-mock")]
|
|
29
|
-
mod mock;
|
|
32
|
+
pub mod mock;
|
|
30
33
|
/// Types for precompiles.
|
|
31
34
|
pub mod precompile;
|
|
32
35
|
/// Types for Ethereum RPC providers.
|
package/src/log.rs
CHANGED
|
@@ -9,8 +9,8 @@ pub struct ExecutionLog {
|
|
|
9
9
|
pub data: Uint8Array,
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
impl From<&
|
|
13
|
-
fn from(value: &
|
|
12
|
+
impl From<&edr_receipt::log::ExecutionLog> for ExecutionLog {
|
|
13
|
+
fn from(value: &edr_receipt::log::ExecutionLog) -> Self {
|
|
14
14
|
let topics = value
|
|
15
15
|
.topics()
|
|
16
16
|
.iter()
|
package/src/logger.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use std::sync::{mpsc::channel, Arc};
|
|
2
2
|
|
|
3
|
-
use edr_eth::Bytes;
|
|
4
3
|
use edr_napi_core::logger::LoggerError;
|
|
4
|
+
use edr_primitives::Bytes;
|
|
5
5
|
use napi::{
|
|
6
6
|
threadsafe_function::{
|
|
7
7
|
ErrorStrategy, ThreadSafeCallContext, ThreadsafeFunction, ThreadsafeFunctionCallMode,
|
|
@@ -65,7 +65,9 @@ impl LoggerConfig {
|
|
|
65
65
|
);
|
|
66
66
|
assert_eq!(status, Status::Ok);
|
|
67
67
|
|
|
68
|
-
receiver
|
|
68
|
+
receiver
|
|
69
|
+
.recv()
|
|
70
|
+
.expect("Receive can only fail if the channel is closed")
|
|
69
71
|
});
|
|
70
72
|
|
|
71
73
|
let mut print_line_callback: ThreadsafeFunction<_, ErrorStrategy::Fatal> = self
|
package/src/mock/time.rs
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use edr_chain_spec::ChainSpec;
|
|
4
|
+
use edr_chain_spec_block::BlockChainSpec;
|
|
5
|
+
use edr_chain_spec_rpc::RpcBlockChainSpec;
|
|
6
|
+
use edr_generic::GenericChainSpec;
|
|
7
|
+
use edr_napi_core::logger::Logger;
|
|
8
|
+
use edr_primitives::B256;
|
|
9
|
+
use napi::{bindgen_prelude::BigInt, tokio::runtime, Env, JsObject};
|
|
10
|
+
use napi_derive::napi;
|
|
11
|
+
|
|
12
|
+
use crate::{
|
|
13
|
+
cast::TryCast as _,
|
|
14
|
+
config::{resolve_configs, ConfigResolution, ProviderConfig},
|
|
15
|
+
contract_decoder::ContractDecoder,
|
|
16
|
+
logger::LoggerConfig,
|
|
17
|
+
provider::Provider,
|
|
18
|
+
subscription::SubscriptionConfig,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
#[napi]
|
|
22
|
+
pub struct MockTime {
|
|
23
|
+
inner: Arc<edr_provider::time::MockTime>,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#[napi]
|
|
27
|
+
impl MockTime {
|
|
28
|
+
#[doc = "Creates a new instance of `MockTime` with the current time."]
|
|
29
|
+
#[napi(factory, catch_unwind)]
|
|
30
|
+
pub fn now() -> Self {
|
|
31
|
+
Self {
|
|
32
|
+
inner: Arc::new(edr_provider::time::MockTime::now()),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
#[doc = "Adds the specified number of seconds to the current time."]
|
|
37
|
+
#[napi(catch_unwind)]
|
|
38
|
+
pub fn add_seconds(&self, seconds: BigInt) -> napi::Result<()> {
|
|
39
|
+
let seconds = seconds.try_cast()?;
|
|
40
|
+
|
|
41
|
+
self.inner.add_seconds(seconds);
|
|
42
|
+
Ok(())
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#[doc = "Creates a provider with a mock timer."]
|
|
47
|
+
#[doc = "For testing purposes."]
|
|
48
|
+
#[napi(catch_unwind, ts_return_type = "Promise<Provider>")]
|
|
49
|
+
pub fn create_provider_with_mock_timer(
|
|
50
|
+
env: Env,
|
|
51
|
+
provider_config: ProviderConfig,
|
|
52
|
+
logger_config: LoggerConfig,
|
|
53
|
+
subscription_config: SubscriptionConfig,
|
|
54
|
+
contract_decoder: &ContractDecoder,
|
|
55
|
+
time: &MockTime,
|
|
56
|
+
) -> napi::Result<JsObject> {
|
|
57
|
+
let (deferred, promise) = env.create_deferred()?;
|
|
58
|
+
|
|
59
|
+
macro_rules! try_or_reject_promise {
|
|
60
|
+
($expr:expr) => {
|
|
61
|
+
match $expr {
|
|
62
|
+
Ok(value) => value,
|
|
63
|
+
Err(error) => {
|
|
64
|
+
deferred.reject(error);
|
|
65
|
+
return Ok(promise);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let runtime = runtime::Handle::current();
|
|
72
|
+
|
|
73
|
+
let ConfigResolution {
|
|
74
|
+
logger_config,
|
|
75
|
+
provider_config,
|
|
76
|
+
subscription_callback,
|
|
77
|
+
} = try_or_reject_promise!(resolve_configs(
|
|
78
|
+
&env,
|
|
79
|
+
runtime.clone(),
|
|
80
|
+
provider_config,
|
|
81
|
+
logger_config,
|
|
82
|
+
subscription_config,
|
|
83
|
+
));
|
|
84
|
+
|
|
85
|
+
let contract_decoder = Arc::clone(contract_decoder.as_inner());
|
|
86
|
+
let timer = Arc::clone(&time.inner);
|
|
87
|
+
|
|
88
|
+
runtime.clone().spawn_blocking(move || {
|
|
89
|
+
// Using a closure to limit the scope, allowing us to use `?` for error
|
|
90
|
+
// handling. This is necessary because the result of the closure is used
|
|
91
|
+
// to resolve the deferred promise.
|
|
92
|
+
let create_provider = move || -> napi::Result<Provider> {
|
|
93
|
+
let logger = Logger::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
|
|
94
|
+
logger_config,
|
|
95
|
+
Arc::clone(&contract_decoder),
|
|
96
|
+
)?;
|
|
97
|
+
|
|
98
|
+
let provider_config =
|
|
99
|
+
edr_provider::ProviderConfig::<edr_chain_l1::Hardfork>::try_from(provider_config)?;
|
|
100
|
+
|
|
101
|
+
let provider =
|
|
102
|
+
edr_provider::Provider::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
|
|
103
|
+
runtime.clone(),
|
|
104
|
+
Box::new(logger),
|
|
105
|
+
Box::new(move |event| {
|
|
106
|
+
let event = edr_napi_core::subscription::SubscriptionEvent::new::<
|
|
107
|
+
<GenericChainSpec as BlockChainSpec>::Block,
|
|
108
|
+
<GenericChainSpec as RpcBlockChainSpec>::RpcBlock<B256>,
|
|
109
|
+
<GenericChainSpec as ChainSpec>::SignedTransaction,
|
|
110
|
+
>(event);
|
|
111
|
+
|
|
112
|
+
subscription_callback.call(event);
|
|
113
|
+
}),
|
|
114
|
+
provider_config,
|
|
115
|
+
Arc::clone(&contract_decoder),
|
|
116
|
+
timer,
|
|
117
|
+
)
|
|
118
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
119
|
+
|
|
120
|
+
Ok(Provider::new(
|
|
121
|
+
Arc::new(provider),
|
|
122
|
+
runtime,
|
|
123
|
+
contract_decoder,
|
|
124
|
+
#[cfg(feature = "scenarios")]
|
|
125
|
+
None,
|
|
126
|
+
))
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
let result = create_provider();
|
|
130
|
+
deferred.resolve(|_env| result);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
Ok(promise)
|
|
134
|
+
}
|
package/src/mock.rs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
pub mod time;
|
|
2
|
+
|
|
1
3
|
use std::sync::Arc;
|
|
2
4
|
|
|
5
|
+
use edr_chain_spec::EvmHaltReason;
|
|
3
6
|
use edr_napi_core::provider::SyncProvider;
|
|
4
7
|
use edr_rpc_client::jsonrpc;
|
|
5
8
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
@@ -24,7 +27,7 @@ impl SyncProvider for MockProvider {
|
|
|
24
27
|
&self,
|
|
25
28
|
_request: String,
|
|
26
29
|
_contract_decoder: Arc<ContractDecoder>,
|
|
27
|
-
) -> napi::Result<edr_napi_core::spec::Response<
|
|
30
|
+
) -> napi::Result<edr_napi_core::spec::Response<EvmHaltReason>> {
|
|
28
31
|
let response = jsonrpc::ResponseData::Success {
|
|
29
32
|
result: self.mocked_response.clone(),
|
|
30
33
|
};
|
package/src/precompile.rs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
use
|
|
2
|
-
use
|
|
1
|
+
use edr_precompile::PrecompileFn;
|
|
2
|
+
use edr_primitives::Address;
|
|
3
3
|
use napi::bindgen_prelude::Uint8Array;
|
|
4
4
|
use napi_derive::napi;
|
|
5
5
|
|
|
@@ -24,11 +24,11 @@ impl Precompile {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
impl From<
|
|
28
|
-
fn from(value:
|
|
27
|
+
impl From<edr_precompile::Precompile> for Precompile {
|
|
28
|
+
fn from(value: edr_precompile::Precompile) -> Self {
|
|
29
29
|
Self {
|
|
30
|
-
address: value.
|
|
31
|
-
precompile_fn: value.
|
|
30
|
+
address: *value.address(),
|
|
31
|
+
precompile_fn: value.into_precompile(),
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -46,5 +46,5 @@ impl Precompile {
|
|
|
46
46
|
/// secp256r1 precompile.
|
|
47
47
|
#[napi(catch_unwind)]
|
|
48
48
|
pub fn precompile_p256_verify() -> Precompile {
|
|
49
|
-
Precompile::from(
|
|
49
|
+
Precompile::from(edr_precompile::secp256r1::P256VERIFY)
|
|
50
50
|
}
|
package/src/provider/response.rs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use
|
|
1
|
+
use edr_chain_spec::EvmHaltReason;
|
|
2
2
|
use edr_napi_core::spec::SolidityTraceData;
|
|
3
3
|
use edr_solidity::contract_decoder::NestedTraceDecoder as _;
|
|
4
4
|
use napi::Either;
|
|
@@ -11,11 +11,11 @@ use crate::{
|
|
|
11
11
|
|
|
12
12
|
#[napi]
|
|
13
13
|
pub struct Response {
|
|
14
|
-
inner: edr_napi_core::spec::Response<
|
|
14
|
+
inner: edr_napi_core::spec::Response<EvmHaltReason>,
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
impl From<edr_napi_core::spec::Response<
|
|
18
|
-
fn from(value: edr_napi_core::spec::Response<
|
|
17
|
+
impl From<edr_napi_core::spec::Response<EvmHaltReason>> for Response {
|
|
18
|
+
fn from(value: edr_napi_core::spec::Response<EvmHaltReason>) -> Self {
|
|
19
19
|
Self { inner: value }
|
|
20
20
|
}
|
|
21
21
|
}
|