@@ -297,3 +297,87 @@ fn meter_block_timing_consistency() -> eyre::Result<()> {
297297
298298 Ok ( ( ) )
299299}
300+
301+ // ============================================================================
302+ // Error Path Tests
303+ // ============================================================================
304+
305+ #[ test]
306+ fn meter_block_parent_header_not_found ( ) -> eyre:: Result < ( ) > {
307+ let harness = setup_harness ( ) ?;
308+
309+ // Create a block that references a non-existent parent
310+ let fake_parent_hash = B256 :: random ( ) ;
311+ let header = Header {
312+ parent_hash : fake_parent_hash, // This parent doesn't exist
313+ number : 999 ,
314+ timestamp : harness. genesis_header_timestamp + 2 ,
315+ gas_limit : 30_000_000 ,
316+ beneficiary : Address :: random ( ) ,
317+ base_fee_per_gas : Some ( 1 ) ,
318+ parent_beacon_block_root : Some ( B256 :: ZERO ) ,
319+ ..Default :: default ( )
320+ } ;
321+
322+ let body = OpBlockBody { transactions : vec ! [ ] , ommers : vec ! [ ] , withdrawals : None } ;
323+ let block = OpBlock :: new ( header, body) ;
324+
325+ let result = meter_block ( harness. provider . clone ( ) , harness. chain_spec . clone ( ) , & block) ;
326+
327+ assert ! ( result. is_err( ) , "should fail when parent header is not found" ) ;
328+ let err = result. unwrap_err ( ) ;
329+ let err_str = err. to_string ( ) ;
330+ assert ! (
331+ err_str. contains( "Parent header not found" ) || err_str. contains( "not found" ) ,
332+ "error should indicate parent header not found: {}" ,
333+ err_str
334+ ) ;
335+
336+ Ok ( ( ) )
337+ }
338+
339+ #[ test]
340+ fn meter_block_invalid_transaction_signature ( ) -> eyre:: Result < ( ) > {
341+ use alloy_consensus:: TxEip1559 ;
342+ use alloy_primitives:: Signature ;
343+
344+ let harness = setup_harness ( ) ?;
345+
346+ // Create a transaction with an invalid signature
347+ let tx = TxEip1559 {
348+ chain_id : harness. chain_spec . chain_id ( ) ,
349+ nonce : 0 ,
350+ gas_limit : 21_000 ,
351+ max_fee_per_gas : 10 ,
352+ max_priority_fee_per_gas : 1 ,
353+ to : alloy_primitives:: TxKind :: Call ( Address :: random ( ) ) ,
354+ value : alloy_primitives:: U256 :: from ( 1000 ) ,
355+ access_list : Default :: default ( ) ,
356+ input : Default :: default ( ) ,
357+ } ;
358+
359+ // Create a signature with invalid values (all zeros is invalid for secp256k1)
360+ let invalid_signature = Signature :: new (
361+ alloy_primitives:: U256 :: ZERO ,
362+ alloy_primitives:: U256 :: ZERO ,
363+ false ,
364+ ) ;
365+
366+ let signed_tx = alloy_consensus:: Signed :: new_unchecked ( tx, invalid_signature, B256 :: random ( ) ) ;
367+ let op_tx = OpTransactionSigned :: Eip1559 ( signed_tx) ;
368+
369+ let block = create_block_with_transactions ( & harness, vec ! [ op_tx] ) ;
370+
371+ let result = meter_block ( harness. provider . clone ( ) , harness. chain_spec . clone ( ) , & block) ;
372+
373+ assert ! ( result. is_err( ) , "should fail when transaction has invalid signature" ) ;
374+ let err = result. unwrap_err ( ) ;
375+ let err_str = err. to_string ( ) ;
376+ assert ! (
377+ err_str. contains( "recover signer" ) || err_str. contains( "signature" ) ,
378+ "error should indicate signer recovery failure: {}" ,
379+ err_str
380+ ) ;
381+
382+ Ok ( ( ) )
383+ }
0 commit comments