From 9ad128f04e1b605ff8e45d51d6e6300c18c9fa14 Mon Sep 17 00:00:00 2001 From: lilyjjo Date: Wed, 3 Apr 2024 08:48:20 -0400 Subject: [PATCH] fix(sequencer): respect max_tx_bytes when preparing proposals --- crates/astria-sequencer/src/app.rs | 35 +++++++++++++++++-- .../src/proposal/commitment.rs | 19 ++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/crates/astria-sequencer/src/app.rs b/crates/astria-sequencer/src/app.rs index 4f46131ef3..c348d82a91 100644 --- a/crates/astria-sequencer/src/app.rs +++ b/crates/astria-sequencer/src/app.rs @@ -75,6 +75,7 @@ use crate::{ ibc::component::IbcComponent, proposal::commitment::{ generate_rollup_datas_commitment, + Example, GeneratedCommitments, }, state_ext::{ @@ -237,7 +238,17 @@ impl App { self.is_proposer = true; self.update_state_for_new_round(&storage); - let (signed_txs, txs_to_include) = self.execute_block_data(prepare_proposal.txs).await; + let remaining_tx_bytes = prepare_proposal + .max_tx_bytes + .checked_sub( + i64::try_from(GeneratedCommitments::example().commitments_size()) + .expect("failed to turn commitment's usize into i64"), + ) + .expect("commitment size should not be larger than the prepare proposal's max bytes"); + + let (signed_txs, txs_to_include) = self + .execute_block_data(prepare_proposal.txs, Some(remaining_tx_bytes)) + .await; let deposits = self .state @@ -295,7 +306,7 @@ impl App { let expected_txs_len = txs.len(); - let (signed_txs, txs_to_include) = self.execute_block_data(txs.into()).await; + let (signed_txs, txs_to_include) = self.execute_block_data(txs.into(), None).await; // all txs in the proposal should be deserializable and executable // if any txs were not deserializeable or executable, they would not have been @@ -344,6 +355,7 @@ impl App { async fn execute_block_data( &mut self, txs: Vec, + mut remaining_cometbft_bytes: Option, ) -> (Vec, Vec) { let mut signed_txs = Vec::with_capacity(txs.len()); let mut validated_txs = Vec::with_capacity(txs.len()); @@ -387,9 +399,28 @@ impl App { continue; } + // Don't include tx if it would make the cometbft block too large + if let Some(remaining) = remaining_cometbft_bytes { + if remaining < i64::try_from(tx.len()).expect("failed to turn tx length into i64") { + debug!( + transaction_hash = %telemetry::display::hex(&tx_hash), + remaining_cometbft_bytes = remaining, + tx_len = tx.len(), + "excluding transaction: max cometbft data limit reached" + ); + excluded_tx_count += 1; + continue; + } + } + // store transaction execution result, indexed by tx hash match self.deliver_tx(signed_tx.clone()).await { Ok(events) => { + if let Some(mut remaining) = remaining_cometbft_bytes { + remaining -= + i64::try_from(tx.len()).expect("failed to turn tx length into i64"); + remaining_cometbft_bytes = Some(remaining); + } self.execution_result.insert(tx_hash.into(), Ok(events)); signed_txs.push(signed_tx); validated_txs.push(tx); diff --git a/crates/astria-sequencer/src/proposal/commitment.rs b/crates/astria-sequencer/src/proposal/commitment.rs index 931188e295..d8747cdea1 100644 --- a/crates/astria-sequencer/src/proposal/commitment.rs +++ b/crates/astria-sequencer/src/proposal/commitment.rs @@ -30,6 +30,25 @@ impl GeneratedCommitments { } } +pub(crate) trait Example { + fn example() -> Self; + fn commitments_size(self) -> usize; +} + +impl Example for GeneratedCommitments { + fn example() -> Self { + GeneratedCommitments { + rollup_datas_root: [0; 32], + rollup_ids_root: [0; 32], + } + } + + // used for accounting for commitments' data size in cometbft block + fn commitments_size(self) -> usize { + self.rollup_datas_root.len() + self.rollup_ids_root.len() + } +} + /// Called when we receive a `PrepareProposal` or `ProcessProposal` consensus message. /// /// In the case of `PrepareProposal`, we use this function to generate the `rollup_datas_commitment`