Skip to content

Commit a03c2ed

Browse files
committed
dispatcher: watch incoming messages gas
1 parent c3a024e commit a03c2ed

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

runtime-sdk/src/dispatcher.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)