Skip to content

Commit d1cdaf6

Browse files
authored
Allow debug-bench-machine to read execution payloads from json (#712)
## 📝 Summary Allows to reproduce blocks submitted to the MEV-Boost relay from the error storage. ## 💡 Motivation and Context <!--- (Optional) Why is this change required? What problem does it solve? Remove this section if not applicable. --> --- ## ✅ I have completed the following steps: * [ ] Run `make lint` * [ ] Run `make test` * [ ] Added tests (if applicable)
1 parent a73f5ec commit d1cdaf6

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

crates/rbuilder/src/bin/debug-bench-machine.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
//! App to benchmark/test the tx block execution.
22
//! This only works when reth node is stopped and the chain moved forward from its synced state
33
//! It downloads block after the last one synced and re-executes all the txs in it.
4+
use alloy_consensus::TxEnvelope;
5+
use alloy_eips::Decodable2718;
46
use alloy_provider::Provider;
57
use clap::Parser;
68
use eyre::Context;
@@ -11,9 +13,11 @@ use rbuilder::{
1113
PartialBlock, PartialBlockFork, ThreadBlockBuildingContext,
1214
},
1315
live_builder::{base_config::load_config_toml_and_env, cli::LiveBuilderConfig, config::Config},
16+
mev_boost::submission::SubmitBlockRequest,
1417
provider::StateProviderFactory,
1518
utils::{extract_onchain_block_txs, find_suggested_fee_recipient, http_provider, Signer},
1619
};
20+
use reth_primitives_traits::SignerRecoverable;
1721
use reth_provider::StateProvider;
1822
use std::{path::PathBuf, sync::Arc, time::Instant};
1923
use tracing::{debug, info};
@@ -31,6 +35,11 @@ struct Cli {
3135
rpc_url: String,
3236
#[clap(long, help = "Config file path", env = "RBUILDER_CONFIG")]
3337
config: PathBuf,
38+
#[clap(
39+
long,
40+
help = "Path to submit block request to replay to use instead of the onchain block"
41+
)]
42+
submit_block_request_json: Option<PathBuf>,
3443
}
3544

3645
#[tokio::main]
@@ -54,6 +63,15 @@ async fn main() -> eyre::Result<()> {
5463
.await?
5564
.ok_or_else(|| eyre::eyre!("block not found on rpc"))?;
5665

66+
let onchain_block = if let Some(submit_block_request_json) = cli.submit_block_request_json {
67+
let mut block = read_execution_payload_from_json(submit_block_request_json)?;
68+
// without parent_beacon_block_root we can't build block and its not available in submit_block_request_json
69+
block.header.parent_beacon_block_root = onchain_block.header.parent_beacon_block_root;
70+
block
71+
} else {
72+
onchain_block
73+
};
74+
5775
let txs = extract_onchain_block_txs(&onchain_block)?;
5876
let suggested_fee_recipient = find_suggested_fee_recipient(&onchain_block, &txs);
5977
info!(
@@ -99,15 +117,19 @@ async fn main() -> eyre::Result<()> {
99117

100118
let build_time = Instant::now();
101119

120+
partial_block.pre_block_call(&ctx, &mut local_ctx, &mut state)?;
121+
102122
let mut space_state = BlockBuildingSpaceState::ZERO;
103123
for (idx, tx) in txs.into_iter().enumerate() {
104124
let result = {
105125
let mut fork = PartialBlockFork::new(&mut state, &ctx, &mut local_ctx);
126+
106127
fork.commit_tx(&tx, space_state)?.with_context(|| {
107128
format!("Failed to commit tx: {} {:?}", idx, tx.hash())
108129
})?
109130
};
110131
space_state.use_space(result.space_used());
132+
partial_block.executed_tx_infos.push(result.tx_info);
111133
}
112134

113135
let build_time = build_time.elapsed();
@@ -140,6 +162,27 @@ async fn main() -> eyre::Result<()> {
140162
Ok(())
141163
}
142164

165+
fn read_execution_payload_from_json(path: PathBuf) -> eyre::Result<alloy_rpc_types::Block> {
166+
let req = std::fs::read_to_string(&path)?;
167+
let req: SubmitBlockRequest = serde_json::from_str(&req)?;
168+
let block_raw = match req {
169+
SubmitBlockRequest::Capella(req) => req.execution_payload.clone().into_block_raw()?,
170+
SubmitBlockRequest::Fulu(req) => req.execution_payload.clone().into_block_raw()?,
171+
SubmitBlockRequest::Deneb(req) => req.execution_payload.clone().into_block_raw()?,
172+
SubmitBlockRequest::Electra(req) => req.execution_payload.clone().into_block_raw()?,
173+
};
174+
let rpc_block = alloy_rpc_types::Block::from_consensus(block_raw, None);
175+
let rpc_block = rpc_block.try_map_transactions(|bytes| -> eyre::Result<_> {
176+
let envelope = TxEnvelope::decode_2718(&mut bytes.as_ref())?;
177+
let recovered = envelope.try_into_recovered()?;
178+
Ok(alloy_rpc_types::Transaction::from_transaction(
179+
recovered,
180+
alloy_rpc_types::TransactionInfo::default(),
181+
))
182+
})?;
183+
Ok(rpc_block)
184+
}
185+
143186
fn report_time_data(action: &str, data: &[u128]) {
144187
let mean = data.iter().sum::<u128>() as f64 / data.len() as f64;
145188
let median = *data.iter().sorted().nth(data.len() / 2).unwrap();

0 commit comments

Comments
 (0)