feat(reth-optimism-node): Add OP E2E mineblock test with isthmus activated at genesis (#19305)

This commit is contained in:
Mablr
2025-10-28 21:13:44 +01:00
committed by GitHub
parent 6651ae7852
commit adb4f48471
2 changed files with 99 additions and 19 deletions

View File

@@ -98,31 +98,66 @@ where
finalized_block_hash: parent_hash,
};
let fcu_result = EngineApiClient::<Engine>::fork_choice_updated_v2(
// Try v2 first for backwards compatibility, fall back to v3 on error.
match EngineApiClient::<Engine>::fork_choice_updated_v2(
&engine_client,
fork_choice_state,
Some(self.payload_attributes.clone()),
)
.await?;
debug!("FCU result: {:?}", fcu_result);
// check if we got a valid payload ID
match fcu_result.payload_status.status {
PayloadStatusEnum::Valid => {
if let Some(payload_id) = fcu_result.payload_id {
debug!("Got payload ID: {payload_id}");
// get the payload that was built
let _engine_payload =
EngineApiClient::<Engine>::get_payload_v2(&engine_client, payload_id)
.await
{
Ok(fcu_result) => {
debug!(?fcu_result, "FCU v2 result");
match fcu_result.payload_status.status {
PayloadStatusEnum::Valid => {
if let Some(payload_id) = fcu_result.payload_id {
debug!(id=%payload_id, "Got payload");
let _engine_payload = EngineApiClient::<Engine>::get_payload_v2(
&engine_client,
payload_id,
)
.await?;
Ok(())
} else {
Err(eyre::eyre!("No payload ID returned from forkchoiceUpdated"))
Ok(())
} else {
Err(eyre::eyre!("No payload ID returned from forkchoiceUpdated"))
}
}
_ => Err(eyre::eyre!(
"Payload status not valid: {:?}",
fcu_result.payload_status
))?,
}
}
Err(_) => {
// If v2 fails due to unsupported fork/missing fields, try v3
let fcu_result = EngineApiClient::<Engine>::fork_choice_updated_v3(
&engine_client,
fork_choice_state,
Some(self.payload_attributes.clone()),
)
.await?;
debug!(?fcu_result, "FCU v3 result");
match fcu_result.payload_status.status {
PayloadStatusEnum::Valid => {
if let Some(payload_id) = fcu_result.payload_id {
debug!(id=%payload_id, "Got payload");
let _engine_payload = EngineApiClient::<Engine>::get_payload_v3(
&engine_client,
payload_id,
)
.await?;
Ok(())
} else {
Err(eyre::eyre!("No payload ID returned from forkchoiceUpdated"))
}
}
_ => Err(eyre::eyre!(
"Payload status not valid: {:?}",
fcu_result.payload_status
)),
}
}
_ => Err(eyre::eyre!("Payload status not valid: {:?}", fcu_result.payload_status)),
}
})
}

View File

@@ -1,4 +1,4 @@
use alloy_primitives::{Address, B256};
use alloy_primitives::{Address, B256, B64};
use eyre::Result;
use op_alloy_rpc_types_engine::OpPayloadAttributes;
use reth_e2e_test_utils::testsuite::{
@@ -53,3 +53,48 @@ async fn test_testsuite_op_assert_mine_block() -> Result<()> {
Ok(())
}
#[tokio::test]
async fn test_testsuite_op_assert_mine_block_isthmus_activated() -> Result<()> {
reth_tracing::init_test_tracing();
let setup = Setup::default()
.with_chain_spec(Arc::new(
OpChainSpecBuilder::default()
.chain(OP_MAINNET.chain)
.genesis(serde_json::from_str(include_str!("../assets/genesis.json")).unwrap())
.isthmus_activated()
.build()
.into(),
))
.with_network(NetworkSetup::single_node());
let test =
TestBuilder::new().with_setup(setup).with_action(AssertMineBlock::<OpEngineTypes>::new(
0,
vec![],
Some(B256::ZERO),
// TODO: refactor once we have actions to generate payload attributes.
OpPayloadAttributes {
payload_attributes: alloy_rpc_types_engine::PayloadAttributes {
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
prev_randao: B256::random(),
suggested_fee_recipient: Address::random(),
withdrawals: Some(vec![]),
parent_beacon_block_root: Some(B256::ZERO),
},
transactions: None,
no_tx_pool: None,
eip_1559_params: Some(B64::ZERO),
min_base_fee: None,
gas_limit: Some(30_000_000),
},
));
test.run::<OpNode>().await?;
Ok(())
}