Skip to content
This repository was archived by the owner on Aug 3, 2026. It is now read-only.

Commit 50e3507

Browse files
committed
refactor: simplify core and lib modules
- core: extract helpers (build_batch_blocks, verify_parent_hash_chain, get_prover_config), fix EventFilterConditioin typo, add constants - lib: extract reth_chain_spec_for_name, active_fork_spec_id, simplify matches!/clamp/is_empty, dedupe keccak in mpt, add docs Made-with: Cursor
1 parent 57a7efc commit 50e3507

20 files changed

Lines changed: 263 additions & 372 deletions

File tree

core/src/interfaces.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -390,22 +390,16 @@ impl std::str::FromStr for BatchMetadata {
390390

391391
fn from_str(s: &str) -> Result<Self, Self::Err> {
392392
let parts: Vec<&str> = s.split(':').collect();
393-
if parts.len() != 2 {
393+
let [batch_id_str, l1_str] = parts.as_slice() else {
394394
return Err(anyhow::anyhow!(
395395
"Invalid BatchMetadata format. Expected 'batch_id:l1_inclusion_block_number'"
396396
));
397-
}
398-
399-
let batch_id = parts[0]
400-
.parse::<u64>()
401-
.map_err(|_| anyhow::anyhow!("Invalid batch_id"))?;
402-
let l1_inclusion_block_number = parts[1]
403-
.parse::<u64>()
404-
.map_err(|_| anyhow::anyhow!("Invalid l1_inclusion_block_number"))?;
405-
397+
};
406398
Ok(Self {
407-
batch_id,
408-
l1_inclusion_block_number,
399+
batch_id: batch_id_str.parse().map_err(|_| anyhow::anyhow!("Invalid batch_id"))?,
400+
l1_inclusion_block_number: l1_str
401+
.parse()
402+
.map_err(|_| anyhow::anyhow!("Invalid l1_inclusion_block_number"))?,
409403
})
410404
}
411405
}

core/src/lib.rs

