@@ -35,7 +35,10 @@ use strata_ol_state_types::{
3535 IAccountState , ISnarkAccountState , IStateAccessor , StateError , StateResult ,
3636} ;
3737use strata_ol_state_types_v1:: { IStateBatchApplicable , OLStateV1 , WriteBatch } ;
38- use strata_ol_stf_v1:: { BlockInfo , EpochInfo , apply_da_epoch, verify_block} ;
38+ use strata_ol_stf_v1:: {
39+ BlockInfo , EpochInfo , apply_da_epoch, verify_block, verify_block_structure,
40+ verify_header_continuity,
41+ } ;
3942use strata_primitives:: { epoch:: EpochCommitment , l1:: L1BlockCommitment } ;
4043use strata_service:: ServiceState ;
4144use strata_snark_acct_types:: Seqno ;
@@ -45,6 +48,7 @@ use crate::{
4548 ChainWorkerContextImpl ,
4649 errors:: { WorkerError , WorkerResult } ,
4750 output:: OLBlockExecutionOutput ,
51+ provenance:: validate_manifests,
4852 traits:: ChainWorkerContext ,
4953} ;
5054
@@ -324,10 +328,37 @@ fn fetch_block_with_parent(
324328 Ok ( ( block, parent_header, parent_commitment) )
325329}
326330
331+ /// Validates all block inputs without executing or persisting state.
332+ fn validate_block_inputs (
333+ ctx : & impl ChainWorkerContext ,
334+ block : & OLBlockV1 ,
335+ parent_header : Option < & OLBlockHeaderV1 > ,
336+ parent_state : & impl IStateAccessor ,
337+ ) -> WorkerResult < ( ) > {
338+ verify_header_continuity ( block. header ( ) , parent_header) ?;
339+ verify_block_structure ( block. header ( ) , block. body ( ) ) ?;
340+ if let Some ( container) = block. body ( ) . manifests ( ) {
341+ validate_manifests ( ctx, parent_state. last_l1_height ( ) , container. manifests ( ) ) ?;
342+ }
343+ Ok ( ( ) )
344+ }
345+
346+ /// Loads the parent state used by input validation and STF execution.
347+ fn fetch_parent_state (
348+ ctx : & impl ChainWorkerContext ,
349+ parent_commitment : OLBlockCommitment ,
350+ ) -> WorkerResult < MemoryStateBaseLayer > {
351+ let parent_state = ctx
352+ . fetch_ol_state ( parent_commitment) ?
353+ . ok_or ( WorkerError :: MissingPreState ( parent_commitment) ) ?;
354+ Ok ( MemoryStateBaseLayer :: new ( parent_state) )
355+ }
356+
327357/// Executes the STF on a block and returns the execution output.
328358///
329359/// This fetches parent state, builds the state stack, runs verification,
330360/// and extracts the resulting write batch and indexer writes.
361+ /// Callers classify failures; pending canonical manifests are expected during L1 catch-up.
331362#[ instrument(
332363 skip_all,
333364 fields(
@@ -336,7 +367,6 @@ fn fetch_block_with_parent(
336367 is_terminal = block. header( ) . is_terminal( ) ,
337368 %parent_commitment,
338369 ) ,
339- err,
340370) ]
341371fn execute_stf (
342372 ctx : & impl ChainWorkerContext ,
@@ -345,11 +375,8 @@ fn execute_stf(
345375 parent_header : Option < & OLBlockHeaderV1 > ,
346376 parent_commitment : OLBlockCommitment ,
347377) -> WorkerResult < ( OLBlockExecutionOutput , OLStateV1 ) > {
348- // Fetch parent state and wrap in MemoryStateBaseLayer for IStateAccessor
349- let parent_state_raw = ctx
350- . fetch_ol_state ( parent_commitment) ?
351- . ok_or ( WorkerError :: MissingPreState ( parent_commitment) ) ?;
352- let parent_state = MemoryStateBaseLayer :: new ( parent_state_raw) ;
378+ let parent_state = fetch_parent_state ( ctx, parent_commitment) ?;
379+ validate_block_inputs ( ctx, block, parent_header, & parent_state) ?;
353380
354381 // Execute and extract outputs
355382 let ( write_batch, indexer_writes, logs) =
0 commit comments