Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/ninety-hornets-ask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@nomicfoundation/edr": minor
---

Removed `getLatestSupportedSolcVersion` API

BREAKING CHANGE: A new API `latestSupportedSolidityVersion` was previously introduced to replace the deprecated `getLatestSupportedSolcVersion`. The old API has now been removed. Users should update their code to use `latestSupportedSolidityVersion` instead.
9 changes: 9 additions & 0 deletions .changeset/tasty-ears-drive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@nomicfoundation/edr": minor
---

Added support to the `debug_traceCall` & `debug_traceTransaction` JSON-RPC methods for different tracers (`4byteTracer`, `callTracer`, `flatCallTracer`, `prestateTracer`, `noopTracer`, and `muxTracer`).

Our API is now aligned with Geth's tracing capabilities.

BREAKING CHANGE: Memory capture used to be enabled by default on geth, but has since been flipped <https://github.com/ethereum/go-ethereum/pull/23558> and is now disabled by default. We have followed suit and disabled it by default as well. If you were relying on memory capture, you will need to explicitly enable it by setting the `enableMemory` option to `true` in your tracer configuration.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,6 @@ useless_transmute = "warn"
verbose_file_reads = "warn"
wildcard-imports = "warn"
zero_sized_map_values = "warn"

[patch.crates-io]
revm-inspectors = { git = "https://github.com/Wodann/revm-inspectors", rev = "062c206" }
5 changes: 0 additions & 5 deletions crates/edr_napi/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1501,11 +1501,6 @@ export interface TracingMessageResult {
/** Execution result */
readonly executionResult: ExecutionResult
}
/**
* Returns the latest version of solc that EDR officially
* supports and is tested against.
*/
export declare function getLatestSupportedSolcVersion(): string
export interface Withdrawal {
/** The index of withdrawal */
index: bigint
Expand Down
3 changes: 1 addition & 2 deletions crates/edr_napi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

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, OSAKA, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, ContractDecoder, GasReportExecutionStatus, addStatementCoverageInstrumentation, latestSupportedSolidityVersion, 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
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, OSAKA, OpHardfork, opHardforkFromString, opHardforkToString, opLatestHardfork, OP_CHAIN_TYPE, opGenesisState, opProviderFactory, BEDROCK, REGOLITH, CANYON, ECOTONE, FJORD, GRANITE, HOLOCENE, ISTHMUS, MineOrdering, EdrContext, ContractDecoder, GasReportExecutionStatus, addStatementCoverageInstrumentation, latestSupportedSolidityVersion, 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 } = nativeBinding

module.exports.GENERIC_CHAIN_TYPE = GENERIC_CHAIN_TYPE
module.exports.genericChainProviderFactory = genericChainProviderFactory
Expand Down Expand Up @@ -399,4 +399,3 @@ module.exports.UNKNOWN_FUNCTION_NAME = UNKNOWN_FUNCTION_NAME
module.exports.PRECOMPILE_FUNCTION_NAME = PRECOMPILE_FUNCTION_NAME
module.exports.UNRECOGNIZED_CONTRACT_NAME = UNRECOGNIZED_CONTRACT_NAME
module.exports.RawTrace = RawTrace
module.exports.getLatestSupportedSolcVersion = getLatestSupportedSolcVersion
7 changes: 0 additions & 7 deletions crates/edr_napi/src/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,3 @@ impl RawTrace {
.collect()
}
}

