mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
feat(test): add rpc e2e tests (#17284)
This commit is contained in:
@@ -63,6 +63,7 @@ alloy-rpc-types-engine.workspace = true
|
||||
alloy-network.workspace = true
|
||||
alloy-consensus = { workspace = true, features = ["kzg"] }
|
||||
alloy-provider = { workspace = true, features = ["reqwest"] }
|
||||
alloy-genesis.workspace = true
|
||||
|
||||
futures-util.workspace = true
|
||||
eyre.workspace = true
|
||||
|
||||
@@ -53,6 +53,9 @@ impl std::fmt::Debug for ChainImportResult {
|
||||
/// Note: This function is currently specific to `EthereumNode` because the import process
|
||||
/// uses Ethereum-specific consensus and block format. It can be made generic in the future
|
||||
/// by abstracting the import process.
|
||||
/// It uses `NoopConsensus` during import to bypass validation checks like gas limit constraints,
|
||||
/// which allows importing test chains that may not strictly conform to mainnet consensus rules. The
|
||||
/// nodes themselves still run with proper consensus when started.
|
||||
pub async fn setup_engine_with_chain_import(
|
||||
num_nodes: usize,
|
||||
chain_spec: Arc<ChainSpec>,
|
||||
@@ -128,12 +131,14 @@ pub async fn setup_engine_with_chain_import(
|
||||
reth_db_common::init::init_genesis(&provider_factory)?;
|
||||
|
||||
// Import the chain data
|
||||
// Use no_state to skip state validation for test chains
|
||||
let import_config = ImportConfig::default();
|
||||
let config = Config::default();
|
||||
|
||||
// Create EVM and consensus for Ethereum
|
||||
let evm_config = reth_node_ethereum::EthEvmConfig::new(chain_spec.clone());
|
||||
let consensus = reth_ethereum_consensus::EthBeaconConsensus::new(chain_spec.clone());
|
||||
// Use NoopConsensus to skip gas limit validation for test imports
|
||||
let consensus = reth_consensus::noop::NoopConsensus::arc();
|
||||
|
||||
let result = import_blocks_from_file(
|
||||
rlp_path,
|
||||
@@ -141,7 +146,7 @@ pub async fn setup_engine_with_chain_import(
|
||||
provider_factory.clone(),
|
||||
&config,
|
||||
evm_config,
|
||||
Arc::new(consensus),
|
||||
consensus,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -248,7 +253,8 @@ pub fn load_forkchoice_state(path: &Path) -> eyre::Result<alloy_rpc_types_engine
|
||||
let json_str = std::fs::read_to_string(path)?;
|
||||
let fcu_data: serde_json::Value = serde_json::from_str(&json_str)?;
|
||||
|
||||
let state = &fcu_data["forkchoiceState"];
|
||||
// The headfcu.json file contains a JSON-RPC request with the forkchoice state in params[0]
|
||||
let state = &fcu_data["params"][0];
|
||||
Ok(alloy_rpc_types_engine::ForkchoiceState {
|
||||
head_block_hash: state["headBlockHash"]
|
||||
.as_str()
|
||||
@@ -330,7 +336,8 @@ mod tests {
|
||||
let import_config = ImportConfig::default();
|
||||
let config = Config::default();
|
||||
let evm_config = reth_node_ethereum::EthEvmConfig::new(chain_spec.clone());
|
||||
let consensus = reth_ethereum_consensus::EthBeaconConsensus::new(chain_spec.clone());
|
||||
// Use NoopConsensus to skip gas limit validation for test imports
|
||||
let consensus = reth_consensus::noop::NoopConsensus::arc();
|
||||
|
||||
let result = import_blocks_from_file(
|
||||
&rlp_path,
|
||||
@@ -338,7 +345,7 @@ mod tests {
|
||||
provider_factory.clone(),
|
||||
&config,
|
||||
evm_config,
|
||||
Arc::new(consensus),
|
||||
consensus,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -480,7 +487,8 @@ mod tests {
|
||||
let import_config = ImportConfig::default();
|
||||
let config = Config::default();
|
||||
let evm_config = reth_node_ethereum::EthEvmConfig::new(chain_spec.clone());
|
||||
let consensus = reth_ethereum_consensus::EthBeaconConsensus::new(chain_spec.clone());
|
||||
// Use NoopConsensus to skip gas limit validation for test imports
|
||||
let consensus = reth_consensus::noop::NoopConsensus::arc();
|
||||
|
||||
let result = import_blocks_from_file(
|
||||
&rlp_path,
|
||||
@@ -488,7 +496,7 @@ mod tests {
|
||||
provider_factory.clone(),
|
||||
&config,
|
||||
evm_config,
|
||||
Arc::new(consensus),
|
||||
consensus,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -176,10 +176,10 @@ pub fn write_blocks_to_rlp(blocks: &[SealedBlock], path: &Path) -> std::io::Resu
|
||||
/// Create FCU JSON for the tip of the chain
|
||||
pub fn create_fcu_json(tip: &SealedBlock) -> serde_json::Value {
|
||||
serde_json::json!({
|
||||
"forkchoiceState": {
|
||||
"params": [{
|
||||
"headBlockHash": format!("0x{:x}", tip.hash()),
|
||||
"safeBlockHash": format!("0x{:x}", tip.hash()),
|
||||
"finalizedBlockHash": format!("0x{:x}", tip.hash()),
|
||||
}
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
@@ -293,6 +293,17 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the test setup with chain import from RLP file
|
||||
pub fn with_setup_and_import(
|
||||
mut self,
|
||||
mut setup: Setup<I>,
|
||||
rlp_path: impl Into<std::path::PathBuf>,
|
||||
) -> Self {
|
||||
setup.import_rlp_path = Some(rlp_path.into());
|
||||
self.setup = Some(setup);
|
||||
self
|
||||
}
|
||||
|
||||
/// Add an action to the test
|
||||
pub fn with_action<A>(mut self, action: A) -> Self
|
||||
where
|
||||
|
||||
@@ -46,6 +46,8 @@ pub struct Setup<I> {
|
||||
/// Holds the import result to keep nodes alive when using imported chain
|
||||
/// This is stored as an option to avoid lifetime issues with `tokio::spawn`
|
||||
import_result_holder: Option<crate::setup_import::ChainImportResult>,
|
||||
/// Path to RLP file to import during setup
|
||||
pub import_rlp_path: Option<std::path::PathBuf>,
|
||||
}
|
||||
|
||||
impl<I> Default for Setup<I> {
|
||||
@@ -61,6 +63,7 @@ impl<I> Default for Setup<I> {
|
||||
is_dev: true,
|
||||
_phantom: Default::default(),
|
||||
import_result_holder: None,
|
||||
import_rlp_path: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,6 +177,10 @@ where
|
||||
<<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes,
|
||||
>,
|
||||
{
|
||||
// If import_rlp_path is set, use apply_with_import instead
|
||||
if let Some(rlp_path) = self.import_rlp_path.take() {
|
||||
return self.apply_with_import::<N>(env, &rlp_path).await;
|
||||
}
|
||||
let chain_spec =
|
||||
self.chain_spec.clone().ok_or_else(|| eyre!("Chain specification is required"))?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user