@@ -788,14 +788,15 @@ func (c *EngineClient) GetExecutionInfo(ctx context.Context, height uint64) (exe
788788 return execution.ExecutionInfo {MaxGas : gasLimit }, nil
789789}
790790
791- // FilterTxs validates force-included transactions and calculates gas for all transactions .
791+ // FilterTxs validates force-included transactions and applies gas filtering .
792792// Only transactions with forceIncludedMask[i]=true are validated for correctness.
793793// Mempool transactions (forceIncludedMask[i]=false) are passed through unchanged.
794- // Gas limiting is NOT performed by this function - the caller handles that using GasPerTx .
795- func (c * EngineClient ) FilterTxs (ctx context.Context , txs [][]byte , forceIncludedMask []bool ) (* execution.FilterTxsResult , error ) {
794+ // Gas limiting is applied to force-included transactions; remaining valid ones are returned in RemainingTxs .
795+ func (c * EngineClient ) FilterTxs (ctx context.Context , txs [][]byte , forceIncludedMask []bool , maxGas uint64 ) (* execution.FilterTxsResult , error ) {
796796 validTxs := make ([][]byte , 0 , len (txs ))
797797 validMask := make ([]bool , 0 , len (txs ))
798- gasPerTx := make ([]uint64 , 0 , len (txs ))
798+ var remainingTxs [][]byte
799+ var cumulativeGas uint64
799800
800801 for i , tx := range txs {
801802 isForceIncluded := i < len (forceIncludedMask ) && forceIncludedMask [i ]
@@ -817,32 +818,62 @@ func (c *EngineClient) FilterTxs(ctx context.Context, txs [][]byte, forceInclude
817818 continue
818819 }
819820
821+ txGas := ethTx .Gas ()
822+
823+ // Check gas limit for force-included transactions
824+ if maxGas > 0 && cumulativeGas + txGas > maxGas {
825+ // This tx and remaining force-included txs don't fit - add to remaining
826+ remainingTxs = append (remainingTxs , tx )
827+ // Continue to collect remaining valid force-included txs
828+ for j := i + 1 ; j < len (txs ); j ++ {
829+ if j < len (forceIncludedMask ) && forceIncludedMask [j ] {
830+ if len (txs [j ]) == 0 {
831+ continue
832+ }
833+ var remainingEthTx types.Transaction
834+ if err := remainingEthTx .UnmarshalBinary (txs [j ]); err != nil {
835+ c .logger .Debug ().
836+ Int ("tx_index" , j ).
837+ Err (err ).
838+ Msg ("filtering out invalid force-included transaction in remaining (gibberish)" )
839+ continue
840+ }
841+ remainingTxs = append (remainingTxs , txs [j ])
842+ } else {
843+ // Add remaining mempool txs to validTxs
844+ validTxs = append (validTxs , txs [j ])
845+ validMask = append (validMask , false )
846+ }
847+ }
848+
849+ c .logger .Debug ().
850+ Int ("valid_txs" , len (validTxs )).
851+ Int ("remaining_txs" , len (remainingTxs )).
852+ Uint64 ("cumulative_gas" , cumulativeGas ).
853+ Uint64 ("max_gas" , maxGas ).
854+ Msg ("force-included transactions exceeded gas limit, splitting batch" )
855+
856+ return & execution.FilterTxsResult {
857+ ValidTxs : validTxs ,
858+ ForceIncludedMask : validMask ,
859+ RemainingTxs : remainingTxs ,
860+ }, nil
861+ }
862+
863+ cumulativeGas += txGas
820864 validTxs = append (validTxs , tx )
821865 validMask = append (validMask , true )
822- gasPerTx = append (gasPerTx , ethTx .Gas ())
823866 } else {
824867 // Mempool transactions pass through unchanged
825- // Still calculate gas for them
826- var txGas uint64
827- if len (tx ) > 0 {
828- var ethTx types.Transaction
829- if err := ethTx .UnmarshalBinary (tx ); err == nil {
830- txGas = ethTx .Gas ()
831- }
832- // If parsing fails for mempool tx, we still include it with gas=0
833- // The execution layer will handle it during actual execution
834- }
835-
836868 validTxs = append (validTxs , tx )
837869 validMask = append (validMask , false )
838- gasPerTx = append (gasPerTx , txGas )
839870 }
840871 }
841872
842873 return & execution.FilterTxsResult {
843874 ValidTxs : validTxs ,
844875 ForceIncludedMask : validMask ,
845- GasPerTx : gasPerTx ,
876+ RemainingTxs : nil ,
846877 }, nil
847878}
848879
0 commit comments