@nomicfoundation/edr 0.12.0-next.3 → 0.12.0-next.5
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 +31 -18
- package/package.json +8 -8
- package/src/account.rs +1 -1
- package/src/chains/generic.rs +20 -15
- package/src/chains/l1.rs +19 -14
- package/src/chains/op.rs +22 -17
- package/src/config.rs +49 -1
- package/src/context.rs +37 -56
- package/src/mock/time.rs +56 -54
- package/src/result.rs +0 -21
- package/src/solidity_tests/config.rs +41 -10
- package/src/trace/return_data.rs +16 -2
package/index.d.ts
CHANGED
|
@@ -405,8 +405,7 @@ export enum SuccessReason {
|
|
|
405
405
|
/** The opcode `RETURN` was called */
|
|
406
406
|
Return = 1,
|
|
407
407
|
/** The opcode `SELFDESTRUCT` was called */
|
|
408
|
-
SelfDestruct = 2
|
|
409
|
-
EofReturnContract = 3
|
|
408
|
+
SelfDestruct = 2
|
|
410
409
|
}
|
|
411
410
|
export interface CallOutput {
|
|
412
411
|
/** Return value */
|
|
@@ -459,15 +458,7 @@ export enum ExceptionalHalt {
|
|
|
459
458
|
/** Error on created contract that begins with EF */
|
|
460
459
|
CreateContractStartingWithEF = 12,
|
|
461
460
|
/** EIP-3860: Limit and meter initcode. Initcode size limit exceeded. */
|
|
462
|
-
CreateInitCodeSizeLimit = 13
|
|
463
|
-
/** Aux data overflow, new aux data is larger tha u16 max size. */
|
|
464
|
-
EofAuxDataOverflow = 14,
|
|
465
|
-
/** Aud data is smaller then already present data size. */
|
|
466
|
-
EofAuxDataTooSmall = 15,
|
|
467
|
-
/** EOF Subroutine stack overflow */
|
|
468
|
-
SubRoutineStackOverflow = 16,
|
|
469
|
-
/** Check for target address validity is only done inside subcall. */
|
|
470
|
-
InvalidEXTCALLTarget = 17
|
|
461
|
+
CreateInitCodeSizeLimit = 13
|
|
471
462
|
}
|
|
472
463
|
/** The result when the EVM terminates due to an exceptional halt. */
|
|
473
464
|
export interface HaltResult {
|
|
@@ -812,14 +803,36 @@ export interface PathPermission {
|
|
|
812
803
|
/** The targeted path guarded by the permission */
|
|
813
804
|
path: string
|
|
814
805
|
}
|
|
815
|
-
/**
|
|
806
|
+
/**
|
|
807
|
+
* Determines the level of file system access for the given path.
|
|
808
|
+
*
|
|
809
|
+
* Exact path matching is used for file permissions. Prefix matching is used
|
|
810
|
+
* for directory permissions.
|
|
811
|
+
*
|
|
812
|
+
* Giving write access to configuration files, source files or executables
|
|
813
|
+
* in a project is considered dangerous, because it can be used by malicious
|
|
814
|
+
* Solidity dependencies to escape the EVM sandbox. It is therefore
|
|
815
|
+
* recommended to give write access to specific safe files only. If write
|
|
816
|
+
* access to a directory is needed, please make sure that it doesn't contain
|
|
817
|
+
* configuration files, source files or executables neither in the top level
|
|
818
|
+
* directory, nor in any subdirectories.
|
|
819
|
+
*/
|
|
816
820
|
export enum FsAccessPermission {
|
|
817
|
-
/**
|
|
818
|
-
|
|
819
|
-
/** Only reading
|
|
820
|
-
|
|
821
|
-
/** Only writing
|
|
822
|
-
|
|
821
|
+
/** Allows reading and writing the file */
|
|
822
|
+
ReadWriteFile = 0,
|
|
823
|
+
/** Only allows reading the file */
|
|
824
|
+
ReadFile = 1,
|
|
825
|
+
/** Only allows writing the file */
|
|
826
|
+
WriteFile = 2,
|
|
827
|
+
/**
|
|
828
|
+
* Allows reading and writing all files in the directory and its
|
|
829
|
+
* subdirectories
|
|
830
|
+
*/
|
|
831
|
+
DangerouslyReadWriteDirectory = 3,
|
|
832
|
+
/** Allows reading all files in the directory and its subdirectories */
|
|
833
|
+
ReadDirectory = 4,
|
|
834
|
+
/** Allows writing all files in the directory and its subdirectories */
|
|
835
|
+
DangerouslyWriteDirectory = 5
|
|
823
836
|
}
|
|
824
837
|
export interface AddressLabel {
|
|
825
838
|
/** The address to label */
|
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.5",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@napi-rs/cli": "^2.18.4",
|
|
6
6
|
"@nomicfoundation/ethereumjs-util": "^9.0.4",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"repository": "NomicFoundation/edr.git",
|
|
60
60
|
"types": "index.d.ts",
|
|
61
61
|
"optionalDependencies": {
|
|
62
|
-
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.
|
|
63
|
-
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.
|
|
64
|
-
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.
|
|
65
|
-
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.
|
|
66
|
-
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.
|
|
67
|
-
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.
|
|
68
|
-
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.
|
|
62
|
+
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.5",
|
|
63
|
+
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.5",
|
|
64
|
+
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.5",
|
|
65
|
+
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.5",
|
|
66
|
+
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.5",
|
|
67
|
+
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.5",
|
|
68
|
+
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.5"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"artifacts": "napi artifacts",
|
package/src/account.rs
CHANGED
|
@@ -53,7 +53,7 @@ impl TryFrom<AccountOverride> for (edr_eth::Address, edr_provider::AccountOverri
|
|
|
53
53
|
.into_iter()
|
|
54
54
|
.map(|StorageSlot { index, value }| {
|
|
55
55
|
let value = value.try_cast()?;
|
|
56
|
-
let slot = edr_evm::state::EvmStorageSlot::new(value);
|
|
56
|
+
let slot = edr_evm::state::EvmStorageSlot::new(value, 0);
|
|
57
57
|
|
|
58
58
|
let index: edr_eth::U256 = index.try_cast()?;
|
|
59
59
|
Ok((index, slot))
|
package/src/chains/generic.rs
CHANGED
|
@@ -3,12 +3,13 @@ use std::sync::Arc;
|
|
|
3
3
|
use edr_eth::l1;
|
|
4
4
|
use edr_generic::GenericChainSpec;
|
|
5
5
|
use edr_napi_core::{
|
|
6
|
-
logger::
|
|
7
|
-
provider::{
|
|
8
|
-
subscription,
|
|
6
|
+
logger::Logger,
|
|
7
|
+
provider::{SyncProvider, SyncProviderFactory},
|
|
8
|
+
subscription::subscriber_callback_for_chain_spec,
|
|
9
9
|
};
|
|
10
10
|
use edr_provider::time::CurrentTime;
|
|
11
11
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
12
|
+
use napi::tokio::runtime;
|
|
12
13
|
use napi_derive::napi;
|
|
13
14
|
|
|
14
15
|
use crate::provider::ProviderFactory;
|
|
@@ -16,14 +17,14 @@ use crate::provider::ProviderFactory;
|
|
|
16
17
|
pub struct GenericChainProviderFactory;
|
|
17
18
|
|
|
18
19
|
impl SyncProviderFactory for GenericChainProviderFactory {
|
|
19
|
-
fn
|
|
20
|
+
fn create_provider(
|
|
20
21
|
&self,
|
|
21
|
-
|
|
22
|
+
runtime: runtime::Handle,
|
|
22
23
|
provider_config: edr_napi_core::provider::Config,
|
|
23
|
-
logger_config: logger::Config,
|
|
24
|
-
|
|
24
|
+
logger_config: edr_napi_core::logger::Config,
|
|
25
|
+
subscription_callback: edr_napi_core::subscription::Callback,
|
|
25
26
|
contract_decoder: Arc<ContractDecoder>,
|
|
26
|
-
) -> napi::Result<
|
|
27
|
+
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
27
28
|
let logger = Logger::<GenericChainSpec, CurrentTime>::new(
|
|
28
29
|
logger_config,
|
|
29
30
|
Arc::clone(&contract_decoder),
|
|
@@ -32,15 +33,19 @@ impl SyncProviderFactory for GenericChainProviderFactory {
|
|
|
32
33
|
let provider_config =
|
|
33
34
|
edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
|
|
34
35
|
|
|
35
|
-
let
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Ok(Box::new(ProviderBuilder::new(
|
|
39
|
-
contract_decoder,
|
|
36
|
+
let provider = edr_provider::Provider::<GenericChainSpec>::new(
|
|
37
|
+
runtime.clone(),
|
|
40
38
|
Box::new(logger),
|
|
39
|
+
subscriber_callback_for_chain_spec::<GenericChainSpec, CurrentTime>(
|
|
40
|
+
subscription_callback,
|
|
41
|
+
),
|
|
41
42
|
provider_config,
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
contract_decoder,
|
|
44
|
+
CurrentTime,
|
|
45
|
+
)
|
|
46
|
+
.map_err(|error| napi::Error::new(napi::Status::GenericFailure, error.to_string()))?;
|
|
47
|
+
|
|
48
|
+
Ok(Arc::new(provider))
|
|
44
49
|
}
|
|
45
50
|
}
|
|
46
51
|
|
package/src/chains/l1.rs
CHANGED
|
@@ -7,12 +7,15 @@ use edr_evm::eips::{
|
|
|
7
7
|
};
|
|
8
8
|
use edr_napi_core::{
|
|
9
9
|
logger::Logger,
|
|
10
|
-
provider::{
|
|
11
|
-
subscription,
|
|
10
|
+
provider::{SyncProvider, SyncProviderFactory},
|
|
11
|
+
subscription::subscriber_callback_for_chain_spec,
|
|
12
12
|
};
|
|
13
13
|
use edr_provider::time::CurrentTime;
|
|
14
14
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
15
|
-
use napi::
|
|
15
|
+
use napi::{
|
|
16
|
+
bindgen_prelude::{BigInt, Uint8Array},
|
|
17
|
+
tokio::runtime,
|
|
18
|
+
};
|
|
16
19
|
use napi_derive::napi;
|
|
17
20
|
|
|
18
21
|
use crate::{account::AccountOverride, provider::ProviderFactory};
|
|
@@ -20,29 +23,31 @@ use crate::{account::AccountOverride, provider::ProviderFactory};
|
|
|
20
23
|
pub struct L1ProviderFactory;
|
|
21
24
|
|
|
22
25
|
impl SyncProviderFactory for L1ProviderFactory {
|
|
23
|
-
fn
|
|
26
|
+
fn create_provider(
|
|
24
27
|
&self,
|
|
25
|
-
|
|
28
|
+
runtime: runtime::Handle,
|
|
26
29
|
provider_config: edr_napi_core::provider::Config,
|
|
27
30
|
logger_config: edr_napi_core::logger::Config,
|
|
28
|
-
|
|
31
|
+
subscription_callback: edr_napi_core::subscription::Callback,
|
|
29
32
|
contract_decoder: Arc<ContractDecoder>,
|
|
30
|
-
) -> napi::Result<
|
|
33
|
+
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
31
34
|
let logger =
|
|
32
35
|
Logger::<L1ChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
|
33
36
|
|
|
34
37
|
let provider_config =
|
|
35
38
|
edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
|
|
36
39
|
|
|
37
|
-
let
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Ok(Box::new(ProviderBuilder::new(
|
|
41
|
-
contract_decoder,
|
|
40
|
+
let provider = edr_provider::Provider::<L1ChainSpec>::new(
|
|
41
|
+
runtime.clone(),
|
|
42
42
|
Box::new(logger),
|
|
43
|
+
subscriber_callback_for_chain_spec::<L1ChainSpec, CurrentTime>(subscription_callback),
|
|
43
44
|
provider_config,
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
contract_decoder,
|
|
46
|
+
CurrentTime,
|
|
47
|
+
)
|
|
48
|
+
.map_err(|error| napi::Error::new(napi::Status::GenericFailure, error.to_string()))?;
|
|
49
|
+
|
|
50
|
+
Ok(Arc::new(provider))
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
|
package/src/chains/op.rs
CHANGED
|
@@ -2,14 +2,17 @@ use std::{str::FromStr, sync::Arc};
|
|
|
2
2
|
|
|
3
3
|
use edr_eth::hex;
|
|
4
4
|
use edr_napi_core::{
|
|
5
|
-
logger::
|
|
6
|
-
provider::{
|
|
7
|
-
subscription,
|
|
5
|
+
logger::Logger,
|
|
6
|
+
provider::{SyncProvider, SyncProviderFactory},
|
|
7
|
+
subscription::subscriber_callback_for_chain_spec,
|
|
8
8
|
};
|
|
9
9
|
use edr_op::{predeploys::GAS_PRICE_ORACLE_ADDRESS, OpChainSpec, OpSpecId};
|
|
10
10
|
use edr_provider::time::CurrentTime;
|
|
11
11
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
12
|
-
use napi::
|
|
12
|
+
use napi::{
|
|
13
|
+
bindgen_prelude::{BigInt, Uint8Array},
|
|
14
|
+
tokio::runtime,
|
|
15
|
+
};
|
|
13
16
|
use napi_derive::napi;
|
|
14
17
|
|
|
15
18
|
use crate::{
|
|
@@ -20,28 +23,30 @@ use crate::{
|
|
|
20
23
|
pub struct OpProviderFactory;
|
|
21
24
|
|
|
22
25
|
impl SyncProviderFactory for OpProviderFactory {
|
|
23
|
-
fn
|
|
26
|
+
fn create_provider(
|
|
24
27
|
&self,
|
|
25
|
-
|
|
26
|
-
provider_config: provider::Config,
|
|
27
|
-
logger_config: logger::Config,
|
|
28
|
-
|
|
28
|
+
runtime: runtime::Handle,
|
|
29
|
+
provider_config: edr_napi_core::provider::Config,
|
|
30
|
+
logger_config: edr_napi_core::logger::Config,
|
|
31
|
+
subscription_callback: edr_napi_core::subscription::Callback,
|
|
29
32
|
contract_decoder: Arc<ContractDecoder>,
|
|
30
|
-
) -> napi::Result<
|
|
33
|
+
) -> napi::Result<Arc<dyn SyncProvider>> {
|
|
31
34
|
let logger =
|
|
32
35
|
Logger::<OpChainSpec, CurrentTime>::new(logger_config, Arc::clone(&contract_decoder))?;
|
|
33
36
|
|
|
34
37
|
let provider_config = edr_provider::ProviderConfig::<OpSpecId>::try_from(provider_config)?;
|
|
35
38
|
|
|
36
|
-
let
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Ok(Box::new(ProviderBuilder::new(
|
|
40
|
-
contract_decoder,
|
|
39
|
+
let provider = edr_provider::Provider::<OpChainSpec>::new(
|
|
40
|
+
runtime.clone(),
|
|
41
41
|
Box::new(logger),
|
|
42
|
+
subscriber_callback_for_chain_spec::<OpChainSpec, CurrentTime>(subscription_callback),
|
|
42
43
|
provider_config,
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
contract_decoder,
|
|
45
|
+
CurrentTime,
|
|
46
|
+
)
|
|
47
|
+
.map_err(|error| napi::Error::new(napi::Status::GenericFailure, error.to_string()))?;
|
|
48
|
+
|
|
49
|
+
Ok(Arc::new(provider))
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
|
package/src/config.rs
CHANGED
|
@@ -2,6 +2,7 @@ use core::fmt::{Debug, Display};
|
|
|
2
2
|
use std::{
|
|
3
3
|
num::NonZeroU64,
|
|
4
4
|
path::PathBuf,
|
|
5
|
+
sync::Arc,
|
|
5
6
|
time::{Duration, SystemTime},
|
|
6
7
|
};
|
|
7
8
|
|
|
@@ -10,6 +11,7 @@ use edr_eth::{
|
|
|
10
11
|
signature::{secret_key_from_str, SecretKey},
|
|
11
12
|
Bytes, HashMap, HashSet,
|
|
12
13
|
};
|
|
14
|
+
use edr_solidity::contract_decoder::ContractDecoder;
|
|
13
15
|
use napi::{
|
|
14
16
|
bindgen_prelude::{BigInt, Promise, Reference, Uint8Array},
|
|
15
17
|
threadsafe_function::{
|
|
@@ -20,7 +22,10 @@ use napi::{
|
|
|
20
22
|
};
|
|
21
23
|
use napi_derive::napi;
|
|
22
24
|
|
|
23
|
-
use crate::{
|
|
25
|
+
use crate::{
|
|
26
|
+
account::AccountOverride, block::BlobGas, cast::TryCast, logger::LoggerConfig,
|
|
27
|
+
precompile::Precompile, subscription::SubscriptionConfig,
|
|
28
|
+
};
|
|
24
29
|
|
|
25
30
|
/// Specification of a chain with possible overrides.
|
|
26
31
|
#[napi(object)]
|
|
@@ -541,3 +546,46 @@ impl From<BuildInfoAndOutput> for edr_napi_core::solidity::config::BuildInfoAndO
|
|
|
541
546
|
}
|
|
542
547
|
}
|
|
543
548
|
}
|
|
549
|
+
|
|
550
|
+
/// Result of [`resolve_configs`].
|
|
551
|
+
pub struct ConfigResolution {
|
|
552
|
+
pub contract_decoder: Arc<ContractDecoder>,
|
|
553
|
+
pub logger_config: edr_napi_core::logger::Config,
|
|
554
|
+
pub provider_config: edr_napi_core::provider::Config,
|
|
555
|
+
pub subscription_callback: edr_napi_core::subscription::Callback,
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/// Helper function for resolving the provided N-API configs.
|
|
559
|
+
pub fn resolve_configs(
|
|
560
|
+
env: &napi::Env,
|
|
561
|
+
runtime: runtime::Handle,
|
|
562
|
+
provider_config: ProviderConfig,
|
|
563
|
+
logger_config: LoggerConfig,
|
|
564
|
+
subscription_config: SubscriptionConfig,
|
|
565
|
+
tracing_config: TracingConfigWithBuffers,
|
|
566
|
+
) -> napi::Result<ConfigResolution> {
|
|
567
|
+
let provider_config = provider_config.resolve(env, runtime)?;
|
|
568
|
+
let logger_config = logger_config.resolve(env)?;
|
|
569
|
+
|
|
570
|
+
// TODO: https://github.com/NomicFoundation/edr/issues/760
|
|
571
|
+
let build_info_config = edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
|
|
572
|
+
(&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(tracing_config)).into(),
|
|
573
|
+
)
|
|
574
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
575
|
+
|
|
576
|
+
let contract_decoder = ContractDecoder::new(&build_info_config).map_or_else(
|
|
577
|
+
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
578
|
+
|contract_decoder| Ok(Arc::new(contract_decoder)),
|
|
579
|
+
)?;
|
|
580
|
+
|
|
581
|
+
let subscription_config = edr_napi_core::subscription::Config::from(subscription_config);
|
|
582
|
+
let subscription_callback =
|
|
583
|
+
edr_napi_core::subscription::Callback::new(env, subscription_config.subscription_callback)?;
|
|
584
|
+
|
|
585
|
+
Ok(ConfigResolution {
|
|
586
|
+
contract_decoder,
|
|
587
|
+
logger_config,
|
|
588
|
+
provider_config,
|
|
589
|
+
subscription_callback,
|
|
590
|
+
})
|
|
591
|
+
}
|
package/src/context.rs
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
3
|
use edr_eth::HashMap;
|
|
4
|
-
use edr_napi_core::{
|
|
5
|
-
provider::{self, SyncProviderFactory},
|
|
6
|
-
solidity,
|
|
7
|
-
};
|
|
8
|
-
use edr_solidity::contract_decoder::ContractDecoder;
|
|
4
|
+
use edr_napi_core::{provider::SyncProviderFactory, solidity};
|
|
9
5
|
use edr_solidity_tests::{
|
|
10
6
|
decode::RevertDecoder,
|
|
11
7
|
multi_runner::{SuiteResultAndArtifactId, TestContract, TestContracts},
|
|
@@ -22,7 +18,7 @@ use napi_derive::napi;
|
|
|
22
18
|
use tracing_subscriber::{prelude::*, EnvFilter, Registry};
|
|
23
19
|
|
|
24
20
|
use crate::{
|
|
25
|
-
config::{ProviderConfig, TracingConfigWithBuffers},
|
|
21
|
+
config::{resolve_configs, ConfigResolution, ProviderConfig, TracingConfigWithBuffers},
|
|
26
22
|
logger::LoggerConfig,
|
|
27
23
|
provider::{Provider, ProviderFactory},
|
|
28
24
|
solidity_tests::{
|
|
@@ -78,25 +74,20 @@ impl EdrContext {
|
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
let runtime = runtime::Handle::current();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let contract_decoder = try_or_reject_promise!(ContractDecoder::new(&build_info_config)
|
|
96
|
-
.map_or_else(
|
|
97
|
-
|error| Err(napi::Error::from_reason(error.to_string())),
|
|
98
|
-
|contract_decoder| Ok(Arc::new(contract_decoder))
|
|
99
|
-
));
|
|
77
|
+
|
|
78
|
+
let ConfigResolution {
|
|
79
|
+
contract_decoder,
|
|
80
|
+
logger_config,
|
|
81
|
+
provider_config,
|
|
82
|
+
subscription_callback,
|
|
83
|
+
} = try_or_reject_promise!(resolve_configs(
|
|
84
|
+
&env,
|
|
85
|
+
runtime.clone(),
|
|
86
|
+
provider_config,
|
|
87
|
+
logger_config,
|
|
88
|
+
subscription_config,
|
|
89
|
+
tracing_config
|
|
90
|
+
));
|
|
100
91
|
|
|
101
92
|
#[cfg(feature = "scenarios")]
|
|
102
93
|
let scenario_file =
|
|
@@ -106,31 +97,32 @@ impl EdrContext {
|
|
|
106
97
|
logger_config.enable,
|
|
107
98
|
)));
|
|
108
99
|
|
|
109
|
-
let
|
|
100
|
+
let factory = {
|
|
110
101
|
// TODO: https://github.com/NomicFoundation/edr/issues/760
|
|
111
102
|
// TODO: Don't block the JS event loop
|
|
112
103
|
let context = runtime.block_on(async { self.inner.lock().await });
|
|
113
104
|
|
|
114
|
-
try_or_reject_promise!(context.
|
|
115
|
-
&env,
|
|
116
|
-
&chain_type,
|
|
117
|
-
provider_config,
|
|
118
|
-
logger_config,
|
|
119
|
-
subscription_config.into(),
|
|
120
|
-
&contract_decoder,
|
|
121
|
-
))
|
|
105
|
+
try_or_reject_promise!(context.get_provider_factory(&chain_type))
|
|
122
106
|
};
|
|
123
107
|
|
|
124
108
|
runtime.clone().spawn_blocking(move || {
|
|
125
|
-
let result =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
109
|
+
let result = factory
|
|
110
|
+
.create_provider(
|
|
111
|
+
runtime.clone(),
|
|
112
|
+
provider_config,
|
|
113
|
+
logger_config,
|
|
114
|
+
subscription_callback,
|
|
115
|
+
Arc::clone(&contract_decoder),
|
|
132
116
|
)
|
|
133
|
-
|
|
117
|
+
.map(|provider| {
|
|
118
|
+
Provider::new(
|
|
119
|
+
provider,
|
|
120
|
+
runtime,
|
|
121
|
+
contract_decoder,
|
|
122
|
+
#[cfg(feature = "scenarios")]
|
|
123
|
+
scenario_file,
|
|
124
|
+
)
|
|
125
|
+
});
|
|
134
126
|
|
|
135
127
|
deferred.resolve(|_env| result);
|
|
136
128
|
});
|
|
@@ -410,23 +402,12 @@ impl Context {
|
|
|
410
402
|
|
|
411
403
|
/// Tries to create a new provider for the provided chain type and
|
|
412
404
|
/// configuration.
|
|
413
|
-
pub fn
|
|
405
|
+
pub fn get_provider_factory(
|
|
414
406
|
&self,
|
|
415
|
-
env: &napi::Env,
|
|
416
407
|
chain_type: &str,
|
|
417
|
-
|
|
418
|
-
logger_config: edr_napi_core::logger::Config,
|
|
419
|
-
subscription_config: edr_napi_core::subscription::Config,
|
|
420
|
-
contract_decoder: &Arc<ContractDecoder>,
|
|
421
|
-
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
408
|
+
) -> napi::Result<Arc<dyn SyncProviderFactory>> {
|
|
422
409
|
if let Some(factory) = self.provider_factories.get(chain_type) {
|
|
423
|
-
factory
|
|
424
|
-
env,
|
|
425
|
-
provider_config,
|
|
426
|
-
logger_config,
|
|
427
|
-
subscription_config,
|
|
428
|
-
contract_decoder.clone(),
|
|
429
|
-
)
|
|
410
|
+
Ok(Arc::clone(factory))
|
|
430
411
|
} else {
|
|
431
412
|
Err(napi::Error::new(
|
|
432
413
|
napi::Status::GenericFailure,
|
package/src/mock/time.rs
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
|
+
use edr_eth::{spec::ChainSpec, B256};
|
|
4
|
+
use edr_evm::spec::RuntimeSpec;
|
|
3
5
|
use edr_generic::GenericChainSpec;
|
|
4
6
|
use edr_napi_core::logger::Logger;
|
|
5
|
-
use
|
|
7
|
+
use edr_rpc_eth::RpcSpec;
|
|
6
8
|
use napi::{bindgen_prelude::BigInt, tokio::runtime, Env, JsObject};
|
|
7
9
|
use napi_derive::napi;
|
|
8
10
|
|
|
9
11
|
use crate::{
|
|
10
12
|
cast::TryCast as _,
|
|
11
|
-
config::{ProviderConfig, TracingConfigWithBuffers},
|
|
13
|
+
config::{resolve_configs, ConfigResolution, ProviderConfig, TracingConfigWithBuffers},
|
|
12
14
|
logger::LoggerConfig,
|
|
13
15
|
provider::Provider,
|
|
14
16
|
subscription::SubscriptionConfig,
|
|
@@ -65,65 +67,65 @@ pub fn create_provider_with_mock_timer(
|
|
|
65
67
|
}
|
|
66
68
|
|
|
67
69
|
let runtime = runtime::Handle::current();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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(
|
|
70
|
+
|
|
71
|
+
let ConfigResolution {
|
|
72
|
+
contract_decoder,
|
|
73
|
+
logger_config,
|
|
74
|
+
provider_config,
|
|
75
|
+
subscription_callback,
|
|
76
|
+
} = try_or_reject_promise!(resolve_configs(
|
|
89
77
|
&env,
|
|
90
|
-
|
|
78
|
+
runtime.clone(),
|
|
79
|
+
provider_config,
|
|
80
|
+
logger_config,
|
|
81
|
+
subscription_config,
|
|
82
|
+
tracing_config,
|
|
91
83
|
));
|
|
92
84
|
|
|
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
85
|
let timer = Arc::clone(&time.inner);
|
|
103
86
|
|
|
104
87
|
runtime.clone().spawn_blocking(move || {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
88
|
+
// Using a closure to limit the scope, allowing us to use `?` for error
|
|
89
|
+
// handling. This is necessary because the result of the closure is used
|
|
90
|
+
// to resolve the deferred promise.
|
|
91
|
+
let create_provider = move || -> napi::Result<Provider> {
|
|
92
|
+
let logger = Logger::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
|
|
93
|
+
logger_config,
|
|
94
|
+
Arc::clone(&contract_decoder),
|
|
95
|
+
)?;
|
|
96
|
+
|
|
97
|
+
let provider_config =
|
|
98
|
+
edr_provider::ProviderConfig::<edr_eth::l1::SpecId>::try_from(provider_config)?;
|
|
99
|
+
|
|
100
|
+
let provider =
|
|
101
|
+
edr_provider::Provider::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
|
|
102
|
+
runtime.clone(),
|
|
103
|
+
Box::new(logger),
|
|
104
|
+
Box::new(move |event| {
|
|
105
|
+
let event = edr_napi_core::subscription::SubscriptionEvent::new::<
|
|
106
|
+
<GenericChainSpec as RuntimeSpec>::Block,
|
|
107
|
+
<GenericChainSpec as RpcSpec>::RpcBlock<B256>,
|
|
108
|
+
<GenericChainSpec as ChainSpec>::SignedTransaction,
|
|
109
|
+
>(event);
|
|
110
|
+
|
|
111
|
+
subscription_callback.call(event);
|
|
112
|
+
}),
|
|
113
|
+
provider_config,
|
|
114
|
+
contract_decoder.clone(),
|
|
115
|
+
timer,
|
|
116
|
+
)
|
|
117
|
+
.map_err(|error| napi::Error::from_reason(error.to_string()))?;
|
|
118
|
+
|
|
119
|
+
Ok(Provider::new(
|
|
120
|
+
Arc::new(provider),
|
|
121
|
+
runtime,
|
|
122
|
+
contract_decoder,
|
|
123
|
+
#[cfg(feature = "scenarios")]
|
|
124
|
+
None,
|
|
125
|
+
))
|
|
126
|
+
};
|
|
126
127
|
|
|
128
|
+
let result = create_provider();
|
|
127
129
|
deferred.resolve(|_env| result);
|
|
128
130
|
});
|
|
129
131
|
|
package/src/result.rs
CHANGED
|
@@ -16,7 +16,6 @@ pub enum SuccessReason {
|
|
|
16
16
|
Return,
|
|
17
17
|
/// The opcode `SELFDESTRUCT` was called
|
|
18
18
|
SelfDestruct,
|
|
19
|
-
EofReturnContract,
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
impl From<edr_eth::result::SuccessReason> for SuccessReason {
|
|
@@ -25,7 +24,6 @@ impl From<edr_eth::result::SuccessReason> for SuccessReason {
|
|
|
25
24
|
edr_eth::result::SuccessReason::Stop => Self::Stop,
|
|
26
25
|
edr_eth::result::SuccessReason::Return => Self::Return,
|
|
27
26
|
edr_eth::result::SuccessReason::SelfDestruct => Self::SelfDestruct,
|
|
28
|
-
edr_eth::result::SuccessReason::EofReturnContract => Self::EofReturnContract,
|
|
29
27
|
}
|
|
30
28
|
}
|
|
31
29
|
}
|
|
@@ -36,7 +34,6 @@ impl From<SuccessReason> for edr_eth::result::SuccessReason {
|
|
|
36
34
|
SuccessReason::Stop => Self::Stop,
|
|
37
35
|
SuccessReason::Return => Self::Return,
|
|
38
36
|
SuccessReason::SelfDestruct => Self::SelfDestruct,
|
|
39
|
-
SuccessReason::EofReturnContract => Self::EofReturnContract,
|
|
40
37
|
}
|
|
41
38
|
}
|
|
42
39
|
}
|
|
@@ -100,14 +97,6 @@ pub enum ExceptionalHalt {
|
|
|
100
97
|
CreateContractStartingWithEF,
|
|
101
98
|
/// EIP-3860: Limit and meter initcode. Initcode size limit exceeded.
|
|
102
99
|
CreateInitCodeSizeLimit,
|
|
103
|
-
/// Aux data overflow, new aux data is larger tha u16 max size.
|
|
104
|
-
EofAuxDataOverflow,
|
|
105
|
-
/// Aud data is smaller then already present data size.
|
|
106
|
-
EofAuxDataTooSmall,
|
|
107
|
-
/// EOF Subroutine stack overflow
|
|
108
|
-
SubRoutineStackOverflow,
|
|
109
|
-
/// Check for target address validity is only done inside subcall.
|
|
110
|
-
InvalidEXTCALLTarget,
|
|
111
100
|
}
|
|
112
101
|
|
|
113
102
|
impl From<edr_eth::l1::HaltReason> for ExceptionalHalt {
|
|
@@ -133,12 +122,6 @@ impl From<edr_eth::l1::HaltReason> for ExceptionalHalt {
|
|
|
133
122
|
edr_eth::l1::HaltReason::CreateInitCodeSizeLimit => {
|
|
134
123
|
ExceptionalHalt::CreateInitCodeSizeLimit
|
|
135
124
|
}
|
|
136
|
-
edr_eth::l1::HaltReason::EofAuxDataOverflow => ExceptionalHalt::EofAuxDataOverflow,
|
|
137
|
-
edr_eth::l1::HaltReason::EofAuxDataTooSmall => ExceptionalHalt::EofAuxDataTooSmall,
|
|
138
|
-
edr_eth::l1::HaltReason::SubRoutineStackOverflow => {
|
|
139
|
-
ExceptionalHalt::SubRoutineStackOverflow
|
|
140
|
-
}
|
|
141
|
-
edr_eth::l1::HaltReason::InvalidEXTCALLTarget => ExceptionalHalt::InvalidEXTCALLTarget,
|
|
142
125
|
edr_eth::l1::HaltReason::OverflowPayment
|
|
143
126
|
| edr_eth::l1::HaltReason::StateChangeDuringStaticCall
|
|
144
127
|
| edr_eth::l1::HaltReason::CallNotAllowedInsideStatic
|
|
@@ -167,10 +150,6 @@ impl From<ExceptionalHalt> for edr_eth::l1::HaltReason {
|
|
|
167
150
|
ExceptionalHalt::CreateContractSizeLimit => Self::CreateContractSizeLimit,
|
|
168
151
|
ExceptionalHalt::CreateContractStartingWithEF => Self::CreateContractStartingWithEF,
|
|
169
152
|
ExceptionalHalt::CreateInitCodeSizeLimit => Self::CreateInitCodeSizeLimit,
|
|
170
|
-
ExceptionalHalt::EofAuxDataOverflow => Self::EofAuxDataOverflow,
|
|
171
|
-
ExceptionalHalt::EofAuxDataTooSmall => Self::EofAuxDataTooSmall,
|
|
172
|
-
ExceptionalHalt::SubRoutineStackOverflow => Self::SubRoutineStackOverflow,
|
|
173
|
-
ExceptionalHalt::InvalidEXTCALLTarget => Self::InvalidEXTCALLTarget,
|
|
174
153
|
}
|
|
175
154
|
}
|
|
176
155
|
}
|
|
@@ -657,24 +657,55 @@ impl From<PathPermission> for foundry_cheatcodes::PathPermission {
|
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
-
|
|
660
|
+
/**
|
|
661
|
+
* Determines the level of file system access for the given path.
|
|
662
|
+
*
|
|
663
|
+
* Exact path matching is used for file permissions. Prefix matching is used
|
|
664
|
+
* for directory permissions.
|
|
665
|
+
*
|
|
666
|
+
* Giving write access to configuration files, source files or executables
|
|
667
|
+
* in a project is considered dangerous, because it can be used by malicious
|
|
668
|
+
* Solidity dependencies to escape the EVM sandbox. It is therefore
|
|
669
|
+
* recommended to give write access to specific safe files only. If write
|
|
670
|
+
* access to a directory is needed, please make sure that it doesn't contain
|
|
671
|
+
* configuration files, source files or executables neither in the top level
|
|
672
|
+
* directory, nor in any subdirectories.
|
|
673
|
+
*/
|
|
661
674
|
#[napi]
|
|
662
675
|
#[derive(Debug, serde::Serialize)]
|
|
663
676
|
pub enum FsAccessPermission {
|
|
664
|
-
///
|
|
665
|
-
|
|
666
|
-
/// Only reading
|
|
667
|
-
|
|
668
|
-
/// Only writing
|
|
669
|
-
|
|
677
|
+
/// Allows reading and writing the file
|
|
678
|
+
ReadWriteFile,
|
|
679
|
+
/// Only allows reading the file
|
|
680
|
+
ReadFile,
|
|
681
|
+
/// Only allows writing the file
|
|
682
|
+
WriteFile,
|
|
683
|
+
/// Allows reading and writing all files in the directory and its
|
|
684
|
+
/// subdirectories
|
|
685
|
+
DangerouslyReadWriteDirectory,
|
|
686
|
+
/// Allows reading all files in the directory and its subdirectories
|
|
687
|
+
ReadDirectory,
|
|
688
|
+
/// Allows writing all files in the directory and its subdirectories
|
|
689
|
+
DangerouslyWriteDirectory,
|
|
670
690
|
}
|
|
671
691
|
|
|
672
692
|
impl From<FsAccessPermission> for foundry_cheatcodes::FsAccessPermission {
|
|
673
693
|
fn from(value: FsAccessPermission) -> Self {
|
|
674
694
|
match value {
|
|
675
|
-
FsAccessPermission::
|
|
676
|
-
|
|
677
|
-
|
|
695
|
+
FsAccessPermission::ReadWriteFile => {
|
|
696
|
+
foundry_cheatcodes::FsAccessPermission::ReadWriteFile
|
|
697
|
+
}
|
|
698
|
+
FsAccessPermission::ReadFile => foundry_cheatcodes::FsAccessPermission::ReadFile,
|
|
699
|
+
FsAccessPermission::WriteFile => foundry_cheatcodes::FsAccessPermission::WriteFile,
|
|
700
|
+
FsAccessPermission::DangerouslyReadWriteDirectory => {
|
|
701
|
+
foundry_cheatcodes::FsAccessPermission::DangerouslyReadWriteDirectory
|
|
702
|
+
}
|
|
703
|
+
FsAccessPermission::ReadDirectory => {
|
|
704
|
+
foundry_cheatcodes::FsAccessPermission::ReadDirectory
|
|
705
|
+
}
|
|
706
|
+
FsAccessPermission::DangerouslyWriteDirectory => {
|
|
707
|
+
foundry_cheatcodes::FsAccessPermission::DangerouslyWriteDirectory
|
|
708
|
+
}
|
|
678
709
|
}
|
|
679
710
|
}
|
|
680
711
|
}
|
package/src/trace/return_data.rs
CHANGED
|
@@ -57,10 +57,17 @@ impl ReturnData {
|
|
|
57
57
|
return Ok(String::new());
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
if !self.is_error_return_data() {
|
|
61
|
+
return Err(napi::Error::new(
|
|
62
|
+
napi::Status::InvalidArg,
|
|
63
|
+
"VM Exception while processing transaction: Expected return data to be a Error(string)",
|
|
64
|
+
));
|
|
65
|
+
}
|
|
66
|
+
|
|
60
67
|
let result = Error::abi_decode(&self.value[..]).map_err(|_err| {
|
|
61
68
|
napi::Error::new(
|
|
62
69
|
napi::Status::InvalidArg,
|
|
63
|
-
"Expected return data to
|
|
70
|
+
"VM Exception while processing transaction: Expected return data to contain a valid string",
|
|
64
71
|
)
|
|
65
72
|
})?;
|
|
66
73
|
|
|
@@ -69,10 +76,17 @@ impl ReturnData {
|
|
|
69
76
|
|
|
70
77
|
#[napi(catch_unwind)]
|
|
71
78
|
pub fn decode_panic(&self) -> napi::Result<BigInt> {
|
|
79
|
+
if !self.is_panic_return_data() {
|
|
80
|
+
return Err(napi::Error::new(
|
|
81
|
+
napi::Status::InvalidArg,
|
|
82
|
+
"VM Exception while processing transaction: Expected return data to be a Panic(uint256)",
|
|
83
|
+
));
|
|
84
|
+
}
|
|
85
|
+
|
|
72
86
|
let result = Panic::abi_decode(&self.value[..]).map_err(|_err| {
|
|
73
87
|
napi::Error::new(
|
|
74
88
|
napi::Status::InvalidArg,
|
|
75
|
-
"Expected return data to
|
|
89
|
+
"VM Exception while processing transaction: Expected return data to contain a valid uint256",
|
|
76
90
|
)
|
|
77
91
|
})?;
|
|
78
92
|
|