@nomicfoundation/edr 0.12.0-next.1 → 0.12.0-next.3
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 +17 -6
- package/package.json +25 -20
- package/src/chains/generic.rs +6 -3
- package/src/chains/l1.rs +4 -3
- package/src/chains/op.rs +3 -1
- package/src/config.rs +2 -2
- package/src/context.rs +30 -19
- package/src/lib.rs +1 -1
- package/src/logger.rs +3 -1
- package/src/mock/time.rs +131 -0
- package/src/mock.rs +11 -0
- package/src/provider.rs +26 -0
- package/src/solidity_tests/test_results.rs +7 -9
- package/src/trace/debug.rs +26 -25
- package/src/trace/solidity_stack_trace.rs +53 -26
- package/src/ts/solidity_tests.ts +46 -0
- package/Cargo.toml +0 -92
- package/build.rs +0 -3
package/index.d.ts
CHANGED
|
@@ -982,11 +982,10 @@ export interface CallTrace {
|
|
|
982
982
|
gasUsed: bigint
|
|
983
983
|
/** The amount of native token that was included with the call. */
|
|
984
984
|
value: bigint
|
|
985
|
-
/**
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
contract: string
|
|
985
|
+
/** The target address of the call. */
|
|
986
|
+
address: string
|
|
987
|
+
/** The name of the contract that is the target of the call, if known. */
|
|
988
|
+
contract?: string
|
|
990
989
|
/**
|
|
991
990
|
* The input (calldata) to the call. If it encodes a known function call,
|
|
992
991
|
* it will be decoded into the function name and a list of arguments.
|
|
@@ -1116,7 +1115,8 @@ export enum StackTraceEntryType {
|
|
|
1116
1115
|
UNMAPPED_SOLC_0_6_3_REVERT_ERROR = 20,
|
|
1117
1116
|
CONTRACT_TOO_LARGE_ERROR = 21,
|
|
1118
1117
|
INTERNAL_FUNCTION_CALLSTACK_ENTRY = 22,
|
|
1119
|
-
CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR = 23
|
|
1118
|
+
CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR = 23,
|
|
1119
|
+
CHEATCODE_ERROR = 24
|
|
1120
1120
|
}
|
|
1121
1121
|
export declare function stackTraceEntryTypeToString(val: StackTraceEntryType): string
|
|
1122
1122
|
export const FALLBACK_FUNCTION_NAME: string
|
|
@@ -1246,6 +1246,11 @@ export interface ContractCallRunOutOfGasError {
|
|
|
1246
1246
|
type: StackTraceEntryType.CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR
|
|
1247
1247
|
sourceReference?: SourceReference
|
|
1248
1248
|
}
|
|
1249
|
+
export interface CheatcodeErrorStackTraceEntry {
|
|
1250
|
+
type: StackTraceEntryType.CHEATCODE_ERROR
|
|
1251
|
+
message: string
|
|
1252
|
+
sourceReference: SourceReference
|
|
1253
|
+
}
|
|
1249
1254
|
export interface TracingMessage {
|
|
1250
1255
|
/** Sender address */
|
|
1251
1256
|
readonly caller: Uint8Array
|
|
@@ -1337,6 +1342,12 @@ export declare class Response {
|
|
|
1337
1342
|
}
|
|
1338
1343
|
/** A JSON-RPC provider for Ethereum. */
|
|
1339
1344
|
export declare class Provider {
|
|
1345
|
+
/**
|
|
1346
|
+
*Adds a compilation result to the instance.
|
|
1347
|
+
*
|
|
1348
|
+
*For internal use only. Support for this method may be removed in the future.
|
|
1349
|
+
*/
|
|
1350
|
+
addCompilationResult(solcVersion: string, compilerInput: any, compilerOutput: any): Promise<boolean>
|
|
1340
1351
|
/**Handles a JSON-RPC request and returns a JSON-RPC response. */
|
|
1341
1352
|
handleRequest(request: string): Promise<Response>
|
|
1342
1353
|
setCallOverrideCallback(callOverrideCallback: (contract_address: ArrayBuffer, data: ArrayBuffer) => Promise<CallOverrideResult | undefined>): Promise<void>
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomicfoundation/edr",
|
|
3
|
-
"version": "0.12.0-next.
|
|
3
|
+
"version": "0.12.0-next.3",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@napi-rs/cli": "^2.18.4",
|
|
6
6
|
"@nomicfoundation/ethereumjs-util": "^9.0.4",
|
|
7
|
+
"@tsconfig/node20": "^20.1.6",
|
|
7
8
|
"@types/chai": "^4.2.0",
|
|
8
9
|
"@types/chai-as-promised": "^7.1.8",
|
|
9
10
|
"@types/mocha": ">=9.1.0",
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
"@typescript-eslint/parser": "5.61.0",
|
|
13
14
|
"chai": "^4.3.6",
|
|
14
15
|
"chai-as-promised": "^7.1.1",
|
|
16
|
+
"chalk": "^2.4.2",
|
|
15
17
|
"eslint": "^8.44.0",
|
|
16
18
|
"eslint-config-prettier": "9.1.0",
|
|
17
19
|
"eslint-plugin-import": "2.27.5",
|
|
@@ -25,14 +27,17 @@
|
|
|
25
27
|
"typescript": "~5.8.2"
|
|
26
28
|
},
|
|
27
29
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
30
|
+
"node": ">= 20"
|
|
31
|
+
},
|
|
32
|
+
"exports": {
|
|
33
|
+
".": "./index.js",
|
|
34
|
+
"./solidity-tests": "./dist/src/ts/solidity_tests.js"
|
|
29
35
|
},
|
|
30
36
|
"files": [
|
|
31
37
|
"index.js",
|
|
32
38
|
"index.d.ts",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"src/"
|
|
39
|
+
"src/",
|
|
40
|
+
"dist/src/"
|
|
36
41
|
],
|
|
37
42
|
"license": "MIT",
|
|
38
43
|
"main": "index.js",
|
|
@@ -54,31 +59,31 @@
|
|
|
54
59
|
"repository": "NomicFoundation/edr.git",
|
|
55
60
|
"types": "index.d.ts",
|
|
56
61
|
"optionalDependencies": {
|
|
57
|
-
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.
|
|
58
|
-
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.
|
|
59
|
-
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.
|
|
60
|
-
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.
|
|
61
|
-
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.
|
|
62
|
-
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.
|
|
63
|
-
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.
|
|
62
|
+
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.3",
|
|
63
|
+
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.3",
|
|
64
|
+
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.3",
|
|
65
|
+
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.3",
|
|
66
|
+
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.3",
|
|
67
|
+
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.3",
|
|
68
|
+
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.3"
|
|
64
69
|
},
|
|
65
70
|
"scripts": {
|
|
66
71
|
"artifacts": "napi artifacts",
|
|
67
72
|
"build": "pnpm run build:publish",
|
|
68
|
-
"build:debug": "
|
|
69
|
-
"build:dev": "
|
|
70
|
-
"build:publish": "
|
|
71
|
-
"build:scenarios": "
|
|
72
|
-
"build:tracing": "
|
|
73
|
-
"build:typingFile": "
|
|
73
|
+
"build:debug": "bash ../../scripts/build_edr_napi.sh --features op",
|
|
74
|
+
"build:dev": "bash ../../scripts/build_edr_napi.sh --release --features op,test-mock",
|
|
75
|
+
"build:publish": "bash ../../scripts/build_edr_napi.sh --profile napi-publish --features op",
|
|
76
|
+
"build:scenarios": "bash ../../scripts/build_edr_napi.sh --release --features op,scenarios",
|
|
77
|
+
"build:tracing": "bash ../../scripts/build_edr_napi.sh --release --features op,tracing",
|
|
78
|
+
"build:typingFile": "bash ../../scripts/build_edr_napi.sh --features op",
|
|
74
79
|
"clean": "rm -rf @nomicfoundation/edr.node",
|
|
75
80
|
"eslint": "eslint 'test/**/*.ts'",
|
|
76
81
|
"lint": "pnpm run prettier && pnpm run eslint",
|
|
77
82
|
"lint:fix": "pnpm run prettier --write",
|
|
78
83
|
"pretest": "pnpm build:dev",
|
|
79
84
|
"prettier": "prettier --check \"test/**.ts\"",
|
|
80
|
-
"test": "
|
|
81
|
-
"testNoBuild": "
|
|
85
|
+
"test": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
|
|
86
|
+
"testNoBuild": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(logs|mock)}.ts\"",
|
|
82
87
|
"universal": "napi universal",
|
|
83
88
|
"version": "napi version"
|
|
84
89
|
}
|
package/src/chains/generic.rs
CHANGED
|
@@ -5,9 +5,9 @@ use edr_generic::GenericChainSpec;
|
|
|
5
5
|
use edr_napi_core::{
|
|
6
6
|
logger::{self, Logger},
|
|
7
7
|
provider::{self, ProviderBuilder, SyncProviderFactory},
|
|
8
|
-
spec::SyncNapiSpec as _,
|
|
9
8
|
subscription,
|
|
10
9
|
};
|
|
10
|
+
use edr_provider::time::CurrentTime;
|
|
11
11
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
12
12
|
use napi_derive::napi;
|
|
13
13
|
|
|
@@ -24,7 +24,10 @@ impl SyncProviderFactory for GenericChainProviderFactory {
|
|
|
24
24
|
subscription_config: subscription::Config,
|
|
25
25
|
contract_decoder: Arc<ContractDecoder>,
|
|
26
26
|
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
27
|
-
let logger = Logger::<GenericChainSpec>::new(
|
|
27
|
+
let logger = Logger::<GenericChainSpec, CurrentTime>::new(
|
|
28
|
+
logger_config,
|
|
29
|
+
Arc::clone(&contract_decoder),
|
|
30
|
+
)?;
|
|
28
31
|
|
|
29
32
|
let provider_config =
|
|
30
33
|
edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
|
|
@@ -42,7 +45,7 @@ impl SyncProviderFactory for GenericChainProviderFactory {
|
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
#[napi]
|
|
45
|
-
pub const GENERIC_CHAIN_TYPE: &str =
|
|
48
|
+
pub const GENERIC_CHAIN_TYPE: &str = edr_generic::CHAIN_TYPE;
|
|
46
49
|
|
|
47
50
|
#[napi(catch_unwind)]
|
|
48
51
|
pub fn generic_chain_provider_factory() -> ProviderFactory {
|
package/src/chains/l1.rs
CHANGED
|
@@ -8,9 +8,9 @@ use edr_evm::eips::{
|
|
|
8
8
|
use edr_napi_core::{
|
|
9
9
|
logger::Logger,
|
|
10
10
|
provider::{self, ProviderBuilder, SyncProviderFactory},
|
|
11
|
-
spec::SyncNapiSpec as _,
|
|
12
11
|
subscription,
|
|
13
12
|
};
|
|
13
|
+
use edr_provider::time::CurrentTime;
|
|
14
14
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
15
15
|
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
|
16
16
|
use napi_derive::napi;
|
|
@@ -28,7 +28,8 @@ impl SyncProviderFactory for L1ProviderFactory {
|
|
|
28
28
|
subscription_config: edr_napi_core::subscription::Config,
|
|
29
29
|
contract_decoder: Arc<ContractDecoder>,
|
|
30
30
|
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
31
|
-
let logger =
|
|
31
|
+
let logger =
|
|
32
|
+
Logger::<L1ChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
|
32
33
|
|
|
33
34
|
let provider_config =
|
|
34
35
|
edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
|
|
@@ -46,7 +47,7 @@ impl SyncProviderFactory for L1ProviderFactory {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
#[napi]
|
|
49
|
-
pub const L1_CHAIN_TYPE: &str =
|
|
50
|
+
pub const L1_CHAIN_TYPE: &str = edr_eth::l1::CHAIN_TYPE;
|
|
50
51
|
|
|
51
52
|
#[napi(catch_unwind)]
|
|
52
53
|
pub fn l1_genesis_state(hardfork: SpecId) -> Vec<AccountOverride> {
|
package/src/chains/op.rs
CHANGED
|
@@ -7,6 +7,7 @@ use edr_napi_core::{
|
|
|
7
7
|
subscription,
|
|
8
8
|
};
|
|
9
9
|
use edr_op::{predeploys::GAS_PRICE_ORACLE_ADDRESS, OpChainSpec, OpSpecId};
|
|
10
|
+
use edr_provider::time::CurrentTime;
|
|
10
11
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
11
12
|
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
|
12
13
|
use napi_derive::napi;
|
|
@@ -27,7 +28,8 @@ impl SyncProviderFactory for OpProviderFactory {
|
|
|
27
28
|
subscription_config: subscription::Config,
|
|
28
29
|
contract_decoder: Arc<ContractDecoder>,
|
|
29
30
|
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
30
|
-
let logger =
|
|
31
|
+
let logger =
|
|
32
|
+
Logger::<OpChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
|
31
33
|
|
|
32
34
|
let provider_config = edr_provider::ProviderConfig::<OpSpecId>::try_from(provider_config)?;
|
|
33
35
|
|
package/src/config.rs
CHANGED
|
@@ -385,10 +385,10 @@ impl ObservabilityConfig {
|
|
|
385
385
|
Ok(())
|
|
386
386
|
});
|
|
387
387
|
|
|
388
|
-
let () = receiver.recv().expect("Receive can only fail if the channel is closed")?;
|
|
389
|
-
|
|
390
388
|
assert_eq!(status, napi::Status::Ok);
|
|
391
389
|
|
|
390
|
+
let () = receiver.recv().expect("Receive can only fail if the channel is closed")?;
|
|
391
|
+
|
|
392
392
|
Ok(())
|
|
393
393
|
});
|
|
394
394
|
|
package/src/context.rs
CHANGED
|
@@ -281,11 +281,12 @@ impl EdrContext {
|
|
|
281
281
|
|
|
282
282
|
let include_traces = config.include_traces.into();
|
|
283
283
|
|
|
284
|
+
let runtime_for_factory = runtime.clone();
|
|
284
285
|
let test_runner = try_or_reject_deferred!(runtime
|
|
285
286
|
.clone()
|
|
286
287
|
.spawn_blocking(move || {
|
|
287
288
|
factory.create_test_runner(
|
|
288
|
-
|
|
289
|
+
runtime_for_factory,
|
|
289
290
|
config,
|
|
290
291
|
contracts,
|
|
291
292
|
linking_output.known_contracts,
|
|
@@ -297,28 +298,38 @@ impl EdrContext {
|
|
|
297
298
|
.await
|
|
298
299
|
.expect("Failed to join test runner factory thread"));
|
|
299
300
|
|
|
300
|
-
let
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
301
|
+
let runtime_for_runner = runtime.clone();
|
|
302
|
+
let () = try_or_reject_deferred!(runtime
|
|
303
|
+
.clone()
|
|
304
|
+
.spawn_blocking(move || {
|
|
305
|
+
test_runner.run_tests(
|
|
306
|
+
runtime_for_runner,
|
|
307
|
+
test_filter,
|
|
308
|
+
Arc::new(
|
|
309
|
+
move |SuiteResultAndArtifactId {
|
|
310
|
+
artifact_id,
|
|
311
|
+
result,
|
|
312
|
+
}| {
|
|
313
|
+
let suite_result =
|
|
314
|
+
SuiteResult::new(artifact_id, result, include_traces);
|
|
315
|
+
|
|
316
|
+
let status = on_test_suite_completed_callback
|
|
317
|
+
.call(suite_result, ThreadsafeFunctionCallMode::Blocking);
|
|
318
|
+
|
|
319
|
+
// This should always succeed since we're using an unbounded queue.
|
|
320
|
+
// We add an assertion for
|
|
321
|
+
// completeness.
|
|
322
|
+
assert_eq!(
|
|
315
323
|
status,
|
|
316
324
|
napi::Status::Ok,
|
|
317
325
|
"Failed to call on_test_suite_completed_callback with status: {status}"
|
|
318
326
|
);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
327
|
+
},
|
|
328
|
+
),
|
|
329
|
+
)
|
|
330
|
+
})
|
|
331
|
+
.await
|
|
332
|
+
.expect("Failed to join test runner thread"));
|
|
322
333
|
|
|
323
334
|
deferred.resolve(move |_env| Ok(()));
|
|
324
335
|
});
|
package/src/lib.rs
CHANGED
package/src/logger.rs
CHANGED
|
@@ -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,131 @@
|
|
|
1
|
+
use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use edr_generic::GenericChainSpec;
|
|
4
|
+
use edr_napi_core::logger::Logger;
|
|
5
|
+
use edr_solidity::contract_decoder::ContractDecoder;
|
|
6
|
+
use napi::{bindgen_prelude::BigInt, tokio::runtime, Env, JsObject};
|
|
7
|
+
use napi_derive::napi;
|
|
8
|
+
|
|
9
|
+
use crate::{
|
|
10
|
+
cast::TryCast as _,
|
|
11
|
+
config::{ProviderConfig, TracingConfigWithBuffers},
|
|
12
|
+
logger::LoggerConfig,
|
|
13
|
+
provider::Provider,
|
|
14
|
+
subscription::SubscriptionConfig,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
#[napi]
|
|
18
|
+
pub struct MockTime {
|
|
19
|
+
inner: Arc<edr_provider::time::MockTime>,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#[napi]
|
|
23
|
+
impl MockTime {
|
|
24
|
+
#[doc = "Creates a new instance of `MockTime` with the current time."]
|
|
25
|
+
#[napi(factory, catch_unwind)]
|
|
26
|
+
pub fn now() -> Self {
|
|
27
|
+
Self {
|
|
28
|
+
inner: Arc::new(edr_provider::time::MockTime::now()),
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#[doc = "Adds the specified number of seconds to the current time."]
|
|
33
|
+
#[napi(catch_unwind)]
|
|
34
|
+
pub fn add_seconds(&self, seconds: BigInt) -> napi::Result<()> {
|
|
35
|
+
let seconds = seconds.try_cast()?;
|
|
36
|
+
|
|
37
|
+
self.inner.add_seconds(seconds);
|
|
38
|
+
Ok(())
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#[doc = "Creates a provider with a mock timer."]
|
|
43
|
+
#[doc = "For testing purposes."]
|
|
44
|
+
#[napi(catch_unwind, ts_return_type = "Promise<Provider>")]
|
|
45
|
+
pub fn create_provider_with_mock_timer(
|
|
46
|
+
env: Env,
|
|
47
|
+
provider_config: ProviderConfig,
|
|
48
|
+
logger_config: LoggerConfig,
|
|
49
|
+
subscription_config: SubscriptionConfig,
|
|
50
|
+
tracing_config: TracingConfigWithBuffers,
|
|
51
|
+
time: &MockTime,
|
|
52
|
+
) -> napi::Result<JsObject> {
|
|
53
|
+
let (deferred, promise) = env.create_deferred()?;
|
|
54
|
+
|
|
55
|
+
macro_rules! try_or_reject_promise {
|
|
56
|
+
($expr:expr) => {
|
|
57
|
+
match $expr {
|
|
58
|
+
Ok(value) => value,
|
|
59
|
+
Err(error) => {
|
|
60
|
+
deferred.reject(error);
|
|
61
|
+
return Ok(promise);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let runtime = runtime::Handle::current();
|
|
68
|
+
let provider_config = try_or_reject_promise!(provider_config.resolve(&env, runtime.clone()));
|
|
69
|
+
|
|
70
|
+
let logger_config = try_or_reject_promise!(logger_config.resolve(&env));
|
|
71
|
+
|
|
72
|
+
// TODO: https://github.com/NomicFoundation/edr/issues/760
|
|
73
|
+
let build_info_config = try_or_reject_promise!(
|
|
74
|
+
edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
|
|
75
|
+
(&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(tracing_config))
|
|
76
|
+
.into(),
|
|
77
|
+
)
|
|
78
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
let contract_decoder = try_or_reject_promise!(ContractDecoder::new(&build_info_config)
|
|
82
|
+
.map_or_else(
|
|
83
|
+
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
84
|
+
|contract_decoder| Ok(Arc::new(contract_decoder))
|
|
85
|
+
));
|
|
86
|
+
|
|
87
|
+
let subscription_config = edr_napi_core::subscription::Config::from(subscription_config);
|
|
88
|
+
let subscription_callback = try_or_reject_promise!(edr_napi_core::subscription::Callback::new(
|
|
89
|
+
&env,
|
|
90
|
+
subscription_config.subscription_callback,
|
|
91
|
+
));
|
|
92
|
+
|
|
93
|
+
let logger = try_or_reject_promise!(Logger::<
|
|
94
|
+
GenericChainSpec,
|
|
95
|
+
Arc<edr_provider::time::MockTime>,
|
|
96
|
+
>::new(logger_config, Arc::clone(&contract_decoder),));
|
|
97
|
+
|
|
98
|
+
let provider_config = try_or_reject_promise!(
|
|
99
|
+
edr_provider::ProviderConfig::<edr_eth::l1::SpecId>::try_from(provider_config)
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
let timer = Arc::clone(&time.inner);
|
|
103
|
+
|
|
104
|
+
runtime.clone().spawn_blocking(move || {
|
|
105
|
+
let result =
|
|
106
|
+
edr_provider::Provider::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
|
|
107
|
+
runtime.clone(),
|
|
108
|
+
Box::new(logger),
|
|
109
|
+
Box::new(move |event| subscription_callback.call(event)),
|
|
110
|
+
provider_config,
|
|
111
|
+
contract_decoder.clone(),
|
|
112
|
+
timer,
|
|
113
|
+
)
|
|
114
|
+
.map_or_else(
|
|
115
|
+
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
116
|
+
|provider| {
|
|
117
|
+
Ok(Provider::new(
|
|
118
|
+
Arc::new(provider),
|
|
119
|
+
runtime,
|
|
120
|
+
contract_decoder,
|
|
121
|
+
#[cfg(feature = "scenarios")]
|
|
122
|
+
None,
|
|
123
|
+
))
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
deferred.resolve(|_env| result);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
Ok(promise)
|
|
131
|
+
}
|
package/src/mock.rs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
pub mod time;
|
|
2
|
+
|
|
1
3
|
use std::sync::Arc;
|
|
2
4
|
|
|
3
5
|
use edr_napi_core::provider::SyncProvider;
|
|
@@ -20,6 +22,15 @@ impl MockProvider {
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
impl SyncProvider for MockProvider {
|
|
25
|
+
fn add_compilation_result(
|
|
26
|
+
&self,
|
|
27
|
+
_solc_version: String,
|
|
28
|
+
_compiler_input: edr_solidity::artifacts::CompilerInput,
|
|
29
|
+
_compiler_output: edr_solidity::artifacts::CompilerOutput,
|
|
30
|
+
) -> napi::Result<bool> {
|
|
31
|
+
Ok(false) // Mock provider does not handle compilation results
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
fn handle_request(
|
|
24
35
|
&self,
|
|
25
36
|
_request: String,
|
package/src/provider.rs
CHANGED
|
@@ -45,6 +45,32 @@ impl Provider {
|
|
|
45
45
|
|
|
46
46
|
#[napi]
|
|
47
47
|
impl Provider {
|
|
48
|
+
#[doc = "Adds a compilation result to the instance."]
|
|
49
|
+
#[doc = ""]
|
|
50
|
+
#[doc = "For internal use only. Support for this method may be removed in the future."]
|
|
51
|
+
#[napi(catch_unwind)]
|
|
52
|
+
pub async fn add_compilation_result(
|
|
53
|
+
&self,
|
|
54
|
+
solc_version: String,
|
|
55
|
+
compiler_input: serde_json::Value,
|
|
56
|
+
compiler_output: serde_json::Value,
|
|
57
|
+
) -> napi::Result<bool> {
|
|
58
|
+
let provider = self.provider.clone();
|
|
59
|
+
|
|
60
|
+
self.runtime
|
|
61
|
+
.spawn_blocking(move || {
|
|
62
|
+
let compiler_input = serde_json::from_value(compiler_input)
|
|
63
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
64
|
+
|
|
65
|
+
let compiler_output = serde_json::from_value(compiler_output)
|
|
66
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
67
|
+
|
|
68
|
+
provider.add_compilation_result(solc_version, compiler_input, compiler_output)
|
|
69
|
+
})
|
|
70
|
+
.await
|
|
71
|
+
.map_err(|error| napi::Error::new(Status::GenericFailure, error.to_string()))?
|
|
72
|
+
}
|
|
73
|
+
|
|
48
74
|
#[doc = "Handles a JSON-RPC request and returns a JSON-RPC response."]
|
|
49
75
|
#[napi(catch_unwind)]
|
|
50
76
|
pub async fn handle_request(&self, request: String) -> napi::Result<Response> {
|
|
@@ -470,9 +470,10 @@ pub struct CallTrace {
|
|
|
470
470
|
pub gas_used: BigInt,
|
|
471
471
|
/// The amount of native token that was included with the call.
|
|
472
472
|
pub value: BigInt,
|
|
473
|
-
/// The target of the call.
|
|
474
|
-
|
|
475
|
-
|
|
473
|
+
/// The target address of the call.
|
|
474
|
+
pub address: String,
|
|
475
|
+
/// The name of the contract that is the target of the call, if known.
|
|
476
|
+
pub contract: Option<String>,
|
|
476
477
|
/// The input (calldata) to the call. If it encodes a known function call,
|
|
477
478
|
/// it will be decoded into the function name and a list of arguments.
|
|
478
479
|
/// For example, `{ name: "ownerOf", arguments: ["1"] }`. Note that the
|
|
@@ -541,12 +542,8 @@ impl CallTrace {
|
|
|
541
542
|
/// Instantiates a `CallTrace` with the details from a node and the supplied
|
|
542
543
|
/// children.
|
|
543
544
|
fn new(node: &traces::CallTraceNode, children: Vec<Either<CallTrace, LogTrace>>) -> Self {
|
|
544
|
-
let contract = node
|
|
545
|
-
|
|
546
|
-
.decoded
|
|
547
|
-
.label
|
|
548
|
-
.clone()
|
|
549
|
-
.unwrap_or(node.trace.address.to_checksum(None));
|
|
545
|
+
let contract = node.trace.decoded.label.clone();
|
|
546
|
+
let address = node.trace.address.to_checksum(None);
|
|
550
547
|
|
|
551
548
|
let inputs = match &node.trace.decoded.call_data {
|
|
552
549
|
Some(traces::DecodedCallData { signature, args }) => {
|
|
@@ -579,6 +576,7 @@ impl CallTrace {
|
|
|
579
576
|
gas_used: node.trace.gas_used.into(),
|
|
580
577
|
value: u256_to_bigint(&node.trace.value),
|
|
581
578
|
contract,
|
|
579
|
+
address,
|
|
582
580
|
inputs,
|
|
583
581
|
outputs,
|
|
584
582
|
children,
|
package/src/trace/debug.rs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//! Port of `hardhat-network/stack-traces/debug.ts` from Hardhat.
|
|
2
2
|
|
|
3
|
-
use napi::bindgen_prelude::
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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())
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
use std::convert::Infallible;
|
|
5
5
|
|
|
6
6
|
use edr_eth::{hex, U256};
|
|
7
|
-
use napi::bindgen_prelude::{BigInt,
|
|
7
|
+
use napi::bindgen_prelude::{BigInt, Either25, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
|
|
8
8
|
use napi_derive::napi;
|
|
9
9
|
use serde::{Serialize, Serializer};
|
|
10
10
|
|
|
@@ -45,6 +45,7 @@ pub enum StackTraceEntryType {
|
|
|
45
45
|
CONTRACT_TOO_LARGE_ERROR,
|
|
46
46
|
INTERNAL_FUNCTION_CALLSTACK_ENTRY,
|
|
47
47
|
CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR,
|
|
48
|
+
CHEATCODE_ERROR,
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
#[napi(catch_unwind)]
|
|
@@ -155,7 +156,7 @@ pub struct CallstackEntryStackTraceEntry {
|
|
|
155
156
|
|
|
156
157
|
impl From<CallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
|
157
158
|
fn from(val: CallstackEntryStackTraceEntry) -> Self {
|
|
158
|
-
|
|
159
|
+
Either25::A(val)
|
|
159
160
|
}
|
|
160
161
|
}
|
|
161
162
|
|
|
@@ -174,7 +175,7 @@ pub struct UnrecognizedCreateCallstackEntryStackTraceEntry {
|
|
|
174
175
|
|
|
175
176
|
impl From<UnrecognizedCreateCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
|
176
177
|
fn from(val: UnrecognizedCreateCallstackEntryStackTraceEntry) -> Self {
|
|
177
|
-
|
|
178
|
+
Either25::B(val)
|
|
178
179
|
}
|
|
179
180
|
}
|
|
180
181
|
|
|
@@ -195,7 +196,7 @@ pub struct UnrecognizedContractCallstackEntryStackTraceEntry {
|
|
|
195
196
|
|
|
196
197
|
impl From<UnrecognizedContractCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
|
197
198
|
fn from(val: UnrecognizedContractCallstackEntryStackTraceEntry) -> Self {
|
|
198
|
-
|
|
199
|
+
Either25::C(val)
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
|
|
@@ -210,7 +211,7 @@ pub struct PrecompileErrorStackTraceEntry {
|
|
|
210
211
|
|
|
211
212
|
impl From<PrecompileErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
212
213
|
fn from(val: PrecompileErrorStackTraceEntry) -> Self {
|
|
213
|
-
|
|
214
|
+
Either25::D(val)
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
|
|
@@ -227,7 +228,7 @@ pub struct RevertErrorStackTraceEntry {
|
|
|
227
228
|
|
|
228
229
|
impl From<RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
229
230
|
fn from(val: RevertErrorStackTraceEntry) -> Self {
|
|
230
|
-
|
|
231
|
+
Either25::E(val)
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
|
|
@@ -243,7 +244,7 @@ pub struct PanicErrorStackTraceEntry {
|
|
|
243
244
|
|
|
244
245
|
impl From<PanicErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
245
246
|
fn from(val: PanicErrorStackTraceEntry) -> Self {
|
|
246
|
-
|
|
247
|
+
Either25::F(val)
|
|
247
248
|
}
|
|
248
249
|
}
|
|
249
250
|
|
|
@@ -259,7 +260,7 @@ pub struct CustomErrorStackTraceEntry {
|
|
|
259
260
|
|
|
260
261
|
impl From<CustomErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
261
262
|
fn from(val: CustomErrorStackTraceEntry) -> Self {
|
|
262
|
-
|
|
263
|
+
Either25::G(val)
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
|
|
@@ -278,7 +279,7 @@ pub struct FunctionNotPayableErrorStackTraceEntry {
|
|
|
278
279
|
|
|
279
280
|
impl From<FunctionNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
280
281
|
fn from(val: FunctionNotPayableErrorStackTraceEntry) -> Self {
|
|
281
|
-
|
|
282
|
+
Either25::H(val)
|
|
282
283
|
}
|
|
283
284
|
}
|
|
284
285
|
|
|
@@ -292,7 +293,7 @@ pub struct InvalidParamsErrorStackTraceEntry {
|
|
|
292
293
|
|
|
293
294
|
impl From<InvalidParamsErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
294
295
|
fn from(val: InvalidParamsErrorStackTraceEntry) -> Self {
|
|
295
|
-
|
|
296
|
+
Either25::I(val)
|
|
296
297
|
}
|
|
297
298
|
}
|
|
298
299
|
|
|
@@ -311,7 +312,7 @@ pub struct FallbackNotPayableErrorStackTraceEntry {
|
|
|
311
312
|
|
|
312
313
|
impl From<FallbackNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
313
314
|
fn from(val: FallbackNotPayableErrorStackTraceEntry) -> Self {
|
|
314
|
-
|
|
315
|
+
Either25::J(val)
|
|
315
316
|
}
|
|
316
317
|
}
|
|
317
318
|
|
|
@@ -332,7 +333,7 @@ pub struct FallbackNotPayableAndNoReceiveErrorStackTraceEntry {
|
|
|
332
333
|
|
|
333
334
|
impl From<FallbackNotPayableAndNoReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
334
335
|
fn from(val: FallbackNotPayableAndNoReceiveErrorStackTraceEntry) -> Self {
|
|
335
|
-
|
|
336
|
+
Either25::K(val)
|
|
336
337
|
}
|
|
337
338
|
}
|
|
338
339
|
|
|
@@ -351,7 +352,7 @@ pub struct UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry {
|
|
|
351
352
|
|
|
352
353
|
impl From<UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
353
354
|
fn from(val: UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry) -> Self {
|
|
354
|
-
|
|
355
|
+
Either25::L(val)
|
|
355
356
|
}
|
|
356
357
|
}
|
|
357
358
|
|
|
@@ -369,7 +370,7 @@ pub struct MissingFallbackOrReceiveErrorStackTraceEntry {
|
|
|
369
370
|
|
|
370
371
|
impl From<MissingFallbackOrReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
371
372
|
fn from(val: MissingFallbackOrReceiveErrorStackTraceEntry) -> Self {
|
|
372
|
-
|
|
373
|
+
Either25::M(val)
|
|
373
374
|
}
|
|
374
375
|
}
|
|
375
376
|
|
|
@@ -386,7 +387,7 @@ pub struct ReturndataSizeErrorStackTraceEntry {
|
|
|
386
387
|
|
|
387
388
|
impl From<ReturndataSizeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
388
389
|
fn from(val: ReturndataSizeErrorStackTraceEntry) -> Self {
|
|
389
|
-
|
|
390
|
+
Either25::N(val)
|
|
390
391
|
}
|
|
391
392
|
}
|
|
392
393
|
|
|
@@ -404,7 +405,7 @@ pub struct NonContractAccountCalledErrorStackTraceEntry {
|
|
|
404
405
|
|
|
405
406
|
impl From<NonContractAccountCalledErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
406
407
|
fn from(val: NonContractAccountCalledErrorStackTraceEntry) -> Self {
|
|
407
|
-
|
|
408
|
+
Either25::O(val)
|
|
408
409
|
}
|
|
409
410
|
}
|
|
410
411
|
|
|
@@ -418,7 +419,7 @@ pub struct CallFailedErrorStackTraceEntry {
|
|
|
418
419
|
|
|
419
420
|
impl From<CallFailedErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
420
421
|
fn from(val: CallFailedErrorStackTraceEntry) -> Self {
|
|
421
|
-
|
|
422
|
+
Either25::P(val)
|
|
422
423
|
}
|
|
423
424
|
}
|
|
424
425
|
|
|
@@ -435,7 +436,7 @@ pub struct DirectLibraryCallErrorStackTraceEntry {
|
|
|
435
436
|
|
|
436
437
|
impl From<DirectLibraryCallErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
437
438
|
fn from(val: DirectLibraryCallErrorStackTraceEntry) -> Self {
|
|
438
|
-
|
|
439
|
+
Either25::Q(val)
|
|
439
440
|
}
|
|
440
441
|
}
|
|
441
442
|
|
|
@@ -455,7 +456,7 @@ pub struct UnrecognizedCreateErrorStackTraceEntry {
|
|
|
455
456
|
|
|
456
457
|
impl From<UnrecognizedCreateErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
457
458
|
fn from(val: UnrecognizedCreateErrorStackTraceEntry) -> Self {
|
|
458
|
-
|
|
459
|
+
Either25::R(val)
|
|
459
460
|
}
|
|
460
461
|
}
|
|
461
462
|
|
|
@@ -477,7 +478,7 @@ pub struct UnrecognizedContractErrorStackTraceEntry {
|
|
|
477
478
|
|
|
478
479
|
impl From<UnrecognizedContractErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
479
480
|
fn from(val: UnrecognizedContractErrorStackTraceEntry) -> Self {
|
|
480
|
-
|
|
481
|
+
Either25::S(val)
|
|
481
482
|
}
|
|
482
483
|
}
|
|
483
484
|
|
|
@@ -494,7 +495,7 @@ pub struct OtherExecutionErrorStackTraceEntry {
|
|
|
494
495
|
|
|
495
496
|
impl From<OtherExecutionErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
496
497
|
fn from(val: OtherExecutionErrorStackTraceEntry) -> Self {
|
|
497
|
-
|
|
498
|
+
Either25::T(val)
|
|
498
499
|
}
|
|
499
500
|
}
|
|
500
501
|
|
|
@@ -512,7 +513,7 @@ pub struct UnmappedSolc063RevertErrorStackTraceEntry {
|
|
|
512
513
|
|
|
513
514
|
impl From<UnmappedSolc063RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
514
515
|
fn from(val: UnmappedSolc063RevertErrorStackTraceEntry) -> Self {
|
|
515
|
-
|
|
516
|
+
Either25::U(val)
|
|
516
517
|
}
|
|
517
518
|
}
|
|
518
519
|
|
|
@@ -529,7 +530,7 @@ pub struct ContractTooLargeErrorStackTraceEntry {
|
|
|
529
530
|
|
|
530
531
|
impl From<ContractTooLargeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
531
532
|
fn from(val: ContractTooLargeErrorStackTraceEntry) -> Self {
|
|
532
|
-
|
|
533
|
+
Either25::V(val)
|
|
533
534
|
}
|
|
534
535
|
}
|
|
535
536
|
|
|
@@ -548,7 +549,7 @@ pub struct InternalFunctionCallStackEntry {
|
|
|
548
549
|
|
|
549
550
|
impl From<InternalFunctionCallStackEntry> for SolidityStackTraceEntry {
|
|
550
551
|
fn from(val: InternalFunctionCallStackEntry) -> Self {
|
|
551
|
-
|
|
552
|
+
Either25::W(val)
|
|
552
553
|
}
|
|
553
554
|
}
|
|
554
555
|
|
|
@@ -566,7 +567,23 @@ pub struct ContractCallRunOutOfGasError {
|
|
|
566
567
|
|
|
567
568
|
impl From<ContractCallRunOutOfGasError> for SolidityStackTraceEntry {
|
|
568
569
|
fn from(val: ContractCallRunOutOfGasError) -> Self {
|
|
569
|
-
|
|
570
|
+
Either25::X(val)
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
#[napi(object)]
|
|
575
|
+
#[derive(Clone, Serialize)]
|
|
576
|
+
pub struct CheatcodeErrorStackTraceEntry {
|
|
577
|
+
#[napi(js_name = "type", ts_type = "StackTraceEntryType.CHEATCODE_ERROR")]
|
|
578
|
+
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CHEATCODE_ERROR as u8 }>,
|
|
579
|
+
// The parsed cheatcode error message that can be displayed to the user
|
|
580
|
+
pub message: String,
|
|
581
|
+
pub source_reference: SourceReference,
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
impl From<CheatcodeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
|
585
|
+
fn from(val: CheatcodeErrorStackTraceEntry) -> Self {
|
|
586
|
+
Either25::Y(val)
|
|
570
587
|
}
|
|
571
588
|
}
|
|
572
589
|
|
|
@@ -580,7 +597,7 @@ impl From<ContractCallRunOutOfGasError> for SolidityStackTraceEntry {
|
|
|
580
597
|
// Rather, we just bite the bullet for now and use the type alias directly
|
|
581
598
|
// (which falls back to `any` as it's not recognized in the context of the
|
|
582
599
|
// index.d.ts file) until we finish the porting work.
|
|
583
|
-
pub type SolidityStackTraceEntry =
|
|
600
|
+
pub type SolidityStackTraceEntry = Either25<
|
|
584
601
|
CallstackEntryStackTraceEntry,
|
|
585
602
|
UnrecognizedCreateCallstackEntryStackTraceEntry,
|
|
586
603
|
UnrecognizedContractCallstackEntryStackTraceEntry,
|
|
@@ -605,6 +622,7 @@ pub type SolidityStackTraceEntry = Either24<
|
|
|
605
622
|
ContractTooLargeErrorStackTraceEntry,
|
|
606
623
|
InternalFunctionCallStackEntry,
|
|
607
624
|
ContractCallRunOutOfGasError,
|
|
625
|
+
CheatcodeErrorStackTraceEntry,
|
|
608
626
|
>;
|
|
609
627
|
|
|
610
628
|
impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::StackTraceEntry {
|
|
@@ -663,6 +681,15 @@ impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::St
|
|
|
663
681
|
source_reference: source_reference.map(std::convert::Into::into),
|
|
664
682
|
}
|
|
665
683
|
.into(),
|
|
684
|
+
StackTraceEntry::CheatCodeError {
|
|
685
|
+
message,
|
|
686
|
+
source_reference,
|
|
687
|
+
} => CheatcodeErrorStackTraceEntry {
|
|
688
|
+
type_: StackTraceEntryTypeConst,
|
|
689
|
+
message,
|
|
690
|
+
source_reference: source_reference.into(),
|
|
691
|
+
}
|
|
692
|
+
.into(),
|
|
666
693
|
StackTraceEntry::CustomError {
|
|
667
694
|
message,
|
|
668
695
|
source_reference,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { StandardTestKind, FuzzTestKind, InvariantTestKind } from "../../index";
|
|
2
|
+
|
|
3
|
+
export enum SortOrder {
|
|
4
|
+
Ascending,
|
|
5
|
+
Descending,
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface GasUsageFilter {
|
|
9
|
+
minThreshold?: bigint;
|
|
10
|
+
maxThreshold?: bigint;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function extractGasUsage(
|
|
14
|
+
testResults: {
|
|
15
|
+
name: string;
|
|
16
|
+
kind: StandardTestKind | FuzzTestKind | InvariantTestKind;
|
|
17
|
+
}[],
|
|
18
|
+
filter?: GasUsageFilter,
|
|
19
|
+
ordering?: SortOrder
|
|
20
|
+
): { name: string; gas: bigint }[] {
|
|
21
|
+
const gasUsage: { name: string; gas: bigint }[] = [];
|
|
22
|
+
|
|
23
|
+
for (const result of testResults) {
|
|
24
|
+
// Default to zero gas for invariant tests
|
|
25
|
+
const gas = "consumedGas" in result.kind
|
|
26
|
+
? result.kind.consumedGas
|
|
27
|
+
: "medianGas" in result.kind
|
|
28
|
+
? result.kind.medianGas
|
|
29
|
+
: BigInt(0);
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
(!filter?.minThreshold || gas >= filter.minThreshold) &&
|
|
33
|
+
(!filter?.maxThreshold || gas <= filter.maxThreshold)
|
|
34
|
+
) {
|
|
35
|
+
gasUsage.push({ name: result.name, gas });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (ordering === SortOrder.Ascending) {
|
|
40
|
+
gasUsage.sort((a, b) => (a.gas < b.gas ? -1 : a.gas > b.gas ? 1 : 0));
|
|
41
|
+
} else if (ordering === SortOrder.Descending) {
|
|
42
|
+
gasUsage.sort((a, b) => (a.gas > b.gas ? -1 : a.gas < b.gas ? 1 : 0));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return gasUsage;
|
|
46
|
+
}
|
package/Cargo.toml
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
[package]
|
|
2
|
-
name = "edr_napi"
|
|
3
|
-
version.workspace = true
|
|
4
|
-
edition.workspace = true
|
|
5
|
-
|
|
6
|
-
[lib]
|
|
7
|
-
crate-type = ["cdylib"]
|
|
8
|
-
|
|
9
|
-
[dependencies]
|
|
10
|
-
alloy-dyn-abi.workspace = true
|
|
11
|
-
alloy-json-abi.workspace = true
|
|
12
|
-
alloy-sol-types.workspace = true
|
|
13
|
-
derive_more.workspace = true
|
|
14
|
-
derive-where.workspace = true
|
|
15
|
-
edr_coverage.workspace = true
|
|
16
|
-
edr_defaults = { path = "../edr_defaults" }
|
|
17
|
-
edr_eth = { path = "../edr_eth" }
|
|
18
|
-
edr_evm = { path = "../edr_evm" }
|
|
19
|
-
edr_generic = { path = "../edr_generic" }
|
|
20
|
-
edr_instrument = { path = "../edr_instrument" }
|
|
21
|
-
edr_napi_core = { path = "../edr_napi_core" }
|
|
22
|
-
edr_op = { path = "../edr_op", optional = true }
|
|
23
|
-
edr_provider = { path = "../edr_provider" }
|
|
24
|
-
edr_rpc_client = { path = "../edr_rpc_client" }
|
|
25
|
-
edr_scenarios = { version = "0.3.5", path = "../edr_scenarios", optional = true }
|
|
26
|
-
edr_solidity = { version = "0.3.5", path = "../edr_solidity" }
|
|
27
|
-
k256 = { version = "0.13.1", default-features = false, features = [
|
|
28
|
-
"arithmetic",
|
|
29
|
-
"ecdsa",
|
|
30
|
-
"pkcs8",
|
|
31
|
-
] }
|
|
32
|
-
mimalloc = { version = "0.1.39", default-features = false, features = [
|
|
33
|
-
"local_dynamic_tls",
|
|
34
|
-
] }
|
|
35
|
-
# The `async` feature ensures that a tokio runtime is available
|
|
36
|
-
napi = { version = "2.16.17", default-features = false, features = [
|
|
37
|
-
"async",
|
|
38
|
-
"error_anyhow",
|
|
39
|
-
"napi8",
|
|
40
|
-
"serde-json",
|
|
41
|
-
] }
|
|
42
|
-
napi-derive = "2.16.13"
|
|
43
|
-
rand = { version = "0.8.4", optional = true }
|
|
44
|
-
semver = "1.0.22"
|
|
45
|
-
serde.workspace = true
|
|
46
|
-
serde_json.workspace = true
|
|
47
|
-
static_assertions = "1.1.0"
|
|
48
|
-
strum = { version = "0.26.0", features = ["derive"] }
|
|
49
|
-
thiserror = { version = "1.0.37", default-features = false }
|
|
50
|
-
tracing = { version = "0.1.37", default-features = false, features = ["std"] }
|
|
51
|
-
tracing-flame = { version = "0.2.0", default-features = false, features = [
|
|
52
|
-
"smallvec",
|
|
53
|
-
] }
|
|
54
|
-
tracing-subscriber = { version = "0.3.18", default-features = false, features = [
|
|
55
|
-
"ansi",
|
|
56
|
-
"env-filter",
|
|
57
|
-
"fmt",
|
|
58
|
-
"parking_lot",
|
|
59
|
-
"smallvec",
|
|
60
|
-
"std",
|
|
61
|
-
] }
|
|
62
|
-
|
|
63
|
-
# Solidity tests
|
|
64
|
-
edr_solidity_tests.workspace = true
|
|
65
|
-
foundry-cheatcodes.workspace = true
|
|
66
|
-
foundry-compilers.workspace = true
|
|
67
|
-
edr_common.workspace = true
|
|
68
|
-
tempfile = "3.10.1"
|
|
69
|
-
|
|
70
|
-
[target.x86_64-unknown-linux-gnu.dependencies]
|
|
71
|
-
openssl-sys = { version = "0.9.93", features = ["vendored"] }
|
|
72
|
-
|
|
73
|
-
[target.x86_64-unknown-linux-musl.dependencies]
|
|
74
|
-
openssl-sys = { version = "0.9.93", features = ["vendored"] }
|
|
75
|
-
|
|
76
|
-
[target.aarch64-unknown-linux-gnu.dependencies]
|
|
77
|
-
openssl-sys = { version = "0.9.93", features = ["vendored"] }
|
|
78
|
-
|
|
79
|
-
[target.aarch64-unknown-linux-musl.dependencies]
|
|
80
|
-
openssl-sys = { version = "0.9.93", features = ["vendored"] }
|
|
81
|
-
|
|
82
|
-
[build-dependencies]
|
|
83
|
-
napi-build = "2.0.1"
|
|
84
|
-
|
|
85
|
-
[features]
|
|
86
|
-
op = ["dep:edr_op"]
|
|
87
|
-
scenarios = ["dep:edr_scenarios", "dep:rand"]
|
|
88
|
-
tracing = ["edr_evm/tracing", "edr_napi_core/tracing", "edr_provider/tracing"]
|
|
89
|
-
test-mock = []
|
|
90
|
-
|
|
91
|
-
[lints]
|
|
92
|
-
workspace = true
|
package/build.rs
DELETED