@nomicfoundation/edr 0.12.0-next.0 → 0.12.0-next.2

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 CHANGED
@@ -841,6 +841,20 @@ export enum IncludeTraces {
841
841
  }
842
842
  export declare function l1SolidityTestRunnerFactory(): SolidityTestRunnerFactory
843
843
  export declare function opSolidityTestRunnerFactory(): SolidityTestRunnerFactory
844
+ /** A grouping of value snapshot entries for a test. */
845
+ export interface ValueSnapshotGroup {
846
+ /** The group name. */
847
+ name: string
848
+ /** The entries in the group. */
849
+ entries: Array<ValueSnapshotEntry>
850
+ }
851
+ /** An entry in a value snapshot group. */
852
+ export interface ValueSnapshotEntry {
853
+ /** The name of the entry. */
854
+ name: string
855
+ /** The value of the entry. */
856
+ value: string
857
+ }
844
858
  /** The stack trace result */
845
859
  export interface StackTrace {
846
860
  /** Enum tag for JS. */
@@ -968,11 +982,10 @@ export interface CallTrace {
968
982
  gasUsed: bigint
969
983
  /** The amount of native token that was included with the call. */
970
984
  value: bigint
971
- /**
972
- * The target of the call. Provided as a contract name if known, otherwise
973
- * a checksum address.
974
- */
975
- 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
976
989
  /**
977
990
  * The input (calldata) to the call. If it encodes a known function call,
978
991
  * it will be decoded into the function name and a list of arguments.
@@ -1365,6 +1378,13 @@ export declare class TestResult {
1365
1378
  readonly kind: StandardTestKind | FuzzTestKind | InvariantTestKind
1366
1379
  /** See [edr_solidity_tests::result::TestResult::duration] */
1367
1380
  readonly durationNs: bigint
1381
+ /**
1382
+ * Groups of value snapshot entries (incl. gas).
1383
+ *
1384
+ * Only present if the test runner collected scoped snapshots. Currently,
1385
+ * this is always the case.
1386
+ */
1387
+ readonly valueSnapshotGroups?: Array<ValueSnapshotGroup>
1368
1388
  /**
1369
1389
  * Compute the error stack trace.
1370
1390
  * The result is either the stack trace or the reason why we couldn't
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@nomicfoundation/edr",
3
- "version": "0.12.0-next.0",
3
+ "version": "0.12.0-next.2",
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",
@@ -25,14 +26,17 @@
25
26
  "typescript": "~5.8.2"
26
27
  },
27
28
  "engines": {
28
- "node": ">= 18"
29
+ "node": ">= 20"
30
+ },
31
+ "exports": {
32
+ ".": "./index.js",
33
+ "./solidity-tests": "./dist/src/ts/solidity_tests.js"
29
34
  },
30
35
  "files": [
31
36
  "index.js",
32
37
  "index.d.ts",
33
- "Cargo.toml",
34
- "build.rs",
35
- "src/"
38
+ "src/",
39
+ "dist/src/"
36
40
  ],
37
41
  "license": "MIT",
38
42
  "main": "index.js",
@@ -54,31 +58,31 @@
54
58
  "repository": "NomicFoundation/edr.git",
55
59
  "types": "index.d.ts",
56
60
  "optionalDependencies": {
57
- "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.0",
58
- "@nomicfoundation/edr-darwin-x64": "0.12.0-next.0",
59
- "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.0",
60
- "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.0",
61
- "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.0",
62
- "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.0",
63
- "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.0"
61
+ "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.2",
62
+ "@nomicfoundation/edr-darwin-x64": "0.12.0-next.2",
63
+ "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.2",
64
+ "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.2",
65
+ "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.2",
66
+ "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.2",
67
+ "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.2"
64
68
  },
65
69
  "scripts": {
66
70
  "artifacts": "napi artifacts",
67
71
  "build": "pnpm run build:publish",
68
- "build:debug": "napi build --platform --no-const-enum --features op",
69
- "build:dev": "napi build --platform --release --no-const-enum --features op,test-mock",
70
- "build:publish": "napi build --platform --profile napi-publish --no-const-enum --features op",
71
- "build:scenarios": "napi build --platform --release --no-const-enum --features op,scenarios",
72
- "build:tracing": "napi build --platform --release --no-const-enum --features op,tracing",
73
- "build:typingFile": "napi build --platform --no-const-enum --features op",
72
+ "build:debug": "bash ../../scripts/build_edr_napi.sh --features op",
73
+ "build:dev": "bash ../../scripts/build_edr_napi.sh --release --features op,test-mock",
74
+ "build:publish": "bash ../../scripts/build_edr_napi.sh --profile napi-publish --features op",
75
+ "build:scenarios": "bash ../../scripts/build_edr_napi.sh --release --features op,scenarios",
76
+ "build:tracing": "bash ../../scripts/build_edr_napi.sh --release --features op,tracing",
77
+ "build:typingFile": "bash ../../scripts/build_edr_napi.sh --features op",
74
78
  "clean": "rm -rf @nomicfoundation/edr.node",
75
79
  "eslint": "eslint 'test/**/*.ts'",
76
80
  "lint": "pnpm run prettier && pnpm run eslint",
77
81
  "lint:fix": "pnpm run prettier --write",
78
82
  "pretest": "pnpm build:dev",
79
83
  "prettier": "prettier --check \"test/**.ts\"",
80
- "test": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
81
- "testNoBuild": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(mock)}.ts\"",
84
+ "test": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
85
+ "testNoBuild": "node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(mock)}.ts\"",
82
86
  "universal": "napi universal",
83
87
  "version": "napi version"
84
88
  }
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
- runtime,
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 () = try_or_reject_deferred!(test_runner.run_tests(
301
- test_filter,
302
- Arc::new(
303
- move |SuiteResultAndArtifactId {
304
- artifact_id,
305
- result,
306
- }| {
307
- let suite_result = SuiteResult::new(artifact_id, result, include_traces);
308
-
309
- let status = on_test_suite_completed_callback
310
- .call(suite_result, ThreadsafeFunctionCallMode::Blocking);
311
-
312
- // This should always succeed since we're using an unbounded queue. We add
313
- // an assertion for completeness.
314
- assert_eq!(
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
  });
@@ -22,6 +22,26 @@ use crate::{
22
22
  trace::{solidity_stack_trace::SolidityStackTraceEntry, u256_to_bigint},
23
23
  };
24
24
 
25
+ /// A grouping of value snapshot entries for a test.
26
+ #[napi(object)]
27
+ #[derive(Clone, Debug)]
28
+ pub struct ValueSnapshotGroup {
29
+ /// The group name.
30
+ pub name: String,
31
+ /// The entries in the group.
32
+ pub entries: Vec<ValueSnapshotEntry>,
33
+ }
34
+
35
+ /// An entry in a value snapshot group.
36
+ #[napi(object)]
37
+ #[derive(Clone, Debug)]
38
+ pub struct ValueSnapshotEntry {
39
+ /// The name of the entry.
40
+ pub name: String,
41
+ /// The value of the entry.
42
+ pub value: String,
43
+ }
44
+
25
45
  /// See [edr_solidity_tests::result::SuiteResult]
26
46
  #[napi]
27
47
  #[derive(Clone, Debug)]
@@ -85,6 +105,12 @@ pub struct TestResult {
85
105
  /// See [edr_solidity_tests::result::TestResult::duration]
86
106
  #[napi(readonly)]
87
107
  pub duration_ns: BigInt,
108
+ /// Groups of value snapshot entries (incl. gas).
109
+ ///
110
+ /// Only present if the test runner collected scoped snapshots. Currently,
111
+ /// this is always the case.
112
+ #[napi(readonly)]
113
+ pub value_snapshot_groups: Option<Vec<ValueSnapshotGroup>>,
88
114
 
89
115
  stack_trace_result: Option<Arc<StackTraceResult<String>>>,
90
116
  call_trace_arenas: Vec<(traces::TraceKind, SparsedTraceArena)>,
@@ -264,6 +290,19 @@ impl TestResult {
264
290
  }),
265
291
  },
266
292
  duration_ns: BigInt::from(test_result.duration.as_nanos()),
293
+ value_snapshot_groups: Some(
294
+ test_result
295
+ .value_snapshots
296
+ .into_iter()
297
+ .map(|(group_name, entries)| ValueSnapshotGroup {
298
+ name: group_name,
299
+ entries: entries
300
+ .into_iter()
301
+ .map(|(name, value)| ValueSnapshotEntry { name, value })
302
+ .collect(),
303
+ })
304
+ .collect(),
305
+ ),
267
306
  stack_trace_result: test_result.stack_trace_result.map(Arc::new),
268
307
  call_trace_arenas: if include_trace {
269
308
  test_result.traces
@@ -431,9 +470,10 @@ pub struct CallTrace {
431
470
  pub gas_used: BigInt,
432
471
  /// The amount of native token that was included with the call.
433
472
  pub value: BigInt,
434
- /// The target of the call. Provided as a contract name if known, otherwise
435
- /// a checksum address.
436
- pub contract: String,
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>,
437
477
  /// The input (calldata) to the call. If it encodes a known function call,
438
478
  /// it will be decoded into the function name and a list of arguments.
439
479
  /// For example, `{ name: "ownerOf", arguments: ["1"] }`. Note that the
@@ -502,12 +542,8 @@ impl CallTrace {
502
542
  /// Instantiates a `CallTrace` with the details from a node and the supplied
503
543
  /// children.
504
544
  fn new(node: &traces::CallTraceNode, children: Vec<Either<CallTrace, LogTrace>>) -> Self {
505
- let contract = node
506
- .trace
507
- .decoded
508
- .label
509
- .clone()
510
- .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);
511
547
 
512
548
  let inputs = match &node.trace.decoded.call_data {
513
549
  Some(traces::DecodedCallData { signature, args }) => {
@@ -540,6 +576,7 @@ impl CallTrace {
540
576
  gas_used: node.trace.gas_used.into(),
541
577
  value: u256_to_bigint(&node.trace.value),
542
578
  contract,
579
+ address,
543
580
  inputs,
544
581
  outputs,
545
582
  children,
@@ -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
@@ -1,3 +0,0 @@
1
- fn main() {
2
- napi_build::setup();
3
- }