#[napi]
/// Returns the latest version of solc that EDR officially
/// supports and is tested against.
pub fn get_latest_supported_solc_version() -> String {
"0.8.28".to_string()
}
2 changes: 2 additions & 0 deletions crates/edr_provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ alloy-dyn-abi.workspace = true
alloy-eips.workspace = true
alloy-rlp.workspace = true
alloy-rpc-types.workspace = true
alloy-rpc-types-trace = "1.1.2"
alloy-serde.workspace = true
alloy-sol-types.workspace = true
anyhow = { workspace = true, optional = true }
Expand Down Expand Up @@ -71,6 +72,7 @@ lru = "0.12.2"
parking_lot.workspace = true
rand.workspace = true
revm-inspector.workspace = true
revm-inspectors.workspace = true
rpds = { version = "1.1.0", default-features = false, features = ["std"] }
serde.workspace = true
serde_json.workspace = true
Expand Down
55 changes: 34 additions & 21 deletions crates/edr_provider/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ use std::{
use alloy_dyn_abi::eip712::TypedData;
use alloy_eips::eip7825;
use alloy_rpc_types::EIP1186AccountProofResponse;
use alloy_rpc_types_trace::geth::GethDebugTracingOptions;
use edr_block_api::{
Block, BlockAndTotalDifficulty, FetchBlockReceipts as _, GenesisBlockFactory,
GenesisBlockOptions,
};
use edr_block_builder_api::BuiltBlockAndState;
use edr_block_builder_api::{BuiltBlockAndState, DatabaseComponents, WrapDatabaseRef};
use edr_block_header::{
calculate_next_base_fee_per_blob_gas, BlockConfig, BlockHeader, HeaderOverrides,
};
Expand All @@ -44,6 +45,7 @@ use edr_eth::{
reward_percentile::RewardPercentile,
BlockSpec, BlockTag, Eip1898BlockSpec,
};
use edr_evm::guaranteed_dry_run_with_inspector;
use edr_gas_report::{GasReport, SyncOnCollectedGasReportCallback};
use edr_mem_pool::{account_next_nonce, MemPool, OrderedTransaction};
use edr_precompile::PrecompileFn;
Expand Down Expand Up @@ -76,18 +78,19 @@ use gas::gas_used_ratio;
use indexmap::IndexMap;
use itertools::izip;
use lru::LruCache;
use revm_inspectors::tracing::DebugInspector;
use rpds::HashTrieMapSync;
use tokio::runtime;

use crate::{
data::gas::{compute_rewards, BinarySearchEstimationArgs, CheckGasLimitArgs},
data::{
call::BlockEnvWithZeroBaseFee,
gas::{compute_rewards, BinarySearchEstimationArgs, CheckGasLimitArgs},
},
debug_mine::{
DebugMineBlockResult, DebugMineBlockResultAndState, DebugMineBlockResultForChainSpec,
},
debug_trace::{
debug_trace_transaction, execution_result_to_debug_result, DebugTraceConfig,
DebugTraceResultWithTraces, TracerEip3155,
},
debug_trace::{debug_trace_transaction, DebugTraceResultWithTraces},
error::{
CreationError, CreationErrorForChainSpec, EstimateGasFailure, ProviderErrorForChainSpec,
TransactionFailure, TransactionFailureWithTraces,
Expand All @@ -104,7 +107,7 @@ use crate::{
SyncBlockchainForChainSpec, SyncProviderSpec, TransactionAndBlockForChainSpec,
},
time::{CurrentTime, TimeSinceEpoch},
ForkConfig, MiningConfig, ProviderConfig, ProviderError, SubscriptionEvent,
DebugTraceError, ForkConfig, MiningConfig, ProviderConfig, ProviderError, SubscriptionEvent,
SubscriptionEventData, SyncSubscriberCallback,
};

Expand Down Expand Up @@ -1767,38 +1770,39 @@ where
&mut self,
transaction: ChainSpecT::SignedTransaction,
block_spec: &BlockSpec,
trace_config: DebugTraceConfig,
tracing_options: GethDebugTracingOptions,
) -> Result<
DebugTraceResultWithTraces<ChainSpecT::HaltReason>,
ProviderErrorForChainSpec<ChainSpecT>,
> {
let cfg_env = self.create_evm_config_at_block_spec(block_spec)?;

let mut debug_inspector = DebugInspector::new(tracing_options)
.map_err(DebugTraceError::from_debug_inspector_creation_error)?;

let mut evm_observer = EvmObserver::new(EvmObserverConfig {
call_override: None,
..EvmObserverConfig::from(&self.observability)
});
let mut eip3155_tracer = TracerEip3155::new(trace_config);

let custom_precompiles = self.precompile_overrides.clone();

let scheduled_blob_params = self.scheduled_blob_params().cloned();
self.execute_in_block_context(Some(block_spec), move |blockchain, block, state| {
let mut inspector = DualInspector::new(&mut eip3155_tracer, &mut evm_observer);
let block_env = ChainSpecT::BlockEnv::new_block_env(
let block_env = BlockEnvWithZeroBaseFee::new(ChainSpecT::BlockEnv::new_block_env(
block.block_header(),
cfg_env.spec,
scheduled_blob_params.as_ref(),
);
));

let result = call::run_call::<ChainSpecT, _, _, _>(
let result = guaranteed_dry_run_with_inspector::<ChainSpecT, _, _, _, _>(
blockchain,
block_env,
state.as_ref(),
cfg_env,
transaction,
transaction.clone(),
&block_env,
&custom_precompiles,
&mut inspector,
&mut DualInspector::new(&mut debug_inspector, &mut evm_observer),
)?;

let EvmObserver {
Expand All @@ -1814,10 +1818,19 @@ where
.map_err(ProviderError::OnCollectedCoverageCallback)?;
}

let debug_result =
execution_result_to_debug_result(result, trace_collector, eip3155_tracer);
let mut database = WrapDatabaseRef(DatabaseComponents {
blockchain,
state: state.as_ref(),
});

let geth_trace = debug_inspector
.get_result(None, &transaction, &block_env, &result, &mut database)
.map_err(DebugTraceError::from_debug_inspector_result_error)?;

Ok(debug_result)
Ok(DebugTraceResultWithTraces {
result: geth_trace,
traces: trace_collector.into_traces(),
})
})?
}

Expand Down Expand Up @@ -2514,7 +2527,7 @@ where
pub fn debug_trace_transaction(
&mut self,
transaction_hash: &B256,
trace_config: DebugTraceConfig,
tracing_options: GethDebugTracingOptions,
) -> Result<
DebugTraceResultWithTraces<ChainSpecT::HaltReason>,
ProviderErrorForChainSpec<ChainSpecT>,
Expand Down Expand Up @@ -2552,7 +2565,7 @@ where
blockchain,
state.clone(),
cfg_env,
trace_config,
tracing_options,
block_env,
transactions,
transaction_hash,
Expand Down
11 changes: 11 additions & 0 deletions crates/edr_provider/src/data/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,21 @@ use edr_state_api::{State, StateError};

use crate::{error::ProviderErrorForChainSpec, ProviderError};

/// A wrapper around a block environment that forces the base fee to be zero.
///
/// This is required to mimick Geth's behaviour, as its call requests use a base
/// fee of zero.
pub(super) struct BlockEnvWithZeroBaseFee<BlockEnvT: BlockEnvTrait> {
inner: BlockEnvT,
}

impl<BlockEnvT: BlockEnvTrait> BlockEnvWithZeroBaseFee<BlockEnvT> {
/// Creates a new instance wrapping the provided block environment.
pub fn new(inner: BlockEnvT) -> Self {
Self { inner }
}
}

impl<BlockEnvT: BlockEnvTrait> BlockEnvTrait for BlockEnvWithZeroBaseFee<BlockEnvT> {
fn number(&self) -> U256 {
self.inner.number()
Expand Down
Loading
Loading