Lines changed: 69 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,12 @@ impl Raiko {
5454
batch_id: self.request.batch_id,
5555
block_numbers: self.request.l2_block_numbers.clone(),
5656
l1_inclusion_block_number: self.request.l1_inclusion_block_number,
57-
l1_chain_spec: self.l1_chain_spec.to_owned(),
58-
taiko_chain_spec: self.taiko_chain_spec.to_owned(),
57+
l1_chain_spec: self.l1_chain_spec.clone(),
58+
taiko_chain_spec: self.taiko_chain_spec.clone(),
5959
prover_data: TaikoProverData {
6060
graffiti: self.request.graffiti,
6161
actual_prover: self.request.prover,
62-
checkpoint: self
63-
.request
64-
.checkpoint
65-
.clone()
66-
.map(ShastaProposalCheckpoint::into),
62+
checkpoint: self.request.checkpoint.clone().map(ShastaProposalCheckpoint::into),
6763
last_anchor_block_number: self.request.last_anchor_block_number,
6864
},
6965
blob_proof_type: self.request.blob_proof_type.clone(),
@@ -95,66 +91,31 @@ impl Raiko {
9591
builder
9692
.execute_transactions(pool_tx, false)
9793
.expect("execute");
98-
let result = builder.finalize();
99-
100-
match result {
101-
Ok(header) => {
102-
debug!("Verifying final state using provider data ...");
103-
debug!(
104-
"Final block hash derived successfully. {}",
105-
header.hash_slow()
106-
);
107-
debug!("Final block header derived successfully. {header:?}");
108-
// Check if the header is the expected one
109-
check_header(&input.block.header, &header)?;
110-
111-
Ok(GuestOutput {
112-
header: header.clone(),
113-
hash: ProtocolInstance::new(input, &header, self.request.proof_type)?
114-
.instance_hash(),
115-
})
116-
}
117-
Err(e) => {
118-
warn!("Proving bad block construction!");
119-
Err(RaikoError::Guest(
120-
raiko_lib::prover::ProverError::GuestError(e.to_string()),
121-
))
122-
}
123-
}
94+
95+
let header = builder.finalize().map_err(|e| {
96+
warn!("Proving bad block construction!");
97+
RaikoError::Guest(raiko_lib::prover::ProverError::GuestError(e.to_string()))
98+
})?;
99+
100+
debug!("Verifying final state using provider data ...");
101+
debug!("Final block hash derived successfully. {}", header.hash_slow());
102+
debug!("Final block header derived successfully. {header:?}");
103+
check_header(&input.block.header, &header)?;
104+
105+
Ok(GuestOutput {
106+
header: header.clone(),
107+
hash: ProtocolInstance::new(input, &header, self.request.proof_type)?.instance_hash(),
108+
})
124109
}
125110

126111
pub fn get_batch_output(&self, batch_input: &GuestBatchInput) -> RaikoResult<GuestBatchOutput> {
127112
info!(
128113
"Generating {} output for batch id: {}",
129114
self.request.proof_type, batch_input.taiko.batch_id
130115
);
131-
let pool_txs_list = generate_transactions_for_batch_blocks(&batch_input);
132-
let blocks = batch_input
133-
.inputs
134-
.iter()
135-
.zip(pool_txs_list)
136-
.enumerate()
137-
.try_fold(
138-
Vec::new(),
139-
|mut acc, (idx, input_and_txs)| -> RaikoResult<Vec<Block>> {
140-
let (input, txs_with_flag) = input_and_txs;
141-
let (pool_txs, _) = txs_with_flag;
142-
let output = self.single_output_for_batch(pool_txs, input, idx == 0)?;
143-
acc.push(output);
144-
Ok(acc)
145-
},
146-
)?;
147-
148-
blocks.windows(2).try_for_each(|window| {
149-
let parent = &window[0];
150-
let current = &window[1];
151-
if parent.header.hash_slow() != current.header.parent_hash {
152-
return Err(RaikoError::Guest(
153-
raiko_lib::prover::ProverError::GuestError("Parent hash mismatch".to_string()),
154-
));
155-
}
156-
Ok(())
157-
})?;
116+
let pool_txs_list = generate_transactions_for_batch_blocks(batch_input);
117+
let blocks = self.build_batch_blocks(&batch_input.inputs, &pool_txs_list)?;
118+
verify_parent_hash_chain(&blocks)?;
158119

159120
Ok(GuestBatchOutput {
160121
blocks: blocks.clone(),
@@ -163,6 +124,21 @@ impl Raiko {
163124
})
164125
}
165126

127+
fn build_batch_blocks(
128+
&self,
129+
inputs: &[GuestInput],
130+
pool_txs_list: &[(Vec<reth_primitives::TransactionSigned>, bool)],
131+
) -> RaikoResult<Vec<Block>> {
132+
inputs
133+
.iter()
134+
.zip(pool_txs_list)
135+
.enumerate()
136+
.map(|(idx, (input, (pool_txs, _)))| {
137+
self.single_output_for_batch(pool_txs.clone(), input, idx == 0)
138+
})
139+
.collect()
140+
}
141+
166142
fn single_output_for_batch(
167143
&self,
168144
origin_pool_txs: Vec<reth_primitives::TransactionSigned>,
@@ -174,38 +150,27 @@ impl Raiko {
174150
.set_is_first_block_in_proposal(is_first_block_in_proposal);
175151

176152
let mut pool_txs = vec![input.taiko.anchor_tx.clone().unwrap()];
177-
pool_txs.extend_from_slice(&origin_pool_txs);
153+
pool_txs.extend(origin_pool_txs);
178154

179155
builder
180156
.execute_transactions(pool_txs, false)
181157
.expect("execute");
182-
let result = builder.finalize_block();
183-
184-
match result {
185-
Ok(block) => {
186-
let header = block.header.clone();
187-
debug!(
188-
"Verifying final block {} state using provider data ...",
189-
header.number
190-
);
191-
debug!(
192-
"Final block {} hash derived successfully. {}",
193-
header.number,
194-
header.hash_slow()
195-
);
196-
debug!("Final block derived successfully. {block:?}");
197-
// Check if the header is the expected one
198-
check_header(&input.block.header, &header)?;
199-
200-
Ok(block.clone())
201-
}
202-
Err(e) => {
203-
warn!("Proving bad block construction!");
204-
Err(RaikoError::Guest(
205-
raiko_lib::prover::ProverError::GuestError(e.to_string()),
206-
))
207-
}
208-
}
158+
let block = builder.finalize_block().map_err(|e| {
159+
warn!("Proving bad block construction!");
160+
RaikoError::Guest(raiko_lib::prover::ProverError::GuestError(e.to_string()))
161+
})?;
162+
163+
let header = &block.header;
164+
debug!("Verifying final block {} state using provider data ...", header.number);
165+
debug!("Final block {} hash derived successfully. {}", header.number, header.hash_slow());
166+
debug!("Final block derived successfully. {block:?}");
167+
check_header(&input.block.header, header)?;
168+
169+
Ok(block)
170+
}
171+
172+
fn get_prover_config(&self) -> RaikoResult<Value> {
173+
serde_json::to_value(&self.request).map_err(Into::into)
209174
}
210175

211176
pub async fn prove(
@@ -214,7 +179,7 @@ impl Raiko {
214179
output: &GuestOutput,
215180
store: Option<&mut dyn IdWrite>,
216181
) -> RaikoResult<Proof> {
217-
let config = serde_json::to_value(&self.request)?;
182+
let config = self.get_prover_config()?;
218183
run_prover(self.request.proof_type, input, output, &config, store).await
219184
}
220185

@@ -224,7 +189,7 @@ impl Raiko {
224189
output: &GuestBatchOutput,
225190
store: Option<&mut dyn IdWrite>,
226191
) -> RaikoResult<Proof> {
227-
let config = serde_json::to_value(&self.request)?;
192+
let config = self.get_prover_config()?;
228193
run_batch_prover(self.request.proof_type, input, output, &config, store).await
229194
}
230195

@@ -234,7 +199,7 @@ impl Raiko {
234199
output: &GuestBatchOutput,
235200
store: Option<&mut dyn IdWrite>,
236201
) -> RaikoResult<Proof> {
237-
let config = serde_json::to_value(&self.request)?;
202+
let config = self.get_prover_config()?;
238203
run_shasta_proposal_prover(self.request.proof_type, input, output, &config, store).await
239204
}
240205

@@ -247,6 +212,18 @@ impl Raiko {
247212
}
248213
}
249214

215+
fn verify_parent_hash_chain(blocks: &[Block]) -> RaikoResult<()> {
216+
for window in blocks.windows(2) {
217+
let (parent, current) = (&window[0], &window[1]);
218+
if parent.header.hash_slow() != current.header.parent_hash {
219+
return Err(RaikoError::Guest(
220+
raiko_lib::prover::ProverError::GuestError("Parent hash mismatch".to_string()),
221+
));
222+
}
223+
}
224+
Ok(())
225+
}
226+
250227
fn check_header(exp: &Header, header: &Header) -> Result<(), RaikoError> {
251228
// Check against the expected value of all fields for easy debugability
252229
check_eq(&exp.parent_hash, &header.parent_hash, "parent_hash");
@@ -290,7 +267,7 @@ fn check_header(exp: &Header, header: &Header) -> Result<(), RaikoError> {
290267
);
291268
check_eq(&exp.extra_data, &header.extra_data, "extra_data");
292269

293-
// Make sure the blockhash from the node matches the one from the builder
270+
// Block hash must match: node-provided header vs builder-derived header
294271
require_eq(
295272
&exp.hash_slow(),
296273
&header.hash_slow(),
@@ -299,8 +276,6 @@ fn check_header(exp: &Header, header: &Header) -> Result<(), RaikoError> {
299276
}
300277

301278
fn check_eq<T: std::cmp::PartialEq + std::fmt::Debug>(expected: &T, actual: &T, message: &str) {
302-
// printing out error, if any, but ignoring the result
303-
// making sure it's not optimized out
304279
let _ = black_box(require_eq(expected, actual, message));
305280
}
306281

core/src/preflight/lru.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22
use lazy_static::lazy_static;
33
use std::{collections::HashMap, num::NonZeroUsize, sync::Mutex};
44

5+
use lru::LruCache;
56
use raiko_lib::mem_db::MemDb;
67
use reth_primitives::{Header, B256};
78
use tracing::debug;
89

9-
use lru::LruCache;
10-
1110
type ChainBlockCacheKey = (u64, B256);
1211
type ChainBlockCacheEntry = (MemDb, HashMap<u64, Header>);
1312

13+
const LRU_CAPACITY: usize = 256;
14+
1415
lazy_static! {
1516
static ref HISTORY_STATE_DB: Mutex<LruCache<ChainBlockCacheKey, ChainBlockCacheEntry>> =
16-
Mutex::new(LruCache::<ChainBlockCacheKey, ChainBlockCacheEntry>::new(
17-
NonZeroUsize::new(256).unwrap()
18-
));
17+
Mutex::new(LruCache::new(NonZeroUsize::new(LRU_CAPACITY).unwrap()));
1918
}
2019

2120
#[cfg(test)]

core/src/preflight/mod.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use std::{collections::HashSet, env};
22

3+
/// Default number of blocks to process per prefetch task.
4+
const PREFETCH_CHUNK_SIZE_DEFAULT: usize = 7;
5+
36
use crate::{
47
interfaces::{RaikoError, RaikoResult},
58
provider::{db::ProviderDb, rpc::RpcBlockDataProvider, BlockDataProvider},
@@ -76,10 +79,8 @@ pub async fn batch_preflight<BDP: BlockDataProvider>(
7679
)
7780
};
7881

79-
let l2_block_numbers: Vec<(u64, Option<u64>)> = block_numbers
80-
.iter()
81-
.map(|&block_number| (block_number, None))
82-
.collect::<Vec<(u64, Option<u64>)>>();
82+
let l2_block_numbers: Vec<(u64, Option<u64>)> =
83+
block_numbers.iter().map(|&n| (n, None)).collect();
8384
info!(
8485
"batch preflight {} l2_block_numbers: {:?} to {:?}.",
8586
l2_block_numbers.len(),
@@ -139,11 +140,12 @@ pub async fn batch_preflight<BDP: BlockDataProvider>(
139140

140141
assert_eq!(block_parent_pairs.len(), pool_txs_list.len());
141142

142-
let mut handles = Vec::new();
143143
let chunk_size = env::var("PREFETCH_CHUNK_SIZE")
144-
.unwrap_or("10".to_owned())
145-
.parse()
146-
.unwrap_or(10);
144+
.ok()
145+
.and_then(|s| s.parse().ok())
146+
.unwrap_or(PREFETCH_CHUNK_SIZE_DEFAULT);
147+
148+
let mut handles = Vec::new();
147149
let tasks: Vec<(
148150
(reth_primitives::Block, alloy_rpc_types::Block),
149151
(Vec<TransactionSigned>, bool),

0 commit comments

Comments
 (0)