Skip to content

Commit 8471b16

Browse files
authored
feat(raiko): enable blob slice to support multi-blocks in single blob (#390)
* enable blob slice to support multi-blocks in single blob * fix compile * refine tx_list slice * code clean
1 parent 3cb6651 commit 8471b16

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

lib/src/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<DB: Database<Error = ProviderError> + DatabaseCommit + OptimisticDatabase>
131131
let mut block = self.input.block.clone();
132132
block.body = generate_transactions(
133133
&self.input.chain_spec,
134-
self.input.taiko.block_proposed.blob_used(),
134+
&self.input.taiko.block_proposed,
135135
&self.input.taiko.tx_data,
136136
&self.input.taiko.anchor_tx,
137137
);

lib/src/input.rs

+10
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ impl BlockProposedFork {
139139
_ => ProtocolBaseFeeConfig::default(),
140140
}
141141
}
142+
143+
pub fn blob_tx_slice_param(&self) -> Option<(usize, usize)> {
144+
match self {
145+
BlockProposedFork::Ontake(block) => Some((
146+
block.meta.blobTxListOffset as usize,
147+
block.meta.blobTxListLength as usize,
148+
)),
149+
_ => None,
150+
}
151+
}
142152
}
143153

144154
#[serde_as]

lib/src/utils.rs

+32-12
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use alloy_rlp::Decodable;
44
use anyhow::Result;
55
use libflate::zlib::{Decoder as zlibDecoder, Encoder as zlibEncoder};
66
use reth_primitives::TransactionSigned;
7-
use tracing::warn;
7+
use tracing::{error, warn};
88

99
use crate::consts::{ChainSpec, Network};
10+
use crate::input::BlockProposedFork;
1011
#[cfg(not(feature = "std"))]
1112
use crate::no_std::*;
1213

@@ -24,25 +25,41 @@ fn validate_calldata_tx_list(tx_list: &[u8]) -> bool {
2425
tx_list.len() <= CALL_DATA_CAPACITY
2526
}
2627

27-
fn get_tx_list(chain_spec: &ChainSpec, is_blob_data: bool, tx_list: &[u8]) -> Vec<u8> {
28+
fn unzip_tx_list_from_data_buf(
29+
chain_spec: &ChainSpec,
30+
is_blob_data: bool,
31+
blob_slice_param: Option<(usize, usize)>,
32+
tx_list_data_buf: &[u8],
33+
) -> Vec<u8> {
2834
#[allow(clippy::collapsible_else_if)]
2935
if chain_spec.is_taiko() {
3036
// taiko has some limitations to be aligned with taiko-client
3137
if is_blob_data {
32-
let compressed_tx_list = decode_blob_data(tx_list);
33-
zlib_decompress_data(&compressed_tx_list).unwrap_or_default()
38+
let compressed_tx_list = decode_blob_data(tx_list_data_buf);
39+
assert!(compressed_tx_list.len() <= MAX_BLOB_DATA_SIZE);
40+
let slice_compressed_tx_list = if let Some((offset, length)) = blob_slice_param {
41+
if offset + length > compressed_tx_list.len() {
42+
error!("blob_slice_param ({offset},{length}) out of range, use empty tx_list");
43+
vec![]
44+
} else {
45+
compressed_tx_list[offset..offset + length].to_vec()
46+
}
47+
} else {
48+
compressed_tx_list.to_vec()
49+
};
50+
zlib_decompress_data(&slice_compressed_tx_list).unwrap_or_default()
3451
} else {
3552
if Network::TaikoA7.to_string() == chain_spec.network() {
36-
let tx_list = zlib_decompress_data(tx_list).unwrap_or_default();
53+
let tx_list = zlib_decompress_data(tx_list_data_buf).unwrap_or_default();
3754
if validate_calldata_tx_list(&tx_list) {
3855
tx_list
3956
} else {
4057
warn!("validate_calldata_tx_list failed, use empty tx_list");
4158
vec![]
4259
}
4360
} else {
44-
if validate_calldata_tx_list(tx_list) {
45-
zlib_decompress_data(tx_list).unwrap_or_default()
61+
if validate_calldata_tx_list(tx_list_data_buf) {
62+
zlib_decompress_data(tx_list_data_buf).unwrap_or_default()
4663
} else {
4764
warn!("validate_calldata_tx_list failed, use empty tx_list");
4865
vec![]
@@ -51,20 +68,23 @@ fn get_tx_list(chain_spec: &ChainSpec, is_blob_data: bool, tx_list: &[u8]) -> Ve
5168
}
5269
} else {
5370
// no limitation on non-taiko chains
54-
zlib_decompress_data(tx_list).unwrap_or_default()
71+
zlib_decompress_data(tx_list_data_buf).unwrap_or_default()
5572
}
5673
}
5774

5875
pub fn generate_transactions(
5976
chain_spec: &ChainSpec,
60-
is_blob_data: bool,
61-
tx_list: &[u8],
77+
block_proposal: &BlockProposedFork,
78+
tx_list_data_buf: &[u8],
6279
anchor_tx: &Option<TransactionSigned>,
6380
) -> Vec<TransactionSigned> {
81+
let is_blob_data = block_proposal.blob_used();
82+
let blob_slice_param = block_proposal.blob_tx_slice_param();
6483
// Decode the tx list from the raw data posted onchain
65-
let tx_list = get_tx_list(chain_spec, is_blob_data, tx_list);
84+
let unzip_tx_list_buf =
85+
unzip_tx_list_from_data_buf(chain_spec, is_blob_data, blob_slice_param, tx_list_data_buf);
6686
// Decode the transactions from the tx list
67-
let mut transactions = decode_transactions(&tx_list);
87+
let mut transactions = decode_transactions(&unzip_tx_list_buf);
6888
// Add the anchor tx at the start of the list
6989
if let Some(anchor_tx) = anchor_tx {
7090
transactions.insert(0, anchor_tx.clone());

0 commit comments

Comments
 (0)