use alloy_primitives::B256;
use reth_optimism_primitives::bedrock::{BEDROCK_HEADER, BEDROCK_HEADER_HASH, BEDROCK_HEADER_TTD};
use reth_primitives::{
BlockBody, BlockNumber, Header, SealedBlock, SealedBlockWithSenders, SealedHeader,
StaticFileSegment, U256,
};
use reth_provider::{
providers::StaticFileProvider, BlockWriter, StageCheckpointWriter, StaticFileWriter,
};
use reth_stages::{StageCheckpoint, StageId};
use tracing::info;
pub(crate) fn setup_op_mainnet_without_ovm<Provider>(
provider_rw: &Provider,
static_file_provider: &StaticFileProvider,
) -> Result<(), eyre::Error>
where
Provider: StageCheckpointWriter + BlockWriter,
{
info!(target: "reth::cli", "Setting up dummy OVM chain before importing state.");
append_dummy_chain(static_file_provider, BEDROCK_HEADER.number - 1)?;
info!(target: "reth::cli", "Appending Bedrock block.");
append_bedrock_block(provider_rw, static_file_provider)?;
for stage in StageId::ALL {
provider_rw.save_stage_checkpoint(stage, StageCheckpoint::new(BEDROCK_HEADER.number))?;
}
info!(target: "reth::cli", "Set up finished.");
Ok(())
}
fn append_bedrock_block(
provider_rw: impl BlockWriter,
sf_provider: &StaticFileProvider,
) -> Result<(), eyre::Error> {
provider_rw.insert_block(
SealedBlockWithSenders::new(
SealedBlock::new(
SealedHeader::new(BEDROCK_HEADER, BEDROCK_HEADER_HASH),
BlockBody::default(),
),
vec![],
)
.expect("no senders or txes"),
)?;
sf_provider.latest_writer(StaticFileSegment::Headers)?.append_header(
&BEDROCK_HEADER,
BEDROCK_HEADER_TTD,
&BEDROCK_HEADER_HASH,
)?;
sf_provider
.latest_writer(StaticFileSegment::Receipts)?
.increment_block(BEDROCK_HEADER.number)?;
sf_provider
.latest_writer(StaticFileSegment::Transactions)?
.increment_block(BEDROCK_HEADER.number)?;
Ok(())
}
fn append_dummy_chain(
sf_provider: &StaticFileProvider,
target_height: BlockNumber,
) -> Result<(), eyre::Error> {
let (tx, rx) = std::sync::mpsc::channel();
for segment in [StaticFileSegment::Transactions, StaticFileSegment::Receipts] {
let tx_clone = tx.clone();
let provider = sf_provider.clone();
std::thread::spawn(move || {
let result = provider.latest_writer(segment).and_then(|mut writer| {
for block_num in 1..=target_height {
writer.increment_block(block_num)?;
}
Ok(())
});
tx_clone.send(result).unwrap();
});
}
let provider = sf_provider.clone();
std::thread::spawn(move || {
let mut empty_header = Header::default();
let result = provider.latest_writer(StaticFileSegment::Headers).and_then(|mut writer| {
for block_num in 1..=target_height {
empty_header.number = block_num;
writer.append_header(&empty_header, U256::ZERO, &B256::ZERO)?;
}
Ok(())
});
tx.send(result).unwrap();
});
while let Ok(r) = rx.recv() {
r?;
}
for segment in
[StaticFileSegment::Headers, StaticFileSegment::Receipts, StaticFileSegment::Transactions]
{
assert_eq!(
sf_provider.latest_writer(segment)?.user_header().block_end(),
Some(target_height),
"Static file segment {segment} was unsuccessful advancing its block height."
);
}
Ok(())
}