@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 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
- /** Determines the status of file system access */
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
- /** FS access is allowed with `read` + `write` permission */
818
- ReadWrite = 0,
819
- /** Only reading is allowed */
820
- Read = 1,
821
- /** Only writing is allowed */
822
- Write = 2
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",
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.3",
63
- "@nomicfoundation/edr-darwin-x64": "0.12.0-next.3",
64
- "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.3",
65
- "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.3",
66
- "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.3",
67
- "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.3",
68
- "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.3"
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))
@@ -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::{self, Logger},
7
- provider::{self, ProviderBuilder, SyncProviderFactory},
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 create_provider_builder(
20
+ fn create_provider(
20
21
  &self,
21
- env: &napi::Env,
22
+ runtime: runtime::Handle,
22
23
  provider_config: edr_napi_core::provider::Config,
23
- logger_config: logger::Config,
24
- subscription_config: subscription::Config,
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<Box<dyn provider::Builder>> {
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 subscription_callback =
36
- subscription::Callback::new(env, subscription_config.subscription_callback)?;
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
- subscription_callback,
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::{self, ProviderBuilder, SyncProviderFactory},
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::bindgen_prelude::{BigInt, Uint8Array};
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 create_provider_builder(
26
+ fn create_provider(
24
27
  &self,
25
- env: &napi::Env,
28
+ runtime: runtime::Handle,
26
29
  provider_config: edr_napi_core::provider::Config,
27
30
  logger_config: edr_napi_core::logger::Config,
28
- subscription_config: edr_napi_core::subscription::Config,
31
+ subscription_callback: edr_napi_core::subscription::Callback,
29
32
  contract_decoder: Arc<ContractDecoder>,
30
- ) -> napi::Result<Box<dyn provider::Builder>> {
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 subscription_callback =
38
- subscription::Callback::new(env, subscription_config.subscription_callback)?;
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
- subscription_callback,
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::{self, Logger},
6
- provider::{self, ProviderBuilder, SyncProviderFactory},
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::bindgen_prelude::{BigInt, Uint8Array};
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 create_provider_builder(
26
+ fn create_provider(
24
27
  &self,
25
- env: &napi::Env,
26
- provider_config: provider::Config,
27
- logger_config: logger::Config,
28
- subscription_config: subscription::Config,
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<Box<dyn provider::Builder>> {
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 subscription_callback =
37
- subscription::Callback::new(env, subscription_config.subscription_callback)?;
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
- subscription_callback,
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::{account::AccountOverride, block::BlobGas, cast::TryCast, precompile::Precompile};
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
- let provider_config =
82
- try_or_reject_promise!(provider_config.resolve(&env, runtime.clone()));
83
-
84
- let logger_config = try_or_reject_promise!(logger_config.resolve(&env));
85
-
86
- // TODO: https://github.com/NomicFoundation/edr/issues/760
87
- let build_info_config = try_or_reject_promise!(
88
- edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
89
- (&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(tracing_config))
90
- .into(),
91
- )
92
- .map_err(|error| napi::Error::from_reason(error.to_string()))
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 builder = {
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.create_provider_builder(
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 = builder.build(runtime.clone()).map(|provider| {
126
- Provider::new(
127
- provider,
128
- runtime,
129
- contract_decoder,
130
- #[cfg(feature = "scenarios")]
131
- scenario_file,
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 create_provider_builder(
405
+ pub fn get_provider_factory(
414
406
  &self,
415
- env: &napi::Env,
416
407
  chain_type: &str,
417
- provider_config: edr_napi_core::provider::Config,
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.create_provider_builder(
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 edr_solidity::contract_decoder::ContractDecoder;
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
- let provider_config = try_or_reject_promise!(provider_config.resolve(&env, runtime.clone()));
69
-
70
- let logger_config = try_or_reject_promise!(logger_config.resolve(&env));
71
-
72
- // TODO: https://github.com/NomicFoundation/edr/issues/760
73
- let build_info_config = try_or_reject_promise!(
74
- edr_solidity::artifacts::BuildInfoConfig::parse_from_buffers(
75
- (&edr_napi_core::solidity::config::TracingConfigWithBuffers::from(tracing_config))
76
- .into(),
77
- )
78
- .map_err(|error| napi::Error::from_reason(error.to_string()))
79
- );
80
-
81
- let contract_decoder = try_or_reject_promise!(ContractDecoder::new(&build_info_config)
82
- .map_or_else(
83
- |error| Err(napi::Error::from_reason(error.to_string())),
84
- |contract_decoder| Ok(Arc::new(contract_decoder))
85
- ));
86
-
87
- let subscription_config = edr_napi_core::subscription::Config::from(subscription_config);
88
- let subscription_callback = try_or_reject_promise!(edr_napi_core::subscription::Callback::new(
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
- subscription_config.subscription_callback,
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
- let result =
106
- edr_provider::Provider::<GenericChainSpec, Arc<edr_provider::time::MockTime>>::new(
107
- runtime.clone(),
108
- Box::new(logger),
109
- Box::new(move |event| subscription_callback.call(event)),
110
- provider_config,
111
- contract_decoder.clone(),
112
- timer,
113
- )
114
- .map_or_else(
115
- |error| Err(napi::Error::from_reason(error.to_string())),
116
- |provider| {
117
- Ok(Provider::new(
118
- Arc::new(provider),
119
- runtime,
120
- contract_decoder,
121
- #[cfg(feature = "scenarios")]
122
- None,
123
- ))
124
- },
125
- );
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
- /// Determines the status of file system access
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
- /// FS access is allowed with `read` + `write` permission
665
- ReadWrite,
666
- /// Only reading is allowed
667
- Read,
668
- /// Only writing is allowed
669
- Write,
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::ReadWrite => foundry_cheatcodes::FsAccessPermission::ReadWrite,
676
- FsAccessPermission::Read => foundry_cheatcodes::FsAccessPermission::Read,
677
- FsAccessPermission::Write => foundry_cheatcodes::FsAccessPermission::Write,
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
  }
@@ -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 be a Error(string) and contain a valid string",
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 be a Error(string) and contain a valid string",
89
+ "VM Exception while processing transaction: Expected return data to contain a valid uint256",
76
90
  )
77
91
  })?;
78
92