@nomicfoundation/edr 0.12.0-next.7 → 0.12.0-next.8
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 +70 -10
- package/index.js +2 -1
- package/package.json +1 -10
- package/src/account.rs +6 -5
- package/src/block.rs +1 -1
- package/src/call_override.rs +1 -1
- package/src/cast.rs +1 -1
- package/src/chains/op.rs +11 -20
- package/src/config.rs +72 -4
- package/src/context.rs +29 -14
- package/src/gas_report.rs +92 -0
- package/src/lib.rs +1 -0
- package/src/logger.rs +1 -1
- package/src/mock/time.rs +2 -2
- package/src/precompile.rs +1 -1
- package/src/result.rs +11 -11
- package/src/serde.rs +1 -1
- package/src/solidity_tests/config.rs +8 -1
- package/src/solidity_tests/l1.rs +1 -1
- package/src/solidity_tests/op.rs +1 -1
- package/src/solidity_tests/test_results.rs +17 -0
- package/src/solidity_tests.rs +1 -1
- package/src/trace/solidity_stack_trace.rs +3 -2
- package/src/trace.rs +2 -2
- package/src/withdrawal.rs +5 -5
package/index.d.ts
CHANGED
|
@@ -198,6 +198,16 @@ export interface CodeCoverageConfig {
|
|
|
198
198
|
*/
|
|
199
199
|
onCollectedCoverageCallback: (coverageHits: Uint8Array[]) => Promise<void>
|
|
200
200
|
}
|
|
201
|
+
export interface GasReportConfig {
|
|
202
|
+
/**
|
|
203
|
+
* Gas reports are collected after a block is mined or `eth_call` is
|
|
204
|
+
* executed.
|
|
205
|
+
*
|
|
206
|
+
* Exceptions thrown in the callback will be propagated to the original
|
|
207
|
+
* caller.
|
|
208
|
+
*/
|
|
209
|
+
onCollectedGasReportCallback: (gasReport: GasReport) => Promise<void>
|
|
210
|
+
}
|
|
201
211
|
/** Configuration for forking a blockchain */
|
|
202
212
|
export interface ForkConfig {
|
|
203
213
|
/**
|
|
@@ -258,6 +268,8 @@ export interface MiningConfig {
|
|
|
258
268
|
export interface ObservabilityConfig {
|
|
259
269
|
/** If present, configures runtime observability to collect code coverage. */
|
|
260
270
|
codeCoverage?: CodeCoverageConfig
|
|
271
|
+
/** If present, configures runtime observability to collect gas reports. */
|
|
272
|
+
gasReport?: GasReportConfig
|
|
261
273
|
}
|
|
262
274
|
/** Configuration for a provider */
|
|
263
275
|
export interface ProviderConfig {
|
|
@@ -372,6 +384,27 @@ export interface DebugTraceLogItem {
|
|
|
372
384
|
/** Map of all stored values with keys and values encoded as hex strings. */
|
|
373
385
|
storage?: Record<string, string>
|
|
374
386
|
}
|
|
387
|
+
export interface GasReport {
|
|
388
|
+
contracts: Record<string, ContractGasReport>
|
|
389
|
+
}
|
|
390
|
+
export interface ContractGasReport {
|
|
391
|
+
deployments: Array<DeploymentGasReport>
|
|
392
|
+
functions: Record<string, Array<FunctionGasReport>>
|
|
393
|
+
}
|
|
394
|
+
export enum GasReportExecutionStatus {
|
|
395
|
+
Success = 0,
|
|
396
|
+
Revert = 1,
|
|
397
|
+
Halt = 2
|
|
398
|
+
}
|
|
399
|
+
export interface DeploymentGasReport {
|
|
400
|
+
gas: bigint
|
|
401
|
+
size: bigint
|
|
402
|
+
status: GasReportExecutionStatus
|
|
403
|
+
}
|
|
404
|
+
export interface FunctionGasReport {
|
|
405
|
+
gas: bigint
|
|
406
|
+
status: GasReportExecutionStatus
|
|
407
|
+
}
|
|
375
408
|
export interface InstrumentationResult {
|
|
376
409
|
/** The generated source code with coverage instrumentation. */
|
|
377
410
|
readonly source: string
|
|
@@ -703,6 +736,13 @@ export interface SolidityTestRunnerConfigArgs {
|
|
|
703
736
|
* match the pattern will be executed and reported as a test result.
|
|
704
737
|
*/
|
|
705
738
|
testPattern?: string
|
|
739
|
+
/**
|
|
740
|
+
* Controls whether to generate a gas report after running the tests.
|
|
741
|
+
* Enabling this also enables collection of all traces and EVM isolation
|
|
742
|
+
* mode.
|
|
743
|
+
* Defaults to false.
|
|
744
|
+
*/
|
|
745
|
+
generateGasReport?: boolean
|
|
706
746
|
}
|
|
707
747
|
/** Fuzz testing configuration */
|
|
708
748
|
export interface FuzzConfigArgs {
|
|
@@ -1103,6 +1143,11 @@ export interface DecodedTraceParameters {
|
|
|
1103
1143
|
*/
|
|
1104
1144
|
arguments: Array<string>
|
|
1105
1145
|
}
|
|
1146
|
+
/** The result of a Solidity test run. */
|
|
1147
|
+
export interface SolidityTestResult {
|
|
1148
|
+
/** Gas report, if it was generated. */
|
|
1149
|
+
readonly gasReport?: GasReport
|
|
1150
|
+
}
|
|
1106
1151
|
/** Configuration for subscriptions. */
|
|
1107
1152
|
export interface SubscriptionConfig {
|
|
1108
1153
|
/** Callback to be called when a new event is received. */
|
|
@@ -1363,22 +1408,37 @@ export interface Withdrawal {
|
|
|
1363
1408
|
amount: bigint
|
|
1364
1409
|
}
|
|
1365
1410
|
export declare class EdrContext {
|
|
1366
|
-
/**Creates a new [`EdrContext`] instance. Should only be called once! */
|
|
1411
|
+
/** Creates a new [`EdrContext`] instance. Should only be called once! */
|
|
1367
1412
|
constructor()
|
|
1368
|
-
/**Constructs a new provider with the provided configuration. */
|
|
1413
|
+
/** Constructs a new provider with the provided configuration. */
|
|
1369
1414
|
createProvider(chainType: string, providerConfig: ProviderConfig, loggerConfig: LoggerConfig, subscriptionConfig: SubscriptionConfig, contractDecoder: ContractDecoder): Promise<Provider>
|
|
1370
|
-
/**Registers a new provider factory for the provided chain type. */
|
|
1415
|
+
/** Registers a new provider factory for the provided chain type. */
|
|
1371
1416
|
registerProviderFactory(chainType: string, factory: ProviderFactory): Promise<void>
|
|
1372
1417
|
registerSolidityTestRunnerFactory(chainType: string, factory: SolidityTestRunnerFactory): Promise<void>
|
|
1373
1418
|
/**
|
|
1374
|
-
*Executes Solidity tests
|
|
1419
|
+
* Executes Solidity tests
|
|
1375
1420
|
*
|
|
1376
|
-
*The function will return
|
|
1377
|
-
*
|
|
1378
|
-
*
|
|
1379
|
-
*
|
|
1380
|
-
|
|
1381
|
-
|
|
1421
|
+
* The function will return a promise that resolves to a
|
|
1422
|
+
* [`SolidityTestResult`].
|
|
1423
|
+
*
|
|
1424
|
+
* Arguments:
|
|
1425
|
+
* - `chainType`: the same chain type that was passed to
|
|
1426
|
+
* `registerProviderFactory`.
|
|
1427
|
+
* - `artifacts`: the project's compilation output artifacts. It's
|
|
1428
|
+
* important to include include all artifacts here, otherwise cheatcodes
|
|
1429
|
+
* that access artifacts and other functionality (e.g. auto-linking, gas
|
|
1430
|
+
* reports) can break.
|
|
1431
|
+
* - `testSuites`: the test suite ids that specify which test suites to
|
|
1432
|
+
* execute. The test suite artifacts must be present in `artifacts`.
|
|
1433
|
+
* - `configArgs`: solidity test runner configuration. See the struct docs
|
|
1434
|
+
* for details.
|
|
1435
|
+
* - `tracingConfig`: the build infos used for stack trace generation.
|
|
1436
|
+
* These are lazily parsed and it's important that they're passed as
|
|
1437
|
+
* Uint8 arrays for performance.
|
|
1438
|
+
* - `onTestSuiteCompletedCallback`: The progress callback will be called
|
|
1439
|
+
* with the results of each test suite as soon as it finished executing.
|
|
1440
|
+
*/
|
|
1441
|
+
runSolidityTests(chainType: string, artifacts: Array<Artifact>, testSuites: Array<ArtifactId>, configArgs: SolidityTestRunnerConfigArgs, tracingConfig: TracingConfigWithBuffers, onTestSuiteCompletedCallback: (result: SuiteResult) => void): Promise<SolidityTestResult>
|
|
1382
1442
|
}
|
|
1383
1443
|
export declare class ContractDecoder {
|
|
1384
1444
|
/**Creates an empty instance. */
|
package/index.js
CHANGED
|
@@ -310,7 +310,7 @@ if (!nativeBinding) {
|
|
|
310
310
|
throw new Error(`Failed to load native binding`)
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
-
const { GENERIC_CHAIN_TYPE, genericChainProviderFactory, L1_CHAIN_TYPE, l1GenesisState, l1ProviderFactory, SpecId, l1HardforkFromString, l1HardforkToString, l1HardforkLatest, FRONTIER, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, PRAGUE, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, ContractDecoder, addStatementCoverageInstrumentation, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CachedChains, CachedEndpoints, FsAccessPermission, CollectStackTraces, IncludeTraces, SolidityTestRunnerFactory, l1SolidityTestRunnerFactory, opSolidityTestRunnerFactory, SuiteResult, TestResult, TestStatus, CallKind, LogKind, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace, getLatestSupportedSolcVersion } = nativeBinding
|
|
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, ContractDecoder, GasReportExecutionStatus, addStatementCoverageInstrumentation, Precompile, precompileP256Verify, ProviderFactory, Response, Provider, SuccessReason, ExceptionalHalt, CachedChains, CachedEndpoints, FsAccessPermission, CollectStackTraces, IncludeTraces, SolidityTestRunnerFactory, l1SolidityTestRunnerFactory, opSolidityTestRunnerFactory, SuiteResult, TestResult, TestStatus, CallKind, LogKind, linkHexStringBytecode, printStackTrace, Exit, ExitCode, BytecodeWrapper, ContractFunctionType, ReturnData, StackTraceEntryType, stackTraceEntryTypeToString, FALLBACK_FUNCTION_NAME, RECEIVE_FUNCTION_NAME, CONSTRUCTOR_FUNCTION_NAME, UNRECOGNIZED_FUNCTION_NAME, UNKNOWN_FUNCTION_NAME, PRECOMPILE_FUNCTION_NAME, UNRECOGNIZED_CONTRACT_NAME, RawTrace, getLatestSupportedSolcVersion } = nativeBinding
|
|
314
314
|
|
|
315
315
|
module.exports.GENERIC_CHAIN_TYPE = GENERIC_CHAIN_TYPE
|
|
316
316
|
module.exports.genericChainProviderFactory = genericChainProviderFactory
|
|
@@ -358,6 +358,7 @@ module.exports.ISTHMUS = ISTHMUS
|
|
|
358
358
|
module.exports.MineOrdering = MineOrdering
|
|
359
359
|
module.exports.EdrContext = EdrContext
|
|
360
360
|
module.exports.ContractDecoder = ContractDecoder
|
|
361
|
+
module.exports.GasReportExecutionStatus = GasReportExecutionStatus
|
|
361
362
|
module.exports.addStatementCoverageInstrumentation = addStatementCoverageInstrumentation
|
|
362
363
|
module.exports.Precompile = Precompile
|
|
363
364
|
module.exports.precompileP256Verify = precompileP256Verify
|
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.8",
|
|
4
4
|
"devDependencies": {
|
|
5
5
|
"@napi-rs/cli": "^2.18.4",
|
|
6
6
|
"@nomicfoundation/ethereumjs-util": "^9.0.4",
|
|
@@ -58,15 +58,6 @@
|
|
|
58
58
|
},
|
|
59
59
|
"repository": "NomicFoundation/edr.git",
|
|
60
60
|
"types": "index.d.ts",
|
|
61
|
-
"optionalDependencies": {
|
|
62
|
-
"@nomicfoundation/edr-darwin-arm64": "0.12.0-next.7",
|
|
63
|
-
"@nomicfoundation/edr-darwin-x64": "0.12.0-next.7",
|
|
64
|
-
"@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.7",
|
|
65
|
-
"@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.7",
|
|
66
|
-
"@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.7",
|
|
67
|
-
"@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.7",
|
|
68
|
-
"@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.7"
|
|
69
|
-
},
|
|
70
61
|
"scripts": {
|
|
71
62
|
"artifacts": "napi artifacts",
|
|
72
63
|
"build": "pnpm run build:publish",
|
package/src/account.rs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
use derive_more::Debug;
|
|
2
|
-
use
|
|
2
|
+
use edr_primitives::{hex, Address, HashMap, U256};
|
|
3
3
|
use edr_solidity_tests::{backend::Predeploy, revm::state::AccountInfo};
|
|
4
|
+
use edr_state_api::EvmStorageSlot;
|
|
4
5
|
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
|
5
6
|
use napi_derive::napi;
|
|
6
7
|
|
|
@@ -36,7 +37,7 @@ pub struct AccountOverride {
|
|
|
36
37
|
pub storage: Option<Vec<StorageSlot>>,
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
impl TryFrom<AccountOverride> for (
|
|
40
|
+
impl TryFrom<AccountOverride> for (Address, edr_provider::AccountOverride) {
|
|
40
41
|
type Error = napi::Error;
|
|
41
42
|
|
|
42
43
|
fn try_from(value: AccountOverride) -> Result<Self, Self::Error> {
|
|
@@ -53,9 +54,9 @@ impl TryFrom<AccountOverride> for (edr_eth::Address, edr_provider::AccountOverri
|
|
|
53
54
|
.into_iter()
|
|
54
55
|
.map(|StorageSlot { index, value }| {
|
|
55
56
|
let value = value.try_cast()?;
|
|
56
|
-
let slot =
|
|
57
|
+
let slot = EvmStorageSlot::new(value, 0);
|
|
57
58
|
|
|
58
|
-
let index:
|
|
59
|
+
let index: U256 = index.try_cast()?;
|
|
59
60
|
Ok((index, slot))
|
|
60
61
|
})
|
|
61
62
|
.collect::<napi::Result<_>>()
|
|
@@ -69,7 +70,7 @@ impl TryFrom<AccountOverride> for (edr_eth::Address, edr_provider::AccountOverri
|
|
|
69
70
|
storage,
|
|
70
71
|
};
|
|
71
72
|
|
|
72
|
-
let address:
|
|
73
|
+
let address: Address = address.try_cast()?;
|
|
73
74
|
|
|
74
75
|
Ok((address, account_override))
|
|
75
76
|
}
|
package/src/block.rs
CHANGED
|
@@ -16,7 +16,7 @@ pub struct BlobGas {
|
|
|
16
16
|
pub excess_gas: BigInt,
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
impl TryFrom<BlobGas> for
|
|
19
|
+
impl TryFrom<BlobGas> for edr_block_header::BlobGas {
|
|
20
20
|
type Error = napi::Error;
|
|
21
21
|
|
|
22
22
|
fn try_from(value: BlobGas) -> Result<Self, Self::Error> {
|
package/src/call_override.rs
CHANGED
package/src/cast.rs
CHANGED
package/src/chains/op.rs
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
use std::{str::FromStr, sync::Arc};
|
|
2
2
|
|
|
3
|
-
use edr_eth::hex;
|
|
4
3
|
use edr_napi_core::{
|
|
5
4
|
logger::Logger,
|
|
6
5
|
provider::{SyncProvider, SyncProviderFactory},
|
|
7
6
|
subscription::subscriber_callback_for_chain_spec,
|
|
8
7
|
};
|
|
9
|
-
use edr_op::{
|
|
8
|
+
use edr_op::{
|
|
9
|
+
predeploys::{
|
|
10
|
+
gas_price_oracle_code_ecotone, gas_price_oracle_code_fjord, gas_price_oracle_code_isthmus,
|
|
11
|
+
GAS_PRICE_ORACLE_ADDRESS,
|
|
12
|
+
},
|
|
13
|
+
OpChainSpec,
|
|
14
|
+
};
|
|
15
|
+
use edr_primitives::hex;
|
|
10
16
|
use edr_provider::time::CurrentTime;
|
|
11
17
|
use edr_solidity::contract_decoder::ContractDecoder;
|
|
12
18
|
use napi::{
|
|
@@ -347,16 +353,11 @@ fn gas_price_oracle_override(hardfork: edr_op::Hardfork) -> AccountOverride {
|
|
|
347
353
|
}
|
|
348
354
|
|
|
349
355
|
fn gas_price_oracle_ecotone() -> AccountOverride {
|
|
350
|
-
let gas_price_oracle_code = hex::decode(include_str!(
|
|
351
|
-
"../../data/op/predeploys/gas_price_oracle/ecotone.txt"
|
|
352
|
-
))
|
|
353
|
-
.expect("The bytecode for the GasPriceOracle predeploy should be a valid hex string");
|
|
354
|
-
|
|
355
356
|
AccountOverride {
|
|
356
357
|
address: Uint8Array::with_data_copied(GAS_PRICE_ORACLE_ADDRESS),
|
|
357
358
|
balance: None,
|
|
358
359
|
nonce: None,
|
|
359
|
-
code: Some(
|
|
360
|
+
code: Some(gas_price_oracle_code_ecotone().into()),
|
|
360
361
|
storage: Some(vec![StorageSlot {
|
|
361
362
|
index: BigInt::from(0u64),
|
|
362
363
|
// bool isEcotone = true
|
|
@@ -368,16 +369,11 @@ fn gas_price_oracle_ecotone() -> AccountOverride {
|
|
|
368
369
|
}
|
|
369
370
|
|
|
370
371
|
fn gas_price_oracle_fjord() -> AccountOverride {
|
|
371
|
-
let gas_price_oracle_code = hex::decode(include_str!(
|
|
372
|
-
"../../data/op/predeploys/gas_price_oracle/fjord.txt"
|
|
373
|
-
))
|
|
374
|
-
.expect("The bytecode for the GasPriceOracle predeploy should be a valid hex string");
|
|
375
|
-
|
|
376
372
|
AccountOverride {
|
|
377
373
|
address: Uint8Array::with_data_copied(GAS_PRICE_ORACLE_ADDRESS),
|
|
378
374
|
balance: None,
|
|
379
375
|
nonce: None,
|
|
380
|
-
code: Some(
|
|
376
|
+
code: Some(gas_price_oracle_code_fjord().into()),
|
|
381
377
|
storage: Some(vec![StorageSlot {
|
|
382
378
|
index: BigInt::from(0u64),
|
|
383
379
|
// bool isEcotone = true
|
|
@@ -390,16 +386,11 @@ fn gas_price_oracle_fjord() -> AccountOverride {
|
|
|
390
386
|
}
|
|
391
387
|
|
|
392
388
|
fn gas_price_oracle_isthmus() -> AccountOverride {
|
|
393
|
-
let gas_price_oracle_code = hex::decode(include_str!(
|
|
394
|
-
"../../data/op/predeploys/gas_price_oracle/isthmus.txt"
|
|
395
|
-
))
|
|
396
|
-
.expect("The bytecode for the GasPriceOracle predeploy should be a valid hex string");
|
|
397
|
-
|
|
398
389
|
AccountOverride {
|
|
399
390
|
address: Uint8Array::with_data_copied(GAS_PRICE_ORACLE_ADDRESS),
|
|
400
391
|
balance: None,
|
|
401
392
|
nonce: None,
|
|
402
|
-
code: Some(
|
|
393
|
+
code: Some(gas_price_oracle_code_isthmus().into()),
|
|
403
394
|
storage: Some(vec![StorageSlot {
|
|
404
395
|
index: BigInt::from(0u64),
|
|
405
396
|
// bool isEcotone = true
|
package/src/config.rs
CHANGED
|
@@ -7,7 +7,8 @@ use std::{
|
|
|
7
7
|
|
|
8
8
|
use edr_coverage::reporter::SyncOnCollectedCoverageCallback;
|
|
9
9
|
use edr_eip1559::{BaseFeeActivation, ConstantBaseFeeParams};
|
|
10
|
-
use
|
|
10
|
+
use edr_gas_report::SyncOnCollectedGasReportCallback;
|
|
11
|
+
use edr_primitives::{Bytes, HashMap, HashSet};
|
|
11
12
|
use edr_signer::{secret_key_from_str, SecretKey};
|
|
12
13
|
use napi::{
|
|
13
14
|
bindgen_prelude::{BigInt, Promise, Reference, Uint8Array},
|
|
@@ -20,8 +21,8 @@ use napi::{
|
|
|
20
21
|
use napi_derive::napi;
|
|
21
22
|
|
|
22
23
|
use crate::{
|
|
23
|
-
account::AccountOverride, block::BlobGas, cast::TryCast,
|
|
24
|
-
precompile::Precompile, subscription::SubscriptionConfig,
|
|
24
|
+
account::AccountOverride, block::BlobGas, cast::TryCast, gas_report::GasReport,
|
|
25
|
+
logger::LoggerConfig, precompile::Precompile, subscription::SubscriptionConfig,
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
/// Configuration for EIP-1559 parameters
|
|
@@ -92,6 +93,17 @@ pub struct CodeCoverageConfig {
|
|
|
92
93
|
pub on_collected_coverage_callback: JsFunction,
|
|
93
94
|
}
|
|
94
95
|
|
|
96
|
+
#[napi(object)]
|
|
97
|
+
pub struct GasReportConfig {
|
|
98
|
+
/// Gas reports are collected after a block is mined or `eth_call` is
|
|
99
|
+
/// executed.
|
|
100
|
+
///
|
|
101
|
+
/// Exceptions thrown in the callback will be propagated to the original
|
|
102
|
+
/// caller.
|
|
103
|
+
#[napi(ts_type = "(gasReport: GasReport) => Promise<void>")]
|
|
104
|
+
pub on_collected_gas_report_callback: JsFunction,
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
/// Configuration for forking a blockchain
|
|
96
108
|
#[napi(object)]
|
|
97
109
|
pub struct ForkConfig {
|
|
@@ -169,6 +181,8 @@ pub struct MiningConfig {
|
|
|
169
181
|
pub struct ObservabilityConfig {
|
|
170
182
|
/// If present, configures runtime observability to collect code coverage.
|
|
171
183
|
pub code_coverage: Option<CodeCoverageConfig>,
|
|
184
|
+
/// If present, configures runtime observability to collect gas reports.
|
|
185
|
+
pub gas_report: Option<GasReportConfig>,
|
|
172
186
|
}
|
|
173
187
|
|
|
174
188
|
/// Configuration for a provider
|
|
@@ -385,6 +399,8 @@ impl ObservabilityConfig {
|
|
|
385
399
|
.code_coverage
|
|
386
400
|
.map(
|
|
387
401
|
|code_coverage| -> napi::Result<Box<dyn SyncOnCollectedCoverageCallback>> {
|
|
402
|
+
let runtime = runtime.clone();
|
|
403
|
+
|
|
388
404
|
let mut on_collected_coverage_callback: ThreadsafeFunction<
|
|
389
405
|
_,
|
|
390
406
|
ErrorStrategy::Fatal,
|
|
@@ -450,9 +466,61 @@ impl ObservabilityConfig {
|
|
|
450
466
|
},
|
|
451
467
|
)
|
|
452
468
|
.transpose()?;
|
|
469
|
+
let on_collected_gas_report_fn = self.gas_report.map(
|
|
470
|
+
|gas_report| -> napi::Result<Box<dyn SyncOnCollectedGasReportCallback>> {
|
|
471
|
+
let mut on_collected_gas_report_callback: ThreadsafeFunction<
|
|
472
|
+
_,
|
|
473
|
+
ErrorStrategy::Fatal,
|
|
474
|
+
> = gas_report
|
|
475
|
+
.on_collected_gas_report_callback
|
|
476
|
+
.create_threadsafe_function(
|
|
477
|
+
0,
|
|
478
|
+
|ctx: ThreadSafeCallContext<GasReport>| {
|
|
479
|
+
let report = ctx.value;
|
|
480
|
+
Ok(vec![report])
|
|
481
|
+
}
|
|
482
|
+
,
|
|
483
|
+
)?;
|
|
484
|
+
// Maintain a weak reference to the function to avoid blocking the event loop
|
|
485
|
+
// from exiting.
|
|
486
|
+
on_collected_gas_report_callback.unref(env)?;
|
|
487
|
+
|
|
488
|
+
let on_collected_gas_report_fn: Box<dyn SyncOnCollectedGasReportCallback> =
|
|
489
|
+
Box::new(move |report| {
|
|
490
|
+
let runtime = runtime.clone();
|
|
491
|
+
|
|
492
|
+
let (sender, receiver) = std::sync::mpsc::channel();
|
|
493
|
+
|
|
494
|
+
// Convert the report to the N-API representation
|
|
495
|
+
let status = on_collected_gas_report_callback
|
|
496
|
+
.call_with_return_value(GasReport::from(report), ThreadsafeFunctionCallMode::Blocking, move |result: Promise<()>| {
|
|
497
|
+
// We spawn a background task to handle the async callback
|
|
498
|
+
runtime.spawn(async move {
|
|
499
|
+
let result = result.await;
|
|
500
|
+
sender.send(result).map_err(|_error| {
|
|
501
|
+
napi::Error::new(
|
|
502
|
+
napi::Status::GenericFailure,
|
|
503
|
+
"Failed to send result from on_collected_gas_report_callback",
|
|
504
|
+
)
|
|
505
|
+
})
|
|
506
|
+
});
|
|
507
|
+
Ok(())
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
assert_eq!(status, napi::Status::Ok);
|
|
511
|
+
|
|
512
|
+
let () = receiver.recv().expect("Receive can only fail if the channel is closed")?;
|
|
513
|
+
|
|
514
|
+
Ok(())
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
Ok(on_collected_gas_report_fn)
|
|
518
|
+
},
|
|
519
|
+
).transpose()?;
|
|
453
520
|
|
|
454
521
|
Ok(edr_provider::observability::Config {
|
|
455
522
|
on_collected_coverage_fn,
|
|
523
|
+
on_collected_gas_report_fn,
|
|
456
524
|
..edr_provider::observability::Config::default()
|
|
457
525
|
})
|
|
458
526
|
}
|
|
@@ -509,7 +577,7 @@ impl ProviderConfig {
|
|
|
509
577
|
.genesis_state
|
|
510
578
|
.into_iter()
|
|
511
579
|
.map(TryInto::try_into)
|
|
512
|
-
.collect::<napi::Result<HashMap<
|
|
580
|
+
.collect::<napi::Result<HashMap<edr_primitives::Address, edr_provider::AccountOverride>>>()?;
|
|
513
581
|
|
|
514
582
|
let precompile_overrides = self
|
|
515
583
|
.precompile_overrides
|
package/src/context.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
|
-
use edr_eth::HashMap;
|
|
4
3
|
use edr_napi_core::{provider::SyncProviderFactory, solidity};
|
|
4
|
+
use edr_primitives::HashMap;
|
|
5
5
|
use edr_solidity_tests::{
|
|
6
6
|
decode::RevertDecoder,
|
|
7
7
|
multi_runner::{SuiteResultAndArtifactId, TestContract, TestContracts},
|
|
@@ -26,7 +26,7 @@ use crate::{
|
|
|
26
26
|
artifact::{Artifact, ArtifactId},
|
|
27
27
|
config::SolidityTestRunnerConfigArgs,
|
|
28
28
|
factory::SolidityTestRunnerFactory,
|
|
29
|
-
test_results::SuiteResult,
|
|
29
|
+
test_results::{SolidityTestResult, SuiteResult},
|
|
30
30
|
LinkingOutput,
|
|
31
31
|
},
|
|
32
32
|
subscription::SubscriptionConfig,
|
|
@@ -39,7 +39,7 @@ pub struct EdrContext {
|
|
|
39
39
|
|
|
40
40
|
#[napi]
|
|
41
41
|
impl EdrContext {
|
|
42
|
-
|
|
42
|
+
/// Creates a new [`EdrContext`] instance. Should only be called once!
|
|
43
43
|
#[napi(catch_unwind, constructor)]
|
|
44
44
|
pub fn new() -> napi::Result<Self> {
|
|
45
45
|
let context = Context::new()?;
|
|
@@ -49,7 +49,7 @@ impl EdrContext {
|
|
|
49
49
|
})
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
/// Constructs a new provider with the provided configuration.
|
|
53
53
|
#[napi(catch_unwind, ts_return_type = "Promise<Provider>")]
|
|
54
54
|
pub fn create_provider(
|
|
55
55
|
&self,
|
|
@@ -130,7 +130,7 @@ impl EdrContext {
|
|
|
130
130
|
Ok(promise)
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
/// Registers a new provider factory for the provided chain type.
|
|
134
134
|
#[napi(catch_unwind)]
|
|
135
135
|
pub async fn register_provider_factory(
|
|
136
136
|
&self,
|
|
@@ -153,14 +153,29 @@ impl EdrContext {
|
|
|
153
153
|
Ok(())
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
/// Executes Solidity tests
|
|
157
|
+
///
|
|
158
|
+
/// The function will return a promise that resolves to a
|
|
159
|
+
/// [`SolidityTestResult`].
|
|
160
|
+
///
|
|
161
|
+
/// Arguments:
|
|
162
|
+
/// - `chainType`: the same chain type that was passed to
|
|
163
|
+
/// `registerProviderFactory`.
|
|
164
|
+
/// - `artifacts`: the project's compilation output artifacts. It's
|
|
165
|
+
/// important to include include all artifacts here, otherwise cheatcodes
|
|
166
|
+
/// that access artifacts and other functionality (e.g. auto-linking, gas
|
|
167
|
+
/// reports) can break.
|
|
168
|
+
/// - `testSuites`: the test suite ids that specify which test suites to
|
|
169
|
+
/// execute. The test suite artifacts must be present in `artifacts`.
|
|
170
|
+
/// - `configArgs`: solidity test runner configuration. See the struct docs
|
|
171
|
+
/// for details.
|
|
172
|
+
/// - `tracingConfig`: the build infos used for stack trace generation.
|
|
173
|
+
/// These are lazily parsed and it's important that they're passed as
|
|
174
|
+
/// Uint8 arrays for performance.
|
|
175
|
+
/// - `onTestSuiteCompletedCallback`: The progress callback will be called
|
|
176
|
+
/// with the results of each test suite as soon as it finished executing.
|
|
162
177
|
#[allow(clippy::too_many_arguments)]
|
|
163
|
-
#[napi(catch_unwind, ts_return_type = "Promise<
|
|
178
|
+
#[napi(catch_unwind, ts_return_type = "Promise<SolidityTestResult>")]
|
|
164
179
|
pub fn run_solidity_tests(
|
|
165
180
|
&self,
|
|
166
181
|
env: Env,
|
|
@@ -291,7 +306,7 @@ impl EdrContext {
|
|
|
291
306
|
.expect("Failed to join test runner factory thread"));
|
|
292
307
|
|
|
293
308
|
let runtime_for_runner = runtime.clone();
|
|
294
|
-
let
|
|
309
|
+
let test_result = try_or_reject_deferred!(runtime
|
|
295
310
|
.clone()
|
|
296
311
|
.spawn_blocking(move || {
|
|
297
312
|
test_runner.run_tests(
|
|
@@ -323,7 +338,7 @@ impl EdrContext {
|
|
|
323
338
|
.await
|
|
324
339
|
.expect("Failed to join test runner thread"));
|
|
325
340
|
|
|
326
|
-
deferred.resolve(move |_env| Ok(()));
|
|
341
|
+
deferred.resolve(move |_env| Ok(SolidityTestResult::from(test_result)));
|
|
327
342
|
});
|
|
328
343
|
|
|
329
344
|
Ok(promise)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
|
|
3
|
+
use napi::bindgen_prelude::BigInt;
|
|
4
|
+
use napi_derive::napi;
|
|
5
|
+
|
|
6
|
+
#[napi(object)]
|
|
7
|
+
pub struct GasReport {
|
|
8
|
+
pub contracts: HashMap<String, ContractGasReport>,
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#[napi(object)]
|
|
12
|
+
pub struct ContractGasReport {
|
|
13
|
+
pub deployments: Vec<DeploymentGasReport>,
|
|
14
|
+
pub functions: HashMap<String, Vec<FunctionGasReport>>,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#[napi]
|
|
18
|
+
pub enum GasReportExecutionStatus {
|
|
19
|
+
Success,
|
|
20
|
+
Revert,
|
|
21
|
+
Halt,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#[napi(object)]
|
|
25
|
+
pub struct DeploymentGasReport {
|
|
26
|
+
pub gas: BigInt,
|
|
27
|
+
pub size: BigInt,
|
|
28
|
+
pub status: GasReportExecutionStatus,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
#[napi(object)]
|
|
32
|
+
pub struct FunctionGasReport {
|
|
33
|
+
pub gas: BigInt,
|
|
34
|
+
pub status: GasReportExecutionStatus,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl From<edr_gas_report::GasReport> for GasReport {
|
|
38
|
+
fn from(value: edr_gas_report::GasReport) -> Self {
|
|
39
|
+
Self {
|
|
40
|
+
contracts: value
|
|
41
|
+
.into_inner()
|
|
42
|
+
.into_iter()
|
|
43
|
+
.map(|(k, v)| (k, v.into()))
|
|
44
|
+
.collect(),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
impl From<edr_gas_report::ContractGasReport> for ContractGasReport {
|
|
50
|
+
fn from(value: edr_gas_report::ContractGasReport) -> Self {
|
|
51
|
+
Self {
|
|
52
|
+
deployments: value.deployments.into_iter().map(Into::into).collect(),
|
|
53
|
+
functions: value
|
|
54
|
+
.functions
|
|
55
|
+
.into_iter()
|
|
56
|
+
.map(|(k, v)| {
|
|
57
|
+
let function_reports = v.into_iter().map(FunctionGasReport::from).collect();
|
|
58
|
+
(k, function_reports)
|
|
59
|
+
})
|
|
60
|
+
.collect(),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
impl From<edr_gas_report::GasReportExecutionStatus> for GasReportExecutionStatus {
|
|
66
|
+
fn from(value: edr_gas_report::GasReportExecutionStatus) -> Self {
|
|
67
|
+
match value {
|
|
68
|
+
edr_gas_report::GasReportExecutionStatus::Success => Self::Success,
|
|
69
|
+
edr_gas_report::GasReportExecutionStatus::Revert => Self::Revert,
|
|
70
|
+
edr_gas_report::GasReportExecutionStatus::Halt => Self::Halt,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
impl From<edr_gas_report::DeploymentGasReport> for DeploymentGasReport {
|
|
76
|
+
fn from(value: edr_gas_report::DeploymentGasReport) -> Self {
|
|
77
|
+
Self {
|
|
78
|
+
gas: BigInt::from(value.gas),
|
|
79
|
+
size: BigInt::from(value.size),
|
|
80
|
+
status: value.status.into(),
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
impl From<edr_gas_report::FunctionGasReport> for FunctionGasReport {
|
|
86
|
+
fn from(value: edr_gas_report::FunctionGasReport) -> Self {
|
|
87
|
+
Self {
|
|
88
|
+
gas: BigInt::from(value.gas),
|
|
89
|
+
status: value.status.into(),
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
package/src/lib.rs
CHANGED
|
@@ -20,6 +20,7 @@ pub mod context;
|
|
|
20
20
|
/// Types for decoding smart contract data.
|
|
21
21
|
pub mod contract_decoder;
|
|
22
22
|
mod debug_trace;
|
|
23
|
+
pub mod gas_report;
|
|
23
24
|
/// Types and functions related to code coverage instrumentation.
|
|
24
25
|
pub mod instrument;
|
|
25
26
|
/// Types for EVM execution logs.
|
package/src/logger.rs
CHANGED
package/src/mock/time.rs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
|
-
use edr_eth::B256;
|
|
4
3
|
use edr_evm::spec::RuntimeSpec;
|
|
5
4
|
use edr_evm_spec::ChainSpec;
|
|
6
5
|
use edr_generic::GenericChainSpec;
|
|
7
6
|
use edr_napi_core::logger::Logger;
|
|
8
|
-
use
|
|
7
|
+
use edr_primitives::B256;
|
|
8
|
+
use edr_rpc_spec::RpcSpec;
|
|
9
9
|
use napi::{bindgen_prelude::BigInt, tokio::runtime, Env, JsObject};
|
|
10
10
|
use napi_derive::napi;
|
|
11
11
|
|
package/src/precompile.rs
CHANGED
package/src/result.rs
CHANGED
|
@@ -19,17 +19,17 @@ pub enum SuccessReason {
|
|
|
19
19
|
SelfDestruct,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
impl From<
|
|
23
|
-
fn from(eval:
|
|
22
|
+
impl From<edr_evm::result::SuccessReason> for SuccessReason {
|
|
23
|
+
fn from(eval: edr_evm::result::SuccessReason) -> Self {
|
|
24
24
|
match eval {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
edr_evm::result::SuccessReason::Stop => Self::Stop,
|
|
26
|
+
edr_evm::result::SuccessReason::Return => Self::Return,
|
|
27
|
+
edr_evm::result::SuccessReason::SelfDestruct => Self::SelfDestruct,
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
impl From<SuccessReason> for
|
|
32
|
+
impl From<SuccessReason> for edr_evm::result::SuccessReason {
|
|
33
33
|
fn from(value: SuccessReason) -> Self {
|
|
34
34
|
match value {
|
|
35
35
|
SuccessReason::Stop => Self::Stop,
|
|
@@ -157,7 +157,7 @@ impl From<&AfterMessage<EvmHaltReason>> for ExecutionResult {
|
|
|
157
157
|
} = value;
|
|
158
158
|
|
|
159
159
|
let result = match execution_result {
|
|
160
|
-
|
|
160
|
+
edr_evm::result::ExecutionResult::Success {
|
|
161
161
|
reason,
|
|
162
162
|
gas_used,
|
|
163
163
|
gas_refunded,
|
|
@@ -172,12 +172,12 @@ impl From<&AfterMessage<EvmHaltReason>> for ExecutionResult {
|
|
|
172
172
|
gas_refunded: BigInt::from(*gas_refunded),
|
|
173
173
|
logs,
|
|
174
174
|
output: match output {
|
|
175
|
-
|
|
175
|
+
edr_evm::result::Output::Call(return_value) => {
|
|
176
176
|
let return_value = Uint8Array::with_data_copied(return_value);
|
|
177
177
|
|
|
178
178
|
Either::A(CallOutput { return_value })
|
|
179
179
|
}
|
|
180
|
-
|
|
180
|
+
edr_evm::result::Output::Create(return_value, address) => {
|
|
181
181
|
let return_value = Uint8Array::with_data_copied(return_value);
|
|
182
182
|
|
|
183
183
|
Either::B(CreateOutput {
|
|
@@ -188,7 +188,7 @@ impl From<&AfterMessage<EvmHaltReason>> for ExecutionResult {
|
|
|
188
188
|
},
|
|
189
189
|
})
|
|
190
190
|
}
|
|
191
|
-
|
|
191
|
+
edr_evm::result::ExecutionResult::Revert { gas_used, output } => {
|
|
192
192
|
let output = Uint8Array::with_data_copied(output);
|
|
193
193
|
|
|
194
194
|
Either3::B(RevertResult {
|
|
@@ -196,7 +196,7 @@ impl From<&AfterMessage<EvmHaltReason>> for ExecutionResult {
|
|
|
196
196
|
output,
|
|
197
197
|
})
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
edr_evm::result::ExecutionResult::Halt { reason, gas_used } => Either3::C(HaltResult {
|
|
200
200
|
reason: ExceptionalHalt::from(*reason),
|
|
201
201
|
gas_used: BigInt::from(*gas_used),
|
|
202
202
|
}),
|
package/src/serde.rs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use std::{collections::HashMap, path::PathBuf};
|
|
2
2
|
|
|
3
3
|
use derive_more::Debug;
|
|
4
|
-
use
|
|
4
|
+
use edr_primitives::hex;
|
|
5
5
|
use edr_solidity_tests::{
|
|
6
6
|
executors::invariant::InvariantConfig,
|
|
7
7
|
fuzz::FuzzConfig,
|
|
@@ -155,6 +155,11 @@ pub struct SolidityTestRunnerConfigArgs {
|
|
|
155
155
|
/// A regex pattern to filter tests. If provided, only test methods that
|
|
156
156
|
/// match the pattern will be executed and reported as a test result.
|
|
157
157
|
pub test_pattern: Option<String>,
|
|
158
|
+
/// Controls whether to generate a gas report after running the tests.
|
|
159
|
+
/// Enabling this also enables collection of all traces and EVM isolation
|
|
160
|
+
/// mode.
|
|
161
|
+
/// Defaults to false.
|
|
162
|
+
pub generate_gas_report: Option<bool>,
|
|
158
163
|
}
|
|
159
164
|
|
|
160
165
|
impl SolidityTestRunnerConfigArgs {
|
|
@@ -200,6 +205,7 @@ impl SolidityTestRunnerConfigArgs {
|
|
|
200
205
|
include_traces,
|
|
201
206
|
observability,
|
|
202
207
|
test_pattern,
|
|
208
|
+
generate_gas_report,
|
|
203
209
|
} = self;
|
|
204
210
|
|
|
205
211
|
let test_pattern = TestFilterConfig {
|
|
@@ -305,6 +311,7 @@ impl SolidityTestRunnerConfigArgs {
|
|
|
305
311
|
),
|
|
306
312
|
on_collected_coverage_fn,
|
|
307
313
|
test_pattern,
|
|
314
|
+
generate_gas_report,
|
|
308
315
|
};
|
|
309
316
|
|
|
310
317
|
Ok(config)
|
package/src/solidity_tests/l1.rs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
use std::{collections::BTreeMap, sync::Arc};
|
|
2
2
|
|
|
3
|
-
use edr_eth::Bytes;
|
|
4
3
|
use edr_napi_core::solidity::{
|
|
5
4
|
config::{TestRunnerConfig, TracingConfigWithBuffers},
|
|
6
5
|
SyncTestRunner, SyncTestRunnerFactory,
|
|
7
6
|
};
|
|
7
|
+
use edr_primitives::Bytes;
|
|
8
8
|
use edr_solidity::artifacts::ArtifactId;
|
|
9
9
|
use edr_solidity_tests::{
|
|
10
10
|
contracts::ContractsByArtifact, decode::RevertDecoder, evm_context::L1EvmBuilder,
|
package/src/solidity_tests/op.rs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
use std::{collections::BTreeMap, sync::Arc};
|
|
2
2
|
|
|
3
|
-
use edr_eth::Bytes;
|
|
4
3
|
use edr_napi_core::solidity::{
|
|
5
4
|
config::{TestRunnerConfig, TracingConfigWithBuffers},
|
|
6
5
|
SyncTestRunner, SyncTestRunnerFactory,
|
|
7
6
|
};
|
|
8
7
|
use edr_op::solidity_tests::OpEvmBuilder;
|
|
8
|
+
use edr_primitives::Bytes;
|
|
9
9
|
use edr_solidity::artifacts::ArtifactId;
|
|
10
10
|
use edr_solidity_tests::{
|
|
11
11
|
contracts::ContractsByArtifact, decode::RevertDecoder, multi_runner::TestContract,
|
|
@@ -18,6 +18,7 @@ use napi_derive::napi;
|
|
|
18
18
|
|
|
19
19
|
use crate::{
|
|
20
20
|
cast::TryCast,
|
|
21
|
+
gas_report::GasReport,
|
|
21
22
|
solidity_tests::{artifact::ArtifactId, config::IncludeTraces},
|
|
22
23
|
trace::{solidity_stack_trace::SolidityStackTraceEntry, u256_to_bigint},
|
|
23
24
|
};
|
|
@@ -717,3 +718,19 @@ impl From<traces::CallKind> for CallKind {
|
|
|
717
718
|
}
|
|
718
719
|
}
|
|
719
720
|
}
|
|
721
|
+
|
|
722
|
+
/// The result of a Solidity test run.
|
|
723
|
+
#[napi(object)]
|
|
724
|
+
pub struct SolidityTestResult {
|
|
725
|
+
/// Gas report, if it was generated.
|
|
726
|
+
#[napi(readonly)]
|
|
727
|
+
pub gas_report: Option<GasReport>,
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
impl From<edr_solidity_tests::multi_runner::SolidityTestResult> for SolidityTestResult {
|
|
731
|
+
fn from(value: edr_solidity_tests::multi_runner::SolidityTestResult) -> Self {
|
|
732
|
+
Self {
|
|
733
|
+
gas_report: value.gas_report.map(GasReport::from),
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
package/src/solidity_tests.rs
CHANGED
|
@@ -9,7 +9,7 @@ pub mod test_results;
|
|
|
9
9
|
|
|
10
10
|
use std::path::Path;
|
|
11
11
|
|
|
12
|
-
use
|
|
12
|
+
use edr_primitives::Bytes;
|
|
13
13
|
use edr_solidity::linker::{LinkOutput, Linker};
|
|
14
14
|
use edr_solidity_tests::{constants::LIBRARY_DEPLOYER, contracts::ContractsByArtifact};
|
|
15
15
|
use foundry_compilers::artifacts::Libraries;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
use std::convert::Infallible;
|
|
5
5
|
|
|
6
|
-
use
|
|
6
|
+
use edr_primitives::{hex, U256};
|
|
7
7
|
use napi::bindgen_prelude::{BigInt, Either25, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
|
|
8
8
|
use napi_derive::napi;
|
|
9
9
|
use serde::{Serialize, Serializer};
|
|
@@ -848,7 +848,8 @@ const _: () = {
|
|
|
848
848
|
assert_to_from_napi_value::<SolidityStackTraceEntry>();
|
|
849
849
|
};
|
|
850
850
|
|
|
851
|
-
/// Serializes a [`BigInt`] that represents an EVM value as a
|
|
851
|
+
/// Serializes a [`BigInt`] that represents an EVM value as a
|
|
852
|
+
/// [`edr_primitives::U256`].
|
|
852
853
|
fn serialize_evm_value_bigint_using_u256<S>(bigint: &BigInt, s: S) -> Result<S::Ok, S::Error>
|
|
853
854
|
where
|
|
854
855
|
S: Serializer,
|
package/src/trace.rs
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
use std::sync::Arc;
|
|
9
9
|
|
|
10
|
-
use edr_eth::bytecode::opcode::OpCode;
|
|
11
10
|
use edr_evm::trace::BeforeMessage;
|
|
12
11
|
use edr_evm_spec::EvmHaltReason;
|
|
12
|
+
use edr_primitives::bytecode::opcode::OpCode;
|
|
13
13
|
use napi::bindgen_prelude::{BigInt, Either3, Uint8Array};
|
|
14
14
|
use napi_derive::napi;
|
|
15
15
|
|
|
@@ -145,7 +145,7 @@ impl TracingStep {
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
pub(crate) fn u256_to_bigint(v: &
|
|
148
|
+
pub(crate) fn u256_to_bigint(v: &edr_primitives::U256) -> BigInt {
|
|
149
149
|
BigInt {
|
|
150
150
|
sign_bit: false,
|
|
151
151
|
words: v.into_limbs().to_vec(),
|
package/src/withdrawal.rs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
use
|
|
1
|
+
use edr_primitives::Address;
|
|
2
2
|
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
|
3
3
|
use napi_derive::napi;
|
|
4
4
|
|
|
@@ -16,21 +16,21 @@ pub struct Withdrawal {
|
|
|
16
16
|
pub amount: BigInt,
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
impl From<
|
|
20
|
-
fn from(withdrawal:
|
|
19
|
+
impl From<edr_block_header::Withdrawal> for Withdrawal {
|
|
20
|
+
fn from(withdrawal: edr_block_header::Withdrawal) -> Self {
|
|
21
21
|
Self {
|
|
22
22
|
index: BigInt::from(withdrawal.index),
|
|
23
23
|
validator_index: BigInt::from(withdrawal.validator_index),
|
|
24
24
|
address: Uint8Array::with_data_copied(withdrawal.address),
|
|
25
25
|
amount: BigInt {
|
|
26
26
|
sign_bit: false,
|
|
27
|
-
words: withdrawal.amount
|
|
27
|
+
words: vec![withdrawal.amount],
|
|
28
28
|
},
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
impl TryFrom<Withdrawal> for
|
|
33
|
+
impl TryFrom<Withdrawal> for edr_block_header::Withdrawal {
|
|
34
34
|
type Error = napi::Error;
|
|
35
35
|
|
|
36
36
|
fn try_from(value: Withdrawal) -> Result<Self, Self::Error> {
|