diff --git a/crates/astria-conductor/src/celestia/block_verifier.rs b/crates/astria-conductor/src/celestia/block_verifier.rs index 7d5d3be673..565f284320 100644 --- a/crates/astria-conductor/src/celestia/block_verifier.rs +++ b/crates/astria-conductor/src/celestia/block_verifier.rs @@ -360,7 +360,7 @@ mod test { #[tokio::test] async fn validate_sequencer_blob_with_chain_ids() { - let test_tx = b"test-tx".to_vec(); + let test_tx = Bytes::from_static(b"test-tx"); let rollup_id = RollupId::from_unhashed_bytes(b"test-chain"); let grouped_txs = BTreeMap::from([(rollup_id, vec![test_tx.clone()])]); let rollup_transactions_tree = diff --git a/crates/astria-conductor/src/celestia/mod.rs b/crates/astria-conductor/src/celestia/mod.rs index 96e57eea20..7c209802e6 100644 --- a/crates/astria-conductor/src/celestia/mod.rs +++ b/crates/astria-conductor/src/celestia/mod.rs @@ -13,6 +13,7 @@ use astria_eyre::eyre::{ bail, WrapErr as _, }; +use bytes::Bytes; use celestia_types::nmt::Namespace; use futures::{ future::{ @@ -101,7 +102,7 @@ pub(crate) struct ReconstructedBlock { pub(crate) celestia_height: u64, pub(crate) block_hash: [u8; 32], pub(crate) header: SequencerBlockHeader, - pub(crate) transactions: Vec>, + pub(crate) transactions: Vec, } impl ReconstructedBlock { diff --git a/crates/astria-conductor/src/celestia/reconstruct.rs b/crates/astria-conductor/src/celestia/reconstruct.rs index a9dae3b381..9deae218e1 100644 --- a/crates/astria-conductor/src/celestia/reconstruct.rs +++ b/crates/astria-conductor/src/celestia/reconstruct.rs @@ -7,7 +7,6 @@ use astria_core::{ SubmittedRollupData, }, }; -use bytes::Bytes; use telemetry::display::base64; use tracing::{ info, @@ -57,12 +56,7 @@ pub(super) fn reconstruct_blocks_from_verified_blobs( celestia_height, block_hash: header_blob.block_hash(), header: header_blob.into_unchecked().header, - transactions: rollup - .into_unchecked() - .transactions - .into_iter() - .map(Bytes::into) - .collect(), + transactions: rollup.into_unchecked().transactions, }); } else { let reason = if header_blobs.contains_key(&rollup.sequencer_block_hash()) { diff --git a/crates/astria-conductor/src/executor/client.rs b/crates/astria-conductor/src/executor/client.rs index 8704ee0767..7e694c96b4 100644 --- a/crates/astria-conductor/src/executor/client.rs +++ b/crates/astria-conductor/src/executor/client.rs @@ -117,14 +117,14 @@ impl Client { pub(super) async fn execute_block_with_retry( &mut self, prev_block_hash: Bytes, - transactions: Vec>, + transactions: Vec, timestamp: Timestamp, ) -> eyre::Result { use prost::Message; let transactions = transactions .into_iter() - .map(|tx| RollupData::decode(tx.as_slice())) + .map(|tx| RollupData::decode(tx.as_ref())) .collect::>() .wrap_err("failed to decode tx bytes as RollupData")?; diff --git a/crates/astria-conductor/src/executor/mod.rs b/crates/astria-conductor/src/executor/mod.rs index 2d55ce1fd7..2ef56213d9 100644 --- a/crates/astria-conductor/src/executor/mod.rs +++ b/crates/astria-conductor/src/executor/mod.rs @@ -686,7 +686,7 @@ struct ExecutableBlock { hash: [u8; 32], height: SequencerHeight, timestamp: pbjson_types::Timestamp, - transactions: Vec>, + transactions: Vec, } impl ExecutableBlock { diff --git a/crates/astria-conductor/src/sequencer/snapshots/astria_conductor__sequencer__reporting__tests__snapshots.snap b/crates/astria-conductor/src/sequencer/snapshots/astria_conductor__sequencer__reporting__tests__snapshots.snap index 0d290640c8..d41959e219 100644 --- a/crates/astria-conductor/src/sequencer/snapshots/astria_conductor__sequencer__reporting__tests__snapshots.snap +++ b/crates/astria-conductor/src/sequencer/snapshots/astria_conductor__sequencer__reporting__tests__snapshots.snap @@ -3,6 +3,6 @@ source: crates/astria-conductor/src/sequencer/reporting.rs expression: ReportRollups(block.rollup_transactions()) --- { - "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio=": 2, - "RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUU=": 1 + "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKio=": 3, + "RUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUU=": 2 } diff --git a/crates/astria-core/src/primitive/v1/mod.rs b/crates/astria-core/src/primitive/v1/mod.rs index 5534ca59f6..788100e3e9 100644 --- a/crates/astria-core/src/primitive/v1/mod.rs +++ b/crates/astria-core/src/primitive/v1/mod.rs @@ -493,7 +493,7 @@ impl std::fmt::Display for Address { pub fn derive_merkle_tree_from_rollup_txs<'a, T, U>(rollup_ids_to_txs: T) -> merkle::Tree where T: IntoIterator, - U: AsRef<[Vec]> + 'a + ?Sized, + U: AsRef<[Bytes]> + 'a + ?Sized, { let mut tree = merkle::Tree::new(); for (rollup_id, txs) in rollup_ids_to_txs { diff --git a/crates/astria-core/src/protocol/bridge/v1alpha1/mod.rs b/crates/astria-core/src/protocol/bridge/v1alpha1/mod.rs index af9dabc5c6..a05546d3be 100644 --- a/crates/astria-core/src/protocol/bridge/v1alpha1/mod.rs +++ b/crates/astria-core/src/protocol/bridge/v1alpha1/mod.rs @@ -1,7 +1,4 @@ -use bytes::{ - Buf as _, - Bytes, -}; +use bytes::Bytes; use super::raw; use crate::primitive::v1::{ @@ -27,21 +24,19 @@ impl BridgeAccountLastTxHashResponse { /// /// - if the transaction hash is not 32 bytes pub fn try_from_raw( - raw: raw::BridgeAccountLastTxHashResponse, + raw: &raw::BridgeAccountLastTxHashResponse, ) -> Result { Ok(Self { height: raw.height, tx_hash: raw .tx_hash .clone() - .map(|bytes| bytes.chunk().try_into()) - .transpose() - .map_err(|_| { - let Some(tx_hash) = raw.tx_hash else { - return BridgeAccountLastTxHashResponseError::missing_tx_hash(); - }; - BridgeAccountLastTxHashResponseError::invalid_tx_hash(tx_hash.len()) - })?, + .map(|bytes| { + <[u8; 32]>::try_from(bytes.as_ref()).map_err(|_| { + BridgeAccountLastTxHashResponseError::invalid_tx_hash(bytes.len()) + }) + }) + .transpose()?, }) } @@ -64,7 +59,7 @@ impl raw::BridgeAccountLastTxHashResponse { pub fn try_into_native( self, ) -> Result { - BridgeAccountLastTxHashResponse::try_from_raw(self) + BridgeAccountLastTxHashResponse::try_from_raw(&self) } #[must_use] @@ -86,19 +81,12 @@ impl BridgeAccountLastTxHashResponseError { bytes, )) } - - #[must_use] - pub fn missing_tx_hash() -> Self { - Self(BridgeAccountLastTxHashResponseErrorKind::MissingTxHash()) - } } #[derive(Debug, thiserror::Error)] enum BridgeAccountLastTxHashResponseErrorKind { #[error("invalid tx hash; must be 32 bytes, got {0} bytes")] InvalidTxHash(usize), - #[error("tx hash was not set")] - MissingTxHash(), } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/astria-core/src/protocol/mod.rs b/crates/astria-core/src/protocol/mod.rs index 61b3d5bd8c..c706081eba 100644 --- a/crates/astria-core/src/protocol/mod.rs +++ b/crates/astria-core/src/protocol/mod.rs @@ -1,3 +1,4 @@ +use bytes::Bytes; use indexmap::IndexMap; use transaction::v1alpha1::SignedTransaction; @@ -19,7 +20,7 @@ pub mod test_utils; /// TODO: This can all be done in-place once is stabilized. pub fn group_sequence_actions_in_signed_transaction_transactions_by_rollup_id( signed_transactions: &[SignedTransaction], -) -> IndexMap>> { +) -> IndexMap> { use prost::Message as _; use crate::sequencerblock::v1alpha1::block::RollupData; @@ -30,9 +31,10 @@ pub fn group_sequence_actions_in_signed_transaction_transactions_by_rollup_id( .flat_map(SignedTransaction::actions) { if let Some(action) = action.as_sequence() { - let txs_for_rollup: &mut Vec> = map.entry(action.rollup_id).or_insert(vec![]); - let rollup_data = RollupData::SequencedData(action.data.to_vec()); - txs_for_rollup.push(rollup_data.into_raw().encode_to_vec()); + let txs_for_rollup: &mut Vec = + map.entry(action.rollup_id).or_insert(vec![Bytes::new()]); + let rollup_data = RollupData::SequencedData(action.data.clone()); + txs_for_rollup.push(rollup_data.into_raw().encode_to_vec().into()); } } map.sort_unstable_keys(); diff --git a/crates/astria-core/src/protocol/test_utils.rs b/crates/astria-core/src/protocol/test_utils.rs index 0874b3c770..aa11f42241 100644 --- a/crates/astria-core/src/protocol/test_utils.rs +++ b/crates/astria-core/src/protocol/test_utils.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; +use bytes::Bytes; use prost::Message as _; use super::{ @@ -132,6 +133,7 @@ impl ConfigureSequencerBlock { RollupData::Deposit(Box::new(deposit)) .into_raw() .encode_to_vec() + .into() })); } rollup_transactions.sort_unstable_keys(); @@ -148,7 +150,10 @@ impl ConfigureSequencerBlock { rollup_ids_root.to_vec(), ]; data.extend(txs.into_iter().map(|tx| tx.into_raw().encode_to_vec())); - + let data = data + .into_iter() + .map(|data| Bytes::copy_from_slice(&data)) + .collect(); SequencerBlock::try_from_block_info_and_data( block_hash, chain_id.try_into().unwrap(), diff --git a/crates/astria-core/src/sequencerblock/v1alpha1/block.rs b/crates/astria-core/src/sequencerblock/v1alpha1/block.rs index f79d4f209f..870229ec58 100644 --- a/crates/astria-core/src/sequencerblock/v1alpha1/block.rs +++ b/crates/astria-core/src/sequencerblock/v1alpha1/block.rs @@ -1,9 +1,6 @@ use std::collections::HashMap; -use bytes::{ - Buf as _, - Bytes, -}; +use bytes::Bytes; use indexmap::IndexMap; use sha2::Sha256; use tendermint::{ @@ -72,7 +69,7 @@ enum RollupTransactionsErrorKind { #[derive(Clone, Debug, PartialEq)] pub struct RollupTransactionsParts { pub rollup_id: RollupId, - pub transactions: Vec>, + pub transactions: Vec, pub proof: merkle::Proof, } @@ -82,7 +79,7 @@ pub struct RollupTransactions { /// The 32 bytes identifying a rollup. Usually the sha256 hash of a plain rollup name. rollup_id: RollupId, /// The block data for this rollup in the form of encoded [`RollupData`]. - transactions: Vec>, + transactions: Vec, /// Proof that this set of transactions belongs in the rollup datas merkle tree proof: merkle::Proof, } @@ -96,7 +93,7 @@ impl RollupTransactions { /// Returns the block data for this rollup. #[must_use] - pub fn transactions(&self) -> &[Vec] { + pub fn transactions(&self) -> &[Bytes] { &self.transactions } @@ -202,7 +199,7 @@ impl SequencerBlockError { Self(SequencerBlockErrorKind::NoRollupTransactionsRoot) } - fn incorrect_rollup_transactions_root_length(len: usize) -> Self { + fn incorrect_rollup_tx_root_length(len: usize) -> Self { Self(SequencerBlockErrorKind::IncorrectRollupTransactionsRootLength(len)) } @@ -454,13 +451,13 @@ impl SequencerBlockHeader { .map_err(SequencerBlockHeaderError::time)?; let rollup_transactions_root = - rollup_transactions_root.chunk().try_into().map_err(|_| { + rollup_transactions_root.as_ref().try_into().map_err(|_| { SequencerBlockHeaderError::incorrect_rollup_transactions_root_length( rollup_transactions_root.len(), ) })?; - let data_hash = data_hash.chunk().try_into().map_err(|_| { + let data_hash = data_hash.as_ref().try_into().map_err(|_| { SequencerBlockHeaderError::incorrect_rollup_transactions_root_length(data_hash.len()) })?; @@ -712,7 +709,7 @@ impl SequencerBlock { height: tendermint::block::Height, time: Time, proposer_address: account::Id, - data: Vec>, + data: Vec, deposits: HashMap>, ) -> Result { use prost::Message as _; @@ -724,16 +721,16 @@ impl SequencerBlock { let rollup_transactions_root: [u8; 32] = data_list .next() .ok_or(SequencerBlockError::no_rollup_transactions_root())? + .as_ref() .try_into() - .map_err(|e: Vec<_>| { - SequencerBlockError::incorrect_rollup_transactions_root_length(e.len()) - })?; + .map_err(|_| SequencerBlockError::incorrect_rollup_tx_root_length(data_list.len()))?; let rollup_ids_root: [u8; 32] = data_list .next() .ok_or(SequencerBlockError::no_rollup_ids_root())? + .as_ref() .try_into() - .map_err(|e: Vec<_>| SequencerBlockError::incorrect_rollup_ids_root_length(e.len()))?; + .map_err(|_| SequencerBlockError::incorrect_rollup_ids_root_length(data_list.len()))?; let mut rollup_datas = IndexMap::new(); for elem in data_list { @@ -752,10 +749,11 @@ impl SequencerBlock { fee_asset: _, }) = action { - let elem = rollup_datas.entry(rollup_id).or_insert(vec![]); - let data = RollupData::SequencedData(data.to_vec()) + let elem = rollup_datas.entry(rollup_id).or_insert(vec![Bytes::new()]); + let data = RollupData::SequencedData(data) .into_raw() - .encode_to_vec(); + .encode_to_vec() + .into(); elem.push(data); } } @@ -768,6 +766,7 @@ impl SequencerBlock { RollupData::Deposit(Box::new(deposit)) .into_raw() .encode_to_vec() + .into() })); } @@ -854,7 +853,7 @@ impl SequencerBlock { } = raw; let block_hash = block_hash - .chunk() + .as_ref() .try_into() .map_err(|_| SequencerBlockError::invalid_block_hash(block_hash.len()))?; @@ -1076,7 +1075,7 @@ impl FilteredSequencerBlock { } = raw; let block_hash = block_hash - .chunk() + .as_ref() .try_into() .map_err(|_| FilteredSequencerBlockError::invalid_block_hash(block_hash.len()))?; @@ -1439,7 +1438,7 @@ enum DepositErrorKind { /// and must decode it accordingly. #[derive(Debug, Clone, PartialEq)] pub enum RollupData { - SequencedData(Vec), + SequencedData(Bytes), Deposit(Box), } @@ -1448,7 +1447,7 @@ impl RollupData { pub fn into_raw(self) -> raw::RollupData { match self { Self::SequencedData(data) => raw::RollupData { - value: Some(raw::rollup_data::Value::SequencedData(data.into())), + value: Some(raw::rollup_data::Value::SequencedData(data)), }, Self::Deposit(deposit) => raw::RollupData { value: Some(raw::rollup_data::Value::Deposit(deposit.into_raw())), @@ -1467,9 +1466,7 @@ impl RollupData { value, } = raw; match value { - Some(raw::rollup_data::Value::SequencedData(data)) => { - Ok(Self::SequencedData(data.to_vec())) - } + Some(raw::rollup_data::Value::SequencedData(data)) => Ok(Self::SequencedData(data)), Some(raw::rollup_data::Value::Deposit(deposit)) => Deposit::try_from_raw(deposit) .map(Box::new) .map(Self::Deposit) diff --git a/crates/astria-core/src/sequencerblock/v1alpha1/celestia.rs b/crates/astria-core/src/sequencerblock/v1alpha1/celestia.rs index 6768a871be..b3a0c72f07 100644 --- a/crates/astria-core/src/sequencerblock/v1alpha1/celestia.rs +++ b/crates/astria-core/src/sequencerblock/v1alpha1/celestia.rs @@ -466,7 +466,7 @@ impl UncheckedSubmittedMetadata { }?; let block_hash = block_hash - .chunk() + .as_ref() .try_into() .map_err(|_| SubmittedMetadataError::block_hash(block_hash.len()))?; diff --git a/crates/astria-sequencer/src/app/tests_app.rs b/crates/astria-sequencer/src/app/tests_app.rs index 2e220c5204..ee5add5e5f 100644 --- a/crates/astria-sequencer/src/app/tests_app.rs +++ b/crates/astria-sequencer/src/app/tests_app.rs @@ -358,7 +358,7 @@ async fn app_create_sequencer_block_with_sequenced_data_and_deposits() { for (_, rollup_data) in block.rollup_transactions() { for tx in rollup_data.transactions() { let rollup_data = - RollupData::try_from_raw(RawRollupData::decode(tx.as_slice()).unwrap()).unwrap(); + RollupData::try_from_raw(RawRollupData::decode(tx.as_ref()).unwrap()).unwrap(); if let RollupData::Deposit(deposit) = rollup_data { deposits.push(deposit); } diff --git a/crates/astria-sequencer/src/proposal/commitment.rs b/crates/astria-sequencer/src/proposal/commitment.rs index 6a48b5c6f4..1f6573eb67 100644 --- a/crates/astria-sequencer/src/proposal/commitment.rs +++ b/crates/astria-sequencer/src/proposal/commitment.rs @@ -71,6 +71,7 @@ pub(crate) fn generate_rollup_datas_commitment( RollupData::Deposit(Box::new(deposit)) .into_raw() .encode_to_vec() + .into() })); }