@@ -136,6 +136,7 @@ where
136136 . evm_with_env ( & mut simulation_state, ctx. evm_env . clone ( ) ) ;
137137 evm. modify_cfg ( |cfg| {
138138 cfg. disable_balance_check = true ;
139+ cfg. disable_nonce_check = true ;
139140 } ) ;
140141 let calldata = IFlashtestationRegistry :: getRegistrationStatusCall {
141142 teeAddress : self . tee_service_signer . address ,
@@ -357,6 +358,207 @@ where
357358 ) )
358359 }
359360 }
361+
362+ fn get_permit_nonce (
363+ & self ,
364+ contract_address : Address ,
365+ ctx : & OpPayloadBuilderCtx < ExtraCtx > ,
366+ evm : & mut OpEvm <
367+ & mut State < StateProviderDatabase < impl StateProvider > > ,
368+ NoOpInspector ,
369+ PrecompilesMap ,
370+ > ,
371+ ) -> Result < U256 , BuilderTransactionError > {
372+ let calldata = IERC20Permit :: noncesCall {
373+ owner : self . tee_service_signer . address ,
374+ }
375+ . abi_encode ( ) ;
376+ let SimulationSuccessResult { output, .. } =
377+ self . simulate_call ( contract_address, calldata. into ( ) , None , ctx, evm) ?;
378+ U256 :: abi_decode ( & output)
379+ . map_err ( |_| BuilderTransactionError :: InvalidContract ( contract_address) )
380+ }
381+
382+ fn registration_permit_signature (
383+ & self ,
384+ permit_nonce : U256 ,
385+ ctx : & OpPayloadBuilderCtx < ExtraCtx > ,
386+ evm : & mut OpEvm <
387+ & mut State < StateProviderDatabase < impl StateProvider > > ,
388+ NoOpInspector ,
389+ PrecompilesMap ,
390+ > ,
391+ ) -> Result < Signature , BuilderTransactionError > {
392+ let struct_hash_calldata = IFlashtestationRegistry :: computeStructHashCall {
393+ rawQuote : self . attestation . clone ( ) . into ( ) ,
394+ extendedRegistrationData : self . extra_registration_data . clone ( ) ,
395+ nonce : permit_nonce,
396+ deadline : U256 :: from ( ctx. timestamp ( ) ) ,
397+ }
398+ . abi_encode ( ) ;
399+ let SimulationSuccessResult { output, .. } = self . simulate_call (
400+ self . registry_address ,
401+ struct_hash_calldata. into ( ) ,
402+ None ,
403+ ctx,
404+ evm,
405+ ) ?;
406+ let struct_hash = B256 :: abi_decode ( & output)
407+ . map_err ( |_| BuilderTransactionError :: InvalidContract ( self . registry_address ) ) ?;
408+ let typed_data_hash_calldata = IFlashtestationRegistry :: hashTypedDataV4Call {
409+ structHash : struct_hash,
410+ }
411+ . abi_encode ( ) ;
412+ let SimulationSuccessResult { output, .. } = self . simulate_call (
413+ self . registry_address ,
414+ typed_data_hash_calldata. into ( ) ,
415+ None ,
416+ ctx,
417+ evm,
418+ ) ?;
419+ let typed_data_hash = B256 :: abi_decode ( & output)
420+ . map_err ( |_| BuilderTransactionError :: InvalidContract ( self . registry_address ) ) ?;
421+ let signature = self . tee_service_signer . sign_message ( typed_data_hash) ?;
422+ Ok ( signature)
423+ }
424+
425+ fn signed_registration_permit_tx (
426+ & self ,
427+ ctx : & OpPayloadBuilderCtx < ExtraCtx > ,
428+ evm : & mut OpEvm <
429+ & mut State < StateProviderDatabase < impl StateProvider > > ,
430+ NoOpInspector ,
431+ PrecompilesMap ,
432+ > ,
433+ ) -> Result < BuilderTransactionCtx , BuilderTransactionError > {
434+ let permit_nonce = self . get_permit_nonce ( self . registry_address , ctx, evm) ?;
435+ let signature = self . registration_permit_signature ( permit_nonce, ctx, evm) ?;
436+ let calldata = IFlashtestationRegistry :: permitRegisterTEEServiceCall {
437+ rawQuote : self . attestation . clone ( ) . into ( ) ,
438+ extendedRegistrationData : self . extra_registration_data . clone ( ) ,
439+ nonce : permit_nonce,
440+ deadline : U256 :: from ( ctx. timestamp ( ) ) ,
441+ signature : signature. as_bytes ( ) . into ( ) ,
442+ }
443+ . abi_encode ( ) ;
444+ let SimulationSuccessResult { gas_used, .. } = self . simulate_call (
445+ self . registry_address ,
446+ calldata. clone ( ) . into ( ) ,
447+ Some ( TEEServiceRegistered :: SIGNATURE_HASH ) ,
448+ ctx,
449+ evm,
450+ ) ?;
451+ let signed_tx = self . sign_tx (
452+ self . registry_address ,
453+ self . builder_key ,
454+ gas_used,
455+ calldata. into ( ) ,
456+ ctx,
457+ evm. db_mut ( ) ,
458+ ) ?;
459+ let da_size =
460+ op_alloy_flz:: tx_estimated_size_fjord_bytes ( signed_tx. encoded_2718 ( ) . as_slice ( ) ) ;
461+ Ok ( BuilderTransactionCtx {
462+ gas_used,
463+ da_size,
464+ signed_tx,
465+ is_top_of_block : false ,
466+ } )
467+ }
468+
469+ fn block_proof_permit_signature (
470+ & self ,
471+ permit_nonce : U256 ,
472+ block_content_hash : B256 ,
473+ ctx : & OpPayloadBuilderCtx < ExtraCtx > ,
474+ evm : & mut OpEvm <
475+ & mut State < StateProviderDatabase < impl StateProvider > > ,
476+ NoOpInspector ,
477+ PrecompilesMap ,
478+ > ,
479+ ) -> Result < Signature , BuilderTransactionError > {
480+ let struct_hash_calldata = IBlockBuilderPolicy :: computeStructHashCall {
481+ version : self . builder_proof_version ,
482+ blockContentHash : block_content_hash,
483+ nonce : permit_nonce,
484+ }
485+ . abi_encode ( ) ;
486+ let SimulationSuccessResult { output, .. } = self . simulate_call (
487+ self . builder_policy_address ,
488+ struct_hash_calldata. into ( ) ,
489+ None ,
490+ ctx,
491+ evm,
492+ ) ?;
493+ let struct_hash = B256 :: abi_decode ( & output)
494+ . map_err ( |_| BuilderTransactionError :: InvalidContract ( self . builder_policy_address ) ) ?;
495+ let typed_data_hash_calldata = IBlockBuilderPolicy :: getHashedTypeDataV4Call {
496+ structHash : struct_hash,
497+ }
498+ . abi_encode ( ) ;
499+ let SimulationSuccessResult { output, .. } = self . simulate_call (
500+ self . builder_policy_address ,
501+ typed_data_hash_calldata. into ( ) ,
502+ None ,
503+ ctx,
504+ evm,
505+ ) ?;
506+ let typed_data_hash = B256 :: abi_decode ( & output)
507+ . map_err ( |_| BuilderTransactionError :: InvalidContract ( self . builder_policy_address ) ) ?;
508+ let signature = self . tee_service_signer . sign_message ( typed_data_hash) ?;
509+ Ok ( signature)
510+ }
511+
512+ fn signed_block_proof_permit_tx (
513+ & self ,
514+ transactions : Vec < OpTransactionSigned > ,
515+ ctx : & OpPayloadBuilderCtx < ExtraCtx > ,
516+ evm : & mut OpEvm <
517+ & mut State < StateProviderDatabase < impl StateProvider > > ,
518+ NoOpInspector ,
519+ PrecompilesMap ,
520+ > ,
521+ ) -> Result < BuilderTransactionCtx , BuilderTransactionError > {
522+ let permit_nonce = self . get_permit_nonce ( self . builder_policy_address , ctx, evm) ?;
523+ let block_content_hash = Self :: compute_block_content_hash (
524+ transactions. clone ( ) ,
525+ ctx. parent_hash ( ) ,
526+ ctx. block_number ( ) ,
527+ ctx. timestamp ( ) ,
528+ ) ;
529+ let signature =
530+ self . block_proof_permit_signature ( permit_nonce, block_content_hash, ctx, evm) ?;
531+ let calldata = IBlockBuilderPolicy :: permitVerifyBlockBuilderProofCall {
532+ blockContentHash : block_content_hash,
533+ nonce : U256 :: from ( permit_nonce) ,
534+ version : self . builder_proof_version ,
535+ eip712Sig : signature. as_bytes ( ) . into ( ) ,
536+ }
537+ . abi_encode ( ) ;
538+ let SimulationSuccessResult { gas_used, .. } = self . simulate_call (
539+ self . builder_policy_address ,
540+ calldata. clone ( ) . into ( ) ,
541+ Some ( BlockBuilderProofVerified :: SIGNATURE_HASH ) ,
542+ ctx,
543+ evm,
544+ ) ?;
545+ let signed_tx = self . sign_tx (
546+ self . builder_policy_address ,
547+ self . builder_key ,
548+ gas_used,
549+ calldata. into ( ) ,
550+ ctx,
551+ evm. db_mut ( ) ,
552+ ) ?;
553+ let da_size =
554+ op_alloy_flz:: tx_estimated_size_fjord_bytes ( signed_tx. encoded_2718 ( ) . as_slice ( ) ) ;
555+ Ok ( BuilderTransactionCtx {
556+ gas_used,
557+ da_size,
558+ signed_tx,
559+ is_top_of_block : false ,
560+ } )
561+ }
360562}
361563
362564impl < ExtraCtx , Extra > BuilderTransactions < ExtraCtx , Extra >
0 commit comments