@nomicfoundation/edr 0.12.0-next.23 → 0.12.0-next.25
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 +49 -13
- package/index.js +2 -2
- package/package.json +8 -8
- package/src/chains/generic.rs +2 -1
- package/src/chains/l1.rs +2 -1
- package/src/chains/op.rs +2 -1
- package/src/config.rs +14 -2
- package/src/context.rs +2 -2
- package/src/contract_decoder.rs +9 -6
- package/src/mock.rs +4 -10
- package/src/provider/response.rs +45 -43
- package/src/provider.rs +5 -5
- package/src/solidity_tests/artifact.rs +4 -4
- package/src/solidity_tests/cheatcode_errors.rs +37 -0
- package/src/solidity_tests/config.rs +27 -14
- package/src/solidity_tests/l1.rs +2 -2
- package/src/solidity_tests/op.rs +2 -2
- package/src/solidity_tests/runner.rs +7 -4
- package/src/solidity_tests/test_results.rs +21 -24
- package/src/solidity_tests.rs +1 -0
- package/src/trace/solidity_stack_trace.rs +228 -184
- package/src/trace.rs +0 -7
package/index.d.ts
CHANGED
|
@@ -273,6 +273,13 @@ export interface ObservabilityConfig {
|
|
|
273
273
|
codeCoverage?: CodeCoverageConfig
|
|
274
274
|
/** If present, configures runtime observability to collect gas reports. */
|
|
275
275
|
gasReport?: GasReportConfig
|
|
276
|
+
/**
|
|
277
|
+
* Controls when to include call traces in the results of transaction
|
|
278
|
+
* execution.
|
|
279
|
+
*
|
|
280
|
+
* Defaults to `IncludeTraces.None`.
|
|
281
|
+
*/
|
|
282
|
+
includeCallTraces?: IncludeTraces
|
|
276
283
|
}
|
|
277
284
|
/** Configuration for a provider */
|
|
278
285
|
export interface ProviderConfig {
|
|
@@ -587,6 +594,20 @@ export interface LinkReference {
|
|
|
587
594
|
start: number
|
|
588
595
|
length: number
|
|
589
596
|
}
|
|
597
|
+
/**Error codes that can be returned by cheatcodes in Solidity tests. */
|
|
598
|
+
export enum CheatcodeErrorCode {
|
|
599
|
+
/**The specified cheatcode is not supported. */
|
|
600
|
+
UnsupportedCheatcode = 'UnsupportedCheatcode',
|
|
601
|
+
/**The specified cheatcode is missing. */
|
|
602
|
+
MissingCheatcode = 'MissingCheatcode'
|
|
603
|
+
}
|
|
604
|
+
/**Error returned by a cheatcode in Solidity tests. */
|
|
605
|
+
export interface CheatcodeErrorDetails {
|
|
606
|
+
/**The error code representing the type of cheatcode error. */
|
|
607
|
+
code: CheatcodeErrorCode
|
|
608
|
+
/**The name of the cheatcode that caused the error. */
|
|
609
|
+
cheatcode: string
|
|
610
|
+
}
|
|
590
611
|
/**
|
|
591
612
|
* Solidity test runner configuration arguments exposed through the ffi.
|
|
592
613
|
* Docs based on <https://book.getfoundry.sh/reference/config/testing>.
|
|
@@ -646,6 +667,8 @@ export interface SolidityTestRunnerConfigArgs {
|
|
|
646
667
|
* Defaults to `31337`.
|
|
647
668
|
*/
|
|
648
669
|
chainId?: bigint
|
|
670
|
+
/** The hardfork to use for EVM execution. */
|
|
671
|
+
hardfork: string
|
|
649
672
|
/**
|
|
650
673
|
* The gas limit for each test case.
|
|
651
674
|
* Defaults to `9_223_372_036_854_775_807` (`i64::MAX`).
|
|
@@ -686,6 +709,11 @@ export interface SolidityTestRunnerConfigArgs {
|
|
|
686
709
|
* Defaults to false.
|
|
687
710
|
*/
|
|
688
711
|
disableBlockGasLimit?: boolean
|
|
712
|
+
/**
|
|
713
|
+
* Whether to enable the EIP-7825 (Osaka) transaction gas limit cap.
|
|
714
|
+
* Defaults to false.
|
|
715
|
+
*/
|
|
716
|
+
enableTxGasLimitCap?: boolean
|
|
689
717
|
/**
|
|
690
718
|
* The memory limit of the EVM in bytes.
|
|
691
719
|
* Defaults to `33_554_432` (2^25 = 32MiB).
|
|
@@ -953,15 +981,21 @@ export enum CollectStackTraces {
|
|
|
953
981
|
OnFailure = 1
|
|
954
982
|
}
|
|
955
983
|
/**
|
|
956
|
-
* Configuration
|
|
957
|
-
*
|
|
984
|
+
* Configuration that controls whether execution traces are decoded and
|
|
985
|
+
* included in results.
|
|
986
|
+
*
|
|
987
|
+
* This can either be for Solidity test results or provider transaction
|
|
988
|
+
* execution results.
|
|
958
989
|
*/
|
|
959
990
|
export enum IncludeTraces {
|
|
960
|
-
/** No traces will be included
|
|
991
|
+
/** No traces will be included at all. */
|
|
961
992
|
None = 0,
|
|
962
|
-
/**
|
|
993
|
+
/**
|
|
994
|
+
* Traces will be included only on the results of failed tests or
|
|
995
|
+
* execution.
|
|
996
|
+
*/
|
|
963
997
|
Failing = 1,
|
|
964
|
-
/** Traces will be included
|
|
998
|
+
/** Traces will be included for all test results or executed transactions. */
|
|
965
999
|
All = 2
|
|
966
1000
|
}
|
|
967
1001
|
/** Test function level config override. */
|
|
@@ -1457,6 +1491,7 @@ export interface CheatcodeErrorStackTraceEntry {
|
|
|
1457
1491
|
type: StackTraceEntryType.CHEATCODE_ERROR
|
|
1458
1492
|
message: string
|
|
1459
1493
|
sourceReference: SourceReference
|
|
1494
|
+
details?: CheatcodeErrorDetails
|
|
1460
1495
|
}
|
|
1461
1496
|
export interface TracingMessage {
|
|
1462
1497
|
/** Sender address */
|
|
@@ -1501,11 +1536,6 @@ export interface TracingMessageResult {
|
|
|
1501
1536
|
/** Execution result */
|
|
1502
1537
|
readonly executionResult: ExecutionResult
|
|
1503
1538
|
}
|
|
1504
|
-
/**
|
|
1505
|
-
* Returns the latest version of solc that EDR officially
|
|
1506
|
-
* supports and is tested against.
|
|
1507
|
-
*/
|
|
1508
|
-
export declare function getLatestSupportedSolcVersion(): string
|
|
1509
1539
|
export interface Withdrawal {
|
|
1510
1540
|
/** The index of withdrawal */
|
|
1511
1541
|
index: bigint
|
|
@@ -1564,9 +1594,15 @@ export declare class Response {
|
|
|
1564
1594
|
/**Returns the response data as a JSON string or a JSON object. */
|
|
1565
1595
|
get data(): string | any
|
|
1566
1596
|
/**Compute the error stack trace. Return the stack trace if it can be decoded, otherwise returns none. Throws if there was an error computing the stack trace. */
|
|
1567
|
-
stackTrace():
|
|
1568
|
-
/**
|
|
1569
|
-
|
|
1597
|
+
stackTrace(): StackTrace | UnexpectedError | HeuristicFailed | null
|
|
1598
|
+
/**
|
|
1599
|
+
* Constructs the execution traces for the request. Returns an empty array
|
|
1600
|
+
* if traces are not enabled for this provider according to
|
|
1601
|
+
* [`crate::solidity_tests::config::SolidityTestRunnerConfigArgs::include_traces`]. Otherwise, returns
|
|
1602
|
+
* an array of the root calls of the trace, which always includes the
|
|
1603
|
+
* request's call itself.
|
|
1604
|
+
*/
|
|
1605
|
+
callTraces(): Array<CallTrace>
|
|
1570
1606
|
}
|
|
1571
1607
|
/** A JSON-RPC provider for Ethereum. */
|
|
1572
1608
|
export declare class Provider {
|
package/index.js
CHANGED
|
@@ -310,7 +310,7 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { GENERIC_CHAIN_TYPE, genericChainProviderFactory, L1_CHAIN_TYPE, l1GenesisState, l1ProviderFactory, SpecId, l1HardforkFromString, l1HardforkToString, l1HardforkLatest, FRONTIER, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, PRAGUE, OSAKA, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, ContractDecoder, GasReportExecutionStatus, addStatementCoverageInstrumentation, latestSupportedSolidityVersion, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CachedChains, CachedEndpoints, FsAccessPermission, CollectStackTraces, IncludeTraces, SolidityTestRunnerFactory, l1SolidityTestRunnerFactory, opSolidityTestRunnerFactory, SuiteResult, TestResult, TestStatus, CallKind, LogKind, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace
|
|
313
|
+
const { GENERIC_CHAIN_TYPE, genericChainProviderFactory, L1_CHAIN_TYPE, l1GenesisState, l1ProviderFactory, SpecId, l1HardforkFromString, l1HardforkToString, l1HardforkLatest, FRONTIER, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, PRAGUE, OSAKA, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, ContractDecoder, GasReportExecutionStatus, addStatementCoverageInstrumentation, latestSupportedSolidityVersion, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CheatcodeErrorCode, CachedChains, CachedEndpoints, FsAccessPermission, CollectStackTraces, IncludeTraces, SolidityTestRunnerFactory, l1SolidityTestRunnerFactory, opSolidityTestRunnerFactory, SuiteResult, TestResult, TestStatus, CallKind, LogKind, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace } = nativeBinding
|
|
314
314
|
|
|
315
315
|
module.exports.GENERIC_CHAIN_TYPE = GENERIC_CHAIN_TYPE
|
|
316
316
|
module.exports.genericChainProviderFactory = genericChainProviderFactory
|
|
@@ -369,6 +369,7 @@ module.exports.Response = Response
|
|
|
369
369
|
module.exports.Provider = Provider
|
|
370
370
|
module.exports.SuccessReason = SuccessReason
|
|
371
371
|
module.exports.ExceptionalHalt = ExceptionalHalt
|
|
372
|
+
module.exports.CheatcodeErrorCode = CheatcodeErrorCode
|
|
372
373
|
module.exports.CachedChains = CachedChains
|
|
373
374
|
module.exports.CachedEndpoints = CachedEndpoints
|
|
374
375
|
module.exports.FsAccessPermission = FsAccessPermission
|
|
@@ -399,4 +400,3 @@ module.exports.UNKNOWN_FUNCTION_NAME = UNKNOWN_FUNCTION_NAME
|
|
|
399
400
|
module.exports.PRECOMPILE_FUNCTION_NAME = PRECOMPILE_FUNCTION_NAME
|
|
400
401
|
module.exports.UNRECOGNIZED_CONTRACT_NAME = UNRECOGNIZED_CONTRACT_NAME
|
|
401
402
|
module.exports.RawTrace = RawTrace
|
|
402
|
-
module.exports.getLatestSupportedSolcVersion = getLatestSupportedSolcVersion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomicfoundation/edr",
|
|
3
|
-
"version": "0.12.0-next.
|
|
3
|
+
"version": "0.12.0-next.25",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@napi-rs/cli": "^2.18.4",
|
|
6
6
|
"@nomicfoundation/ethereumjs-util": "^9.0.4",
|
|
@@ -58,13 +58,13 @@
|
|
|
58
58
|
"repository": "NomicFoundation/edr.git",
|
|
59
59
|
"types": "index.d.ts",
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.
|
|
62
|
-
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.
|
|
63
|
-
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.
|
|
64
|
-
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.
|
|
65
|
-
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.
|
|
66
|
-
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.
|
|
67
|
-
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.
|
|
61
|
+
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.25",
|
|
62
|
+
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.25",
|
|
63
|
+
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.25",
|
|
64
|
+
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.25",
|
|
65
|
+
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.25",
|
|
66
|
+
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.25",
|
|
67
|
+
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.25"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"artifacts": "napi artifacts",
|
package/src/chains/generic.rs
CHANGED
|
@@ -10,6 +10,7 @@ use edr_provider::time::CurrentTime;
|
|
|
10
10
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
11
11
|
use napi::tokio::runtime;
|
|
12
12
|
use napi_derive::napi;
|
|
13
|
+
use parking_lot::RwLock;
|
|
13
14
|
|
|
14
15
|
use crate::provider::ProviderFactory;
|
|
15
16
|
|
|
@@ -22,7 +23,7 @@ impl SyncProviderFactory for GenericChainProviderFactory {
|
|
|
22
23
|
provider_config: edr_napi_core::provider::Config,
|
|
23
24
|
logger_config: edr_napi_core::logger::Config,
|
|
24
25
|
subscription_callback: edr_napi_core::subscription::Callback,
|
|
25
|
-
contract_decoder: Arc<ContractDecoder
|
|
26
|
+
contract_decoder: Arc<RwLock<ContractDecoder>>,
|
|
26
27
|
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
27
28
|
let logger = Logger::<GenericChainSpec, CurrentTime>::new(
|
|
28
29
|
logger_config,
|
package/src/chains/l1.rs
CHANGED
|
@@ -17,6 +17,7 @@ use napi::{
|
|
|
17
17
|
tokio::runtime,
|
|
18
18
|
};
|
|
19
19
|
use napi_derive::napi;
|
|
20
|
+
use parking_lot::RwLock;
|
|
20
21
|
|
|
21
22
|
use crate::{account::AccountOverride, provider::ProviderFactory};
|
|
22
23
|
|
|
@@ -29,7 +30,7 @@ impl SyncProviderFactory for L1ProviderFactory {
|
|
|
29
30
|
provider_config: edr_napi_core::provider::Config,
|
|
30
31
|
logger_config: edr_napi_core::logger::Config,
|
|
31
32
|
subscription_callback: edr_napi_core::subscription::Callback,
|
|
32
|
-
contract_decoder: Arc<ContractDecoder
|
|
33
|
+
contract_decoder: Arc<RwLock<ContractDecoder>>,
|
|
33
34
|
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
34
35
|
let logger =
|
|
35
36
|
Logger::<L1ChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
package/src/chains/op.rs
CHANGED
|
@@ -21,6 +21,7 @@ use napi::{
|
|
|
21
21
|
tokio::runtime,
|
|
22
22
|
};
|
|
23
23
|
use napi_derive::napi;
|
|
24
|
+
use parking_lot::RwLock;
|
|
24
25
|
|
|
25
26
|
use crate::{
|
|
26
27
|
account::{AccountOverride, StorageSlot},
|
|
@@ -36,7 +37,7 @@ impl SyncProviderFactory for OpProviderFactory {
|
|
|
36
37
|
provider_config: edr_napi_core::provider::Config,
|
|
37
38
|
logger_config: edr_napi_core::logger::Config,
|
|
38
39
|
subscription_callback: edr_napi_core::subscription::Callback,
|
|
39
|
-
contract_decoder: Arc<ContractDecoder
|
|
40
|
+
contract_decoder: Arc<RwLock<ContractDecoder>>,
|
|
40
41
|
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
41
42
|
let logger =
|
|
42
43
|
Logger::<OpChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
package/src/config.rs
CHANGED
|
@@ -22,7 +22,8 @@ use napi_derive::napi;
|
|
|
22
22
|
|
|
23
23
|
use crate::{
|
|
24
24
|
account::AccountOverride, block::BlobGas, cast::TryCast, gas_report::GasReport,
|
|
25
|
-
logger::LoggerConfig, precompile::Precompile,
|
|
25
|
+
logger::LoggerConfig, precompile::Precompile, solidity_tests::config::IncludeTraces,
|
|
26
|
+
subscription::SubscriptionConfig,
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
/// Configuration for EIP-1559 parameters
|
|
@@ -183,6 +184,11 @@ pub struct ObservabilityConfig {
|
|
|
183
184
|
pub code_coverage: Option<CodeCoverageConfig>,
|
|
184
185
|
/// If present, configures runtime observability to collect gas reports.
|
|
185
186
|
pub gas_report: Option<GasReportConfig>,
|
|
187
|
+
/// Controls when to include call traces in the results of transaction
|
|
188
|
+
/// execution.
|
|
189
|
+
///
|
|
190
|
+
/// Defaults to `IncludeTraces.None`.
|
|
191
|
+
pub include_call_traces: Option<IncludeTraces>,
|
|
186
192
|
}
|
|
187
193
|
|
|
188
194
|
/// Configuration for a provider
|
|
@@ -524,10 +530,16 @@ impl ObservabilityConfig {
|
|
|
524
530
|
},
|
|
525
531
|
).transpose()?;
|
|
526
532
|
|
|
533
|
+
let default_config = edr_provider::observability::Config::default();
|
|
527
534
|
Ok(edr_provider::observability::Config {
|
|
535
|
+
call_override: default_config.call_override,
|
|
536
|
+
include_call_traces: self.include_call_traces.map_or(
|
|
537
|
+
default_config.include_call_traces,
|
|
538
|
+
edr_solidity::config::IncludeTraces::from,
|
|
539
|
+
),
|
|
528
540
|
on_collected_coverage_fn,
|
|
529
541
|
on_collected_gas_report_fn,
|
|
530
|
-
|
|
542
|
+
verbose_raw_tracing: default_config.verbose_raw_tracing,
|
|
531
543
|
})
|
|
532
544
|
}
|
|
533
545
|
}
|
package/src/context.rs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
|
+
use edr_decoder_revert::RevertDecoder;
|
|
3
4
|
use edr_napi_core::{provider::SyncProviderFactory, solidity};
|
|
4
5
|
use edr_primitives::HashMap;
|
|
5
6
|
use edr_solidity_tests::{
|
|
6
|
-
decode::RevertDecoder,
|
|
7
7
|
multi_runner::{SuiteResultAndArtifactId, TestContract, TestContracts},
|
|
8
8
|
TestFilterConfig,
|
|
9
9
|
};
|
|
@@ -251,7 +251,7 @@ impl EdrContext {
|
|
|
251
251
|
|
|
252
252
|
let test_suites = try_or_reject_deferred!(test_suites
|
|
253
253
|
.into_iter()
|
|
254
|
-
.map(
|
|
254
|
+
.map(edr_artifact::ArtifactId::try_from)
|
|
255
255
|
.collect::<Result<Vec<_>, _>>());
|
|
256
256
|
|
|
257
257
|
let contracts = try_or_reject_deferred!(test_suites
|
package/src/contract_decoder.rs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
3
|
use napi_derive::napi;
|
|
4
|
+
use parking_lot::RwLock;
|
|
4
5
|
|
|
5
6
|
use crate::config::TracingConfigWithBuffers;
|
|
6
7
|
|
|
7
8
|
#[napi]
|
|
8
9
|
pub struct ContractDecoder {
|
|
9
|
-
inner: Arc<edr_solidity::contract_decoder::ContractDecoder
|
|
10
|
+
inner: Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>>,
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
#[napi]
|
|
@@ -17,7 +18,7 @@ impl ContractDecoder {
|
|
|
17
18
|
#[allow(clippy::new_without_default)]
|
|
18
19
|
pub fn new() -> Self {
|
|
19
20
|
Self {
|
|
20
|
-
inner: Arc::
|
|
21
|
+
inner: Arc::default(),
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -32,7 +33,7 @@ impl ContractDecoder {
|
|
|
32
33
|
let contract_decoder =
|
|
33
34
|
edr_solidity::contract_decoder::ContractDecoder::new(&build_info_config).map_or_else(
|
|
34
35
|
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
35
|
-
|contract_decoder| Ok(Arc::new(contract_decoder)),
|
|
36
|
+
|contract_decoder| Ok(Arc::new(RwLock::new(contract_decoder))),
|
|
36
37
|
)?;
|
|
37
38
|
|
|
38
39
|
Ok(Self {
|
|
@@ -43,13 +44,15 @@ impl ContractDecoder {
|
|
|
43
44
|
|
|
44
45
|
impl ContractDecoder {
|
|
45
46
|
/// Returns a reference to the inner contract decoder.
|
|
46
|
-
pub fn as_inner(&self) -> &Arc<edr_solidity::contract_decoder::ContractDecoder
|
|
47
|
+
pub fn as_inner(&self) -> &Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>> {
|
|
47
48
|
&self.inner
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
impl From<Arc<edr_solidity::contract_decoder::ContractDecoder
|
|
52
|
-
fn from(
|
|
52
|
+
impl From<Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>>> for ContractDecoder {
|
|
53
|
+
fn from(
|
|
54
|
+
contract_decoder: Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>>,
|
|
55
|
+
) -> Self {
|
|
53
56
|
Self {
|
|
54
57
|
inner: contract_decoder,
|
|
55
58
|
}
|
package/src/mock.rs
CHANGED
|
@@ -2,10 +2,8 @@ pub mod time;
|
|
|
2
2
|
|
|
3
3
|
use std::sync::Arc;
|
|
4
4
|
|
|
5
|
-
use edr_chain_spec::EvmHaltReason;
|
|
6
5
|
use edr_napi_core::provider::SyncProvider;
|
|
7
6
|
use edr_rpc_client::jsonrpc;
|
|
8
|
-
use edr_solidity::contract_decoder::ContractDecoder;
|
|
9
7
|
use napi::tokio::runtime;
|
|
10
8
|
use napi_derive::napi;
|
|
11
9
|
|
|
@@ -23,19 +21,15 @@ impl MockProvider {
|
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
impl SyncProvider for MockProvider {
|
|
26
|
-
fn handle_request(
|
|
27
|
-
&self,
|
|
28
|
-
_request: String,
|
|
29
|
-
_contract_decoder: Arc<ContractDecoder>,
|
|
30
|
-
) -> napi::Result<edr_napi_core::spec::Response<EvmHaltReason>> {
|
|
24
|
+
fn handle_request(&self, _request: String) -> napi::Result<edr_napi_core::spec::Response> {
|
|
31
25
|
let response = jsonrpc::ResponseData::Success {
|
|
32
26
|
result: self.mocked_response.clone(),
|
|
33
27
|
};
|
|
34
28
|
edr_napi_core::spec::marshal_response_data(response)
|
|
35
29
|
.map(|data| edr_napi_core::spec::Response {
|
|
36
|
-
solidity_trace: None,
|
|
37
30
|
data,
|
|
38
|
-
|
|
31
|
+
stack_trace_result: None,
|
|
32
|
+
call_trace_arenas: Vec::new(),
|
|
39
33
|
})
|
|
40
34
|
.map_err(|error| napi::Error::new(napi::Status::GenericFailure, error.to_string()))
|
|
41
35
|
}
|
|
@@ -61,7 +55,7 @@ impl EdrContext {
|
|
|
61
55
|
let provider = Provider::new(
|
|
62
56
|
Arc::new(MockProvider::new(mocked_response)),
|
|
63
57
|
runtime::Handle::current(),
|
|
64
|
-
Arc::
|
|
58
|
+
Arc::default(),
|
|
65
59
|
#[cfg(feature = "scenarios")]
|
|
66
60
|
None,
|
|
67
61
|
);
|
package/src/provider/response.rs
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
use
|
|
2
|
-
use
|
|
3
|
-
use edr_solidity::contract_decoder::NestedTraceDecoder as _;
|
|
4
|
-
use napi::Either;
|
|
1
|
+
use edr_solidity::solidity_stack_trace::StackTraceCreationResult;
|
|
2
|
+
use napi::{bindgen_prelude::Either3, Either};
|
|
5
3
|
use napi_derive::napi;
|
|
6
4
|
|
|
7
5
|
use crate::{
|
|
8
|
-
|
|
9
|
-
trace::
|
|
6
|
+
solidity_tests::test_results::{CallTrace, HeuristicFailed, StackTrace, UnexpectedError},
|
|
7
|
+
trace::solidity_stack_trace::{
|
|
8
|
+
solidity_stack_trace_error_to_napi, solidity_stack_trace_heuristic_failed_to_napi,
|
|
9
|
+
solidity_stack_trace_success_to_napi,
|
|
10
|
+
},
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
#[napi]
|
|
13
14
|
pub struct Response {
|
|
14
|
-
inner: edr_napi_core::spec::Response
|
|
15
|
+
inner: edr_napi_core::spec::Response,
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
impl From<edr_napi_core::spec::Response
|
|
18
|
-
fn from(value: edr_napi_core::spec::Response
|
|
18
|
+
impl From<edr_napi_core::spec::Response> for Response {
|
|
19
|
+
fn from(value: edr_napi_core::spec::Response) -> Self {
|
|
19
20
|
Self { inner: value }
|
|
20
21
|
}
|
|
21
22
|
}
|
|
@@ -28,46 +29,47 @@ impl Response {
|
|
|
28
29
|
self.inner.data.clone()
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
// Rust port of https://github.com/NomicFoundation/hardhat/blob/c20bf195a6efdc2d74e778b7a4a7799aac224841/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts#L590
|
|
32
32
|
#[doc = "Compute the error stack trace. Return the stack trace if it can be decoded, otherwise returns none. Throws if there was an error computing the stack trace."]
|
|
33
33
|
#[napi(catch_unwind)]
|
|
34
|
-
pub fn stack_trace(&self) ->
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.try_to_decode_nested_trace(vm_trace)
|
|
50
|
-
.map_err(|err| napi::Error::from_reason(err.to_string()))?;
|
|
51
|
-
let stack_trace = edr_solidity::solidity_tracer::get_stack_trace(decoded_trace)
|
|
52
|
-
.map_err(|err| napi::Error::from_reason(err.to_string()))?;
|
|
53
|
-
let stack_trace = stack_trace
|
|
54
|
-
.into_iter()
|
|
55
|
-
.map(TryCast::try_cast)
|
|
56
|
-
.collect::<Result<Vec<_>, _>>()?;
|
|
57
|
-
|
|
58
|
-
Ok(Some(stack_trace))
|
|
59
|
-
} else {
|
|
60
|
-
Ok(None)
|
|
61
|
-
}
|
|
34
|
+
pub fn stack_trace(&self) -> Option<Either3<StackTrace, UnexpectedError, HeuristicFailed>> {
|
|
35
|
+
self.inner
|
|
36
|
+
.stack_trace_result
|
|
37
|
+
.as_ref()
|
|
38
|
+
.map(|stack_trace_result| match stack_trace_result {
|
|
39
|
+
StackTraceCreationResult::Success(stack_trace) => {
|
|
40
|
+
Either3::A(solidity_stack_trace_success_to_napi(stack_trace))
|
|
41
|
+
}
|
|
42
|
+
StackTraceCreationResult::Error(error) => {
|
|
43
|
+
Either3::B(solidity_stack_trace_error_to_napi(error))
|
|
44
|
+
}
|
|
45
|
+
StackTraceCreationResult::HeuristicFailed => {
|
|
46
|
+
Either3::C(solidity_stack_trace_heuristic_failed_to_napi())
|
|
47
|
+
}
|
|
48
|
+
})
|
|
62
49
|
}
|
|
63
50
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
51
|
+
/// Constructs the execution traces for the request. Returns an empty array
|
|
52
|
+
/// if traces are not enabled for this provider according to
|
|
53
|
+
/// [`crate::solidity_tests::config::SolidityTestRunnerConfigArgs::include_traces`]. Otherwise, returns
|
|
54
|
+
/// an array of the root calls of the trace, which always includes the
|
|
55
|
+
/// request's call itself.
|
|
56
|
+
#[napi(catch_unwind)]
|
|
57
|
+
pub fn call_traces(&self) -> Vec<CallTrace> {
|
|
67
58
|
self.inner
|
|
68
|
-
.
|
|
59
|
+
.call_trace_arenas
|
|
69
60
|
.iter()
|
|
70
|
-
.map(|
|
|
61
|
+
.map(|call_trace_arena| CallTrace::from_arena_node(call_trace_arena, 0))
|
|
71
62
|
.collect()
|
|
72
63
|
}
|
|
64
|
+
|
|
65
|
+
// TODO(#1288): Add backwards compatibility layer for Hardhat 2
|
|
66
|
+
// #[doc = "Returns the raw traces of executed contracts. This maybe contain
|
|
67
|
+
// zero or more traces."] #[napi(catch_unwind, getter)]
|
|
68
|
+
// pub fn traces(&self) -> Vec<RawTrace> {
|
|
69
|
+
// self.inner
|
|
70
|
+
// .call_trace_arenas
|
|
71
|
+
// .iter()
|
|
72
|
+
// .map(|trace| RawTrace::from(trace.clone()))
|
|
73
|
+
// .collect()
|
|
74
|
+
// }
|
|
73
75
|
}
|
package/src/provider.rs
CHANGED
|
@@ -8,6 +8,7 @@ use edr_napi_core::provider::SyncProvider;
|
|
|
8
8
|
use edr_solidity::compiler::create_models_and_decode_bytecodes;
|
|
9
9
|
use napi::{tokio::runtime, Env, JsFunction, JsObject, Status};
|
|
10
10
|
use napi_derive::napi;
|
|
11
|
+
use parking_lot::RwLock;
|
|
11
12
|
|
|
12
13
|
pub use self::factory::ProviderFactory;
|
|
13
14
|
use self::response::Response;
|
|
@@ -16,7 +17,7 @@ use crate::{call_override::CallOverrideCallback, contract_decoder::ContractDecod
|
|
|
16
17
|
/// A JSON-RPC provider for Ethereum.
|
|
17
18
|
#[napi]
|
|
18
19
|
pub struct Provider {
|
|
19
|
-
contract_decoder: Arc<edr_solidity::contract_decoder::ContractDecoder
|
|
20
|
+
contract_decoder: Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>>,
|
|
20
21
|
provider: Arc<dyn SyncProvider>,
|
|
21
22
|
runtime: runtime::Handle,
|
|
22
23
|
#[cfg(feature = "scenarios")]
|
|
@@ -28,7 +29,7 @@ impl Provider {
|
|
|
28
29
|
pub fn new(
|
|
29
30
|
provider: Arc<dyn SyncProvider>,
|
|
30
31
|
runtime: runtime::Handle,
|
|
31
|
-
contract_decoder: Arc<edr_solidity::contract_decoder::ContractDecoder
|
|
32
|
+
contract_decoder: Arc<RwLock<edr_solidity::contract_decoder::ContractDecoder>>,
|
|
32
33
|
#[cfg(feature = "scenarios")] scenario_file: Option<
|
|
33
34
|
napi::tokio::sync::Mutex<napi::tokio::fs::File>,
|
|
34
35
|
>,
|
|
@@ -76,6 +77,7 @@ impl Provider {
|
|
|
76
77
|
}
|
|
77
78
|
};
|
|
78
79
|
|
|
80
|
+
let mut contract_decoder = contract_decoder.write();
|
|
79
81
|
for contract in contracts {
|
|
80
82
|
contract_decoder.add_contract_metadata(contract);
|
|
81
83
|
}
|
|
@@ -102,10 +104,8 @@ impl Provider {
|
|
|
102
104
|
crate::scenarios::write_request(scenario_file, &request).await?;
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
let contract_decoder = Arc::clone(&self.contract_decoder);
|
|
106
|
-
|
|
107
107
|
self.runtime
|
|
108
|
-
.spawn_blocking(move || provider.handle_request(request
|
|
108
|
+
.spawn_blocking(move || provider.handle_request(request))
|
|
109
109
|
.await
|
|
110
110
|
.map_err(|error| napi::Error::new(Status::GenericFailure, error.to_string()))?
|
|
111
111
|
.map(Response::from)
|
|
@@ -27,8 +27,8 @@ pub struct ArtifactId {
|
|
|
27
27
|
pub solc_version: String,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
impl From<
|
|
31
|
-
fn from(value:
|
|
30
|
+
impl From<edr_artifact::ArtifactId> for ArtifactId {
|
|
31
|
+
fn from(value: edr_artifact::ArtifactId) -> Self {
|
|
32
32
|
Self {
|
|
33
33
|
name: value.name,
|
|
34
34
|
source: value.source.to_string_lossy().to_string(),
|
|
@@ -37,11 +37,11 @@ impl From<edr_solidity::artifacts::ArtifactId> for ArtifactId {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
impl TryFrom<ArtifactId> for
|
|
40
|
+
impl TryFrom<ArtifactId> for edr_artifact::ArtifactId {
|
|
41
41
|
type Error = napi::Error;
|
|
42
42
|
|
|
43
43
|
fn try_from(value: ArtifactId) -> napi::Result<Self> {
|
|
44
|
-
Ok(
|
|
44
|
+
Ok(edr_artifact::ArtifactId {
|
|
45
45
|
name: value.name,
|
|
46
46
|
source: value.source.parse().map_err(|_err| {
|
|
47
47
|
napi::Error::new(napi::Status::GenericFailure, "Invalid source path")
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
use napi_derive::napi;
|
|
2
|
+
use serde::Serialize;
|
|
3
|
+
|
|
4
|
+
#[napi(string_enum)]
|
|
5
|
+
#[derive(Serialize)]
|
|
6
|
+
#[doc = "Error codes that can be returned by cheatcodes in Solidity tests."]
|
|
7
|
+
pub enum CheatcodeErrorCode {
|
|
8
|
+
#[doc = "The specified cheatcode is not supported."]
|
|
9
|
+
UnsupportedCheatcode,
|
|
10
|
+
#[doc = "The specified cheatcode is missing."]
|
|
11
|
+
MissingCheatcode,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#[napi(object)]
|
|
15
|
+
#[derive(Clone, Serialize)]
|
|
16
|
+
#[doc = "Error returned by a cheatcode in Solidity tests."]
|
|
17
|
+
pub struct CheatcodeErrorDetails {
|
|
18
|
+
#[doc = "The error code representing the type of cheatcode error."]
|
|
19
|
+
pub code: CheatcodeErrorCode,
|
|
20
|
+
#[doc = "The name of the cheatcode that caused the error."]
|
|
21
|
+
pub cheatcode: String,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
impl From<edr_solidity::return_data::CheatcodeErrorCode> for CheatcodeErrorCode {
|
|
25
|
+
fn from(value: edr_solidity::return_data::CheatcodeErrorCode) -> Self {
|
|
26
|
+
match value {
|
|
27
|
+
edr_solidity::return_data::CheatcodeErrorCode::UnsupportedCheatcode => {
|
|
28
|
+
CheatcodeErrorCode::UnsupportedCheatcode
|
|
29
|
+
}
|
|
30
|
+
// __Invalid is generated by alloy_sol_types for invalid encoded values.
|
|
31
|
+
edr_solidity::return_data::CheatcodeErrorCode::MissingCheatcode
|
|
32
|
+
| edr_solidity::return_data::CheatcodeErrorCode::__Invalid => {
|
|
33
|
+
CheatcodeErrorCode::MissingCheatcode
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|