@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
|
@@ -18,6 +18,7 @@ use napi_derive::napi;
|
|
|
18
18
|
|
|
19
19
|
use crate::{
|
|
20
20
|
cast::TryCast,
|
|
21
|
+
gas_report::GasReport,
|
|
21
22
|
solidity_tests::{artifact::ArtifactId, config::IncludeTraces},
|
|
22
23
|
trace::{solidity_stack_trace::SolidityStackTraceEntry, u256_to_bigint},
|
|
23
24
|
};
|
|
@@ -42,7 +43,7 @@ pub struct ValueSnapshotEntry {
|
|
|
42
43
|
pub value: String,
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
/// See [edr_solidity_tests::result::SuiteResult]
|
|
46
|
+
/// See [`edr_solidity_tests::result::SuiteResult`]
|
|
46
47
|
#[napi]
|
|
47
48
|
#[derive(Clone, Debug)]
|
|
48
49
|
pub struct SuiteResult {
|
|
@@ -50,13 +51,13 @@ pub struct SuiteResult {
|
|
|
50
51
|
/// callback
|
|
51
52
|
#[napi(readonly)]
|
|
52
53
|
pub id: ArtifactId,
|
|
53
|
-
/// See [edr_solidity_tests::result::SuiteResult::duration]
|
|
54
|
+
/// See [`edr_solidity_tests::result::SuiteResult::duration`]
|
|
54
55
|
#[napi(readonly)]
|
|
55
56
|
pub duration_ns: BigInt,
|
|
56
|
-
/// See [edr_solidity_tests::result::SuiteResult::test_results]
|
|
57
|
+
/// See [`edr_solidity_tests::result::SuiteResult::test_results`]
|
|
57
58
|
#[napi(readonly)]
|
|
58
59
|
pub test_results: Vec<TestResult>,
|
|
59
|
-
/// See [edr_solidity_tests::result::SuiteResult::warnings]
|
|
60
|
+
/// See [`edr_solidity_tests::result::SuiteResult::warnings`]
|
|
60
61
|
#[napi(readonly)]
|
|
61
62
|
pub warnings: Vec<String>,
|
|
62
63
|
}
|
|
@@ -80,29 +81,29 @@ impl SuiteResult {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
|
|
83
|
-
/// See [edr_solidity_tests::result::TestResult]
|
|
84
|
+
/// See [`edr_solidity_tests::result::TestResult`]
|
|
84
85
|
#[napi]
|
|
85
86
|
#[derive(Clone, Debug)]
|
|
86
87
|
pub struct TestResult {
|
|
87
88
|
/// The name of the test.
|
|
88
89
|
#[napi(readonly)]
|
|
89
90
|
pub name: String,
|
|
90
|
-
/// See [edr_solidity_tests::result::TestResult::status]
|
|
91
|
+
/// See [`edr_solidity_tests::result::TestResult::status`]
|
|
91
92
|
#[napi(readonly)]
|
|
92
93
|
pub status: TestStatus,
|
|
93
|
-
/// See [edr_solidity_tests::result::TestResult::reason]
|
|
94
|
+
/// See [`edr_solidity_tests::result::TestResult::reason`]
|
|
94
95
|
#[napi(readonly)]
|
|
95
96
|
pub reason: Option<String>,
|
|
96
|
-
/// See [edr_solidity_tests::result::TestResult::counterexample]
|
|
97
|
+
/// See [`edr_solidity_tests::result::TestResult::counterexample`]
|
|
97
98
|
#[napi(readonly)]
|
|
98
99
|
pub counterexample: Option<Either<BaseCounterExample, CounterExampleSequence>>,
|
|
99
|
-
/// See [edr_solidity_tests::result::TestResult::decoded_logs]
|
|
100
|
+
/// See [`edr_solidity_tests::result::TestResult::decoded_logs`]
|
|
100
101
|
#[napi(readonly)]
|
|
101
102
|
pub decoded_logs: Vec<String>,
|
|
102
|
-
/// See [edr_solidity_tests::result::TestResult::kind]
|
|
103
|
+
/// See [`edr_solidity_tests::result::TestResult::kind`]
|
|
103
104
|
#[napi(readonly)]
|
|
104
105
|
pub kind: Either3<StandardTestKind, FuzzTestKind, InvariantTestKind>,
|
|
105
|
-
/// See [edr_solidity_tests::result::TestResult::duration]
|
|
106
|
+
/// See [`edr_solidity_tests::result::TestResult::duration`]
|
|
106
107
|
#[napi(readonly)]
|
|
107
108
|
pub duration_ns: BigInt,
|
|
108
109
|
/// Groups of value snapshot entries (incl. gas).
|
|
@@ -263,7 +264,7 @@ impl TestResult {
|
|
|
263
264
|
}),
|
|
264
265
|
decoded_logs: test_result.decoded_logs,
|
|
265
266
|
kind: match test_result.kind {
|
|
266
|
-
edr_solidity_tests::result::TestKind::
|
|
267
|
+
edr_solidity_tests::result::TestKind::Unit { gas: gas_consumed } => {
|
|
267
268
|
Either3::A(StandardTestKind {
|
|
268
269
|
consumed_gas: BigInt::from(gas_consumed),
|
|
269
270
|
})
|
|
@@ -282,11 +283,27 @@ impl TestResult {
|
|
|
282
283
|
runs,
|
|
283
284
|
calls,
|
|
284
285
|
reverts,
|
|
286
|
+
metrics,
|
|
287
|
+
failed_corpus_replays,
|
|
285
288
|
} => Either3::C(InvariantTestKind {
|
|
286
289
|
// usize as u64 is always safe
|
|
287
290
|
runs: BigInt::from(runs as u64),
|
|
288
291
|
calls: BigInt::from(calls as u64),
|
|
289
292
|
reverts: BigInt::from(reverts as u64),
|
|
293
|
+
metrics: metrics
|
|
294
|
+
.into_iter()
|
|
295
|
+
.map(|(name, metric)| {
|
|
296
|
+
(
|
|
297
|
+
name,
|
|
298
|
+
InvariantMetrics {
|
|
299
|
+
calls: BigInt::from(metric.calls as u64),
|
|
300
|
+
reverts: BigInt::from(metric.reverts as u64),
|
|
301
|
+
discards: BigInt::from(metric.discards as u64),
|
|
302
|
+
},
|
|
303
|
+
)
|
|
304
|
+
})
|
|
305
|
+
.collect(),
|
|
306
|
+
failed_corpus_replays: BigInt::from(failed_corpus_replays as u64),
|
|
290
307
|
}),
|
|
291
308
|
},
|
|
292
309
|
duration_ns: BigInt::from(test_result.duration.as_nanos()),
|
|
@@ -335,7 +352,7 @@ impl From<edr_solidity_tests::result::TestStatus> for TestStatus {
|
|
|
335
352
|
}
|
|
336
353
|
}
|
|
337
354
|
|
|
338
|
-
/// See [edr_solidity_tests::result::TestKind::
|
|
355
|
+
/// See [`edr_solidity_tests::result::TestKind::Unit`]
|
|
339
356
|
#[napi(object)]
|
|
340
357
|
#[derive(Debug, Clone)]
|
|
341
358
|
pub struct StandardTestKind {
|
|
@@ -344,22 +361,22 @@ pub struct StandardTestKind {
|
|
|
344
361
|
pub consumed_gas: BigInt,
|
|
345
362
|
}
|
|
346
363
|
|
|
347
|
-
/// See [edr_solidity_tests::result::TestKind::Fuzz]
|
|
364
|
+
/// See [`edr_solidity_tests::result::TestKind::Fuzz`]
|
|
348
365
|
#[napi(object)]
|
|
349
366
|
#[derive(Debug, Clone)]
|
|
350
367
|
pub struct FuzzTestKind {
|
|
351
|
-
/// See [edr_solidity_tests::result::TestKind::Fuzz]
|
|
368
|
+
/// See [`edr_solidity_tests::result::TestKind::Fuzz`]
|
|
352
369
|
#[napi(readonly)]
|
|
353
370
|
pub runs: BigInt,
|
|
354
|
-
/// See [edr_solidity_tests::result::TestKind::Fuzz]
|
|
371
|
+
/// See [`edr_solidity_tests::result::TestKind::Fuzz`]
|
|
355
372
|
#[napi(readonly)]
|
|
356
373
|
pub mean_gas: BigInt,
|
|
357
|
-
/// See [edr_solidity_tests::result::TestKind::Fuzz]
|
|
374
|
+
/// See [`edr_solidity_tests::result::TestKind::Fuzz`]
|
|
358
375
|
#[napi(readonly)]
|
|
359
376
|
pub median_gas: BigInt,
|
|
360
377
|
}
|
|
361
378
|
|
|
362
|
-
/// See [edr_solidity_tests::fuzz::FuzzCase]
|
|
379
|
+
/// See [`edr_solidity_tests::fuzz::FuzzCase`]
|
|
363
380
|
#[napi(object)]
|
|
364
381
|
#[derive(Clone)]
|
|
365
382
|
pub struct FuzzCase {
|
|
@@ -383,19 +400,40 @@ impl Debug for FuzzCase {
|
|
|
383
400
|
}
|
|
384
401
|
}
|
|
385
402
|
|
|
386
|
-
/// See [edr_solidity_tests::result::TestKind::Invariant]
|
|
403
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
387
404
|
#[napi(object)]
|
|
388
405
|
#[derive(Debug, Clone)]
|
|
389
406
|
pub struct InvariantTestKind {
|
|
390
|
-
/// See [edr_solidity_tests::result::TestKind::Invariant]
|
|
407
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
391
408
|
#[napi(readonly)]
|
|
392
409
|
pub runs: BigInt,
|
|
393
|
-
/// See [edr_solidity_tests::result::TestKind::Invariant]
|
|
410
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
394
411
|
#[napi(readonly)]
|
|
395
412
|
pub calls: BigInt,
|
|
396
|
-
/// See [edr_solidity_tests::result::TestKind::Invariant]
|
|
413
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
397
414
|
#[napi(readonly)]
|
|
398
415
|
pub reverts: BigInt,
|
|
416
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
417
|
+
#[napi(readonly)]
|
|
418
|
+
pub metrics: std::collections::HashMap<String, InvariantMetrics>,
|
|
419
|
+
/// See [`edr_solidity_tests::result::TestKind::Invariant`]
|
|
420
|
+
#[napi(readonly)]
|
|
421
|
+
pub failed_corpus_replays: BigInt,
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/// See [`edr_solidity_tests::result::InvariantMetrics`]
|
|
425
|
+
#[napi(object)]
|
|
426
|
+
#[derive(Debug, Clone)]
|
|
427
|
+
pub struct InvariantMetrics {
|
|
428
|
+
// Count of fuzzed selector calls.
|
|
429
|
+
#[napi(readonly)]
|
|
430
|
+
pub calls: BigInt,
|
|
431
|
+
// Count of fuzzed selector reverts.
|
|
432
|
+
#[napi(readonly)]
|
|
433
|
+
pub reverts: BigInt,
|
|
434
|
+
// Count of fuzzed selector discards (through assume cheatcodes).
|
|
435
|
+
#[napi(readonly)]
|
|
436
|
+
pub discards: BigInt,
|
|
399
437
|
}
|
|
400
438
|
|
|
401
439
|
/// Original sequence size and sequence of calls used as a counter example
|
|
@@ -409,26 +447,26 @@ pub struct CounterExampleSequence {
|
|
|
409
447
|
pub sequence: Vec<BaseCounterExample>,
|
|
410
448
|
}
|
|
411
449
|
|
|
412
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample]
|
|
450
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample`]
|
|
413
451
|
#[napi(object)]
|
|
414
452
|
#[derive(Clone)]
|
|
415
453
|
pub struct BaseCounterExample {
|
|
416
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::sender]
|
|
454
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::sender`]
|
|
417
455
|
#[napi(readonly)]
|
|
418
456
|
pub sender: Option<Uint8Array>,
|
|
419
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::addr]
|
|
457
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::addr`]
|
|
420
458
|
#[napi(readonly)]
|
|
421
459
|
pub address: Option<Uint8Array>,
|
|
422
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::calldata]
|
|
460
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::calldata`]
|
|
423
461
|
#[napi(readonly)]
|
|
424
462
|
pub calldata: Uint8Array,
|
|
425
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::contract_name]
|
|
463
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::contract_name`]
|
|
426
464
|
#[napi(readonly)]
|
|
427
465
|
pub contract_name: Option<String>,
|
|
428
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::signature]
|
|
466
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::signature`]
|
|
429
467
|
#[napi(readonly)]
|
|
430
468
|
pub signature: Option<String>,
|
|
431
|
-
/// See [edr_solidity_tests::fuzz::BaseCounterExample::args]
|
|
469
|
+
/// See [`edr_solidity_tests::fuzz::BaseCounterExample::args`]
|
|
432
470
|
#[napi(readonly)]
|
|
433
471
|
pub args: Option<String>,
|
|
434
472
|
}
|
|
@@ -542,10 +580,19 @@ impl CallTrace {
|
|
|
542
580
|
/// Instantiates a `CallTrace` with the details from a node and the supplied
|
|
543
581
|
/// children.
|
|
544
582
|
fn new(node: &traces::CallTraceNode, children: Vec<Either<CallTrace, LogTrace>>) -> Self {
|
|
545
|
-
let contract = node
|
|
583
|
+
let contract = node
|
|
584
|
+
.trace
|
|
585
|
+
.decoded
|
|
586
|
+
.as_ref()
|
|
587
|
+
.and_then(|decoded| decoded.label.clone());
|
|
546
588
|
let address = node.trace.address.to_checksum(None);
|
|
547
589
|
|
|
548
|
-
let inputs = match &node
|
|
590
|
+
let inputs = match &node
|
|
591
|
+
.trace
|
|
592
|
+
.decoded
|
|
593
|
+
.as_ref()
|
|
594
|
+
.and_then(|decoded| decoded.call_data.as_ref())
|
|
595
|
+
{
|
|
549
596
|
Some(traces::DecodedCallData { signature, args }) => {
|
|
550
597
|
let name = signature
|
|
551
598
|
.split('(')
|
|
@@ -558,7 +605,12 @@ impl CallTrace {
|
|
|
558
605
|
None => Either::B(node.trace.data.as_ref().into()),
|
|
559
606
|
};
|
|
560
607
|
|
|
561
|
-
let outputs = match
|
|
608
|
+
let outputs = match node
|
|
609
|
+
.trace
|
|
610
|
+
.decoded
|
|
611
|
+
.as_ref()
|
|
612
|
+
.and_then(|decoded| decoded.return_data.as_ref())
|
|
613
|
+
{
|
|
562
614
|
Some(outputs) => Either::A(outputs.clone()),
|
|
563
615
|
None => {
|
|
564
616
|
if node.kind().is_any_create() && node.trace.success {
|
|
@@ -604,7 +656,10 @@ impl CallTrace {
|
|
|
604
656
|
loop {
|
|
605
657
|
// We will break out of the loop before the stack goes empty.
|
|
606
658
|
let mut item = stack.pop().unwrap();
|
|
607
|
-
let node =
|
|
659
|
+
let node = arena
|
|
660
|
+
.nodes()
|
|
661
|
+
.get(item.arena_index)
|
|
662
|
+
.expect("Arena index should be valid");
|
|
608
663
|
|
|
609
664
|
if item.visited {
|
|
610
665
|
let mut logs = node
|
|
@@ -618,11 +673,20 @@ impl CallTrace {
|
|
|
618
673
|
.iter()
|
|
619
674
|
.filter_map(|ord| match *ord {
|
|
620
675
|
traces::TraceMemberOrder::Log(i) => {
|
|
621
|
-
let log = logs
|
|
676
|
+
let log = logs
|
|
677
|
+
.get_mut(i)
|
|
678
|
+
.expect("Log index should be valid")
|
|
679
|
+
.take()
|
|
680
|
+
.unwrap();
|
|
622
681
|
Some(Either::B(log))
|
|
623
682
|
}
|
|
624
683
|
traces::TraceMemberOrder::Call(i) => {
|
|
625
|
-
let child_trace = item
|
|
684
|
+
let child_trace = item
|
|
685
|
+
.child_traces
|
|
686
|
+
.get_mut(i)
|
|
687
|
+
.expect("Child trace index should be valid")
|
|
688
|
+
.take()
|
|
689
|
+
.unwrap();
|
|
626
690
|
Some(Either::A(child_trace))
|
|
627
691
|
}
|
|
628
692
|
traces::TraceMemberOrder::Step(_) => None,
|
|
@@ -632,7 +696,9 @@ impl CallTrace {
|
|
|
632
696
|
let trace = CallTrace::new(node, children);
|
|
633
697
|
|
|
634
698
|
if let Some(parent_stack_index) = item.parent_stack_index {
|
|
635
|
-
let parent =
|
|
699
|
+
let parent = stack
|
|
700
|
+
.get_mut(parent_stack_index)
|
|
701
|
+
.expect("Parent stack index should be valid");
|
|
636
702
|
parent.child_traces.push(Some(trace));
|
|
637
703
|
} else {
|
|
638
704
|
return trace;
|
|
@@ -661,7 +727,10 @@ impl CallTrace {
|
|
|
661
727
|
|
|
662
728
|
impl From<&traces::CallLog> for LogTrace {
|
|
663
729
|
fn from(log: &traces::CallLog) -> Self {
|
|
664
|
-
let decoded_log = log
|
|
730
|
+
let decoded_log = log
|
|
731
|
+
.decoded
|
|
732
|
+
.as_ref()
|
|
733
|
+
.and_then(|decoded| decoded.name.clone().zip(decoded.params.as_ref()));
|
|
665
734
|
|
|
666
735
|
let parameters = decoded_log.map_or_else(
|
|
667
736
|
|| {
|
|
@@ -703,3 +772,19 @@ impl From<traces::CallKind> for CallKind {
|
|
|
703
772
|
}
|
|
704
773
|
}
|
|
705
774
|
}
|
|
775
|
+
|
|
776
|
+
/// The result of a Solidity test run.
|
|
777
|
+
#[napi(object)]
|
|
778
|
+
pub struct SolidityTestResult {
|
|
779
|
+
/// Gas report, if it was generated.
|
|
780
|
+
#[napi(readonly)]
|
|
781
|
+
pub gas_report: Option<GasReport>,
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
impl From<edr_solidity_tests::multi_runner::SolidityTestResult> for SolidityTestResult {
|
|
785
|
+
fn from(value: edr_solidity_tests::multi_runner::SolidityTestResult) -> Self {
|
|
786
|
+
Self {
|
|
787
|
+
gas_report: value.gas_report.map(GasReport::from),
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
package/src/solidity_tests.rs
CHANGED
|
@@ -9,7 +9,7 @@ pub mod test_results;
|
|
|
9
9
|
|
|
10
10
|
use std::path::Path;
|
|
11
11
|
|
|
12
|
-
use
|
|
12
|
+
use edr_primitives::Bytes;
|
|
13
13
|
use edr_solidity::linker::{LinkOutput, Linker};
|
|
14
14
|
use edr_solidity_tests::{constants::LIBRARY_DEPLOYER, contracts::ContractsByArtifact};
|
|
15
15
|
use foundry_compilers::artifacts::Libraries;
|
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())
|
|
@@ -45,7 +46,9 @@ fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
|
|
|
45
46
|
})?;
|
|
46
47
|
|
|
47
48
|
let mut value = serde_json::to_value(entry)?;
|
|
48
|
-
|
|
49
|
+
if let Some(obj) = value.as_object_mut() {
|
|
50
|
+
obj.insert("message".to_string(), decoded_error_msg.into());
|
|
51
|
+
}
|
|
49
52
|
Ok(value)
|
|
50
53
|
}
|
|
51
54
|
})
|
package/src/trace/exit.rs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
use std::fmt;
|
|
5
5
|
|
|
6
|
+
use edr_chain_spec::EvmHaltReason;
|
|
6
7
|
use napi_derive::napi;
|
|
7
8
|
|
|
8
9
|
#[napi]
|
|
@@ -50,20 +51,20 @@ impl fmt::Display for ExitCode {
|
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
#[allow(clippy::fallible_impl_from)] // naively ported for now
|
|
53
|
-
impl From<edr_solidity::exit_code::ExitCode<
|
|
54
|
-
fn from(code: edr_solidity::exit_code::ExitCode<
|
|
54
|
+
impl From<edr_solidity::exit_code::ExitCode<EvmHaltReason>> for ExitCode {
|
|
55
|
+
fn from(code: edr_solidity::exit_code::ExitCode<EvmHaltReason>) -> Self {
|
|
55
56
|
use edr_solidity::exit_code::ExitCode;
|
|
56
57
|
|
|
57
58
|
match code {
|
|
58
59
|
ExitCode::Success => Self::SUCCESS,
|
|
59
60
|
ExitCode::Revert => Self::REVERT,
|
|
60
|
-
ExitCode::Halt(
|
|
61
|
-
ExitCode::Halt(
|
|
61
|
+
ExitCode::Halt(EvmHaltReason::OutOfGas(_)) => Self::OUT_OF_GAS,
|
|
62
|
+
ExitCode::Halt(EvmHaltReason::OpcodeNotFound | EvmHaltReason::InvalidFEOpcode
|
|
62
63
|
// Returned when an opcode is not implemented for the hardfork
|
|
63
|
-
|
|
|
64
|
-
ExitCode::Halt(
|
|
65
|
-
ExitCode::Halt(
|
|
66
|
-
ExitCode::Halt(
|
|
64
|
+
| EvmHaltReason::NotActivated) => Self::INVALID_OPCODE,
|
|
65
|
+
ExitCode::Halt(EvmHaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
|
|
66
|
+
ExitCode::Halt(EvmHaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
|
|
67
|
+
ExitCode::Halt(EvmHaltReason::CreateCollision) => Self::CREATE_COLLISION,
|
|
67
68
|
_ => Self::UNKNOWN_HALT_REASON,
|
|
68
69
|
}
|
|
69
70
|
}
|
package/src/trace/return_data.rs
CHANGED
|
@@ -22,11 +22,9 @@ pub struct ReturnData {
|
|
|
22
22
|
impl ReturnData {
|
|
23
23
|
#[napi(catch_unwind, constructor)]
|
|
24
24
|
pub fn new(value: Uint8Array) -> Self {
|
|
25
|
-
let selector =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
None
|
|
29
|
-
};
|
|
25
|
+
let selector = value
|
|
26
|
+
.get(0..4)
|
|
27
|
+
.map(|selector| selector.try_into().expect("selector is 4 bytes"));
|
|
30
28
|
|
|
31
29
|
Self { value, selector }
|
|
32
30
|
}
|
|
@@ -57,10 +55,17 @@ impl ReturnData {
|
|
|
57
55
|
return Ok(String::new());
|
|
58
56
|
}
|
|
59
57
|
|
|
58
|
+
if !self.is_error_return_data() {
|
|
59
|
+
return Err(napi::Error::new(
|
|
60
|
+
napi::Status::InvalidArg,
|
|
61
|
+
"VM Exception while processing transaction: Expected return data to be a Error(string)",
|
|
62
|
+
));
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
let result = Error::abi_decode(&self.value[..]).map_err(|_err| {
|
|
61
66
|
napi::Error::new(
|
|
62
67
|
napi::Status::InvalidArg,
|
|
63
|
-
"Expected return data to
|
|
68
|
+
"VM Exception while processing transaction: Expected return data to contain a valid string",
|
|
64
69
|
)
|
|
65
70
|
})?;
|
|
66
71
|
|
|
@@ -69,10 +74,17 @@ impl ReturnData {
|
|
|
69
74
|
|
|
70
75
|
#[napi(catch_unwind)]
|
|
71
76
|
pub fn decode_panic(&self) -> napi::Result<BigInt> {
|
|
77
|
+
if !self.is_panic_return_data() {
|
|
78
|
+
return Err(napi::Error::new(
|
|
79
|
+
napi::Status::InvalidArg,
|
|
80
|
+
"VM Exception while processing transaction: Expected return data to be a Panic(uint256)",
|
|
81
|
+
));
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
let result = Panic::abi_decode(&self.value[..]).map_err(|_err| {
|
|
73
85
|
napi::Error::new(
|
|
74
86
|
napi::Status::InvalidArg,
|
|
75
|
-
"Expected return data to
|
|
87
|
+
"VM Exception while processing transaction: Expected return data to contain a valid uint256",
|
|
76
88
|
)
|
|
77
89
|
})?;
|
|
78
90
|
|