@nomicfoundation/edr 0.11.3 → 0.12.0-next.0
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/Cargo.toml +61 -27
- package/LICENSE +5 -1
- package/index.d.ts +875 -137
- package/index.js +61 -3
- package/package.json +20 -16
- package/src/account.rs +109 -32
- package/src/block.rs +2 -103
- package/src/call_override.rs +7 -7
- package/src/cast.rs +47 -17
- package/src/chains/generic.rs +51 -0
- package/src/chains/l1.rs +262 -0
- package/src/chains/op.rs +425 -0
- package/src/chains.rs +7 -0
- package/src/config.rs +537 -67
- package/src/context.rs +374 -17
- package/src/debug_trace.rs +2 -2
- package/src/instrument.rs +109 -0
- package/src/lib.rs +38 -14
- package/src/log.rs +12 -14
- package/src/logger.rs +77 -1177
- package/src/mock.rs +68 -0
- package/src/precompile.rs +50 -0
- package/src/provider/factory.rs +22 -0
- package/src/provider/response.rs +73 -0
- package/src/provider.rs +64 -325
- package/src/result.rs +60 -69
- package/src/scenarios.rs +11 -17
- package/src/serde.rs +57 -0
- package/src/solidity_tests/artifact.rs +184 -0
- package/src/solidity_tests/config.rs +725 -0
- package/src/solidity_tests/factory.rs +22 -0
- package/src/solidity_tests/l1.rs +68 -0
- package/src/solidity_tests/op.rs +69 -0
- package/src/solidity_tests/runner.rs +51 -0
- package/src/solidity_tests/test_results.rs +668 -0
- package/src/solidity_tests.rs +56 -0
- package/src/subscription.rs +32 -0
- package/src/trace/debug.rs +1 -1
- package/src/trace/exit.rs +12 -13
- package/src/trace/library_utils.rs +1 -1
- package/src/trace/return_data.rs +11 -11
- package/src/trace/solidity_stack_trace.rs +11 -8
- package/src/trace.rs +37 -44
- package/src/withdrawal.rs +4 -4
- package/src/provider/config.rs +0 -291
- package/src/subscribe.rs +0 -63
package/index.js
CHANGED
|
@@ -310,15 +310,73 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { SpecId,
|
|
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, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, addStatementCoverageInstrumentation, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CachedChains, CachedEndpoints, FsAccessPermission, 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, getLatestSupportedSolcVersion } = nativeBinding
|
|
314
314
|
|
|
315
|
+
module.exports.GENERIC_CHAIN_TYPE = GENERIC_CHAIN_TYPE
|
|
316
|
+
module.exports.genericChainProviderFactory = genericChainProviderFactory
|
|
317
|
+
module.exports.L1_CHAIN_TYPE = L1_CHAIN_TYPE
|
|
318
|
+
module.exports.l1GenesisState = l1GenesisState
|
|
319
|
+
module.exports.l1ProviderFactory = l1ProviderFactory
|
|
315
320
|
module.exports.SpecId = SpecId
|
|
316
|
-
module.exports.
|
|
321
|
+
module.exports.l1HardforkFromString = l1HardforkFromString
|
|
322
|
+
module.exports.l1HardforkToString = l1HardforkToString
|
|
323
|
+
module.exports.l1HardforkLatest = l1HardforkLatest
|
|
324
|
+
module.exports.FRONTIER = FRONTIER
|
|
325
|
+
module.exports.FRONTIER_THAWING = FRONTIER_THAWING
|
|
326
|
+
module.exports.HOMESTEAD = HOMESTEAD
|
|
327
|
+
module.exports.DAO_FORK = DAO_FORK
|
|
328
|
+
module.exports.TANGERINE = TANGERINE
|
|
329
|
+
module.exports.SPURIOUS_DRAGON = SPURIOUS_DRAGON
|
|
330
|
+
module.exports.BYZANTIUM = BYZANTIUM
|
|
331
|
+
module.exports.CONSTANTINOPLE = CONSTANTINOPLE
|
|
332
|
+
module.exports.PETERSBURG = PETERSBURG
|
|
333
|
+
module.exports.ISTANBUL = ISTANBUL
|
|
334
|
+
module.exports.MUIR_GLACIER = MUIR_GLACIER
|
|
335
|
+
module.exports.BERLIN = BERLIN
|
|
336
|
+
module.exports.LONDON = LONDON
|
|
337
|
+
module.exports.ARROW_GLACIER = ARROW_GLACIER
|
|
338
|
+
module.exports.GRAY_GLACIER = GRAY_GLACIER
|
|
339
|
+
module.exports.MERGE = MERGE
|
|
340
|
+
module.exports.SHANGHAI = SHANGHAI
|
|
341
|
+
module.exports.CANCUN = CANCUN
|
|
342
|
+
module.exports.PRAGUE = PRAGUE
|
|
343
|
+
module.exports.OpHardfork = OpHardfork
|
|
344
|
+
module.exports.opHardforkFromString = opHardforkFromString
|
|
345
|
+
module.exports.opHardforkToString = opHardforkToString
|
|
346
|
+
module.exports.opLatestHardfork = opLatestHardfork
|
|
347
|
+
module.exports.OP_CHAIN_TYPE = OP_CHAIN_TYPE
|
|
348
|
+
module.exports.opGenesisState = opGenesisState
|
|
349
|
+
module.exports.opProviderFactory = opProviderFactory
|
|
350
|
+
module.exports.BEDROCK = BEDROCK
|
|
351
|
+
module.exports.REGOLITH = REGOLITH
|
|
352
|
+
module.exports.CANYON = CANYON
|
|
353
|
+
module.exports.ECOTONE = ECOTONE
|
|
354
|
+
module.exports.FJORD = FJORD
|
|
355
|
+
module.exports.GRANITE = GRANITE
|
|
356
|
+
module.exports.HOLOCENE = HOLOCENE
|
|
357
|
+
module.exports.ISTHMUS = ISTHMUS
|
|
317
358
|
module.exports.MineOrdering = MineOrdering
|
|
318
|
-
module.exports.
|
|
359
|
+
module.exports.EdrContext = EdrContext
|
|
360
|
+
module.exports.addStatementCoverageInstrumentation = addStatementCoverageInstrumentation
|
|
361
|
+
module.exports.Precompile = Precompile
|
|
362
|
+
module.exports.precompileP256Verify = precompileP256Verify
|
|
363
|
+
module.exports.ProviderFactory = ProviderFactory
|
|
319
364
|
module.exports.Response = Response
|
|
365
|
+
module.exports.Provider = Provider
|
|
320
366
|
module.exports.SuccessReason = SuccessReason
|
|
321
367
|
module.exports.ExceptionalHalt = ExceptionalHalt
|
|
368
|
+
module.exports.CachedChains = CachedChains
|
|
369
|
+
module.exports.CachedEndpoints = CachedEndpoints
|
|
370
|
+
module.exports.FsAccessPermission = FsAccessPermission
|
|
371
|
+
module.exports.IncludeTraces = IncludeTraces
|
|
372
|
+
module.exports.SolidityTestRunnerFactory = SolidityTestRunnerFactory
|
|
373
|
+
module.exports.l1SolidityTestRunnerFactory = l1SolidityTestRunnerFactory
|
|
374
|
+
module.exports.opSolidityTestRunnerFactory = opSolidityTestRunnerFactory
|
|
375
|
+
module.exports.SuiteResult = SuiteResult
|
|
376
|
+
module.exports.TestResult = TestResult
|
|
377
|
+
module.exports.TestStatus = TestStatus
|
|
378
|
+
module.exports.CallKind = CallKind
|
|
379
|
+
module.exports.LogKind = LogKind
|
|
322
380
|
module.exports.linkHexStringBytecode = linkHexStringBytecode
|
|
323
381
|
module.exports.printStackTrace = printStackTrace
|
|
324
382
|
module.exports.Exit = Exit
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nomicfoundation/edr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0-next.0",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@napi-rs/cli": "^2.18.4",
|
|
6
|
+
"@nomicfoundation/ethereumjs-util": "^9.0.4",
|
|
6
7
|
"@types/chai": "^4.2.0",
|
|
7
8
|
"@types/chai-as-promised": "^7.1.8",
|
|
8
9
|
"@types/mocha": ">=9.1.0",
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
"mocha": "^10.0.0",
|
|
22
23
|
"prettier": "^3.2.5",
|
|
23
24
|
"ts-node": "^10.8.0",
|
|
24
|
-
"typescript": "~5.
|
|
25
|
+
"typescript": "~5.8.2"
|
|
25
26
|
},
|
|
26
27
|
"engines": {
|
|
27
28
|
"node": ">= 18"
|
|
@@ -52,29 +53,32 @@
|
|
|
52
53
|
},
|
|
53
54
|
"repository": "NomicFoundation/edr.git",
|
|
54
55
|
"types": "index.d.ts",
|
|
55
|
-
"
|
|
56
|
-
"@nomicfoundation/edr-darwin-arm64": "0.
|
|
57
|
-
"@nomicfoundation/edr-darwin-x64": "0.
|
|
58
|
-
"@nomicfoundation/edr-linux-arm64-gnu": "0.
|
|
59
|
-
"@nomicfoundation/edr-linux-arm64-musl": "0.
|
|
60
|
-
"@nomicfoundation/edr-linux-x64-gnu": "0.
|
|
61
|
-
"@nomicfoundation/edr-linux-x64-musl": "0.
|
|
62
|
-
"@nomicfoundation/edr-win32-x64-msvc": "0.
|
|
56
|
+
"optionalDependencies": {
|
|
57
|
+
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.0",
|
|
58
|
+
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.0",
|
|
59
|
+
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.0",
|
|
60
|
+
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.0",
|
|
61
|
+
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.0",
|
|
62
|
+
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.0",
|
|
63
|
+
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.0"
|
|
63
64
|
},
|
|
64
65
|
"scripts": {
|
|
65
66
|
"artifacts": "napi artifacts",
|
|
66
|
-
"build": "
|
|
67
|
-
"build:debug": "napi build --platform --no-const-enum",
|
|
68
|
-
"build:
|
|
69
|
-
"build:
|
|
67
|
+
"build": "pnpm run build:publish",
|
|
68
|
+
"build:debug": "napi build --platform --no-const-enum --features op",
|
|
69
|
+
"build:dev": "napi build --platform --release --no-const-enum --features op,test-mock",
|
|
70
|
+
"build:publish": "napi build --platform --profile napi-publish --no-const-enum --features op",
|
|
71
|
+
"build:scenarios": "napi build --platform --release --no-const-enum --features op,scenarios",
|
|
72
|
+
"build:tracing": "napi build --platform --release --no-const-enum --features op,tracing",
|
|
73
|
+
"build:typingFile": "napi build --platform --no-const-enum --features op",
|
|
70
74
|
"clean": "rm -rf @nomicfoundation/edr.node",
|
|
71
75
|
"eslint": "eslint 'test/**/*.ts'",
|
|
72
76
|
"lint": "pnpm run prettier && pnpm run eslint",
|
|
73
77
|
"lint:fix": "pnpm run prettier --write",
|
|
74
|
-
"pretest": "pnpm build",
|
|
78
|
+
"pretest": "pnpm build:dev",
|
|
75
79
|
"prettier": "prettier --check \"test/**.ts\"",
|
|
76
80
|
"test": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/*.ts\"",
|
|
77
|
-
"testNoBuild": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test
|
|
81
|
+
"testNoBuild": "pnpm tsc && node --max-old-space-size=8192 node_modules/mocha/bin/_mocha --recursive \"test/**/{,!(mock)}.ts\"",
|
|
78
82
|
"universal": "napi universal",
|
|
79
83
|
"version": "napi version"
|
|
80
84
|
}
|
package/src/account.rs
CHANGED
|
@@ -1,46 +1,123 @@
|
|
|
1
|
-
use
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// `DangerousSecretKeyStr`.
|
|
6
|
-
use edr_eth::signature::{secret_key_from_str, DangerousSecretKeyStr};
|
|
7
|
-
use napi::{bindgen_prelude::BigInt, JsString, Status};
|
|
1
|
+
use derive_more::Debug;
|
|
2
|
+
use edr_eth::{hex, HashMap, U256};
|
|
3
|
+
use edr_solidity_tests::{backend::Predeploy, revm::state::AccountInfo};
|
|
4
|
+
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
|
8
5
|
use napi_derive::napi;
|
|
9
|
-
use serde::Serialize;
|
|
10
6
|
|
|
11
|
-
use crate::
|
|
7
|
+
use crate::{
|
|
8
|
+
cast::TryCast,
|
|
9
|
+
serde::{
|
|
10
|
+
serialize_bigint_as_struct, serialize_optional_bigint_as_struct,
|
|
11
|
+
serialize_optional_uint8array_as_hex, serialize_uint8array_as_hex,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
12
14
|
|
|
13
|
-
///
|
|
15
|
+
/// Specification of overrides for an account and its storage.
|
|
14
16
|
#[napi(object)]
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
#[derive(Clone, Debug, serde::Serialize)]
|
|
18
|
+
pub struct AccountOverride {
|
|
19
|
+
/// The account's address
|
|
20
|
+
#[debug("{}", hex::encode(address))]
|
|
21
|
+
#[serde(serialize_with = "serialize_uint8array_as_hex")]
|
|
22
|
+
pub address: Uint8Array,
|
|
23
|
+
/// If present, the overwriting balance.
|
|
24
|
+
#[serde(serialize_with = "serialize_optional_bigint_as_struct")]
|
|
25
|
+
pub balance: Option<BigInt>,
|
|
26
|
+
/// If present, the overwriting nonce.
|
|
27
|
+
#[serde(serialize_with = "serialize_optional_bigint_as_struct")]
|
|
28
|
+
pub nonce: Option<BigInt>,
|
|
29
|
+
/// If present, the overwriting code.
|
|
30
|
+
#[debug("{:?}", code.as_ref().map(hex::encode))]
|
|
31
|
+
#[serde(serialize_with = "serialize_optional_uint8array_as_hex")]
|
|
32
|
+
pub code: Option<Uint8Array>,
|
|
33
|
+
/// BEWARE: This field is not supported yet. See <https://github.com/NomicFoundation/edr/issues/911>
|
|
34
|
+
///
|
|
35
|
+
/// If present, the overwriting storage.
|
|
36
|
+
pub storage: Option<Vec<StorageSlot>>,
|
|
22
37
|
}
|
|
23
38
|
|
|
24
|
-
impl TryFrom<
|
|
39
|
+
impl TryFrom<AccountOverride> for (edr_eth::Address, edr_provider::AccountOverride) {
|
|
25
40
|
type Error = napi::Error;
|
|
26
41
|
|
|
27
|
-
fn try_from(value:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
42
|
+
fn try_from(value: AccountOverride) -> Result<Self, Self::Error> {
|
|
43
|
+
let AccountOverride {
|
|
44
|
+
address,
|
|
45
|
+
balance,
|
|
46
|
+
nonce,
|
|
47
|
+
code,
|
|
48
|
+
storage,
|
|
49
|
+
} = value;
|
|
50
|
+
let storage = storage
|
|
51
|
+
.map(|storage| {
|
|
52
|
+
storage
|
|
53
|
+
.into_iter()
|
|
54
|
+
.map(|StorageSlot { index, value }| {
|
|
55
|
+
let value = value.try_cast()?;
|
|
56
|
+
let slot = edr_evm::state::EvmStorageSlot::new(value);
|
|
57
|
+
|
|
58
|
+
let index: edr_eth::U256 = index.try_cast()?;
|
|
59
|
+
Ok((index, slot))
|
|
60
|
+
})
|
|
61
|
+
.collect::<napi::Result<_>>()
|
|
62
|
+
})
|
|
63
|
+
.transpose()?;
|
|
64
|
+
|
|
65
|
+
let account_override = edr_provider::AccountOverride {
|
|
66
|
+
balance: balance.map(TryCast::try_cast).transpose()?,
|
|
67
|
+
nonce: nonce.map(TryCast::try_cast).transpose()?,
|
|
68
|
+
code: code.map(TryCast::try_cast).transpose()?,
|
|
69
|
+
storage,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
let address: edr_eth::Address = address.try_cast()?;
|
|
32
73
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
74
|
+
Ok((address, account_override))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
impl TryFrom<AccountOverride> for Predeploy {
|
|
79
|
+
type Error = napi::Error;
|
|
80
|
+
|
|
81
|
+
fn try_from(value: AccountOverride) -> Result<Self, Self::Error> {
|
|
82
|
+
let (address, account_override) = value.try_into()?;
|
|
83
|
+
|
|
84
|
+
let storage = account_override.storage.unwrap_or_else(HashMap::new);
|
|
85
|
+
let balance = account_override.balance.unwrap_or(U256::ZERO);
|
|
86
|
+
let nonce = account_override.nonce.unwrap_or(0);
|
|
87
|
+
let code = account_override.code.ok_or_else(|| {
|
|
88
|
+
napi::Error::from_reason(format!("Predeploy with address '{address}' must have code"))
|
|
89
|
+
})?;
|
|
90
|
+
|
|
91
|
+
if code.is_empty() {
|
|
92
|
+
return Err(napi::Error::from_reason(
|
|
93
|
+
"Predeploy with address '{address}' must have non-empty code",
|
|
94
|
+
));
|
|
95
|
+
}
|
|
96
|
+
let code_hash = code.hash_slow();
|
|
97
|
+
|
|
98
|
+
let account_info = AccountInfo {
|
|
99
|
+
balance,
|
|
100
|
+
nonce,
|
|
101
|
+
code_hash,
|
|
102
|
+
code: Some(code),
|
|
103
|
+
};
|
|
40
104
|
|
|
41
105
|
Ok(Self {
|
|
42
|
-
|
|
43
|
-
|
|
106
|
+
address,
|
|
107
|
+
account_info,
|
|
108
|
+
storage,
|
|
44
109
|
})
|
|
45
110
|
}
|
|
46
111
|
}
|
|
112
|
+
|
|
113
|
+
/// A description of a storage slot's state.
|
|
114
|
+
#[napi(object)]
|
|
115
|
+
#[derive(Clone, Debug, serde::Serialize)]
|
|
116
|
+
pub struct StorageSlot {
|
|
117
|
+
/// The storage slot's index
|
|
118
|
+
#[serde(serialize_with = "serialize_bigint_as_struct")]
|
|
119
|
+
pub index: BigInt,
|
|
120
|
+
/// The storage slot's value
|
|
121
|
+
#[serde(serialize_with = "serialize_bigint_as_struct")]
|
|
122
|
+
pub value: BigInt,
|
|
123
|
+
}
|
package/src/block.rs
CHANGED
|
@@ -1,108 +1,7 @@
|
|
|
1
|
-
use
|
|
2
|
-
use napi::bindgen_prelude::{BigInt, Buffer};
|
|
1
|
+
use napi::bindgen_prelude::BigInt;
|
|
3
2
|
use napi_derive::napi;
|
|
4
3
|
|
|
5
|
-
use crate::
|
|
6
|
-
|
|
7
|
-
#[napi(object)]
|
|
8
|
-
pub struct BlockOptions {
|
|
9
|
-
/// The parent block's hash
|
|
10
|
-
pub parent_hash: Option<Buffer>,
|
|
11
|
-
/// The block's beneficiary
|
|
12
|
-
pub beneficiary: Option<Buffer>,
|
|
13
|
-
/// The state's root hash
|
|
14
|
-
pub state_root: Option<Buffer>,
|
|
15
|
-
/// The block's difficulty
|
|
16
|
-
pub difficulty: Option<BigInt>,
|
|
17
|
-
/// The block's number
|
|
18
|
-
pub number: Option<BigInt>,
|
|
19
|
-
/// The block's gas limit
|
|
20
|
-
pub gas_limit: Option<BigInt>,
|
|
21
|
-
/// The block's timestamp
|
|
22
|
-
pub timestamp: Option<BigInt>,
|
|
23
|
-
/// The block's extra data
|
|
24
|
-
pub extra_data: Option<Buffer>,
|
|
25
|
-
/// The block's mix hash (or prevrandao)
|
|
26
|
-
pub mix_hash: Option<Buffer>,
|
|
27
|
-
/// The block's nonce
|
|
28
|
-
pub nonce: Option<Buffer>,
|
|
29
|
-
/// The block's base gas fee
|
|
30
|
-
pub base_fee: Option<BigInt>,
|
|
31
|
-
/// The block's withdrawals
|
|
32
|
-
pub withdrawals: Option<Vec<Withdrawal>>,
|
|
33
|
-
/// Blob gas was added by EIP-4844 and is ignored in older headers.
|
|
34
|
-
pub blob_gas: Option<BlobGas>,
|
|
35
|
-
/// The hash tree root of the parent beacon block for the given execution
|
|
36
|
-
/// block (EIP-4788).
|
|
37
|
-
pub parent_beacon_block_root: Option<Buffer>,
|
|
38
|
-
/// The commitment hash calculated for a list of [EIP-7685] data requests.
|
|
39
|
-
///
|
|
40
|
-
/// [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685
|
|
41
|
-
pub requests_hash: Option<Buffer>,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
impl TryFrom<BlockOptions> for edr_eth::block::BlockOptions {
|
|
45
|
-
type Error = napi::Error;
|
|
46
|
-
|
|
47
|
-
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
|
|
48
|
-
fn try_from(value: BlockOptions) -> Result<Self, Self::Error> {
|
|
49
|
-
Ok(Self {
|
|
50
|
-
parent_hash: value
|
|
51
|
-
.parent_hash
|
|
52
|
-
.map(TryCast::<B256>::try_cast)
|
|
53
|
-
.transpose()?,
|
|
54
|
-
beneficiary: value
|
|
55
|
-
.beneficiary
|
|
56
|
-
.map(TryCast::<Address>::try_cast)
|
|
57
|
-
.transpose()?,
|
|
58
|
-
state_root: value
|
|
59
|
-
.state_root
|
|
60
|
-
.map(TryCast::<B256>::try_cast)
|
|
61
|
-
.transpose()?,
|
|
62
|
-
difficulty: value
|
|
63
|
-
.difficulty
|
|
64
|
-
.map_or(Ok(None), |difficulty| difficulty.try_cast().map(Some))?,
|
|
65
|
-
number: value
|
|
66
|
-
.number
|
|
67
|
-
.map_or(Ok(None), |number| number.try_cast().map(Some))?,
|
|
68
|
-
gas_limit: value
|
|
69
|
-
.gas_limit
|
|
70
|
-
.map_or(Ok(None), |gas_limit| gas_limit.try_cast().map(Some))?,
|
|
71
|
-
timestamp: value
|
|
72
|
-
.timestamp
|
|
73
|
-
.map_or(Ok(None), |timestamp| timestamp.try_cast().map(Some))?,
|
|
74
|
-
extra_data: value
|
|
75
|
-
.extra_data
|
|
76
|
-
.map(|extra_data| Bytes::copy_from_slice(&extra_data)),
|
|
77
|
-
mix_hash: value.mix_hash.map(TryCast::<B256>::try_cast).transpose()?,
|
|
78
|
-
nonce: value.nonce.map(TryCast::<B64>::try_cast).transpose()?,
|
|
79
|
-
base_fee: value
|
|
80
|
-
.base_fee
|
|
81
|
-
.map_or(Ok(None), |basefee| basefee.try_cast().map(Some))?,
|
|
82
|
-
withdrawals: value
|
|
83
|
-
.withdrawals
|
|
84
|
-
.map(|withdrawals| {
|
|
85
|
-
withdrawals
|
|
86
|
-
.into_iter()
|
|
87
|
-
.map(edr_eth::withdrawal::Withdrawal::try_from)
|
|
88
|
-
.collect()
|
|
89
|
-
})
|
|
90
|
-
.transpose()?,
|
|
91
|
-
blob_gas: value
|
|
92
|
-
.blob_gas
|
|
93
|
-
.map(edr_eth::block::BlobGas::try_from)
|
|
94
|
-
.transpose()?,
|
|
95
|
-
parent_beacon_block_root: value
|
|
96
|
-
.parent_beacon_block_root
|
|
97
|
-
.map(TryCast::<B256>::try_cast)
|
|
98
|
-
.transpose()?,
|
|
99
|
-
requests_hash: value
|
|
100
|
-
.requests_hash
|
|
101
|
-
.map(TryCast::<B256>::try_cast)
|
|
102
|
-
.transpose()?,
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
}
|
|
4
|
+
use crate::cast::TryCast;
|
|
106
5
|
|
|
107
6
|
/// Information about the blob gas used in a block.
|
|
108
7
|
#[napi(object)]
|
package/src/call_override.rs
CHANGED
|
@@ -2,7 +2,7 @@ use std::sync::mpsc::channel;
|
|
|
2
2
|
|
|
3
3
|
use edr_eth::{Address, Bytes};
|
|
4
4
|
use napi::{
|
|
5
|
-
bindgen_prelude::{
|
|
5
|
+
bindgen_prelude::{Promise, Uint8Array},
|
|
6
6
|
threadsafe_function::{
|
|
7
7
|
ErrorStrategy, ThreadSafeCallContext, ThreadsafeFunction, ThreadsafeFunctionCallMode,
|
|
8
8
|
},
|
|
@@ -16,7 +16,7 @@ use crate::cast::TryCast;
|
|
|
16
16
|
/// The result of executing a call override.
|
|
17
17
|
#[napi(object)]
|
|
18
18
|
pub struct CallOverrideResult {
|
|
19
|
-
pub result:
|
|
19
|
+
pub result: Uint8Array,
|
|
20
20
|
pub should_revert: bool,
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ impl TryCast<Option<edr_provider::CallOverrideResult>> for Option<CallOverrideRe
|
|
|
27
27
|
match self {
|
|
28
28
|
None => Ok(None),
|
|
29
29
|
Some(result) => Ok(Some(edr_provider::CallOverrideResult {
|
|
30
|
-
output: result.result
|
|
30
|
+
output: Bytes::copy_from_slice(&result.result),
|
|
31
31
|
should_revert: result.should_revert,
|
|
32
32
|
})),
|
|
33
33
|
}
|
|
@@ -56,20 +56,20 @@ impl CallOverrideCallback {
|
|
|
56
56
|
|ctx: ThreadSafeCallContext<CallOverrideCall>| {
|
|
57
57
|
let address = ctx
|
|
58
58
|
.env
|
|
59
|
-
.
|
|
59
|
+
.create_arraybuffer_with_data(ctx.value.contract_address.to_vec())?
|
|
60
60
|
.into_raw();
|
|
61
61
|
|
|
62
62
|
let data = ctx
|
|
63
63
|
.env
|
|
64
|
-
.
|
|
64
|
+
.create_arraybuffer_with_data(ctx.value.data.to_vec())?
|
|
65
65
|
.into_raw();
|
|
66
66
|
|
|
67
67
|
Ok(vec![address, data])
|
|
68
68
|
},
|
|
69
69
|
)?;
|
|
70
70
|
|
|
71
|
-
// Maintain a weak reference to the function to avoid the event loop
|
|
72
|
-
// exiting.
|
|
71
|
+
// Maintain a weak reference to the function to avoid blocking the event loop
|
|
72
|
+
// from exiting.
|
|
73
73
|
call_override_callback_fn.unref(env)?;
|
|
74
74
|
|
|
75
75
|
Ok(Self {
|
package/src/cast.rs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
use edr_eth::{Address, Bytes, B256, B64, U256};
|
|
1
|
+
use edr_eth::{Address, Bytecode, Bytes, B256, B64, U256};
|
|
2
2
|
use napi::{
|
|
3
|
-
bindgen_prelude::{BigInt,
|
|
3
|
+
bindgen_prelude::{BigInt, Uint8Array},
|
|
4
4
|
Status,
|
|
5
5
|
};
|
|
6
6
|
|
|
@@ -15,48 +15,62 @@ pub trait TryCast<T>: Sized {
|
|
|
15
15
|
fn try_cast(self) -> Result<T, Self::Error>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
impl TryCast<Address> for
|
|
18
|
+
impl TryCast<Address> for Uint8Array {
|
|
19
19
|
type Error = napi::Error;
|
|
20
20
|
|
|
21
21
|
fn try_cast(self) -> std::result::Result<Address, Self::Error> {
|
|
22
22
|
if self.len() != 20 {
|
|
23
23
|
return Err(napi::Error::new(
|
|
24
24
|
Status::InvalidArg,
|
|
25
|
-
"
|
|
25
|
+
"Uint8Array was expected to be 20 bytes.".to_string(),
|
|
26
26
|
));
|
|
27
27
|
}
|
|
28
28
|
Ok(Address::from_slice(&self))
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
impl TryCast<B64> for
|
|
32
|
+
impl TryCast<B64> for Uint8Array {
|
|
33
33
|
type Error = napi::Error;
|
|
34
34
|
|
|
35
35
|
fn try_cast(self) -> std::result::Result<B64, Self::Error> {
|
|
36
36
|
if self.len() != 8 {
|
|
37
37
|
return Err(napi::Error::new(
|
|
38
38
|
Status::InvalidArg,
|
|
39
|
-
"
|
|
39
|
+
"Uint8Array was expected to be 8 bytes.".to_string(),
|
|
40
40
|
));
|
|
41
41
|
}
|
|
42
42
|
Ok(B64::from_slice(&self))
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
impl TryCast<B256> for
|
|
46
|
+
impl TryCast<B256> for Uint8Array {
|
|
47
47
|
type Error = napi::Error;
|
|
48
48
|
|
|
49
49
|
fn try_cast(self) -> std::result::Result<B256, Self::Error> {
|
|
50
50
|
if self.len() != 32 {
|
|
51
51
|
return Err(napi::Error::new(
|
|
52
52
|
Status::InvalidArg,
|
|
53
|
-
"
|
|
53
|
+
"Uint8Array was expected to be 32 bytes.".to_string(),
|
|
54
54
|
));
|
|
55
55
|
}
|
|
56
56
|
Ok(B256::from_slice(&self))
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
impl TryCast<Bytecode> for Uint8Array {
|
|
61
|
+
type Error = napi::Error;
|
|
62
|
+
|
|
63
|
+
fn try_cast(self) -> std::result::Result<Bytecode, Self::Error> {
|
|
64
|
+
let bytes = Bytes::copy_from_slice(&self);
|
|
65
|
+
Bytecode::new_raw_checked(bytes).map_err(|error| {
|
|
66
|
+
napi::Error::new(
|
|
67
|
+
Status::InvalidArg,
|
|
68
|
+
format!("Uint8Array was not valid bytecode: {error}"),
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
60
74
|
impl TryCast<u64> for BigInt {
|
|
61
75
|
type Error = napi::Error;
|
|
62
76
|
|
|
@@ -81,6 +95,30 @@ impl TryCast<u64> for BigInt {
|
|
|
81
95
|
}
|
|
82
96
|
}
|
|
83
97
|
|
|
98
|
+
impl TryCast<u128> for BigInt {
|
|
99
|
+
type Error = napi::Error;
|
|
100
|
+
|
|
101
|
+
fn try_cast(self) -> std::result::Result<u128, Self::Error> {
|
|
102
|
+
let (signed, value, lossless) = self.get_u128();
|
|
103
|
+
|
|
104
|
+
if signed {
|
|
105
|
+
return Err(napi::Error::new(
|
|
106
|
+
Status::InvalidArg,
|
|
107
|
+
"BigInt was expected to be unsigned.".to_string(),
|
|
108
|
+
));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if !lossless {
|
|
112
|
+
return Err(napi::Error::new(
|
|
113
|
+
Status::InvalidArg,
|
|
114
|
+
"BigInt was expected to fit within 128 bits.".to_string(),
|
|
115
|
+
));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Ok(value)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
84
122
|
impl TryCast<usize> for BigInt {
|
|
85
123
|
type Error = napi::Error;
|
|
86
124
|
|
|
@@ -118,15 +156,7 @@ impl<T> TryCast<T> for T {
|
|
|
118
156
|
}
|
|
119
157
|
}
|
|
120
158
|
|
|
121
|
-
impl TryCast<Bytes
|
|
122
|
-
type Error = napi::Error;
|
|
123
|
-
|
|
124
|
-
fn try_cast(self) -> Result<Bytes, Self::Error> {
|
|
125
|
-
Ok(Bytes::copy_from_slice(&self))
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
impl TryCast<Option<Bytes>> for Option<Buffer> {
|
|
159
|
+
impl TryCast<Option<Bytes>> for Option<Uint8Array> {
|
|
130
160
|
type Error = napi::Error;
|
|
131
161
|
|
|
132
162
|
fn try_cast(self) -> Result<Option<Bytes>, Self::Error> {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
use std::sync::Arc;
|
|
2
|
+
|
|
3
|
+
use edr_eth::l1;
|
|
4
|
+
use edr_generic::GenericChainSpec;
|
|
5
|
+
use edr_napi_core::{
|
|
6
|
+
logger::{self, Logger},
|
|
7
|
+
provider::{self, ProviderBuilder, SyncProviderFactory},
|
|
8
|
+
spec::SyncNapiSpec as _,
|
|
9
|
+
subscription,
|
|
10
|
+
};
|
|
11
|
+
use edr_solidity::contract_decoder::ContractDecoder;
|
|
12
|
+
use napi_derive::napi;
|
|
13
|
+
|
|
14
|
+
use crate::provider::ProviderFactory;
|
|
15
|
+
|
|
16
|
+
pub struct GenericChainProviderFactory;
|
|
17
|
+
|
|
18
|
+
impl SyncProviderFactory for GenericChainProviderFactory {
|
|
19
|
+
fn create_provider_builder(
|
|
20
|
+
&self,
|
|
21
|
+
env: &napi::Env,
|
|
22
|
+
provider_config: edr_napi_core::provider::Config,
|
|
23
|
+
logger_config: logger::Config,
|
|
24
|
+
subscription_config: subscription::Config,
|
|
25
|
+
contract_decoder: Arc<ContractDecoder>,
|
|
26
|
+
) -> napi::Result<Box<dyn provider::Builder>> {
|
|
27
|
+
let logger = Logger::<GenericChainSpec>::new(logger_config, Arc::clone(&contract_decoder))?;
|
|
28
|
+
|
|
29
|
+
let provider_config =
|
|
30
|
+
edr_provider::ProviderConfig::<l1::SpecId>::try_from(provider_config)?;
|
|
31
|
+
|
|
32
|
+
let subscription_callback =
|
|
33
|
+
subscription::Callback::new(env, subscription_config.subscription_callback)?;
|
|
34
|
+
|
|
35
|
+
Ok(Box::new(ProviderBuilder::new(
|
|
36
|
+
contract_decoder,
|
|
37
|
+
Box::new(logger),
|
|
38
|
+
provider_config,
|
|
39
|
+
subscription_callback,
|
|
40
|
+
)))
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
#[napi]
|
|
45
|
+
pub const GENERIC_CHAIN_TYPE: &str = GenericChainSpec::CHAIN_TYPE;
|
|
46
|
+
|
|
47
|
+
#[napi(catch_unwind)]
|
|
48
|
+
pub fn generic_chain_provider_factory() -> ProviderFactory {
|
|
49
|
+
let factory: Arc<dyn SyncProviderFactory> = Arc::new(GenericChainProviderFactory);
|
|
50
|
+
factory.into()
|
|
51
|
+
}
|