mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
test: add testing_buildBlockV1 RPC method and Osaka test (#20990)
This commit is contained in:
@@ -2,11 +2,11 @@ use crate::{network::NetworkTestContext, payload::PayloadTestContext, rpc::RpcTe
|
||||
use alloy_consensus::{transaction::TxHashRef, BlockHeader};
|
||||
use alloy_eips::BlockId;
|
||||
use alloy_primitives::{BlockHash, BlockNumber, Bytes, Sealable, B256};
|
||||
use alloy_rpc_types_engine::ForkchoiceState;
|
||||
use alloy_rpc_types_engine::{ExecutionPayloadEnvelopeV5, ForkchoiceState};
|
||||
use alloy_rpc_types_eth::BlockNumberOrTag;
|
||||
use eyre::Ok;
|
||||
use futures_util::Future;
|
||||
use jsonrpsee::http_client::HttpClient;
|
||||
use jsonrpsee::{core::client::ClientT, http_client::HttpClient};
|
||||
use reth_chainspec::EthereumHardforks;
|
||||
use reth_network_api::test_utils::PeersHandleProvider;
|
||||
use reth_node_api::{
|
||||
@@ -20,6 +20,7 @@ use reth_provider::{
|
||||
BlockReader, BlockReaderIdExt, CanonStateNotificationStream, CanonStateSubscriptions,
|
||||
HeaderProvider, StageCheckpointReader,
|
||||
};
|
||||
use reth_rpc_api::TestingBuildBlockRequestV1;
|
||||
use reth_rpc_builder::auth::AuthServerHandle;
|
||||
use reth_rpc_eth_api::helpers::{EthApiSpec, EthTransactions, TraceExt};
|
||||
use reth_stages_types::StageId;
|
||||
@@ -319,4 +320,20 @@ where
|
||||
|
||||
Ok(crate::testsuite::NodeClient::new_with_beacon_engine(rpc, auth, url, beacon_handle))
|
||||
}
|
||||
|
||||
/// Calls the `testing_buildBlockV1` RPC on this node.
|
||||
///
|
||||
/// This endpoint builds a block using the provided parent, payload attributes, and
|
||||
/// transactions. Requires the `Testing` RPC module to be enabled.
|
||||
pub async fn testing_build_block_v1(
|
||||
&self,
|
||||
request: TestingBuildBlockRequestV1,
|
||||
) -> eyre::Result<ExecutionPayloadEnvelopeV5> {
|
||||
let client =
|
||||
self.rpc_client().ok_or_else(|| eyre::eyre!("HTTP RPC client not available"))?;
|
||||
|
||||
let res: ExecutionPayloadEnvelopeV5 =
|
||||
client.request("testing_buildBlockV1", [request]).await?;
|
||||
eyre::Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
use crate::utils::eth_payload_attributes;
|
||||
use alloy_eips::eip7685::RequestsOrHash;
|
||||
use alloy_genesis::Genesis;
|
||||
use reth_chainspec::{ChainSpecBuilder, MAINNET};
|
||||
use alloy_primitives::{Address, B256};
|
||||
use alloy_rpc_types_engine::{PayloadAttributes, PayloadStatusEnum};
|
||||
use jsonrpsee_core::client::ClientT;
|
||||
use reth_chainspec::{ChainSpecBuilder, EthChainSpec, MAINNET};
|
||||
use reth_e2e_test_utils::{
|
||||
node::NodeTestContext, setup, transaction::TransactionTestContext, wallet::Wallet,
|
||||
};
|
||||
@@ -8,6 +12,7 @@ use reth_node_builder::{NodeBuilder, NodeHandle};
|
||||
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
||||
use reth_node_ethereum::EthereumNode;
|
||||
use reth_provider::BlockNumReader;
|
||||
use reth_rpc_api::TestingBuildBlockRequestV1;
|
||||
use reth_tasks::TaskManager;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -180,3 +185,74 @@ async fn test_engine_graceful_shutdown() -> eyre::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_testing_build_block_v1_osaka() -> eyre::Result<()> {
|
||||
reth_tracing::init_test_tracing();
|
||||
let tasks = TaskManager::current();
|
||||
let exec = tasks.executor();
|
||||
|
||||
let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap();
|
||||
let chain_spec = Arc::new(
|
||||
ChainSpecBuilder::default().chain(MAINNET.chain).genesis(genesis).osaka_activated().build(),
|
||||
);
|
||||
let genesis_hash = chain_spec.genesis_hash();
|
||||
|
||||
let node_config =
|
||||
NodeConfig::test().with_chain(chain_spec.clone()).with_unused_ports().with_rpc(
|
||||
RpcServerArgs::default()
|
||||
.with_unused_ports()
|
||||
.with_http()
|
||||
.with_http_api(reth_rpc_server_types::RpcModuleSelection::All),
|
||||
);
|
||||
|
||||
let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config)
|
||||
.testing_node(exec)
|
||||
.node(EthereumNode::default())
|
||||
.launch()
|
||||
.await?;
|
||||
|
||||
let node = NodeTestContext::new(node, eth_payload_attributes).await?;
|
||||
|
||||
let wallet = Wallet::default();
|
||||
let raw_tx = TransactionTestContext::transfer_tx_bytes(1, wallet.inner).await;
|
||||
|
||||
let payload_attributes = PayloadAttributes {
|
||||
timestamp: chain_spec.genesis().timestamp + 1,
|
||||
prev_randao: B256::ZERO,
|
||||
suggested_fee_recipient: Address::ZERO,
|
||||
withdrawals: Some(vec![]),
|
||||
parent_beacon_block_root: Some(B256::ZERO),
|
||||
};
|
||||
|
||||
let request = TestingBuildBlockRequestV1 {
|
||||
parent_block_hash: genesis_hash,
|
||||
payload_attributes,
|
||||
transactions: vec![raw_tx],
|
||||
extra_data: None,
|
||||
};
|
||||
|
||||
let envelope = node.testing_build_block_v1(request).await?;
|
||||
|
||||
let engine_client = node.auth_server_handle().http_client();
|
||||
let payload = envelope.execution_payload.clone();
|
||||
let block_hash = payload.payload_inner.payload_inner.block_hash;
|
||||
|
||||
let versioned_hashes: Vec<B256> = Vec::new();
|
||||
let parent_beacon_block_root = B256::ZERO;
|
||||
let execution_requests = RequestsOrHash::Requests(envelope.execution_requests);
|
||||
|
||||
let status: alloy_rpc_types_engine::PayloadStatus = engine_client
|
||||
.request(
|
||||
"engine_newPayloadV4",
|
||||
(payload, versioned_hashes, parent_beacon_block_root, execution_requests),
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(status.status, PayloadStatusEnum::Valid);
|
||||
|
||||
node.update_forkchoice(genesis_hash, block_hash).await?;
|
||||
|
||||
node.wait_block(1, block_hash, false).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user