@@ -614,17 +614,58 @@ impl<R: Runtime + Send + Sync> transaction::dispatcher::Dispatcher for Dispatche
614614 rt_ctx,
615615 |ctx| -> Result < Vec < ExecuteTxResult > , RuntimeError > {
616616 // Execute incoming messages.
617+ let in_msgs_gas_limit = R :: Core :: remaining_in_msgs_gas ( ctx) ;
618+ let mut in_msgs_processed = 0usize ;
617619 for in_msg in in_msgs {
618620 let data = Self :: decode_in_msg ( in_msg) . unwrap_or_else ( |err| {
619621 warn ! ( ctx. get_logger( "dispatcher" ) , "incoming message data malformed" ; "id" => in_msg. id, "err" => ?err) ;
620622 IncomingMessageData :: noop ( )
621623 } ) ;
622- let tx = data. ut . as_ref ( ) . and_then ( |ut| Self :: decode_tx ( ctx, ut) . map_err ( |err| {
623- warn ! ( ctx. get_logger( "dispatcher" ) , "incoming message transaction malformed" ; "id" => in_msg. id, "err" => ?err) ;
624- } ) . ok ( ) ) ;
624+ let tx = match data. ut . as_ref ( ) {
625+ Some ( ut) => {
626+ match Self :: decode_tx ( ctx, ut) {
627+ Ok ( tx) => {
628+ let remaining_gas = R :: Core :: remaining_in_msgs_gas ( ctx) ;
629+ if remaining_gas < cfg. min_remaining_gas {
630+ // This next message has a transaction, but we won't have
631+ // enough gas to execute it, so leave it for the next
632+ // round and stop.
633+ break ;
634+ } else if tx. auth_info . fee . gas > in_msgs_gas_limit {
635+ // The transaction is too large to execute under our
636+ // current parameters, so skip over it.
637+ warn ! ( ctx. get_logger( "dispatcher" ) , "incoming message transaction fee gas exceeds round gas limit" ;
638+ "id" => in_msg. id,
639+ "tx_gas" => tx. auth_info. fee. gas,
640+ "in_msgs_gas_limit" => in_msgs_gas_limit,
641+ ) ;
642+ // Actually don't skip the message entirely, just don't
643+ // execute the transaction.
644+ None
645+ } else if tx. auth_info . fee . gas > remaining_gas {
646+ // The transaction is too large to execute in this round,
647+ // so leave it for the next round and stop.
648+ break ;
649+ } else {
650+ Some ( tx)
651+ }
652+ }
653+ Err ( err) => {
654+ warn ! ( ctx. get_logger( "dispatcher" ) , "incoming message transaction malformed" ;
655+ "id" => in_msg. id,
656+ "err" => ?err,
657+ ) ;
658+ None
659+ }
660+ }
661+ }
662+ None => None ,
663+ } ;
664+
625665 Self :: execute_in_msg ( ctx, in_msg, & data, & tx) ?;
666+ in_msgs_processed += 1 ;
626667 }
627- ctx. set_in_msgs_processed ( in_msgs . len ( ) ) ;
668+ ctx. set_in_msgs_processed ( in_msgs_processed ) ;
628669
629670 // Schedule and execute the batch.
630671 //
0 commit comments