diff --git a/crates/edr_napi/index.d.ts b/crates/edr_napi/index.d.ts index 47e4c45a2..b6c71a625 100644 --- a/crates/edr_napi/index.d.ts +++ b/crates/edr_napi/index.d.ts @@ -645,7 +645,7 @@ export declare class EdrContext { /** A JSON-RPC provider for Ethereum. */ export declare class Provider { /**Constructs a new provider with the provided configuration. */ - static withConfig(context: EdrContext, config: ProviderConfig, loggerConfig: LoggerConfig, subscriberCallback: (event: SubscriptionEvent) => void): Promise + static withConfig(context: EdrContext, config: ProviderConfig, loggerConfig: LoggerConfig, tracingConfig: any, subscriberCallback: (event: SubscriptionEvent) => void): Promise /**Handles a JSON-RPC request and returns a JSON-RPC response. */ handleRequest(jsonRequest: string): Promise setCallOverrideCallback(callOverrideCallback: (contract_address: Buffer, data: Buffer) => Promise): void @@ -661,8 +661,8 @@ export declare class Response { /** Returns the response data as a JSON string or a JSON object. */ get data(): string | any get solidityTrace(): RawTrace | null - /**Compute the error stack trace. Return undefined if there was no error, returns the stack trace if it can be computed or returns the error message if available as fallback. */ - stackTrace(config: any): SolidityStackTrace | string | null + /**Compute the error stack trace. Return undefined if there was no error, returns the stack trace if it can be computed or returns the error message if available as a fallback. */ + stackTrace(): SolidityStackTrace | string | null get traces(): Array } /** diff --git a/crates/edr_napi/src/provider.rs b/crates/edr_napi/src/provider.rs index d42fae2d4..d56f4197c 100644 --- a/crates/edr_napi/src/provider.rs +++ b/crates/edr_napi/src/provider.rs @@ -22,6 +22,7 @@ use crate::{ pub struct Provider { provider: Arc>, runtime: runtime::Handle, + tracing_config: Arc, #[cfg(feature = "scenarios")] scenario_file: Option>, } @@ -36,6 +37,8 @@ impl Provider { _context: &EdrContext, config: ProviderConfig, logger_config: LoggerConfig, + // TODO avoid opaque type + tracing_config: serde_json::Value, #[napi(ts_arg_type = "(event: SubscriptionEvent) => void")] subscriber_callback: JsFunction, ) -> napi::Result { let config = edr_provider::ProviderConfig::try_from(config)?; @@ -45,6 +48,10 @@ impl Provider { let subscriber_callback = SubscriberCallback::new(&env, subscriber_callback)?; let subscriber_callback = Box::new(move |event| subscriber_callback.call(event)); + // TODO get actual type as argument + let tracing_config: edr_solidity::vm_trace_decoder::TracingConfig = + serde_json::from_value(tracing_config)?; + let (deferred, promise) = env.create_deferred()?; runtime.clone().spawn_blocking(move || { #[cfg(feature = "scenarios")] @@ -67,6 +74,7 @@ impl Provider { Ok(Provider { provider: Arc::new(provider), runtime, + tracing_config: Arc::new(tracing_config), #[cfg(feature = "scenarios")] scenario_file, }) @@ -125,6 +133,7 @@ impl Provider { solidity_trace: None, data: Either::A(json), traces: Vec::new(), + tracing_config: Arc::clone(&self.tracing_config), }); } }; @@ -189,6 +198,7 @@ impl Provider { solidity_trace, data, traces: traces.into_iter().map(Arc::new).collect(), + tracing_config: Arc::clone(&self.tracing_config), }) } @@ -234,6 +244,7 @@ pub struct Response { solidity_trace: Option>, /// This may contain zero or more traces, depending on the (batch) request traces: Vec>, + tracing_config: Arc, } #[napi] @@ -252,12 +263,9 @@ impl Response { } // Rust port of https://github.com/NomicFoundation/hardhat/blob/c20bf195a6efdc2d74e778b7a4a7799aac224841/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts#L590 - #[doc = "Compute the error stack trace. Return undefined if there was no error, returns the stack trace if it can be computed or returns the error message if available as fallback."] + #[doc = "Compute the error stack trace. Return undefined if there was no error, returns the stack trace if it can be computed or returns the error message if available as a fallback."] #[napi] - pub fn stack_trace( - &self, - config: serde_json::Value, - ) -> napi::Result>> { + pub fn stack_trace(&self) -> napi::Result>> { let Some(trace) = &self.solidity_trace else { return Ok(None); }; @@ -267,13 +275,10 @@ impl Response { let mut vm_trace = vm_tracer.get_last_top_level_message_trace(); let vm_tracer_error = vm_tracer.get_last_error(); - // TODO get actual type as argument - let tracing_config: edr_solidity::vm_trace_decoder::TracingConfig = - serde_json::from_value(config)?; let mut vm_trace_decoder = edr_solidity::vm_trace_decoder::VmTraceDecoder::new(); edr_solidity::vm_trace_decoder::initialize_vm_trace_decoder( &mut vm_trace_decoder, - tracing_config, + &self.tracing_config, )?; vm_trace = vm_trace.map(|trace| vm_trace_decoder.try_to_decode_message_trace(trace)); diff --git a/crates/edr_solidity/src/vm_trace_decoder.rs b/crates/edr_solidity/src/vm_trace_decoder.rs index 1e4317856..50ca6858c 100644 --- a/crates/edr_solidity/src/vm_trace_decoder.rs +++ b/crates/edr_solidity/src/vm_trace_decoder.rs @@ -183,13 +183,13 @@ pub struct ContractAndFunctionName { pub fn initialize_vm_trace_decoder( vm_trace_decoder: &mut VmTraceDecoder, - config: TracingConfig, + config: &TracingConfig, ) -> anyhow::Result<()> { - let Some(build_infos) = config.build_infos else { + let Some(build_infos) = &config.build_infos else { return Ok(()); }; - for build_info in &build_infos { + for build_info in build_infos { let bytecodes = create_models_and_decode_bytecodes( build_info.solc_version.clone(), &build_info.input, diff --git a/hardhat-tests/test/internal/hardhat-network/stack-traces/execution.ts b/hardhat-tests/test/internal/hardhat-network/stack-traces/execution.ts index 9abb53591..06ca2fad1 100644 --- a/hardhat-tests/test/internal/hardhat-network/stack-traces/execution.ts +++ b/hardhat-tests/test/internal/hardhat-network/stack-traces/execution.ts @@ -106,8 +106,7 @@ interface TxData { export async function traceTransaction( provider: EdrProviderWrapper, - txData: TxData, - tracingConfig: TracingConfig + txData: TxData ): Promise { const stringifiedArgs = JSON.stringify({ method: "eth_sendTransaction", @@ -150,7 +149,7 @@ export async function traceTransaction( params: [response.result ?? response.error.data.transactionHash], }); - const stackTrace = responseObject.stackTrace(tracingConfig); + const stackTrace = responseObject.stackTrace(); const contractAddress = receipt.contractAddress?.slice(2); diff --git a/hardhat-tests/test/internal/hardhat-network/stack-traces/test.ts b/hardhat-tests/test/internal/hardhat-network/stack-traces/test.ts index 97ad5ee8a..930e83c11 100644 --- a/hardhat-tests/test/internal/hardhat-network/stack-traces/test.ts +++ b/hardhat-tests/test/internal/hardhat-network/stack-traces/test.ts @@ -501,8 +501,7 @@ async function runTest( tx, provider, compilerOutput, - txIndexToContract, - tracingConfig, + txIndexToContract ); if (typeof stackTraceOrContractAddress === "string") { @@ -525,21 +524,22 @@ async function runTest( tx, provider, compilerOutput, - contract!, - tracingConfig, + contract! ); } try { if (tx.stackTrace === undefined) { assert.isTrue( - stackTraceOrContractAddress === undefined || typeof stackTraceOrContractAddress === "string", + stackTraceOrContractAddress === undefined || + typeof stackTraceOrContractAddress === "string", // FVTODO `Transaction ${txIndex} shouldn't have failed` ); } else { assert.isFalse( - stackTraceOrContractAddress === undefined || typeof stackTraceOrContractAddress === "string", + stackTraceOrContractAddress === undefined || + typeof stackTraceOrContractAddress === "string", `Transaction ${txIndex} should have failed` ); } @@ -549,7 +549,10 @@ async function runTest( throw error; } - if (stackTraceOrContractAddress !== undefined && typeof stackTraceOrContractAddress !== "string") { + if ( + stackTraceOrContractAddress !== undefined && + typeof stackTraceOrContractAddress !== "string" + ) { try { compareStackTraces( txIndex, @@ -630,8 +633,7 @@ async function runDeploymentTransactionTest( tx: DeploymentTransaction, provider: EdrProviderWrapper, compilerOutput: CompilerOutput, - txIndexToContract: Map, - tracingConfig: TracingConfig, + txIndexToContract: Map ): Promise { const file = compilerOutput.contracts[tx.file]; @@ -665,7 +667,7 @@ async function runDeploymentTransactionTest( value: tx.value !== undefined ? BigInt(tx.value) : undefined, data, gas: tx.gas !== undefined ? BigInt(tx.gas) : undefined, - }, tracingConfig); + }); return trace; } @@ -675,8 +677,7 @@ async function runCallTransactionTest( tx: CallTransaction, provider: EdrProviderWrapper, compilerOutput: CompilerOutput, - contract: DeployedContract, - tracingConfig: TracingConfig, + contract: DeployedContract ): Promise { const compilerContract = compilerOutput.contracts[contract.file][contract.name]; @@ -700,7 +701,7 @@ async function runCallTransactionTest( value: tx.value !== undefined ? BigInt(tx.value) : undefined, data, gas: tx.gas !== undefined ? BigInt(tx.gas) : undefined, - }, tracingConfig); + }); return trace; } diff --git a/package.json b/package.json index d7f2831ba..d01f5f0bb 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,9 @@ "pnpm": { "overrides": { "hardhat>@nomicfoundation/edr": "workspace:*" + }, + "patchedDependencies": { + "hardhat@2.22.15": "patches/hardhat@2.22.15.patch" } }, "private": true, diff --git a/patches/hardhat@2.22.15.patch b/patches/hardhat@2.22.15.patch new file mode 100644 index 000000000..ecb3587ad --- /dev/null +++ b/patches/hardhat@2.22.15.patch @@ -0,0 +1,13 @@ +diff --git a/internal/hardhat-network/provider/provider.js b/internal/hardhat-network/provider/provider.js +index a4b921c8a37b7d5967955d0449df3d05dbe725a8..7ff9eac18cb9a587aa6bd13ff69904cb4b610611 100644 +--- a/internal/hardhat-network/provider/provider.js ++++ b/internal/hardhat-network/provider/provider.js +@@ -196,7 +196,7 @@ class EdrProviderWrapper extends events_1.EventEmitter { + printLineFn(message); + } + }, +- }, (event) => { ++ }, tracingConfig ?? {}, (event) => { + eventAdapter.emit("ethEvent", event); + }); + const minimalEthereumJsNode = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72c72585c..d61c94f6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,11 @@ settings: overrides: hardhat>@nomicfoundation/edr: workspace:* +patchedDependencies: + hardhat@2.22.15: + hash: bv5kqmujiion6gbtrpeh3dexx4 + path: patches/hardhat@2.22.15.patch + importers: .: @@ -124,7 +129,7 @@ importers: version: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5) hardhat: specifier: 2.22.15 - version: 2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) + version: 2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) lodash: specifier: ^4.17.11 version: 4.17.21 @@ -250,7 +255,7 @@ importers: version: 7.0.1 hardhat: specifier: 2.22.15 - version: 2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) + version: 2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) mocha: specifier: ^10.0.0 version: 10.3.0 @@ -280,10 +285,10 @@ importers: devDependencies: '@defi-wonderland/smock': specifier: ^2.4.0 - version: 2.4.0(@ethersproject/abi@5.7.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)))(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) + version: 2.4.0(@ethersproject/abi@5.7.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)))(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) '@nomiclabs/hardhat-ethers': specifier: ^2.2.3 - version: 2.2.3(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) + version: 2.2.3(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) '@types/node': specifier: ^20.0.0 version: 20.16.1 @@ -295,7 +300,7 @@ importers: version: 5.7.2 hardhat: specifier: 2.22.15 - version: 2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) + version: 2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) mocha: specifier: ^10.0.0 version: 10.3.0 @@ -3351,16 +3356,16 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@defi-wonderland/smock@2.4.0(@ethersproject/abi@5.7.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)))(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4))': + '@defi-wonderland/smock@2.4.0(@ethersproject/abi@5.7.0)(@ethersproject/abstract-provider@5.7.0)(@ethersproject/abstract-signer@5.7.0)(@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)))(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4))': dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/abstract-provider': 5.7.0 '@ethersproject/abstract-signer': 5.7.0 '@nomicfoundation/ethereumjs-util': 9.0.4 - '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) + '@nomiclabs/hardhat-ethers': 2.2.3(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4)) diff: 5.0.0 ethers: 5.7.2 - hardhat: 2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) + hardhat: 2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) lodash.isequal: 4.5.0 lodash.isequalwith: 4.4.0 rxjs: 7.8.1 @@ -3876,10 +3881,10 @@ snapshots: '@nomicfoundation/solidity-analyzer-win32-ia32-msvc': 0.1.1 '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.1 - '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4))': + '@nomiclabs/hardhat-ethers@2.2.3(ethers@5.7.2)(hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4))': dependencies: ethers: 5.7.2 - hardhat: 2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) + hardhat: 2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4) '@pkgr/core@0.1.1': {} @@ -5193,7 +5198,7 @@ snapshots: hard-rejection@2.1.0: {} - hardhat@2.22.15(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4): + hardhat@2.22.15(patch_hash=bv5kqmujiion6gbtrpeh3dexx4)(ts-node@10.9.2(@types/node@20.16.1)(typescript@5.0.4))(typescript@5.0.4): dependencies: '@ethersproject/abi': 5.7.0 '@metamask/eth-sig-util': 4.0.1