@@ -659,6 +659,70 @@ pub fn get_pending_partial_withdrawals<E: EthSpec>(
659659 Ok ( Some ( processed_count) )
660660}
661661
662+ /// Get withdrawals from the builders sweep.
663+ ///
664+ /// This function iterates through builders starting from `next_withdrawal_builder_index`
665+ /// and adds withdrawals for builders whose withdrawable_epoch has been reached and have balance.
666+ ///
667+ /// https://ethereum.github.io/consensus-specs/specs/gloas/beacon-chain/#new-get_builders_sweep_withdrawals
668+ pub fn get_builders_sweep_withdrawals < E : EthSpec > (
669+ state : & BeaconState < E > ,
670+ withdrawal_index : & mut u64 ,
671+ withdrawals : & mut Vec < Withdrawal > ,
672+ ) -> Result < Option < u64 > , BlockProcessingError > {
673+ let Ok ( builders) = state. builders ( ) else {
674+ // Pre-Gloas, nothing to do.
675+ return Ok ( None ) ;
676+ } ;
677+
678+ if builders. is_empty ( ) {
679+ return Ok ( Some ( 0 ) ) ;
680+ }
681+
682+ let epoch = state. current_epoch ( ) ;
683+ let builders_limit = std:: cmp:: min ( builders. len ( ) , E :: max_builders_per_withdrawals_sweep ( ) ) ;
684+ // Reserve one slot for validator sweep withdrawals
685+ let withdrawals_limit = E :: max_withdrawals_per_payload ( ) . saturating_sub ( 1 ) ;
686+
687+ block_verify ! (
688+ withdrawals. len( ) <= withdrawals_limit,
689+ BlockProcessingError :: WithdrawalsLimitExceeded {
690+ limit: withdrawals_limit,
691+ prior_withdrawals: withdrawals. len( )
692+ }
693+ ) ;
694+
695+ let mut processed_count: u64 = 0 ;
696+ let mut builder_index = state. next_withdrawal_builder_index ( ) ?;
697+
698+ for _ in 0 ..builders_limit {
699+ if withdrawals. len ( ) >= withdrawals_limit {
700+ break ;
701+ }
702+
703+ let builder = builders
704+ . get ( builder_index as usize )
705+ . ok_or ( BeaconStateError :: UnknownBuilder ( builder_index) ) ?;
706+
707+ if builder. withdrawable_epoch <= epoch && builder. balance > 0 {
708+ withdrawals. push ( Withdrawal {
709+ index : * withdrawal_index,
710+ validator_index : convert_builder_index_to_validator_index ( builder_index) ,
711+ address : builder. execution_address ,
712+ amount : builder. balance ,
713+ } ) ;
714+ withdrawal_index. safe_add_assign ( 1 ) ?;
715+ }
716+
717+ builder_index = builder_index
718+ . safe_add ( 1 ) ?
719+ . safe_rem ( builders. len ( ) as u64 ) ?;
720+ processed_count. safe_add_assign ( 1 ) ?;
721+ }
722+
723+ Ok ( Some ( processed_count) )
724+ }
725+
662726/// Get withdrawals from the validator sweep.
663727///
664728/// This function iterates through validators starting from `next_withdrawal_validator_index`
@@ -737,7 +801,7 @@ pub fn get_validators_sweep_withdrawals<E: EthSpec>(
737801pub fn get_expected_withdrawals < E : EthSpec > (
738802 state : & BeaconState < E > ,
739803 spec : & ChainSpec ,
740- ) -> Result < ( Withdrawals < E > , Option < usize > , Option < usize > , u64 ) , BlockProcessingError > {
804+ ) -> Result < ( Withdrawals < E > , Option < usize > , Option < usize > , Option < u64 > , u64 ) , BlockProcessingError > {
741805 let mut withdrawal_index = state. next_withdrawal_index ( ) ?;
742806 let mut withdrawals = Vec :: < Withdrawal > :: with_capacity ( E :: max_withdrawals_per_payload ( ) ) ;
743807
@@ -751,6 +815,11 @@ pub fn get_expected_withdrawals<E: EthSpec>(
751815 let processed_partial_withdrawals_count =
752816 get_pending_partial_withdrawals ( state, & mut withdrawal_index, & mut withdrawals, spec) ?;
753817
818+ // [New in Gloas:EIP7732]
819+ // Get builders sweep withdrawals
820+ let processed_builders_sweep_count =
821+ get_builders_sweep_withdrawals ( state, & mut withdrawal_index, & mut withdrawals) ?;
822+
754823 // Get validators sweep withdrawals
755824 let processed_validators_sweep_count =
756825 get_validators_sweep_withdrawals ( state, & mut withdrawal_index, & mut withdrawals, spec) ?;
@@ -761,6 +830,7 @@ pub fn get_expected_withdrawals<E: EthSpec>(
761830 . map_err ( BlockProcessingError :: SszTypesError ) ?,
762831 processed_builder_withdrawals_count,
763832 processed_partial_withdrawals_count,
833+ processed_builders_sweep_count,
764834 processed_validators_sweep_count,
765835 ) )
766836}
0 commit comments